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

Behavior of global.components is confusing #845

Open
xanf opened this issue Aug 9, 2021 · 6 comments
Open

Behavior of global.components is confusing #845

xanf opened this issue Aug 9, 2021 · 6 comments

Comments

@xanf
Copy link
Collaborator

xanf commented Aug 9, 2021

I'm struggling to understand the reasoning, why global.components perform two things simultaneously:

  • registers global components (this is perfectly fine)
  • acts as global.stubs, but just for component we are mounting

Second one is provided by this piece of code inside mount:

  if (isObjectComponent(component)) {
    component.components = { ...component.components, ...global.components }
  }

where global.components effectively overwrite local components.

I find this behavior super-confusing:

  • now we have two approaches for stubbing components, and one of them (via global.components) will work only for components, who use Options API
  • relationship between global.stubs and global.components becomes hard-to-explain

For example this test looks super-confusing unless you know what is happening [source]:

 it('allows global stubs to be deactivated without warning', () => {
    const GlobalComponent = {
      template: '<div>Global</div>'
    }
    const spy = jest.spyOn(console, 'warn')
    const wrapper = mount(
      {
        template: '<div><global-component/></div>'
      },
      {
        global: {
          components: {
            GlobalComponent
          },
          stubs: { GlobalComponent: false }
        }
      }
    )

You're like: ...em... what? I'm unstubbing GlobalComponent by passing GlobalComponent: false, but why it is stubbed, we're not using shallowMount?

I see no added benefits in current behavior and would like to suggest dropping it, and matching global.components application API app.component behavior - it simply registers component as global one and nothing more

@xanf
Copy link
Collaborator Author

xanf commented Aug 10, 2021

@lmiller1990 considering I saw some recent activity from you would be happy to hear your thoughts

@lmiller1990
Copy link
Member

lmiller1990 commented Aug 12, 2021

It like the change was made here: #504 to support a use-case in the posva/vue-router-mock library.

I can see why this would be confusing. Have you encountered this use case in your usual development workflow? I have not really found myself using global.stubs and global.components in the same test, I'm guessing this is not a very common edge case.

It looks like reverting it might have some negative impacts, at least on the vue-router-mock library.

@xanf
Copy link
Collaborator Author

xanf commented Aug 12, 2021

@lmiller1990 thank you for giving context! I will take a look and come back today with proposal

@xanf
Copy link
Collaborator Author

xanf commented Aug 29, 2021

@lmiller1990 I've checked that #504 is actually not the issue where problematic code was added
Original source of the problematic code is #116 and after analyzing discussion there I believe it was based at least on assumptions which are not in the play anymore

Regarding "if we meet this in the wild" - I've discovered this while preparing codemod, which "automatically" unpacked non-existent anymore parentComponent to relevant global properties. I still vote for having as simple mental model as possible.

@vpillinger
Copy link

This behavior was very confusing me as well and the main challenge for me was that the globals are registered using app.component() and/or app.use() in Vue. However, this library uses an alternate array syntax for global registration.

Luckily, I was using a custom-built component library so I was able to create an "index" that I could import to this library. I then used a for-loop to register the components in my main.js file.

It seems that this library handles global registration in a completely different way from Vue itself which is very confusing.

@lmiller1990
Copy link
Member

@vpillinger can you share a minimal example showing how Test Utils differs from Vue itself?

Also what do you mean by "array syntax"? You can supply components using an object: https://next.vue-test-utils.vuejs.org/api/#global

import Something from './Something.vue'

mount(Foo, {
  global: {
    components: {
      MyButton: Something,
      InlineComponent: {
        template: `<div>OK</div>`
      }
    }
  }
})

etc.

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

No branches or pull requests

3 participants