Intro
I'm moving from Vue^2 to Vue^3. Therefore I'm updating several dependencies, one of it is Jest.
Everything is working nice ... except code coverage collector.
Context
Having this Vue component:
// src/app/script.js
export default {
name : 'app-layout',
data : () => ({ foo : 'Welcome Foo!' })
};
This unitary test:
// tests/unit/app.js;
import AppLayout from '@/app';
import renderer from '#/utils/renderer';
describe('app-layout', () =>
{
describe('Definition', () =>
{
const { name = '', data } = AppLayout;
it('Expect name is "app-layout"', () => expect(name).toBe('app-layout'));
it('Expect data is a a function', () => expect(data).toBeInstanceOf(Function));
});
describe('Snapshots', () =>
{
it('Default has not been modified', async () =>
expect(await renderer(AppLayout, null, true)).toMatchSnapshot());
});
});
This .babelrc.js config:
module.exports = {
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"shippedProposals": true
}
]
],
"plugins": [
[
"@babel/plugin-proposal-class-properties",
{
"loose": false
}
],
[
"@babel/plugin-proposal-private-methods",
{
"loose": false
}
],
"@babel/plugin-proposal-throw-expressions",
"@babel/plugin-transform-modules-commonjs",
"@babel/plugin-transform-runtime"
],
"env": {
"test": {
"plugins": [
"istanbul"
]
}
}
}
This jest config:
// config/jest/config.js
module.exports = {
testRegex : 'tests/unit/[^_].+js$',
collectCoverageFrom : [
'src/**/*.{mjs,js}',
'!**/tests/**',
'!**/node_modules/**',
'!**/demo/**',
'!**/mock.{mjs,js}'
],
coverageDirectory : '<rootDir>/coverage/unit',
coveragePathIgnorePatterns : [
'/node_modules/',
'/src/index.m?js'
],
coverageThreshold : {
global : {
branches : 90,
functions : 90,
lines : 90,
statements : -10
}
},
moduleFileExtensions : ['js', 'json', 'mjs', 'vue'],
moduleNameMapper : {
'^%/(.*)$' : `${root}/$1`,
'^@/(.*)$' : '<rootDir>/src/$1',
'^#/(.*)$' : '<rootDir>/tests/$1'
},
rootDir : cwd,
roots : ['<rootDir>/src', '<rootDir>/tests'],
setupFiles : [
resolver(path.join('tests', '_setup'))
],
snapshotSerializers : ['jest-serializer-vue'],
transform : {
'.m?js' : 'babel-jest',
'.vue' : 'vue-jest',
},
transformIgnorePatterns : ['node_modules/(?!(?:@amjs))']
}
And this test script runner:
#!/usr/bin/env node
const argv = process.argv.slice(2);
const path = require('path');
argv.push(
'--coverage',
'--no-cache',
'--config',
JSON.stringify(require(path.join(__dirname, '..', 'config', 'jest', 'config')), null, 4)
);
require('jest').run(argv);
Results in ...
If I run the following node scripts/test.js
Outputs:
PASS tests/unit/app-layout.js
app-layout
Definition
✓ Expect name is "app-layout" (2 ms)
✓ Expect data is a a function
Snapshots
✓ Default has not been modified (14 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 0 | 100 | 0 | 0 |
script.js | 0 | 100 | 0 | 0 | 3
-----------|---------|----------|---------|---------|-------------------
Jest: "global" coverage threshold for lines (90%) not met: 0%
Jest: "global" coverage threshold for functions (90%) not met: 0%
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 1 passed, 1 total
Time: 2.073 s
Ran all test suites.
But if I run NODE_ENV=test node scripts/test.js.
It outputs:
PASS tests/unit/app-layout.js
app-layout
Definition
✓ Expect name is "app-layout" (1 ms)
✓ Expect data is a a function
Snapshots
✓ Default has not been modified (11 ms)
Running coverage on untested files...Failed to collect coverage from /Volumes/Projects/com.github/adhara/vue/fw/src/app/script.js
ERROR: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.
plugins: [
['some-plugin', {}],
['some-plugin', {}, 'some unique name'],
]
Duplicates detected are:
[
{
"alias": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"dirname": "/Volumes/Projects/com.github/adhara/vue/fw",
"ownPass": false,
"file": {
"request": "istanbul",
"resolved": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js"
}
},
{
"alias": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"options": {
"cwd": "/Volumes/Projects/com.github/adhara/vue/fw",
"exclude": []
},
"dirname": "/Volumes/Projects/com.github/adhara/vue/fw",
"ownPass": false,
"file": {
"request": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"resolved": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js"
}
}
]
STACK: Error: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.
plugins: [
['some-plugin', {}],
['some-plugin', {}, 'some unique name'],
]
Duplicates detected are:
[
{
"alias": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"dirname": "/Volumes/Projects/com.github/adhara/vue/fw",
"ownPass": false,
"file": {
"request": "istanbul",
"resolved": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js"
}
},
{
"alias": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"options": {
"cwd": "/Volumes/Projects/com.github/adhara/vue/fw",
"exclude": []
},
"dirname": "/Volumes/Projects/com.github/adhara/vue/fw",
"ownPass": false,
"file": {
"request": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js",
"resolved": "/Volumes/Projects/com.github/adhara/vue/fw/node_modules/babel-plugin-istanbul/lib/index.js"
}
}
]
at assertNoDuplicates (/Volumes/Projects/com.github/adhara/vue/fw/node_modules/@babel/core/lib/config/config-descriptors.js:239:13)
at createDescriptors (/Volumes/Projects/com.github/adhara/vue/fw/node_modules/@babel/core/lib/config/config-descriptors.js:147:3)
at createDescriptors.next (<anonymous>)
at createPluginDescriptors (/Volumes/Projects/com.github/adhara/vue/fw/node_modules/@babel/core/lib/config/config-descriptors.js:138:17)
at createPluginDescriptors.next (<anonymous>)
at /Volumes/Projects/com.github/adhara/vue/fw/node_modules/@babel/core/lib/config/config-descriptors.js:94:32
at Generator.next (<anonymous>)
at Function.<anonymous> (/Volumes/Projects/com.github/adhara/vue/fw/node_modules/@babel/core/lib/gensync-utils/async.js:24:3)
at Generator.next (<anonymous>)
at evaluateSync (/Volumes/Projects/com.github/adhara/vue/fw/node_modules/gensync/index.js:251:28)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
file.js | 100 | 100 | 100 | 100 |
script.js | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 1 passed, 1 total
Time: 3.02 s
Ran all test suites.
So in first case, tests are running but coverage no. And in second case, tests and coverage works but an error is thrown.