istanbuljs / babel-plugin-istanbul

A babel plugin that adds istanbul instrumentation to ES6 code
BSD 3-Clause "New" or "Revised" License
622 stars 73 forks source link

import/export statements are ignored #135

Open CWSpear opened 6 years ago

CWSpear commented 6 years ago

Is it unexpected that this plugin appears to be ignoring import and export statements (in terms of statement and line counts)?

Maybe I have a config issue, but when I just use babel transpilation and the traditional instrumentation (left), it counts the import lines, but when I use this plugin (right), it doesn't count them.

screen 20shot 20on 202017-10-16 20at 2011 3a56 3a09

The nyc config in my package.json:

"nyc": {
  "all": true,
  "checkCoverage": true,
  "perFile": true,
  "lines": 80,
  "reporter": [
    "text",
    "html"
  ],
  "include": [
    "server"
  ],
  "exclude": [
    "server/data/relayNode.js",
    "server/data/schema/",
    "server/data/mutations/",
    "server/data/generated/",
    "server/data/types/",
    "server/api/index.js",
    "server/data/models/index.js",
    "server/data/models/analytics/index.js",
    "server/data/events/cli.js",
    "server/lib/tomnodgbdx/scripts/workflowCli.js"
  ],
  "require": [
    "babel-register"
  ],
  "sourceMap": false,
  "instrument": false
}

My .babelrc:

{
    "sourceMaps": "inline",
    "presets": [
        "es2015-node",
        "stage-0"
    ],
    "plugins": [
        "transform-es2015-parameters",
        "transform-es2015-destructuring"
    ],
    "env": {
        "coverage": {
            "plugins": [
                "istanbul"
            ]
        }
    }
}

My relevant package.json scripts entries:

"unit": "BLUEBIRD_DEBUG=1 CONFIG=unit,unit2 mocha --recursive --require longjohn --require babel-register --require babel-polyfill tests/unit",
"coverage": "NODE_ENV=coverage nyc npm run unit",

Relevant package versions:

"babel-cli": "6.22.2",
"babel-core": "6.22.1",
"babel-eslint": "7.1.1",
"babel-plugin-transform-es2015-destructuring": "6.22.0",
"babel-plugin-transform-es2015-parameters": "6.22.0",
"babel-polyfill": "6.22.0",
"babel-preset-es2015-node": "6.1.1",
"babel-preset-stage-0": "6.22.0",
"babel-register": "6.22.0",
"babel-plugin-istanbul": "4.1.5",
"mocha": "3.2.0",
"nyc": "11.2.1",
CWSpear commented 6 years ago

This appears to make it so you can't ignore functions that are exported. Same left/right as above (with and without plugin, respectively):

screen 20shot 20on 202017-10-16 20at 2012 3a11 3a17

All other /* istanbul ignore next */ comments are respected except this one (which is the only one that tries to ignore an exported function).

evanbb commented 6 years ago

I am seeing this same behavior running tests with Jest (which uses this plugin). As a result, no coverage is reported for an entry point to a library, e.g., something like:

// in index.js

import * as MyLib from './internals';
export { MyLib };

Even if I write a spec for the index file to assert, say, the right stuff is exported for my lib:

// in index.spec.js

import { MyLib } from './index';

describe('the lib', () => {
  it('exports the right stuff', () => {
    expect(Object.keys(MyLib).length).toBe(1);
  });
});

I get no coverage :(

evanbb commented 6 years ago

As soon as any other line that "executes code" is included in the module:

// in index.js

import * as MyLib from './internals';
export { MyLib };

const t = true;

then I get 100% coverage... :|

evanbb commented 6 years ago

Small repro repo

yerol commented 5 years ago

I get the same behaviour with Vue components that export simple objects as well. Such as:

export default {
  name: 'WrapLayout',
  props: {
    orientation: {
      type: String,
      default: 'horizontal',
    },
  },
};

I get 0 coverage this way. But when I change it to this:

const WrapLayout = {
  name: 'WrapLayout',
  props: {
    orientation: {
      type: String,
      default: 'horizontal',
    },
  },
  directives: {
    'common-directive': CommonDirective,
  },
};

export default WrapLayout;

I get 100% coverage.

coreyfarrell commented 5 years ago

Can you try again with the latest jest / babel-plugin-istanbul? The versions of these modules mentioned here use an older version of istanbul with babel 6, the current versions use babel 7, so the situation may have changed.

evanbb commented 5 years ago

@coreyfarrell looks like this is still an issue in my case with latest jest (24.1.0) and @babel/preset-env (7.3.4). ive updated my repro repo.

StephenErstad-zz commented 5 years ago

Also an issue for me using Jest and this plugin.

storenth commented 4 years ago

I have absolutely the same issue as @CWSpear created first!

  1. Jest instrument sources and produce .json reporter
  2. Then I collect coverage with babel-plugin-istanbul and get second .json When I merge it with istanbul-merge I get the issue, see screenshot (Jest on the left side and babel-plugin-istanbul on the right): My dependencies:
    "babel-plugin-istanbul": "^4.1.6",
    "jest": "22.4.4",
    "babel-core": "6.26.3",
    "babel-eslint": "8.2.3",
    "babel-jest": "22.4.4",
    "babel-loader": "7.1.4",
    jest_babel_istanbul_coverage
link89 commented 4 years ago

We do have the same issue. That is very strange. Is there a way to also ignore the import statements in jest?

storenth commented 4 years ago

We do have the same issue. That is very strange. Is there a way to also ignore the import statements in jest?

@link89 What is your dependencies and its versions?

sorinpav commented 3 years ago

We've used / istanbul ignore file / statements and it works for us. What that does is it deletes the files from the coverage report, and you no longer see them as uncovered. Obviously, if you add any logic in the file except the import/export statements, then you'd need to remove those statements and test the code from there.

I hope it helps.

VickyKoblinski commented 2 years ago

Reporting from 2022, still having this issue with Jest 27 and babel-plugin-istanbul 6.1.1

I'm using @storybook/test-runner and Next.js Jest tests, and merging the reports with codecov. The problem is that storybook/test-runner (which uses babel-plugin-istanbul) doesn't report imports/exports as statements but jest does. That means a component can have 100% test coverage from storybook/test-runner and 0% coverage from jest, but the merged report will not be 100% because the jest report says the import/export lines are not covered.

I will get like 0/11 Statements covered from Jest and 4/4 statements covered from storybook/test-runner, and merged together I'll get 4/11 statements covered total.

jogelin commented 1 year ago

@VickyKoblinski I have the same issue, did you progress on it?

igorthurow commented 1 year ago

Same problem here. I need to ignore import statement on coverage report from Jest. Have how do this?

seanmorris commented 1 year ago

Are you guys using babel-plugin-transform-merge-sibling-variables & babel-plugin-transform-modules-commonjs by chance? I found a bug where import sourcemappings are lost. If you can check your sourcemap with https://evanw.github.io/source-map-visualization/ you might be able to confirm this.

I've already located the bug and opened a PR with the fix.

https://github.com/babel/minify/issues/1046 https://github.com/babel/minify/pull/1047

gaollard commented 1 year ago

same issue here

fossage commented 7 months ago

FYI, this is an issue in Istanbul itself. I was able to verify this by running NYC directly rather than relying on this plugin. To fix the issue, I had to patch the istanbul-lib-instrument library using patch-package. Note that this patch is specifically for version 4.0.3, so you may need to adjust it for other versions:

diff --git a/node_modules/istanbul-lib-instrument/dist/visitor.js b/node_modules/istanbul-lib-instrument/dist/visitor.js
index b8c59cd..05749ee 100644
--- a/node_modules/istanbul-lib-instrument/dist/visitor.js
+++ b/node_modules/istanbul-lib-instrument/dist/visitor.js
@@ -497,6 +497,8 @@ const codeVisitor = {
   ExportDefaultDeclaration: entries(),
   // ignore processing only
   ExportNamedDeclaration: entries(),
+  ImportDeclaration: entries(),
+  ImportOrExportDeclaration: entries(),
   // ignore processing only
   ClassMethod: entries(coverFunction),
   ClassDeclaration: entries(parenthesizedExpressionProp('superClass')),

This essentially tells the AST visitor to ignore ImportDeclaration and ImportOrExportDeclaration nodes. Not sure why this wasn't in the source initially but it seems to do exactly what we need for our codebase.

ljharb commented 7 months ago

@fossage it'd be great to send a PR to that repo

fossage commented 7 months ago

Just realized that my patch above actually breaks coverage in my unit tests with the error:

ERROR: [path to file]:fns is not iterable.

It works fine in our Cypress tests however and gives us proper coverage counts. I'll continue investigating.