istanbuljs/nyc

ReferenceError: cov_vyj5vtdds is not defined

Closed this issue · 5 comments

Link to bug demonstration repository

I'm having an exception when I try to get the test coverage of my project.
The only thing particular is that I'm using worker threads with a pool.
The error is not thrown when I execute the tests.
Repository

Expected Behavior

No exception should be throwed.

Observed Behavior

When I try to get the coverage

yarn test:coverage
image

When I simply run the tests

yarn test
image

Troubleshooting steps

Environment Information

  System:
    OS: macOS 10.15.5
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 218.24 MB / 16.00 GB
  Binaries:
    Node: 12.16.3 - ~/.asdf/installs/nodejs/12.16.3/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - ~/.asdf/installs/nodejs/12.16.3/bin/npm
  npmPackages:
    nyc: 13.3.0 => 13.3.0 

If you are using Function#toString() this will not work from another thread. I'd suggest trying c8 but then you might just not get coverage for the evaluated function.

If you are using Function#toString() this will not work from another thread. I'd suggest trying c8 but then you might just not get coverage for the evaluated function.

What you mean with Function#toString()?. In the example, there is no call to the toString method. I'm simply doing a console.log.

const os = require('os');
const { DynamicPool } = require('node-worker-threads-pool');

const Pool = new DynamicPool(os.cpus().length, { shareEnv: true });

const someFunction = async (params) =>
  await Pool.exec({
    task: async function() {
      const { params } = this.workerData;
      console.log('params', params);
      return params;
    },
    workerData: {
      params,
    },
  });

module.exports = {
  someFunction,
};

BTW, I used c8 as @coreyfarrell suggested, and the test is passing and the coverages gets computed correctly.

Function#toString is called from inside node-worker-thread-pool, see https://github.com/SUCHMOKUO/node-worker-threads-pool/blob/master/src/dynamic-pool.js#L69.

If you want to use nyc you can do the following:

const os = require('os');
const { DynamicPool } = require('node-worker-threads-pool');

const Pool = new DynamicPool(os.cpus().length, { shareEnv: true });

const someFunction = async (params) =>
  await Pool.exec({
    /* istanbul ignore next: nyc must ignore this `task` function or you will get a failure */
    task: async function() {
      const { params } = this.workerData;
      console.log('params', params);
      return params;
    },
    workerData: {
      params,
    },
  });

module.exports = {
  someFunction,
};

The problem is that nyc rewrites the task function to perform coverage counting but in doing so the task function becomes tied to the source where it exists. You can see this by running nyc instrument --no-compat small-source.js. You will see that function cov_<random> is declared at the source scope and then used through-out. So when you call toString on any function in that source then try running it from outside the source it will contain invalid references.

stale commented

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.