Code coverage for safe navigation (?.) is different between node 20 and 22 when using @swc/jest
When upgrading packages from node 20 to 22 some failed their jest coverage threshold. It happens in packages that use @swc/jest, in tests that use the save navigation operator, but don't test with null and non-null.
// lib.js
export function thing(obj) {
return obj?.key
}
// test.js
//import { it } from 'node:test'
import { thing } from './lib.js'
it("tests thing", () => {
thing({key: 1})
})
jest.config.mjs
export default {
collectCoverage: true,
transform: {
'^.+\\.js$': ['@swc/jest'],
},
}
// package.json
{"type":"module","dependencies":{"@swc/jest":"^0.2.38","jest":"^29.7.0"}}
$ mise exec node@22 -- npx jest
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 50 | 100 | 100 |
lib.js | 100 | 50 | 100 | 100 | 2
----------|---------|----------|---------|---------|-------------------
$ mise exec node@20 -- npx jest
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
lib.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
I'm not sure if this should be considered a bug, in a sense it caught an uncovered branch. However, this will make it harder to upgrade to node 22
- node:test's --experimental-test-coverage was consistent between 20 and 22, but shows 100% branch coverage when only testing the non-null case, and 66% when only testing null.
- vitest was consistent and showed 100% coverage with both node versions
- jest without swc was consistent and showed 100% coverage with both node versions
I was able to work around this by setting jsc target to es2020 or later
jsc: {
target: "es2021",
},
Tho this makes me think that @swc/jest is not setting the right default target. This table stops at node 17 but that was already es2022
I was able to work around this by setting jsc target to es2020 or later
jsc: { target: "es2021", },Tho this makes me think that @swc/jest is not setting the right default target. This table stops at node 17 but that was already es2022
worked for me
I sent a PR to default unknown node versions to the previous known version https://github.com/swc-project/pkgs/pull/99