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

Composition API SFC test issue when using Vue 2.7 or the compat Mode #1983

Open
lisilinhart opened this issue Jul 11, 2022 · 24 comments
Open
Labels

Comments

@lisilinhart
Copy link

lisilinhart commented Jul 11, 2022

Subject of the issue

Hi,

this issue is created, after another issue was opened here in vue-testing-library : testing-library/vue-testing-library#275

The core of the problem seems to be in @vue/test-utils:

When using the compat mode or the 2.7 build, the unit tests start failing when using the composition api in the SFC syntax.
I tried using the composition api in a SFC synctax from the 2.7 build itself and this behaviour appears:

<script setup>
import { ref, onBeforeMount, defineProps } from 'vue'

defineProps({
  msg: {
    type: String,
    default: ''
  },
})

const label = ref('init')

onBeforeMount(() => {
  label.value = 'mounted'
})
</script>

<template>
  <div>{{ msg }} - {{ label }}</div>
</template>

results in this testing html

image

If we use the regular export default syntax with the composition api, it seems to be still working.

Steps to reproduce

To reproduce the behavior:

Use this minimal reproduction repo: https://github.com/lisilinhart/vue-2.7-sfc-test-bug-repo

Expected behaviour

When mounting the component with the composition API in a sfc syntax, it should render the component correctly like it does for the options api.

Actual behaviour

The asynchronous text is never rendered in the mounted component.

Possible Solution

@lisilinhart lisilinhart changed the title Composition API test issue when using Vue 2.7 or the compat Mode Composition API SFC test issue when using Vue 2.7 or the compat Mode Jul 11, 2022
@iMuFeng
Copy link

iMuFeng commented Jul 13, 2022

This problem is not caused by @vue/test-utils but vue-jest.

  "jest": {
    "transform": {
      "^.+.vue$": "vue-jest"
    }
  }

When you started testing, you actually called jest. vue-jest will transform SFCComponent.vue to:

(function () {})();
var defaultExport = module.exports.__esModule
  ? module.exports.default
  : module.exports;
var __vue__options__ =
  typeof defaultExport === "function" ? defaultExport.options : defaultExport;
__vue__options__.render = function render() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_vm.label))]);
};
__vue__options__.staticRenderFns = [];

But with @vue/vue2-jest from vuejs/vue-jest#483 it will be transformed to:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

const vue_1 = require("vue");

const vue_2 = require("vue");

exports.default = (0, vue_1.defineComponent)({
  __name: 'SFCComponent',
  props: {
    msg: {
      type: String,
      default: ''
    }
  },

  setup(__props) {
    const label = (0, vue_2.ref)('init');
    (0, vue_2.onBeforeMount)(() => {
      label.value = 'mounted';
    });
    return {
      __sfc: true,
      label
    };
  }

});
//# sourceMappingURL=xxx
var __options__ = typeof exports.default === 'function' ? exports.default.options : exports.default
var render = function render() {
  var _vm = this,
    _c = _vm._self._c,
    _setup = _vm._self._setupProxy
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_setup.label))])
}
var staticRenderFns = []
render._withStripped = true

__options__.render = render
__options__.staticRenderFns = staticRenderFns

@admhpr
Copy link

admhpr commented Jul 13, 2022

not sure if that is correct as there are similar issues here using vitest.

@iMuFeng
Copy link

iMuFeng commented Jul 13, 2022

@admhpr Here is a vue 2.7 unit test example: https://github.com/iMuFeng/vite-vue2-starter

@lisilinhart
Copy link
Author

This problem is not caused by @vue/test-utils but vue-jest.

  "jest": {
    "transform": {
      "^.+.vue$": "vue-jest"
    }
  }

When you started testing, you actually called jest. vue-jest will transform SFCComponent.vue to:

(function () {})();
var defaultExport = module.exports.__esModule
  ? module.exports.default
  : module.exports;
var __vue__options__ =
  typeof defaultExport === "function" ? defaultExport.options : defaultExport;
__vue__options__.render = function render() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_vm.label))]);
};
__vue__options__.staticRenderFns = [];

But with @vue/vue2-jest from vuejs/vue-jest#483 it will be transformed to:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

const vue_1 = require("vue");

const vue_2 = require("vue");

exports.default = (0, vue_1.defineComponent)({
  __name: 'SFCComponent',
  props: {
    msg: {
      type: String,
      default: ''
    }
  },

  setup(__props) {
    const label = (0, vue_2.ref)('init');
    (0, vue_2.onBeforeMount)(() => {
      label.value = 'mounted';
    });
    return {
      __sfc: true,
      label
    };
  }

});
//# sourceMappingURL=xxx
var __options__ = typeof exports.default === 'function' ? exports.default.options : exports.default
var render = function render() {
  var _vm = this,
    _c = _vm._self._c,
    _setup = _vm._self._setupProxy
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_setup.label))])
}
var staticRenderFns = []
render._withStripped = true

__options__.render = render
__options__.staticRenderFns = staticRenderFns

I'm using preset: '@vue/cli-plugin-unit-jest',, which I don't think is using "vue-jest"

@iMuFeng
Copy link

iMuFeng commented Jul 13, 2022

This problem is not caused by @vue/test-utils but vue-jest.

  "jest": {
    "transform": {
      "^.+.vue$": "vue-jest"
    }
  }

When you started testing, you actually called jest. vue-jest will transform SFCComponent.vue to:

(function () {})();
var defaultExport = module.exports.__esModule
  ? module.exports.default
  : module.exports;
var __vue__options__ =
  typeof defaultExport === "function" ? defaultExport.options : defaultExport;
__vue__options__.render = function render() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_vm.label))]);
};
__vue__options__.staticRenderFns = [];

But with @vue/vue2-jest from vuejs/vue-jest#483 it will be transformed to:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

const vue_1 = require("vue");

const vue_2 = require("vue");

exports.default = (0, vue_1.defineComponent)({
  __name: 'SFCComponent',
  props: {
    msg: {
      type: String,
      default: ''
    }
  },

  setup(__props) {
    const label = (0, vue_2.ref)('init');
    (0, vue_2.onBeforeMount)(() => {
      label.value = 'mounted';
    });
    return {
      __sfc: true,
      label
    };
  }

});
//# sourceMappingURL=xxx
var __options__ = typeof exports.default === 'function' ? exports.default.options : exports.default
var render = function render() {
  var _vm = this,
    _c = _vm._self._c,
    _setup = _vm._self._setupProxy
  return _c("div", [_vm._v(_vm._s(_vm.msg) + " - " + _vm._s(_setup.label))])
}
var staticRenderFns = []
render._withStripped = true

__options__.render = render
__options__.staticRenderFns = staticRenderFns

I'm using preset: '@vue/cli-plugin-unit-jest',, which I don't think is using "vue-jest"

You can take a look at this line: https://github.com/lisilinhart/vue-2.7-sfc-test-bug-repo/blob/63ed5b486b037b59c690188493af432a7e860284/yarn.lock#L1643

If you have used @vue/cli 5.x version, it should be @vue/vue2-jest https://github.com/vuejs/vue-cli/blob/b154dbd7aca4b4538e6c483b1d4b817499d7b8eb/packages/%40vue/cli-plugin-unit-jest/package.json#L45

@Weetbix
Copy link

Weetbix commented Jul 14, 2022

Hi @iMuFeng

Check out this test file / repo on the jh/vue-utils-version branch: https://github.com/Weetbix/vue-compat-composition-api-bug-repo/blob/jh/vue-utils-version/test.spec.js

Run yarn test:vue3 to run in vue 3 and notice all tests pass.

Run yarn test:vue-compat to run with the vue compat alias.

All 3 tests fail when using vue in compat mode, and there is no jest-dom dependency, its only using vitest.

@iMuFeng
Copy link

iMuFeng commented Jul 15, 2022

Hi @Weetbix

Your testing of Vue 3.x depends on @vue/[email protected] (https://github.com/vuejs/test-utils/), which I think there must be some bug on combat mode.

But for SFC Vue 2.7 which depends on @vue/[email protected] (https://github.com/vuejs/vue-test-utils).

@Weetbix
Copy link

Weetbix commented Jul 15, 2022

@iMuFeng Ahhhhh I see, sorry for the confusion!

Here is that repo with vue 2.7 and test-utils 1.x: https://github.com/Weetbix/vue-compat-composition-api-bug-repo/tree/jh/vue-utils-v1-vue-27-version

All the tests are passing, so I guess this issue is with vue-jest as you were saying.

Your testing of Vue 3.x depends on @vue/[email protected] (https://github.com/vuejs/test-utils/), which I think there must be some bug on combat mode.

So I will open an issue for vue-compat, vue 3 and test-utils 2.x in that repo 👍

@admhpr
Copy link

admhpr commented Jul 19, 2022

@iMuFeng cheers for the pointers, I switched over to vitest using your example repo and things started breaking.

https://github.com/admhpr/vite-vue2-starter

@lmiller1990
Copy link
Member

The whole back porting of Vue 3 to Vue 2 is making a lot of work for this repo (and old versions of Vue Jest).

I have no bandwidth to work on Vue Test Utils v1/Vue 2/Vue Jest combo right now.

If there's a bug in Vue 3/Vue Test Utils 2 (different repo, as mentioned above) we will actively try to fix/address it.

@kingyue737
Copy link

@lmiller1990 We cannot migrate to Vue 2.7 without test😭😭

@lmiller1990
Copy link
Member

lmiller1990 commented Jul 22, 2022

Probably a silly question - but from a workload point of view, would it be easier to just go straight to Vue 3? Is Vue 2.6 -> 2.7 -> 3.x actually just making more work for your team?

Is anyone interested in helping with this? I can't commit to working on this right now, definitely happy to assist if someone else wants to give it a try.

First step would be to fork this repo and add a failing test case.

@ebisbe
Copy link
Collaborator

ebisbe commented Aug 4, 2022

@kingyue737 this PR is the one you are looking for vuejs/vue-jest#483

@kingyue737
Copy link

kingyue737 commented Aug 4, 2022

Thanks @ebisbe, I'm using vitest and the issue I faced is caused by @vitejs/plugin-vue2 which modifies entry to vue #1982 (comment). vue-test-utils does not need patching.

@lmiller1990
Copy link
Member

I am trying to clean up this repo and get a handle on things.

If anyone is interested in helping, I'd like to get some test cases for Vue 2.7, especially with <script setup>.

@ebisbe
Copy link
Collaborator

ebisbe commented Jan 18, 2023

@lmiller1990 what are you thinking I can help

@lmiller1990
Copy link
Member

lmiller1990 commented Jan 18, 2023

I think we need a few things. At this point, as a mature piece of software (Vue 2 and VTU v1) we should focus on long term maintenance.

  • Issue triage. We've got a ton, we need to find out which are real bugs (eg, "XX doesn't work with Vue 2.7) and just people asking for help (how do I do with ). There's over 150 issues, I'd like to get that under 100.
  • Regarding priorities - this means making sure all existing features work with the latest version of Vue 2 (2.7) including <script setup>. We don't have any tests for that in this library, so I think we probably want to add some, along with some basic smoke tests around all the features (passing props should work, stubs, etc).
  • After we know things generally work with Vue 2.7, we can focus on fixing other, outstanding bugs.

What do you think?

Not sure about the compat mode issue - Vue 3 and VTU v2 works fine with the Vue 3 compat mode to my knowledge.

@ebisbe
Copy link
Collaborator

ebisbe commented Jan 19, 2023

I can help with the initial triage as I think I would be more helpful there. Do you want to move the conversation to somewhere else? ( vuejs discord ? )

@lmiller1990
Copy link
Member

I think working in public is fine, let me get you added as triage - I think we start by labelling issues so we can prioritize and closing stale/old ones.

@lmiller1990
Copy link
Member

@ebisbe done-zo, you should have triage access. I think we probably want to categorize issues, whatever make sense - ideally something like "bug", "Vue 2.7", "composition API" and "needs reproduction".

After that we can go through and try verify any bugs, if we cannot repro, close and move on. 151 issues is daunting, once we trim it down, I think things will be easier. LMK if you need to clarify anything, Discord is fine but in general I prefer work in public, that's what makes OSS great, open collaboration.

@ebisbe
Copy link
Collaborator

ebisbe commented Jan 19, 2023

@lmiller1990 ok, got it. I'll start with those 4 tags and see if I need anymore.

I mentioned the discord as what we are currently talking is not related to this issue. That's all I was thinking.

Edit: I can't add/edit labels

@lmiller1990
Copy link
Member

@ebisbe thanks!

Try now, I elevated your privileges. Please don't push to any of the main branches 🙏

@ebisbe ebisbe added the vue-2.7 label Jan 20, 2023
@ebisbe
Copy link
Collaborator

ebisbe commented Jan 27, 2023

@lmiller1990 all issues tagged. I will start to review old issues as you suggested

@lmiller1990
Copy link
Member

Great, thanks!

Sorry I have not been able to help out much. The issue count is already getting much easier to manage. I wouldn't be scared to close out older issue that don't have reproductions - moving forward, I'd say we close all issues w/o a minimal reproduction - this is what we are doing in Test Utils v2, we don't have time to try and reproduce all the issues on our own.

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

No branches or pull requests

7 participants