`hoisted` does not work with istanbul coverage when overriding coverage excludes
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
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- [X] The provided reproduction is a minimal reproducible example of the bug.
Found the workaround, you need to include coverageConfigDefaults.exclude. I was previously including configDefaults.exclude.
exclude: ['stuff/*', ...coverageConfigDefaults.exclude],
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 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
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]++, );
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'],
Vitest always excludes test files now since Vitest 3, so this should not be an issue.