vitest-dev / vitest

Next generation testing framework powered by Vite.
https://vitest.dev
MIT License
12.38k stars 1.1k forks source link

`hoisted` does not work with istanbul coverage when overriding coverage excludes #6057

Open kwojcik opened 2 weeks ago

kwojcik commented 2 weeks ago

Describe the bug

If you use istanbul coverage (required for browser mode), override the coverage excludes, and use vi.hoisted, then your test runs fail with cryptic syntax errors.

This worked on v2.0.0-beta.12 and is broken on v2.0.1.

 FAIL  test/basic.test.tsx [ test/basic.test.tsx ]
SyntaxError: Unexpected token ')'
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  no tests
   Start at  12:06:27
   Duration  0ms
export default defineConfig({
  test: {
    coverage: {
      provider: "istanbul",
      exclude: [],
    },
  },
});
import { vi } from "vitest";

const mocks = vi.hoisted(() => ({}));

Reproduction

https://github.com/kwojcik/vitestsourcemapbug/tree/hoistedBug

git checkout hoistedBug
npm install
npm run test

System Info

System:
    OS: macOS 13.6.7
    CPU: (12) arm64 Apple M2 Max
    Memory: 11.03 GB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.18.2 - ~/.asdf/installs/nodejs/18.18.2/bin/node
    Yarn: 1.22.21 - /opt/homebrew/bin/yarn
    npm: 9.8.1 - ~/.asdf/plugins/nodejs/shims/npm
    pnpm: 9.4.0 - /opt/homebrew/bin/pnpm
    Watchman: 2024.04.01.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 126.0.6478.127
    Safari: 16.6
  npmPackages:
    @vitest/coverage-istanbul: ^2.0.1 => 2.0.1
    @vitest/coverage-v8: ^2.0.1 => 2.0.1
    @vitest/ui: ^2.0.1 => 2.0.1
    vite: latest => 5.3.2
    vitest: ^2.0.1 => 2.0.1

Used Package Manager

npm

Validations

kwojcik commented 2 weeks ago

Found the workaround, you need to include coverageConfigDefaults.exclude. I was previously including configDefaults.exclude.

      exclude: ['stuff/*', ...coverageConfigDefaults.exclude],
sheremet-va commented 2 weeks ago

It is expected that coverage picks up a test file if you override exclude because test files are not forcefully excluded anymore: https://github.com/vitest-dev/vitest/pull/5997 (they excluded only if exclude is not overridden)

It is unexpected that it throws an error in vi.hoisted though.

MKhasib commented 2 weeks ago

@sheremet-va How about excluding .vue files imported in .js test files from coverage report? how can we do that? Please check this for details: https://github.com/vitest-dev/vitest/issues/6058#issuecomment-2215071109

AriPerkkio commented 2 weeks ago

It's expected that this file is instrumented when you disable all coverage.excludes and use the default coverage.includes: ['**'].

The reason why this errors comes up is that vitest:mocks plugin has bug:

https://github.com/vitest-dev/vitest/blob/16eb6c83f84b8f5ed06a625c8ad517e281112c5f/packages/vitest/src/node/plugins/mocks.ts#L16

// input
import { vi } from "vitest";
const mocks = (cov_29w8m57srg().s[0]++, vi.hoisted(() => {
  cov_29w8m57srg().f[0]++;
  cov_29w8m57srg().s[1]++;
  return {};
}));
// output
const mocks = (cov_29w8m57srg().s[0]++, );