Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support jest v27 in vue3-jest #343

Merged
merged 3 commits into from Jul 19, 2021

Conversation

cexbrayat
Copy link
Member

@cexbrayat cexbrayat commented May 26, 2021

And also babel-jest and ts-jest v27.

The PR is currently failing because of a change/regression in ts-jest (update: fixed in ts-jest v27.0.1)

TODO:

@jurijzahn8019
Copy link

Hi,

kulshekhar/ts-jest#2628 was merged

And ts-jest 27 was released 👍

@cexbrayat cexbrayat force-pushed the feat/jest-v27 branch 4 times, most recently from c0c7226 to fdf77e2 Compare May 27, 2021 09:33
@cexbrayat
Copy link
Member Author

ts-jest v27.0.1 was released including the fix, the PR is now green.

@WIStudent WIStudent mentioned this pull request May 27, 2021
@lmiller1990 lmiller1990 self-requested a review May 31, 2021 01:24
Copy link
Member

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we have some breaking changes (did not go over Jest 27 release notes yet).

I wonder if we can just do something simple like:

const jestVersion = require('jest/package.json').version

if (jestVersion.includes('26')) {
  // v26 specific things
}

Versioning for vue-jest has been a problem for a while. We have several moving targets - Vue 2/3, and Jest 26/27. It's not entirely clear on the best way to do this. What do you think?

@@ -1,5 +1,5 @@
const ensureRequire = require('../ensure-require')
const babelJest = require('babel-jest')
const babelJest = require('babel-jest').default
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has jest changed how it processes modules with default exports? I guess this is the breaking change?

lib/utils.js Outdated
@@ -49,7 +49,11 @@ const transformContent = function transformContent(

const getVueJestConfig = function getVueJestConfig(jestConfig) {
return (
(jestConfig && jestConfig.globals && jestConfig.globals['vue-jest']) || {}
(jestConfig &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this will also be a breaking change.

@nogic1008
Copy link
Collaborator

vue-jest@v5 (for Vue 3, Jest 24~26) is still in alpha, so we can include breaking changes even if following semver.
But, v4 was public released.
If we follow semver, we should increment major version.

How about separating next branch into another package (such as vue3-jest)?

@cexbrayat
Copy link
Member Author

I think a clean way would be to do the same than ts-jest and babel-jest for the versioning: use the jest version as the major one. That would mean releasing vue-jest v27, compatible with jest v27.

If jest 27 support for Vue 2 is important, maybe having another package could avoid the confusion (vue2-jest v27 and vue3-jest v27).

This is definitely a big change but the current versioning is confusing as it is, and I guess more and more projects starting now will bet on Vue 3 and Jest 27. As a developer, it would be clear that using vue-jest v27 (or vue3-jest v27) is what you need.

@lmiller1990
Copy link
Member

lmiller1990 commented Jun 1, 2021

I like the idea to match the Jest versioning. The problem historically was how to we handle Vue 2? And eventually, Vue 4?

A separate package would likely be the easiest solution. In fact, two separate packages, even? Should we deprecate vue-jest entirely, in favor of:

  • vue2-jest26
  • vue2-jest27
  • vue3-jest27

etc. This would future proof us.

Probably a good opportunity to introduce semantic release, too. Currently I do releases manually, which is not very scalable. What do you guys think? I really like this idea - it's a bit of work to set everything up, and will require pretty good communication, but it definitely solves a lot of problems.

@wolfgangwalther
Copy link
Contributor

  • vue2-jest26

  • vue2-jest27

  • vue3-jest27

That's one package for each jest major? Or rather vue2-jest@26.x.x, vue2-jest@27.x.x, vue3-jest@27.x.x? That would make the most sense, I guess.

@yyx990803
Copy link
Member

I think it makes sense for vue-jest to match Jest versions and support the current latest Vue major (where Vue 3 is becoming the default soon). A separate package to support older versions of Vue - i.e.

  • vue-jest@27 -> Vue 3 + Jest 27
  • vue2-jest@27 -> Vue 2 + Jest 27

@lmiller1990
Copy link
Member

lmiller1990 commented Jun 2, 2021

@wolfgangwalther it's not necessarily per major, it can be minor (or) patch. Take a look at ts-jest. They basically just do a release when it makes sense, but generally try to be up to date where possible and practical.

@yyx990803 this seems like a pretty reasonable approach. If (when) we have Vue 4, we can create vue3-jest@x and vue-jest would then default to Vue 4 (thinking really far ahead here, but good to consider these things).

In this case, we can start preparing this now, and make vue-jest default to Vue 3 + Jest 27 when Vue 3 becomes the default on npm. I think a good short term goal is:

  • vue-jest@27 -> Vue 3 / Jest 27 (this PR)
  • vue-jest@26 -> Vue 3 / Jest 26 (already have this)
  • vue2-jest@27 -> Vue 2 / Jest 27 (people will still need this, we will need to back port this PR - not hard)
  • vue2-jest@26 -> Vue 2 / Jest 26 (already exists)

Anyone want to work on this? If not, happy to pick it up, but I won't be able to until around the middle of this month (so, 2 weeks-ish from this post). We'll need

  1. new package for vue2-jest (forked from here)
  2. create branches: vue-jest@26, vue-jest@27. Ensure both work with Vue 3 + relevant Jest version. Probably merge this PR into the vue-jest@27 branch.

@Kocal
Copy link

Kocal commented Jun 2, 2021

Thanks for your work @cexbrayat! ❤️

@nogic1008
Copy link
Collaborator

Is it difficult to make this repository to monorepo?
Like this

  • /
    • /packages
      • /vue2 - npm package for Vue 2 (named vue2-jest?)
        • /src
        • /test
      • /vue3 - npm package for Vue 3 (named vue-jest or vue3-jest?)
        • /src
        • /test
      • /vue-next - npm package for Vue next version
        • /src
        • /test
      • /common - common logic (if available)
        • /src
        • /test

@lmiller1990
Copy link
Member

lmiller1990 commented Jun 2, 2021

@nogic1008 that's probably a good idea. Then we can manage everything here and share code.

I have not set up a monorepo before - is this something you have experience with and would be interested in doing?

@nogic1008
Copy link
Collaborator

@lmiller1990 OK.
I'll make a monorepo sample in my repository. After that, consider the migration plan.

@lmiller1990
Copy link
Member

@nogic1008, ok thanks! You should have access to push branches here too; you could just make a branch in this repo if you like.

If you don't have push access, let me know, we will get it set up. We should do the same for @cexbrayat, since you guys are contributing a lot.

@Tofandel
Copy link

Tofandel commented Jun 14, 2021

I like the idea to have version like
vue-jest@27 -> Vue 3 + Jest 27
vue2-jest@27 -> Vue 2 + Jest 27

Where the default vue-jest always tracks the latest vue version, so if there is a vue v4, this would be in vue-jest and a new vue3-jest would have to be created but that also means the package would need to be changed for users of the lib

So I'm actually more enclined to have both
vue-jest@27 -> Vue 3 + Jest 27
vue3-jest@27 -> Vue 3 + Jest 27
vue2-jest@27 -> Vue 2 + Jest 27

Where the first one is a mirror of the latest vue, and if that's too much to maintain or bad to have npm mirrors for whatever reason then I'd be more inclined for only:
vue3-jest@27 -> Vue 3 + Jest 27
vue2-jest@27 -> Vue 2 + Jest 27

And deprecate
vue-jest

So that we don't need to change library name if we use vue-jest to vue3-jest whenever there is a new version of vue (even if it's very rare)

The previous logic was trying to figure out if CommonJS modules were used in the TS config and if not,
and if no babel configuration provided, then loaded a babel transformer to change the module format.

This changes the logic to use a more straightforward method by directly updating the tsconfig to commonjs,
which should hopefully have the same results without side-effects.
@cexbrayat
Copy link
Member Author

Update: this should now work properly for pure TS projects.

I opened another PR #366 to reflect the most common use-case for TS users that have no babel config (and this one is now on top of this extra test to make sure everything works).
I think it was working a bit by accident for jest v26...
I also added another commit, to replace the logic in the typescript transformer that was using babel to change the module to commonjs. I think it would be simpler to directly update the tsconfig we load with this module format? Please take a look and let me know.

It would be awesome to have an alpha.2 release if that looks good @lmiller1990

@florianrusch
Copy link

Hi all together,

I've tried today to bring my current project to jest 27, but I got this error if I run the tests:

$ npx jest --coverage

TypeError: Jest: a transform must export something.
    at .../node_modules/@jest/transform/build/ScriptTransformer.js:386:19
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Promise.all (index 3)
    at async ScriptTransformer.loadTransformers (.../node_modules/@jest/transform/build/ScriptTransformer.js:378:5)
    at async createScriptTransformer (.../node_modules/@jest/transform/build/ScriptTransformer.js:1106:3)
    at async .../node_modules/@jest/core/build/TestScheduler.js:269:31
    at async Promise.all (index 0)
    at async TestScheduler.scheduleTests (.../node_modules/@jest/core/build/TestScheduler.js:262:5)
    at async runJest (.../node_modules/@jest/core/build/runJest.js:387:19)
    at async _run10000 (.../node_modules/@jest/core/build/cli/index.js:408:7)

My setup:

package.json:

{
  ...,
  "dependencies": {
    "vue": "^3.0.0",
    "vue-i18n": "^9.1.6",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0",
    "vuex-oidc": "^3.10.2",
    ...
  },
  "devDependencies": {
    "@types/jest": "^26.0.24",
    "@typescript-eslint/eslint-plugin": "^4.18.0",
    "@typescript-eslint/parser": "^4.18.0",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-typescript": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-prettier": "^6.0.0",
    "@vue/eslint-config-typescript": "^7.0.0",
    "@vue/test-utils": "^2.0.0-rc.10",
    "eslint": "^6.7.2",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-vue": "^7.0.0",
    "jest": "^27.0.6",
    "jest-junit-reporter": "^1.1.0",
    "prettier": "^2.2.1",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "ts-jest": "^27.0.3",
    "typescript": "~4.1.5",
    "vue3-jest": "^27.0.0-alpha.1"
  }
}

jest.config.js:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  transform: {
    '^.+\\.vue$': 'vue3-jest',
  },
  collectCoverageFrom: ['<rootDir>/src/**/*.{ts,vue,js}'],
  coverageDirectory: '<rootDir>/test-coverage',
  coverageReporters: ['text', 'cobertura'],
  testMatch: ['<rootDir>/src/**/*.spec.ts'],
  modulePaths: ['<rootDir>'],
  testResultsProcessor: './node_modules/jest-junit-reporter',
}

A quick google search brought me to this issue in the ts-jest project: kulshekhar/ts-jest#2612.
However the offered fix with clearing the jest cache didn't work for me.

Does anyone have a clue what is going wrong?

@cexbrayat
Copy link
Member Author

cexbrayat commented Jul 17, 2021

Hi @florianrusch
Thanks for giving it a try.
For the moment the CLI depends on jest 26, so you have to use Yarn and add a resolution in your package.json:

"resolutions": {
  "jest": "27.0.6"
}

Run yarn to install the dependencies, and the error should go away, as jest 27 will be used.

Then you need to update your jest config, as the CLI preset will not work (it uses vue-jest).
Add something like:

  transform: {
    '^.+\\.vue$': 'vue3-jest',
    '^.+\\.tsx?$': 'ts-jest',
    '^.+\\.jsx?$': 'babel-jest'
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  testEnvironment: 'jsdom',

to mimic what the preset does.

Then yarn test:unit should work.
vue3-jest@27.0.0-alpha.1 has an issue though, but as it looks like you use babel as well, it should be fine.

I'm interested to hear if vue3-jest works for you. WHen we're confident enough, I'll open a PR on the CLI to avoid all this manual work 😉

@florianrusch
Copy link

Thanks @cexbrayat for you reply. I directly tested it.

The following makes the error disappear:

  transform: {
    '^.+\\.vue$': 'vue3-jest',
    '^.+\\.tsx?$': 'ts-jest',
    '^.+\\.jsx?$': 'babel-jest'
  },

But after I applied it (also tested with the other changes), I've got a new error:

$ npx jest --coverage
Test environment found at "/Users/fr/Workspace/ZF/web-app/node_modules/jest-environment-jsdom-fifteen/lib/index.js" does not export a "getVmContext" method, which is mandatory from Jest 27. This method is a replacement for "runScript".
Test environment found at "/Users/fr/Workspace/ZF/web-app/node_modules/jest-environment-jsdom-fifteen/lib/index.js" does not export a "getVmContext" method, which is mandatory from Jest 27. This method is a replacement for "runScript".

...

 FAIL  src/components/Header.spec.ts
  ● Test suite failed to run

    Jest worker encountered 4 child process exceptions, exceeding retry limit

      at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21)

The first message seams to appear repeated for all tests.

@cexbrayat
Copy link
Member Author

Try to add

testEnvironment: 'jsdom',

to the jest config maybe?

@florianrusch
Copy link

Awesome 🙂 It works! Thank you very much for your help!

To wrap up, I had to add the following lines into my jest config:

  transform: {
    '^.+\\.vue$': 'vue3-jest',
    '^.+\\.tsx?$': 'ts-jest',
    '^.+\\.jsx?$': 'babel-jest',
  },
  testEnvironment: 'jsdom',

@lmiller1990 lmiller1990 merged commit 47244cd into vuejs:master Jul 19, 2021
@lmiller1990
Copy link
Member

lmiller1990 commented Jul 19, 2021

27.0.0-alpha.2 is now available. I wrote about the new versioning strategy in the release notes. I marked as pre-release for now.

You can try it with npm install vue3-jest@27.0.0-alpha.2. Note: don't forget to type vue3-jest, not vue-jest. The 3 is important.

@dergunovs
Copy link

Getting errors after update to vue3-jest@27.0.0-alpha.2
I tried to remove node_modules and reinstall the dependencies - no effect.

 FAIL  src/components/Example.spec.js        
  ● Test suite failed to run
    TypeError: Cannot read property 'cwd' of undefined
      at Object.getCacheKey (node_modules/babel-jest/build/index.js:297:33)

Versions in my package.json:

"dependencies": {
  "vue": "^3.1.5",
},
"devDependencies": {
  "@vue/cli-plugin-babel": "^4.5.13",
  "@vue/cli-plugin-unit-jest": "^4.5.13",
  "@vue/test-utils": "^2.0.0-rc.10",
  "babel-core": "^7.0.0-bridge.0",
  "babel-jest": "27.0.6",
  "jest": "27.0.6",
  "vue3-jest": "^27.0.0-alpha.2"
},
"resolutions": {
  "jest": "27.0.6"
}

Jest.config.js:

module.exports = {
  moduleFileExtensions: ['js', 'vue'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '^.+\\.vue$': 'vue3-jest',
  },
  testEnvironment: 'jsdom',
  transformIgnorePatterns: ['/node_modules/'],
  moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' },
};

@cexbrayat
Copy link
Member Author

Interesting. Is it still in error after yarn test:unit --clear-cache?

If so, it would be great if you can share a small repro in a github repo so we could investigate.

@cexbrayat cexbrayat deleted the feat/jest-v27 branch July 19, 2021 11:35
@lmiller1990
Copy link
Member

I think the flag might be --no-cache.

@dergunovs
Copy link

dergunovs commented Jul 22, 2021

I searched "jest" in package-lock.json. Found 24.x.x version in vue/cli-plugin-unit-jest dependencies. Manualy changed it to ^27. Then "npm i". Now everything is working.

@dergunovs
Copy link

dergunovs commented Jul 22, 2021

Ok, it worked only once. Second "npm i" returns jest 24 and errors.
Fixed it with https://github.com/rogeriochaves/npm-force-resolutions
But i think this is a bad practice.

@cexbrayat
Copy link
Member Author

@dergunovs Yeah, it's easier to do with Yarn and its resolution feature. If the alpha phase goes smoothly, we'll update the CLI to support vue3-jest, and we'll be able to have jest 27 support without fussing around the dependency resolutions. I'd recommend using Yarn in the meantime if you want to keep using vue3-jest. Thanks for confirming this was not an issue with vue3-jest 👍

@cexbrayat
Copy link
Member Author

FYI, I opened a feature request to the CLI team to include vue3-jest and jest 27 by default in a project vuejs/vue-cli#6602

@lmiller1990
Copy link
Member

Great!

I will review your other PRs in the next day or two. You should really have push access to this repo, you could ping Evan (I cannot give you access).

cexbrayat added a commit to cexbrayat/vue-test-utils-next that referenced this pull request Jul 30, 2021
Updates jest, ts-jest and babel-jest to v27.
vue-jest v5 does not support jest v27,
so a new vue3-jest package has been introduced (see vuejs/vue-jest#343),
with a version number aligned on the jest version (as ts-jest and babel-jest do).

This commits replaces vue-jest by vue3-jest, and updates the jest config to use this new trasnformer.
This will be the default Vue CLI setup in the future.
cexbrayat added a commit to cexbrayat/vue-test-utils-next that referenced this pull request Aug 30, 2021
Updates jest, ts-jest and babel-jest to v27.
vue-jest v5 does not support jest v27,
so a new vue3-jest package has been introduced (see vuejs/vue-jest#343),
with a version number aligned on the jest version (as ts-jest and babel-jest do).

This commits replaces vue-jest by vue3-jest, and updates the jest config to use this new trasnformer.
This will be the default Vue CLI setup in the future.
cexbrayat added a commit to cexbrayat/vue-test-utils-next that referenced this pull request Feb 11, 2022
Updates jest, ts-jest and babel-jest to v27.
vue-jest v5 does not support jest v27,
so a new vue3-jest package has been introduced (see vuejs/vue-jest#343),
with a version number aligned on the jest version (as ts-jest and babel-jest do).

This commits replaces vue-jest by vue3-jest, and updates the jest config to use this new trasnformer.
This will be the default Vue CLI setup in the future.
cexbrayat added a commit to cexbrayat/vue-test-utils-next that referenced this pull request Feb 13, 2022
Updates jest, ts-jest and babel-jest to v27.
vue-jest v5 does not support jest v27,
so a new vue3-jest package has been introduced (see vuejs/vue-jest#343),
with a version number aligned on the jest version (as ts-jest and babel-jest do).

This commits replaces vue-jest by vue3-jest, and updates the jest config to use this new trasnformer.
This will be the default Vue CLI setup in the future.
lmiller1990 pushed a commit to vuejs/test-utils that referenced this pull request Feb 16, 2022
* chore: update to jest 27

Updates jest, ts-jest and babel-jest to v27.
vue-jest v5 does not support jest v27,
so a new vue3-jest package has been introduced (see vuejs/vue-jest#343),
with a version number aligned on the jest version (as ts-jest and babel-jest do).

This commits replaces vue-jest by vue3-jest, and updates the jest config to use this new trasnformer.
This will be the default Vue CLI setup in the future.

* chore: document hasOwnProperty Jest workaround
@tigohenryschultz
Copy link

Getting errors after update to vue3-jest@27.0.0-alpha.2 I tried to remove node_modules and reinstall the dependencies - no effect.

 FAIL  src/components/Example.spec.js        
  ● Test suite failed to run
    TypeError: Cannot read property 'cwd' of undefined
      at Object.getCacheKey (node_modules/babel-jest/build/index.js:297:33)

Versions in my package.json:

"dependencies": {
  "vue": "^3.1.5",
},
"devDependencies": {
  "@vue/cli-plugin-babel": "^4.5.13",
  "@vue/cli-plugin-unit-jest": "^4.5.13",
  "@vue/test-utils": "^2.0.0-rc.10",
  "babel-core": "^7.0.0-bridge.0",
  "babel-jest": "27.0.6",
  "jest": "27.0.6",
  "vue3-jest": "^27.0.0-alpha.2"
},
"resolutions": {
  "jest": "27.0.6"
}

Jest.config.js:

module.exports = {
  moduleFileExtensions: ['js', 'vue'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '^.+\\.vue$': 'vue3-jest',
  },
  testEnvironment: 'jsdom',
  transformIgnorePatterns: ['/node_modules/'],
  moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' },
};

Was this ever resolved?

@lmiller1990
Copy link
Member

No idea, a repo showing the issue would be helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet