Open agilgur5 opened 5 years ago
Started working on this because we have tests so code coverage really makes sense to have too. It turns out nyc
does have support for source mapped files, but after a large amount of trial-and-error on the coverage
branch, I couldn't get everything working. I got webpack
partially working, with some incorrect exclusions, and could not get browserify
working correctly 😕 .
There isn't much documentation on source map support for nyc
, especially when not using babel
. Filed an issue at https://github.com/istanbuljs/nyc/issues/1130 to see if this is a bug or if someone could point me in the right direction
Added a coverage-jest
branch as well just to test if jest
runs into the same problems with its built-in coverage reporting, and indeed, yes it does.
browserify.spec.js
actually hits an infinite loop according to jest
(maybe that's why it was just 0s in the nyc
branch coverage
?). The error looks like:
FAIL test/browserify.spec.js
● Test suite failed to run
Infinite cycle detected
at TraversalContext.maybeQueue (node_modules/@babel/traverse/lib/context.js:61:13)
at NodePath._containerInsert (node_modules/@babel/traverse/lib/path/modification.js:83:15)
at NodePath._containerInsertBefore (node_modules/@babel/traverse/lib/path/modification.js:91:15)
at NodePath.insertBefore (node_modules/@babel/traverse/lib/path/modification.js:51:17)
at VisitState.insertCounter (node_modules/istanbul-lib-instrument/dist/visitor.js:183:12)
at VisitState.insertStatementCounter (node_modules/istanbul-lib-instrument/dist/visitor.js:213:10)
at VisitState.coverStatement (node_modules/istanbul-lib-instrument/dist/visitor.js:334:8)
at enter.forEach.e (node_modules/istanbul-lib-instrument/dist/visitor.js:319:9)
at Array.forEach (<anonymous>)
at VisitState.wrappedEntry (node_modules/istanbul-lib-instrument/dist/visitor.js:318:11)
webpack.spec.js
similarly doesn't ignore correctly, but with nyc
it at least ignored more.
First made me think the problem would be in istanbul
core since it occurs in both, but the output is different in both so maybe not? idk, this is probably gonna go unresolved for some time.
I also realized users of this library trying to test their own code are going to run into similar issues with workers etc welp welp 😕 😞
Ok so I spent far far far far too long trying to figure this out and still failed to get it to work correctly... The source map ignore stuff I'm pretty sure is a bug in some part of istanbul
, though there isn't too much docs on the topic of coverage with source maps (or how to ignore, though I looked through some --exclude-after-remap=false
issues, those didn't help)
That being said, I think I narrowed down the issues:
I believe that the no files output with nyc
and ava
and the jest --coverage
hitting an infinite cycle are probably the same issue. This issue is almost certainly caused by istanbul-lib-instrument
/@babel/traverse
trying to parse some ammo
code and failing spectacularly. When I instrument the code myself and ignore ammo
, like I did with the cypress-coverage
branch, it stops having this issue and runs fine.
Depending on where I use it, it either hits the infinite cycle errors, takes long but passes with no coverage info, or starts getting gc errors and eventually aborts itself.
While I think jest should handle custom instrumentation as well to handle for these types of issues, the browserify output was also giving lots of issues in general that did not happen with the webpack output (like browserifying a browserify bundle caused it to use the requires defined externally and try to require actual files instead of the bundled code). It's possible I might be able to add some transform to browserify so it outputs the ammo
code differently / more like webpack so these issues don't happen (it would probably still need source maps though).
Bundling plus istanbul coverage (with or without source maps) seems to have issues and there seems to be no way to ignore some files. Like I can't ignore the webpack bootstrap
or universalModuleDefinition
. Trying to ignore it with like webpack.bundle.js:/webpack
etc just doesn't work.
Trying to ignore, say, test/utils/
inside of the bundle (webpack.bundle.js:/Physijs/test/utils/
) doesn't work either, neither with trying to ignore the bundled "file" nor the source file. It similarly does not work when source maps are included (which basically just change it to say physijs-webpack/test/utils/
in the output instead).
If it's manually instrumented, then ignoring seems to work correctly. But not if it's bundled and source-mapped, only if it's bundled and manually instrumented in the bundle (it also seemed like source-mapping it when it was manually instrumented made no difference to the output)
The cypress-coverage
, once I got it to work with custom instrumentation, didn't show any usage of physijs_worker.js
. I think the worker just wasn't instrumented or something (I also got coverage results saying the browserify-worker-stub
exported function was never run), so it doesn't appear in the coverage report. physijs_worker.js
probably appeared when using jsdom-worker
because the worker is just run in the same thread vs. Electron and Cypress run a real Web Worker.
I'm not really sure how to instrument and run the worker (this may also need changes to @cypress/code-coverage
potentially) so that it shows the worker coverage, but even if we figured that out, we might still run into the other 2 issues (although I seemed to be able to successfully ignore the physijs
directory once I actually got all the custom instrumentation nyc
config to work right)
Now that #5 adds a test harness, runner, and some tests, it should be simple to just add some code coverage. It'll have to be customized a bit to ignore mostly vendored code, i.e.
physi.js
,physijs_worker.js
, andammo.js
(though there's not much code left after that 😅 ). Here's how to exclude/include withnyc
.I just started looking into it and realized a pretty big problem -- the tests import the bundled code, not the source code, so without some likely quite hacky source mapping, it's probably not possible to actually get coverage numbers for source code. But the non-vendored code basically doesn't branch and is quite tiny, so nbd either way in all honesty.