-
Notifications
You must be signed in to change notification settings - Fork 264
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: Allow stub out async component without name and without need of async/await #518
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, looking good!! Great contribution.
I think we need to be more thorough in getting the name for un-named components, we should be able to match it using some similar techniques. Assuming the component is the first one in components
and grabbing the name from the key doesn't seem very reliable.
If you are able to try to make this change, please do! If you are stuck I can give it a try. I think you are really close, though.
src/stubs.ts
Outdated
string, | ||
ComponentOptions | ||
> | ||
if (!components || Object.keys(components).length !== 1) return null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it will be a problem. For example
it('stubs async component without name', () => {
const TestComponent = defineComponent({
components: {
Foo: {
template: '<div />'
},
MyComponent: AsyncComponentWithoutName,
},
template: '<MyComponent/>'
})
const wrapper = mount(TestComponent, {
global: {
stubs: {
MyComponent: true
}
}
})
expect(wrapper.html()).toBe('<my-component-stub></my-component-stub>')
})
Fails, because of
components: {
Foo: {
template: '<div />'
},
MyComponent: AsyncComponentWithoutName,
We can't rely on the Object.keys
and getting the first element to capture the name of the component.
What we can do, I think, is use the parent component registry. See here: https://github.com/vuejs/vue-test-utils-next/blob/3e85d6ef3da57e5104f2b2ea1e4ca4b2f6ef75fc/src/stubs.ts#L145
I think we can match up using object identity. Something like above. Maybe...
if (instance && instance.parent) {
// try to infer the name based on local resolution
const registry = (instance.type as any).components
for (const [key, comp] of Object.entries(registry)) {
if (args[0] === comp) {
name = key
}
}
}
That's untested, but there should be a way to find the component and get the name from the key.
I have make it much cleaner now. The original issue was that it has already found the name of the I was wondering that it is not possible to stub out a component by using the name in the registered components rather than the name defined in the component. it('stubs component with different names', () => {
const MyComponent = defineComponent({
name: 'MyComponent',
template: '<span>MyComponent</span>'
})
const TestComponent = defineComponent({
components: {
MyComponentAlias: MyComponent
},
template: '<MyComponentAlias/>'
})
const wrapper = mount(TestComponent, {
global: {
stubs: {
MyComponentAlias: true, // does not work
MyComponent: true // works
}
}
})
expect(wrapper.html()).toBe(
'<my-component-alias-stub></my-component-alias-stub>'
)
}) What do you think? |
Ah, I see. I suppose we should use the key the component is registered under, since that is how you would use the component in your template. The only real usage of It looks like you accomplished it? https://github.com/vuejs/vue-test-utils-next/pull/518/files#diff-81bd0aa44ca1f02347a71cafda7db0708dcb4c2fe47e2c402db1925e2ffe49afR511 Can you clarify: are you asking for help on something, or are you asking what I think of your proposal? I think this makes sense. The only edge case I see is someone registered a component using an alias that is used in another component as the Are you making any more changes? If not I can re-review (tonight) and get this merged. Then we can do a release, it's been a while. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for your investigation, and the thorough tests you added 👍
When you're done addressing the feedback, and have rebased and squashed all the commits, we'll be good to merge.
src/stubs.ts
Outdated
const isAsyncComponentWrapper = (type: VNodeTypes) => | ||
isComponent(type) && | ||
type.__asyncLoader && | ||
type.name === 'AsyncComponentWrapper' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment here indicating that AsyncComponentWrapper
is the name given by vue-next
to defineAsyncComponent
.
I changed the stubs resolving to use the key in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea.
Regarding the code, I'm not of fan of using an array for the names. I think it would be easier to follow by using different variables, like registeredName
and componentName
.
Then instead of calling resolveComponentStubByName
with an array, we could call it once with registeredName
and if nothing is found, another time with componentName
..
IIUC what you're doing, that should not change the result, but would be slightly easier to grasp while reading the code.
@cexbrayat I changed the code according to your suggestion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome job, thanks.
I have dealt some more with stubbing out an async component.
With this PR I want to allow to stub out the async component without the need to provide a name and use
async/await
.The async component can now be stubbed out the same way as a sync component:
It can also be stubbed out like before using the name rather than the key.
I'm not pretty sure about the detection of the
AsyncComponentWrapper
. Maybe someone got a better way.