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: add coverage support #13

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

SimenB
Copy link
Contributor

@SimenB SimenB commented Apr 6, 2022

Note that this doesn't really work - the commented out filter needs to be there in some way. I think it's ready

However, copying this over into prettier seems to work fine.

image

Fixes #6.

src/index.js Outdated
@@ -23,6 +33,36 @@ export default class LightRunner {
});
}

#filterCoverage(result, projectConfig) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

doing it here to have access to this.#config

Comment on lines +53 to +70
v8Coverage: result.v8Coverage
.filter(res => res.url.startsWith("file://"))
.map(res => ({ ...res, url: fileURLToPath(res.url) }))
.filter(
({ url }) =>
// TODO: will this work on windows? It might be better if `shouldInstrument` deals with it anyways
url.startsWith(projectConfig.rootDir) &&
shouldInstrument(url, coverageOptions, projectConfig)
)
.map(result => ({ result })),
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SimenB
Copy link
Contributor Author

SimenB commented Apr 6, 2022

@nicolo-ribaudo I have zero attachment to this particular approach, feel free to slice and dice it as needed 🙂 it seems to work fine, at least

@fisker
Copy link
Contributor

fisker commented Apr 6, 2022

I'm not near my laptop, will test later. Good job!

@nicolo-ribaudo
Copy link
Owner

Thanks! I will try reviewing this later today. Hopefully then we'll be able to move Babel from istanbul to v8's coverage tracker 🤞

@SimenB
Copy link
Contributor Author

SimenB commented Apr 6, 2022

It's probably different (counts differently), but afaik there's no bugs with it. Feel free to ping me if there are

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

I got an error, I don't know what is it... https://github.com/prettier/prettier/runs/5861202752?check_suite_focus=true#step:8:14

@fisker

This comment was marked as outdated.

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

wow, what a useless error message 😅

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

image

EDIT: 14.6: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_With_Private_Class_Features#browser_compatibility

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

@fisker pushed again, works on node 12 on my machine

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

All good, got the coverage https://github.com/prettier/prettier/runs/5863566812?check_suite_focus=true#step:6:1139

Thanks again!

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

awesome! it looks like expected coming from c8?

EDIT: https://github.com/prettier/prettier/runs/5863670359 is promising

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

oh, haha

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

Right, seems to be missing coverage of the CLI. You probably spawn it instead of executing from within a test? How is that on main?

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

Our next branch not running CLI test, remember this prettier/prettier#12271 ?
The 96.5% from c8 also not including CLI test.

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

Aha! 😀 And the light runner doesn't solve the issue?

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

The CLI test need features from Jest that this runner don't support 😄

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

We are using different runners, only format test use this runner https://github.com/prettier/prettier/blob/001f8fb086eefb73abefa46eba20370d5f0e84f0/jest-format-test.config.mjs#L5

@fisker
Copy link
Contributor

fisker commented Apr 7, 2022

This is not important, but just a question, why this collectCoverage makes Jest much slower than running with c8?

@SimenB
Copy link
Contributor Author

SimenB commented Apr 7, 2022

I'm guessing because c8 only hooks up the inspector once instead of per test

src/index.js Outdated
const { collectCoverage, coverageProvider } = this.#config;

if (collectCoverage && coverageProvider !== "v8") {
throw new Error("Coverage needs v8 coverage provider");
Copy link
Contributor Author

@SimenB SimenB Apr 7, 2022

Choose a reason for hiding this comment

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

it might be better to just log a warning instead of throwing, i.e. in the case where multiple projects are used

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer either throw an error, or ignore settings, just use v8.

Copy link
Contributor

Choose a reason for hiding this comment

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

People only care where is my coverage report? Who care where is it from.

Copy link
Owner

Choose a reason for hiding this comment

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

It's ok with the error. If someone uses a different provider and decides to use jest-light-runner, it's better to notify them loudly.

@nicolo-ribaudo
Copy link
Owner

It looks like this breaks Babel's coverage collection, making it go down from ~90% to 0%. I just added coverageProvider: "v8" to https://github.com/babel/babel/blob/main/jest.config.js and run make test-ci-coverage.

@nicolo-ribaudo
Copy link
Owner

6dfa6f9 is the minimum to "unbreak" Babel's tests. Feel free to revert it if you know what is the root cause / proper fix 😅

@SimenB
Copy link
Contributor Author

SimenB commented Apr 8, 2022

@nicolo-ribaudo seems fine 🙂 But coverage for the babel repo is broken using v8 coverage? sounds like a bug I need to fix 😅

@nicolo-ribaudo
Copy link
Owner

Could it be because we test the compiled files, but want coverage in the original sources?

@SimenB
Copy link
Contributor Author

SimenB commented Apr 8, 2022

as long as there's a sourcemap that shouldn't be an issue. Jest has some custom mapping, maybe something like that is needed? https://github.com/facebook/jest/blob/a5f1ef43981b7426d61bcd7cbc59a79f548c075a/scripts/mapCoverage.mjs

@fisker
Copy link
Contributor

fisker commented Apr 8, 2022

But Prettier use the source directly, the coverage still lower.

@SimenB
Copy link
Contributor Author

SimenB commented Apr 8, 2022

Some smaller reproduction than prettier or babel would be nice to investigate 🙂 I think this PR can still land in the meantime.

One interesting check would be to check coverage using v8 provider with the default jest runner and if it differs from the one from the light runner

@psychobolt
Copy link

I have simple tests in my repo. You can check it out: psychobolt/yeoman-generator-boilerplate#20

@SimenB
Copy link
Contributor Author

SimenB commented Sep 10, 2022

Rebased this FWIW. I haven't had the time to dig into why it's different

@liuxingbaoyu
Copy link
Contributor

c8 says 96.5% prettier/prettier/runs/5850917095?check_suite_focus=true#step:6:1767 this one says 72.4% prettier/prettier/runs/5863566812?check_suite_focus=true#step:6:1142

I have a possibly related issue, when I reset globalThis.__coverage__ before each test run, babel's coverage drops by 30%.
globalThis.__coverage__ = undefined
It seems that globalThis.__coverage__ is not being merged properly.

coverage: globalThis.__coverage__,

@liuxingbaoyu
Copy link
Contributor

I debugged in babel.
Just removing shouldInstrument() produces coverage output (although coverage is currently around 10% less), since babel is precompiled and does not use jest-transform.
But this also makes coveragePathIgnorePatterns completely invalid, maybe we can move shouldInstrument() to after restoring the source file path using sourcemap?

I also found a problem.
babel-helper-transform-fixture-test-runner will run the dummy file on the vm, which will cause the jest _getCoverageResult method to throw an exception because the file cannot be read.
https://github.com/babel/babel/blob/53e9057d3022cdf41c2593261b8f5c4a4e26265d/packages/babel-helper-transform-fixture-test-runner/src/index.ts#L99-L107

@SimenB
Copy link
Contributor Author

SimenB commented Sep 20, 2022

That last one sounds like a bug in jest - would you mind opening an issue (in jest)? Reproduction of babel repo is fine

@liuxingbaoyu
Copy link
Contributor

OK, I will do it.

@liuxingbaoyu
Copy link
Contributor

Unfortunately cannot reproduce in jest-runtime because dummy files are not in this._v8CoverageSources.😰
https://github.com/facebook/jest/blob/561907ce5d1e9065311cf585f75b9c5864036193/packages/jest-runtime/src/index.ts#L1181-L1190

@SimenB
Copy link
Contributor Author

SimenB commented Sep 20, 2022

Huh. So it's something in this runner

@liuxingbaoyu
Copy link
Contributor

Yes, it seems to be a compatibility issue.

I just applied some skips manually and now v8 and babel have the same result on my local (windows)!

I'll try to parse the source map next to accomplish this filtering.

@liuxingbaoyu
Copy link
Contributor

liuxingbaoyu commented Sep 20, 2022

I found that I don't seem to have to do anything because jest also doesn't support collectCoverageFrom=="packages/*/src/**/*.{js,cjs,mjs,ts}", I just need to use collectCoverageFrom== "packages/*/lib/**/*.{js,cjs,mjs,ts}" is enough.

@SimenB
Copy link
Contributor Author

SimenB commented Sep 20, 2022

What do you mean with "doesn't support"? Is the pattern not supported? Not respected? Sounds like a bug still, but somewhat hard to nail down 😅

@liuxingbaoyu
Copy link
Contributor

liuxingbaoyu commented Sep 20, 2022

That is, the source code is in ./src, and the compiled file is in ./lib.
collectCoverageFrom must be set to ./lib to work.
I think this is acceptable behavior whether it's a bug or not.

Also I seem to find a real bug, when I enable a different number of coverageReporters, the strange thing is that the coverage shown changes, it seems that some reporters are changing the original coverage data.

Update: It doesn't seem to be related to coverageReporters, but the v8 cause, even if I run it twice, the results will be different, very strange.

@liuxingbaoyu
Copy link
Contributor

liuxingbaoyu commented Sep 21, 2022

It seems to be closer to the real cause.
When I use maxWorkers=2, the result is 80%. When I use maxWorkers=16, the result is 90%.
This might also explain #13 (comment) and #13 (comment)

update: It seems like a better approach at the moment is to use c8, which also supports subprocesses.

@Alx101
Copy link

Alx101 commented Dec 23, 2022

Lifted over these changes into my own fork of jest-light-runner (along with some experiments for global setups before all test-suites, still not working). Since I'm running this on a TS project, i've noticed that the coverage report line numbers seem incorrect, probably it's not converting with the source-map?

I'm using "setupFiles": ["source-map-support/register"] in the jest config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate --coverage support
6 participants