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

ES6 EcmaScript 6 Class coverage is generated for transpiled code #817

Closed
StephanBijzitter opened this issue Mar 21, 2016 · 32 comments
Closed

Comments

@StephanBijzitter
Copy link
Contributor

I am currently re-writing my https://github.com/Skelware/node-file-parser package with ES6, but I'm running into an issue where the test coverage appears to be run on the transpiled code, instead of the source code.

src/NodeFileParser.es6

class NodeFileParser {

    static test() {
        return 'dur';
    }
}

export default NodeFileParser;

spec/NodeFileParser.spec.es6:

jest.unmock('../src/NodeFileParser.es6');

import NodeFileParser from '../src/NodeFileParser.es6';

describe('NodeFileParser', () => {

    describe('#test', () => {

        it('should return "dur"', () => {
            expect(NodeFileParser.test()).toEqual('dur');
        });
    });
});

dist/NodeFileParser.js (generated by Babel):

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var NodeFileParser = function NodeFileParser() {
  _classCallCheck(this, NodeFileParser);
};

exports.default = NodeFileParser;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Ob2RlRmlsZVBhcnNlci5lczYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7SUFBTTs7OztrQkFJUyIsImZpbGUiOiJOb2RlRmlsZVBhcnNlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIE5vZGVGaWxlUGFyc2VyIHtcblxufVxuXG5leHBvcnQgZGVmYXVsdCBOb2RlRmlsZVBhcnNlcjtcbiJdfQ==

package.json (excerpt):

{
  "main": "dist/NodeFileParser.js",
  "scripts": {
    "prepublish": "npm run build",
    "postinstall": "npm run build",
    "build": "babel src --out-dir dist --debug",
    "dev": "jest --verbose --watch",
    "test": "jest --no-cache --bail --verbose"
  },
  "devDependencies": {
    "babel-cli": "^6.6.5",
    "babel-jest": "^9.0.3",
    "babel-polyfill": "^6.7.2",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-stage-0": "^6.5.0",
    "jest-cli": "^0.9.2"
  },
  "jest": {
    "collectCoverage": true,
    "testDirectoryName": "spec",
    "testFileExtensions": [
      "js",
      "es6"
    ]
  },
  "babel": {
    "comments": false,
    "sourceMaps": "inline",
    "presets": [
      "es2015",
      "stage-0"
    ]
  }
}

Console output:

---------------------|----------|----------|----------|----------|----------------|
File                 |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
---------------------|----------|----------|----------|----------|----------------|
 src/                |    84.62 |       50 |    71.43 |      100 |                |
  NodeFileParser.es6 |    84.62 |       50 |    71.43 |      100 |                |
---------------------|----------|----------|----------|----------|----------------|
All files            |    84.62 |       50 |    71.43 |      100 |                |
---------------------|----------|----------|----------|----------|----------------|

Lcov html output:

class NodeFileParser { //1x EIE

    static test() {
        return 'dur'; //1x
    }
}

export default NodeFileParser;

I understand that the ES5 code is different from the ES6 code, and contains some boilerplate when transpiled, but it's really annoying when you're trying to cover all of your code, as you have to scroll through the file in your browser to check for any code that's not covered. I guess it's more accurate like this, but it's annoying.

@DaveMBush
Copy link

Further information on this issue from my own attempts to get this working...

I have a basic demo app that I've put together and I have successfully been able to write test and get code coverage working.

Except for one minor problem.

All of the code that use the class keyword from ES2015 end up emitting code at the top that looks like this:

/*istanbul ignore next*/'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var /*istanbul ignore next*/_react = require('react'); /*istanbul ignore next*/var React = _interopRequireWildcard(_react);

It is a very long line, I'll save you the trouble of reading it.

There are a couple of problems.

First, the /istanbul ignore next/ should be /* istanbul ignore next */ with a space before and after the comment, otherwise istanbul does not properly apply it.

Second, even once you fix that, which I tried doing, there are functions in that string that don't get commented at all with the ignore comment. I'm assuming because the set of functions all get added at once so only one comment gets applied at the beginning.

My configuration for babel, both in package.json and .babelrc looks like this:

"presets": ["react","es2015"],
"comments": true,
"compact": false

I've also tried adding babel-plugin-transform-runtime as

"plugins": ["transform-runtime"]

both before and after the "presets" line but when I do that, I get errors that indicate the auto mocking is unable to read the metadata.

It seems that we need some sort of Babel plugin that adds in the comment for all of the transpiled code.

@DaveMBush
Copy link

I finally came up with a solution which you can read about here http://blog.dmbcllc.com/es2015-code-coverage-and-jest-react-js-unit-testing/

@StephanBijzitter
Copy link
Contributor Author

StephanBijzitter commented May 10, 2016

That's quite ingenious

@DaveMBush
Copy link

I would have submitted a pull request, but I'm not sure this is the BEST way of fixing this issue.

@StephanBijzitter
Copy link
Contributor Author

Well the only thing that's holding me back is the use of transform-runtime

@DaveMBush
Copy link

Why?

@cpojer
Copy link
Member

cpojer commented May 10, 2016

It seems to me like these are things that should be fixed in babel instead of in Jest.

@StephanBijzitter
Copy link
Contributor Author

StephanBijzitter commented May 10, 2016

@DaveMBush It seems I was misinformed about the runtime transforms, as I just read the documentation again and it seems pretty good for my use-case.

I do agree with @cpojer that Babel should handle this better. I'll create an issue there and link to this one for reference. Perhaps babel-jest?

@cpojer
Copy link
Member

cpojer commented May 11, 2016

Also happy to help talk to people on the babel side about this. Both issue seem to be simple fixes in Babel, so it should be easy to get them in.

@DaveMBush
Copy link

I'll help where I can. I'm still wrapping my head around React/Jest so I just didn't have time to try to figure out Babel and Syntax trees enough to build a Babel generic fix. I hope my article gives enough information that someone who understands Babel better can apply a generic enough fix.

@vvo
Copy link
Contributor

vvo commented Jun 28, 2016

Is https://github.com/jmcriffey/babel-istanbul relevant to this discussion?

@vvo
Copy link
Contributor

vvo commented Jun 28, 2016

Also this seems to be very recent and maybe a good addition? https://github.com/istanbuljs/babel-plugin-istanbul

@migueloller
Copy link

migueloller commented Jul 14, 2016

I was having a similar issue where multiple files should've had 100% branch coverage but only had 75%. There was a weird behavior in that if I added an extra new line after my imports it would fix the branch coverage. Changing the es6 import statements to require statements also fixed this.

Trying to make a repo that recreates the bug so that I can post an issue, I realized that the problem went away when I ran Jest with --no-cache.

Can any of you having this problem try this as well and check if it works?

🍺

EDIT: I think it's worth mentioning that I tried deleting the cache and that didn't work either. Only using --no-cache fixes this for me.

@vvo
Copy link
Contributor

vvo commented Jul 15, 2016

@migueloller Can you have a look at #1214? I had similar issues but with just ES5 code

@migueloller
Copy link

@vvo, looks like another annoying issue. My problem is with branch coverage as opposed to statement coverage, though. 😕

It also seems you're using --no-cache and still getting an issue. Hopefully the improvements that @cpojer mentioned in #1214 will fix these. 😄

@cpojer
Copy link
Member

cpojer commented Aug 16, 2016

I'm assuming this is fixed now. @DmitriiAbramov rewrote Jest's code coverage support. Please try with jest@test or jest@14.2.2-alpha.22bd3c33 to see if this issue still persists. If it does, we'll reopen this issue.

@cpojer cpojer closed this as completed Aug 16, 2016
@migueloller
Copy link

image

This just made my day! @DmitriiAbramov amazing work!!! 😄

@aaronabramov
Copy link
Contributor

nice!
thanks @migueloller

@a-c-m
Copy link

a-c-m commented Aug 17, 2016

I've created a test repro, as the latest jest did not make a dent in the percentages for us.

https://github.com/a-c-m/react-jest-coverage-test

@lPadier
Copy link
Contributor

lPadier commented Aug 17, 2016

@a-c-m I've Added a pull request to your repo.

  • First remove all jest packages from your repo / clean install npm modules:
    rm -rf node_modules/*jest*

install jest@test and babel-jest@test

npm test will no longer work for your repo as the path to the jest executable is hardcoded.

Running npm test with scripts test changed to jest --no-cache will yield the correct result.

#1425 (comment)

@a-c-m
Copy link

a-c-m commented Aug 17, 2016

@lPadier Many thanks, i've merged and also updated the readme.

@ola-g86
Copy link

ola-g86 commented Sep 2, 2016

@a-c-m I downloaded your project. After install jest@14.2.2-alpha.22bd3c33 or jest@test I have the message "NO TESTS FOUND". At now jest@test is jest@14.3.2-alpha.83c25417.

@cpojer
Copy link
Member

cpojer commented Sep 2, 2016

Try jest 15.

@ola-g86
Copy link

ola-g86 commented Sep 5, 2016

@cpojer I changed jest in my project to 15.1.1 and my tests is running now. But I have old problem with ES6 syntax. What other changes do I need to show the coverage of source files, as in Karma?

@aaronabramov
Copy link
Contributor

@ola-g86 are you using any custom preprocessors? is your project open sourced?

@ola-g86
Copy link

ola-g86 commented Sep 7, 2016

It is working now. My settings for this:
in package.json:
"jest": {
"coverageCollector": "jest-babel-istanbul",
}
in .babelrc:
"env": {
"test": {
"sourceMaps": "both"
}
}

@bankimatglobant
Copy link

Hi,
I am facing the same issue while performing testing using jest. My test never shows 100% for branching and statements covered.

I am using "jest": "20.1.0-delta.3", and "jest-css-modules": "^1.1.0" . Below is my jest configuration

"jest": {
"transform": {
".": "/node_modules/jest-css-modules"
},
"collectCoverageFrom": [
"!app/index.js",
"app/**/
.{js,jsx}",
"!/node_modules/"
],
"coverageThreshold": {
"global": {
"branches": 50,
"functions": 70,
"lines": 70,
"statements": 70
}
}
}

My .babelrc is as below

{
"presets": ["react", "es2015"]
}

Please help me to resolve my problem so that I can have 100% branching and statements in coverage report.

Thanks in advance

@aaronabramov
Copy link
Contributor

@bankimatglobant i think jest-css-modules is missing canInstrument transformer key ( see https://github.com/facebook/jest/blob/master/packages/babel-jest/src/index.js#L80) that makes instrumentation a separate process.

You can try to submit a PR to jess-css-modules to use createTransformer function that we export here https://github.com/facebook/jest/blob/master/packages/babel-jest/src/index.js#L132

@mikeromano38
Copy link

mikeromano38 commented Aug 15, 2017

I was running into this issue. Adding the transform-runtime and sourceMaps: both in my babelrc fixed it.

{
  "presets": ["es2015", "react", "stage-1"],
  "env": {
    "test": {
      "plugins": ["transform-runtime"],
      "sourceMaps": "both"
    }
  }
}

@bankimatglobant
Copy link

@mikeromano38 I have tried above configuration but it's not working. Just one query that what is "stage-1". My babelrc is as mentioned below:

{
"presets": ["es2015", "react"],
"env": {
"test": {
"plugins": ["transform-runtime"],
"sourceMaps": "both"
}
}
}

@mikeromano38
Copy link

@github-actions
Copy link

This issue 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, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests