Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jest-reporters): pass reporterContext to custom reporter constructors as third argument #12657

Merged
merged 17 commits into from Apr 12, 2022

Conversation

mrazauskas
Copy link
Contributor

Summary

Promise, I was refactoring jest-worker, but noticed strange details in types of jest-reporters. Just could not leave it.

What if constructors of custom reporters alongside with their config options would also receive reporterContext?

Similarly default reporters all could receive unified reporterContext object. Currently context is passed to reporters, but is typed somewhat differently. That feels redundant.

Also this change would allow writing custom reporters similar to coverage or notify. Why not? (;

Test plan

Green CI.


```json
{
"reporters": [
"default",
["<rootDir>/my-custom-reporter.js", {"banana": "yes", "pineapple": "no"}]
["jest-junit", {"outputName": "junit-report.xml", "suiteName": "some-name"}]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to convince Prettier to keep this as separate line.

Comment on lines 426 to 410
return {options: this._options, path: reporter};
return {options: {}, path: reporter};
Copy link
Contributor Author

@mrazauskas mrazauskas Apr 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startRun() was passed here. Perhaps for notify reporter?.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.. Possibly this branch is never called, because reporters are already normalised:

https://github.com/facebook/jest/blob/62b4bd701db378b38d360094f55fbd9ba64ca937/packages/jest-config/src/normalize.ts#L415-L429

Copy link
Member

@SimenB SimenB Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove it, probably for legacy reasons

@@ -49,6 +47,7 @@
"@types/istanbul-lib-source-maps": "^4.0.0",
"@types/istanbul-reports": "^3.0.0",
"@types/node-notifier": "^8.0.0",
"jest-resolve": "^28.0.0-alpha.8",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for tests only.

packages/jest-reporters/src/index.ts Outdated Show resolved Hide resolved
Comment on lines -49 to -57
export type OnTestStart = (test: Test) => Promise<void>;
export type OnTestFailure = (
test: Test,
error: SerializableError,
) => Promise<unknown>;
export type OnTestSuccess = (
test: Test,
result: TestResult,
) => Promise<unknown>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used and not public exports.

Comment on lines -94 to -101
export type TestRunnerOptions = {
serial: boolean;
};

export type TestRunData = Array<{
context: Context;
matches: {allTests: number; tests: Array<Test>; total: number};
}>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not used.

export type {
AggregatedResult,
SnapshotSummary,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Types for all public classes and utilities are exported. SnapshotSummary type is only used by getSnapshotSummary() util. This one is not exposed, but perhaps it should be exported together with getSnapshotStatus()? Looks helpful.

@mrazauskas mrazauskas changed the title feat(jest-reporters)!: pass reporterContext to custom reporter constructors as third argument feat(jest-reporters): pass reporterContext to custom reporter constructors as third argument Apr 10, 2022
docs/Configuration.md Outdated Show resolved Hide resolved
CHANGELOG.md Show resolved Hide resolved
docs/Configuration.md Outdated Show resolved Hide resolved
@mrazauskas
Copy link
Contributor Author

mrazauskas commented Apr 11, 2022

@SimenB Documentation got improved to address your last comments.

User defined reporterOptions were already passed as second argument to reporter constructor. There is no change in jest-config. I was just refactoring docs: first all details about reporters option, last all about how to build a custom reporter. The custom reporter part must have more details. It might be better to move it to separate file, but that will be another PR.

I was thinking if options and context could be combined into one object and passed liked this from test scheduler:

new Reporter(this._globalConfig, {...options, _context: this._context})

Could work, but extra nesting is somewhat clumsy. Alternative:

new Reporter(this._globalConfig, {...options, ...this._context})

Oh, that would be dangerous. Another attempt:

new Reporter(
  this._globalConfig,
  {
    ...options,
    _firstRun: this._context.firstRun,
    _previousSuccess: this._context.previousSuccess,
    // and the rest of context in similar fashion
  }
)

Hm.. That’s alright, but what about separation of concerns? These are not user defined options. Also might not work in long term.

It seemed that this signature would be the most optimal:

constructor(globalConfig, reporterOptions, reporterContext)

Will not break with older reporters. Perhaps reporterContext could be named better? Simply context? We have TestContext around, so I though some prefix is good idea. That’s not breaking, can be changed at any time.

docs/Configuration.md Outdated Show resolved Hide resolved
docs/Configuration.md Outdated Show resolved Hide resolved
Copy link
Member

@SimenB SimenB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay!

} {
if (typeof reporter === 'string') {
return {options: this._options, path: reporter};
return {options: {}, path: reporter};
} else if (Array.isArray(reporter)) {
const [path, options] = reporter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a check that tuple length is 2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we leave this for another PR? Currently this method is called twice, that's nothing significant, but still unnecessary. I have an idea how to rework it, but that's another story (;

@@ -411,7 +411,7 @@ export type GlobalConfig = {
passWithNoTests: boolean;
projects: Array<string>;
replname?: string;
reporters?: Array<string | ReporterConfig>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should type normalized config, right? I have added tests jest-config, which show that reporters are always normalized to a tuple. Having more precise type here, makes it possible to have less logic inside TestScheduler. Last commits are added just to illustrate the solution. Perhaps it would be better to send separate PR? Feel free to revert them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep 👍

Copy link
Member

@SimenB SimenB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great!

@SimenB SimenB merged commit 8167899 into jestjs:main Apr 12, 2022
@mrazauskas mrazauskas deleted the feat-reporterContext branch April 12, 2022 07:25
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants