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

Vitest Coverage v8 & Istanbul Providers Broken #27003

Open
lishaduck opened this issue Nov 22, 2024 · 4 comments · May be fixed by #28577 or gopoto/deno#1
Open

Vitest Coverage v8 & Istanbul Providers Broken #27003

lishaduck opened this issue Nov 22, 2024 · 4 comments · May be fixed by #28577 or gopoto/deno#1
Labels
debugger Chrome DevTools inspector/debugger integration node compat testing related to deno test and coverage

Comments

@lishaduck
Copy link

lishaduck commented Nov 22, 2024

Relates to #23882.
Version: Deno 2.1.1

The v8 provider returns 0 for everything.
The istanbul provider is just wrong:
Screenshot 2024-11-22 at 7 25 54 AM
Screenshot 2024-11-22 at 7 26 30 AM
Screenshot 2024-11-22 at 7 28 21 AM

I think instanbul is mostly just mapping the line #s wrong, but it generally looks accurate-ish.

@bartlomieju bartlomieju added needs investigation requires further investigation before determining if it is an issue or not testing related to deno test and coverage node compat labels Nov 22, 2024
@marvinhagemeister
Copy link
Contributor

Looks like something is different in the inspector. On Deno I get these coverage lines:

[
  // ...
  {
    scriptId: '406',
    url: '/Users/marvinh/dev/test/deno-vitest-cov2/src/foo.test.js',
    functions: [ [Object], [Object], [Object] ]
  },
  {
    scriptId: '408',
    url: '/Users/marvinh/dev/test/deno-vitest-cov2/src/foo.ts',
    functions: [ [Object], [Object], [Object], [Object] ]
  }
]

Whereas in Node I get this:

[
  // ...
  {
    scriptId: '265',
    url: 'file:///Users/marvinh/dev/test/deno-vitest-cov2/src/foo.test.js',
    functions: [ [Object], [Object], [Object] ]
  },
  {
    scriptId: '267',
    url: 'file:///Users/marvinh/dev/test/deno-vitest-cov2/src/foo.ts',
    functions: [ [Object], [Object], [Object], [Object] ]
  }
]

This is problematic because vitest filters out anything that doesn't start with file:// here https://github.com/vitest-dev/vitest/blob/021944cd588958f3fa22d632e2bfd3efa0f1310d/packages/coverage-v8/src/index.ts#L20-L34

session.post("Profiler.takePreciseCoverage", async (error, coverage) => {
  //...
  const result = coverage.result.filter(filterResult);
  resolve({ result });
});

function filterResult(coverage) {
  if (!coverage.url.startsWith("file://")) {
    return false;
  }
  if (coverage.url.includes("/node_modules/")) {
    return false;
  }
  return true;
}

I wasn't able to isolate it further as just doing the inspector stuff leads to the correct script urls being printed. Not sure why they are stripped with vitest.

Steps to reproduce

  1. Clone https://github.com/marvinhagemeister/deno-vitest-cov2
  2. Run deno install
  3. Run deno task test

@marvinhagemeister marvinhagemeister added debugger Chrome DevTools inspector/debugger integration and removed needs investigation requires further investigation before determining if it is an issue or not labels Nov 22, 2024
lishaduck added a commit to lishaduck/effect-utils that referenced this issue Nov 23, 2024

Verified

This commit was signed with the committer’s verified signature.
Blocked on denoland/deno#27003.
@yasaichi
Copy link

yasaichi commented Jan 29, 2025

@marvinhagemeister
Any updates on this? This would be the last blocker when trying to use Vitest with Deno in production-grade applications.

lishaduck added a commit to lishaduck/effect-utils that referenced this issue Feb 18, 2025

Verified

This commit was signed with the committer’s verified signature.
Blocked on denoland/deno#27003.
lishaduck added a commit to lishaduck/effect-utils that referenced this issue Feb 18, 2025

Verified

This commit was signed with the committer’s verified signature.
Blocked on denoland/deno#27003.
lishaduck added a commit to lishaduck/effect-utils that referenced this issue Feb 18, 2025

Verified

This commit was signed with the committer’s verified signature.
Blocked on denoland/deno#27003.
@AriPerkkio
Copy link

While looking into issue on Vitest side (vitest-dev/vitest#7660), noticed that this minimal reproduction works on Node but not on Deno. Should Profiler.takePreciseCoverage and Profiler.startPreciseCoverage be supported? This is on deno 2.2.3:

import inspector from "node:inspector";

function firstMethod() {}

const session = new inspector.Session();
session.connect();
session.post("Profiler.enable");
session.post("Profiler.startPreciseCoverage", { callCount: true, detailed: true });

firstMethod();

const coverage = await new Promise((resolve, reject) => {
  session.post("Profiler.takePreciseCoverage", async (error, coverage) => {
    if (error) return reject(error);
    resolve(coverage.result.filter((entry) => !entry.url.startsWith("node:")));
  });
});

console.log(JSON.stringify(coverage, null, 2));
$ deno -v; deno --allow-sys ./coverage.mjs 
deno 2.2.3
[]

$ node -v; node ./coverage.mjs 
v22.14.0
[
  {
    "scriptId": "94",
    "url": "file:///Users/x/coverage.mjs",
    "functions": [
      {
        "functionName": "firstMethod",
        "ranges": [
          {
            "startOffset": 41,
            "endOffset": 66,
            "count": 1
          }
        ],
        "isBlockCoverage": true
      },
      {
        "functionName": "coverage",
        "ranges": [
          {
            "startOffset": 297,
            "endOffset": 520,
            "count": 1
          }
        ],
        "isBlockCoverage": true
      },
      {
        "functionName": "",
        "ranges": [
          {
            "startOffset": 367,
            "endOffset": 516,
            "count": 0
          }
        ],
        "isBlockCoverage": false
      }
    ]
  }
]

@devsnek
Copy link
Member

devsnek commented Mar 24, 2025

I don't know if vitest/istanbul coverage works at this point or not, but I can't reproduce the causes claimed above. Deno is showing file:// urls for scripts. The test script above relies on an implementation detail of node, which is that Session#post sometimes completes synchronously. If the script is refactored to use the callbacks, it has identical output in node and deno:

import inspector from "node:inspector";

function firstMethod() {}

const session = new inspector.Session();
session.connect();
session.post("Profiler.enable", () => {
  session.post("Profiler.startPreciseCoverage", { callCount: true, detailed: true }, () => {
    firstMethod();

    session.post("Profiler.takePreciseCoverage", (error, result) => {
      const coverage = result.result.filter((entry) => !entry.url.startsWith("node:") && !entry.url.startsWith('ext:'));

      console.log(JSON.stringify(coverage, null, 2));
    });
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debugger Chrome DevTools inspector/debugger integration node compat testing related to deno test and coverage
Projects
None yet
6 participants