vuejs / test-utils

Vue Test Utils for Vue 3
https://test-utils.vuejs.org
MIT License
1.03k stars 245 forks source link

Bug: _ctx is missing functions that are returned from the setup functions #1870

Open sevilyilmaz opened 1 year ago

sevilyilmaz commented 1 year ago

Hi, I started getting the error below after upgrading from 2.2.1 to 2.2.2.

    Received message:   "_ctx.hasIcon is not a function"

          209 |           props.countryCode.charAt(0).toUpperCase() +
          210 |           props.countryCode.slice(1),
        > 211 |       };
              |                   ^
          212 |     });
          213 |
          214 |     const hasIcon = () => Boolean(slots.icon);

          at src/components/avatar/Avatar.vue:211:139
          at renderFnWithContext (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:845:19)
          at renderSlot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:2996:55)
          at src/components/box/Box.vue:146:59
          at renderFnWithContext (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:845:19)
          at normalizeChildren (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6939:42)
          at createBaseVNode (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6688:9)
          at _createVNode (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6790:12)
          at createVNodeWithArgsTransform (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6645:12)
          at createBlock (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6617:23)
          at Proxy.render (src/components/box/Box.vue:142:54)
          at renderComponentRoot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:891:44)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5570:57)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5577:21)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5577:21)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at render (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6198:13)
          at mount (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4432:25)
          at Object.app.mount (node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:1549:23)
          at _mount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:8215:18)
          at createWrapper (src/lib/test-utils.js:19:10)
          at src/components/avatar/Avatar.test.js:170:53
          at Object.<anonymous> (node_modules/expect/build/toThrowMatchers.js:83:11)
          at Object.throwingMatcher [as toThrowError] (node_modules/expect/build/index.js:382:21)
          at testBody (src/components/avatar/Avatar.test.js:174:16)
          at testErrors (src/lib/test-utils.js:87:3)
          at Object.<anonymous> (src/components/avatar/Avatar.test.js:169:35)

      172 |                 slots: { icon: '<div />' },
      173 |               }),
    > 174 |             ),
          |                ^
      175 |           ).toThrowError(ERRORS.ONLY_SVG);
      176 |         });
      177 |       });

      at testBody (src/components/avatar/Avatar.test.js:174:16)
      at testErrors (src/lib/test-utils.js:87:3)
      at Object.<anonymous> (src/components/avatar/Avatar.test.js:169:35)

Describe the bug I do slot validations in the setup function, sometimes to hide certain HTML elements and sometimes for their content. I created a helper to capture the errors.

function testErrors(testBody) {
  /**
   * @see https://github.com/vuejs/vue-test-utils/issues/641#issuecomment-443651405
   * @see https://github.com/vuejs/test-utils/issues/1096
   */
  const spyError = jest
    .spyOn(global.console, 'error')
    .mockImplementation(() => {});

  testBody();

  spyError.mockRestore();
}

I write the tests like this:

it('throws an error', () => {
  testErrors(() => {
    expect(() =>
      // mount component
    ).toThrowError(ERROR_MESSAGE);
  });
});

When I upgraded to 2.2.2 I started getting the error above. It seems the functions that I use in the template are not being populated from the setup function.

I assume the problem that I'm having is related to this change https://github.com/vuejs/test-utils/commit/74c9af4e35430fb0c3b5cd7366d349b1a8160fd9

To Reproduce

<template>
  <div v-if="hasSlot('test')">
    <slot name="test"></slot>
  </div>
  <slot></slot>
</template>

<script>
export default {
  setup(_, { slots }) {
    const hasSlot = (slotName) => Boolean(slots[slotName]);

    if (!hasSlot('default')) throw new Error('The default slot is required');

    return { hasSlot }
  }
}
</script>

Expected behavior

The component should be able to use the functions that are returned from the setup function.

Related information:

Additional context

cexbrayat commented 1 year ago

Hi @sevilyilmaz

Can you provide us a small repro online using https://stackblitz.com/edit/vitest-dev-vitest-qoiwy3?file=package.json&initialPath=__vitest__ ?

sevilyilmaz commented 1 year ago

Hi @cexbrayat Upgrading to 2.2.3 didn't solve my issue. Here is the reproduction link: https://stackblitz.com/edit/vitest-dev-vitest-9qeea3?file=test/basic.test.ts

cexbrayat commented 1 year ago

👍 thanks

@xanf What do you think we should do in that case?

xanf commented 1 year ago

@cexbrayat let me investigate that

Theiaz commented 1 year ago

Hey,

had the same issue since yesterday. Got a minimal example repo to reproduce it. Have a look at the README and he commit history to reproduce the error and potentially fixes.

However, we got those errors since 2.2.3. Previous versions are working.

Edit: Maybe this post is more related with https://github.com/vuejs/test-utils/issues/1869

stephan-roolvink commented 1 year ago

I have encountered this same issue with version 2.2.3 on i18n. TypeError: _ctx.$t is not a function

cexbrayat commented 1 year ago

@stephan-roolvink @Theiaz Yes, you are probably encountering #1869 We already have a fix, we just need to merge and release it.

lmiller1990 commented 1 year ago

1869 is out, can anyone encountering this issue try updating to 2.2.4 and see if that fixes it?

sevilyilmaz commented 1 year ago

@lmiller1990 I still have the error after bumping up to 2.2.4. Here is the updated repro link if it helps https://stackblitz.com/edit/vitest-dev-vitest-ezvqg2?file=test%2Fbasic.test.ts

Theiaz commented 1 year ago

1869 is out, can anyone encountering this issue try updating to 2.2.4 and see if that fixes it?

The fix is working at my example repo.

cexbrayat commented 1 year ago

@Theiaz 👍 I think it should work for @stephan-roolvink as well because you were in fact encountering another issue

The issue @sevilyilmaz has is another one, and we need @xanf feedback

xanf commented 1 year ago

Yeah, I'm still looking if we could fix it in vue core, because I'm still looking for non-ugly workaround in VTU

stefanlivens commented 1 year ago

we still have the same error. downgrading to 2.2.2 fixes it immediately... using a combination of options api and composition api in our project. and since 2.2.3 we get this problem: global mocks just disappear (in our case, we 'enhanced' the mount/shallowMount with mocks for all vue-i18n methods, so all our mount/shallowMount have this mocked vue-i18n methods, even adding a mocked $router just ... disappears...)

Theiaz commented 1 year ago

We are still investigating some strange behaviour together with setup-option and vue router (nested routing). Tests keeps failing, only rollback to 2.2.2 solves it.

I created an example repository on stackblitz.

console.warn
    [Vue warn]: Property "$route" was accessed during render but is not defined on instance. 
      at <Page ref="VTU_COMPONENT" > 
      at <VTUROOT>

      31 | </script>
      32 |

      at warn (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:40:17)
      at Object.get (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3172:17)
      at Proxy.$route (src/views/Page.vue:33:19)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
      at ComputedRefImpl.get value [as value] (node_modules/@vue/reactivity/dist/reactivity.cjs.js:1142:39)
      at Object.get [as hasPrevPage] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3452:30)
      at Object.get (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:3127:27)
      at Object.get (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:8140:42)
      at Proxy.hasPrevPage (src/views/Page.vue:55:251)
      at renderComponentRoot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:891:44)
      at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5570:57)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
      at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
      at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
      at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
      at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
      at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5577:21)
      at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
      at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
      at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
      at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
      at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
      at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
      at render (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6198:13)
      at mount (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4432:25)
      at Object.app.mount (node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:1549:23)
      at mount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:8245:18)
      at shallowMount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:8263:12)
      at Object.eval (src/views/Page.spec.js:15:27)
sevilyilmaz commented 1 year ago

Are there any updates? I'm kind of stuck to v2.2.2 because of this issue.

lmiller1990 commented 1 year ago

Did we ever isolate the commit that broke this? That'd be the first step to finding a fix.

stefan-wiebe commented 1 year ago

FYI I have the same issue except with $setup.t, using script setup and vitest. The earliest working version is v2.2.1.

kyrylo93 commented 1 year ago

I have this issue too (

kayijyc commented 1 year ago

FYI I have the same issue except with $setup.t, using script setup and vitest. The earliest working version is v2.2.1.

I have the same issue with <script setup />. I have downgraded to v2.2.1 and it worked. I've also tried v2.2.2 but it doesn't solve the issue. I can confirm that the latest working version is v2.2.1 as @stefan-wiebe said.

It seems that my issue only happens when t (from vue-i18n) is being used directly in the template. If I extract the t() functionality in a computed property and use that computed property in the template, it works.

TypeError: $setup.t is not a function
<template>
      2|   <p>{{ t('title') }}</p>
       |         ^
  ❯ renderComponentRoot ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:812:16
 ❯ ReactiveEffect.componentUpdateFn [as fn] ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5657:46
 ❯ ReactiveEffect.run ../../node_modules/.pnpm/@vue+reactivity@3.3.4/node_modules/@vue/reactivity/dist/reactivity.cjs.js:182:19
 ❯ instance.update ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5770:51
 ❯ setupRenderEffect ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5778:5
 ❯ mountComponent ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5568:5
 ❯ processComponent ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5521:9
 ❯ patch ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5007:11
 ❯ ReactiveEffect.componentUpdateFn [as fn] ../../node_modules/.pnpm/@vue+runtime-core@3.3.4/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5664:11
codeallthethingz commented 6 months ago

I have this issue too, had to downgrade to 2.2.1 to get test utils to find my computed functions.