test-utils icon indicating copy to clipboard operation
test-utils copied to clipboard

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

Open sevilyilmaz opened this issue 2 years ago • 20 comments

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:

  • @vue/test-utils version: 2.2.2
  • Vue version: 3.2.45
  • node version: 16.17.0
  • npm (or yarn) version: yarn v1.22.17

Additional context

sevilyilmaz avatar Nov 16 '22 16:11 sevilyilmaz

Hi @sevilyilmaz

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

cexbrayat avatar Nov 16 '22 17:11 cexbrayat

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

sevilyilmaz avatar Nov 16 '22 19:11 sevilyilmaz

👍 thanks

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

cexbrayat avatar Nov 16 '22 20:11 cexbrayat

@cexbrayat let me investigate that

xanf avatar Nov 16 '22 21:11 xanf

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

Theiaz avatar Nov 17 '22 08:11 Theiaz

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

stephan-roolvink avatar Nov 17 '22 08:11 stephan-roolvink

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

cexbrayat avatar Nov 17 '22 08:11 cexbrayat

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

lmiller1990 avatar Nov 20 '22 22:11 lmiller1990

@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

sevilyilmaz avatar Nov 21 '22 08:11 sevilyilmaz

#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.

Theiaz avatar Nov 21 '22 10:11 Theiaz

@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

cexbrayat avatar Nov 21 '22 10:11 cexbrayat

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

xanf avatar Nov 21 '22 11:11 xanf

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...)

stefanlivens avatar Nov 22 '22 10:11 stefanlivens

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)

Theiaz avatar Dec 09 '22 11:12 Theiaz

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

sevilyilmaz avatar Mar 03 '23 10:03 sevilyilmaz

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

lmiller1990 avatar Mar 05 '23 22:03 lmiller1990

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

stefan-wiebe avatar May 26 '23 15:05 stefan-wiebe

I have this issue too (

kyrylo93 avatar Jul 03 '23 13:07 kyrylo93

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/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:812:16
 ❯ ReactiveEffect.componentUpdateFn [as fn] ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5657:46
 ❯ ReactiveEffect.run ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/reactivity/dist/reactivity.cjs.js:182:19
 ❯ instance.update ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5770:51
 ❯ setupRenderEffect ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5778:5
 ❯ mountComponent ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5568:5
 ❯ processComponent ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5521:9
 ❯ patch ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5007:11
 ❯ ReactiveEffect.componentUpdateFn [as fn] ../../node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5664:11

kayijyc avatar Jul 04 '23 14:07 kayijyc

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

codeallthethingz avatar Mar 21 '24 19:03 codeallthethingz