vitest icon indicating copy to clipboard operation
vitest copied to clipboard

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

Open kwojcik opened this issue 1 year ago • 5 comments

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 avatar Jul 08 '24 19:07 kwojcik

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

      exclude: ['stuff/*', ...coverageConfigDefaults.exclude],

kwojcik avatar Jul 08 '24 19:07 kwojcik

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.

sheremet-va avatar Jul 08 '24 19:07 sheremet-va

@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

MKhasib avatar Jul 08 '24 20:07 MKhasib

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]++, );

AriPerkkio avatar Jul 09 '24 05:07 AriPerkkio

In my case I ran into this issue of hoisted causing SyntaxError when running with istanbul coverage after updating my dependencies. What worked for me was adding test files to my existing test.coverage.exclude:

exclude: [..., '**/*.test.ts'],

Doeke avatar Aug 12 '24 20:08 Doeke

Vitest always excludes test files now since Vitest 3, so this should not be an issue.

sheremet-va avatar Apr 17 '25 15:04 sheremet-va