-
Notifications
You must be signed in to change notification settings - Fork 669
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
fix(setprops): allowed for setProps to be synced with nextTick intervals #1618
Conversation
packages/test-utils/src/wrapper.js
Outdated
nextTick().then(() => { | ||
const isUpdated = Object.keys(data).some(key => { | ||
// $FlowIgnore : Problem with possibly null this.vm | ||
return this.vm[key] === data[key] |
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.
not sure if we need to compare by value here, but figured this is handled above? Might also be a if the same object property is set, but another is not.
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 is comparing by value right?
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.
@lmiller1990 this would be a comparison by reference if we are considering objects/array. But these should be assigned by reference here which makes me think this should be enough to check the reference, unless something is getting mutated under the hood? Might be good to do a value check here to be safe
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.
Kinda hacky but many things are here :)
If you can get the rest of the tests to pass, I think we should be good.
packages/test-utils/src/wrapper.js
Outdated
nextTick().then(() => { | ||
const isUpdated = Object.keys(data).some(key => { | ||
// $FlowIgnore : Problem with possibly null this.vm | ||
return this.vm[key] === data[key] |
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 is comparing by value right?
@lmiller1990 It looks like the tests are timing out? I was able to get them to pass locally so I am unsure of the issue |
ca56456
to
3b03990
Compare
expect(callback.calledOnce) | ||
}) | ||
|
||
it('invokes watchers with immediate set to "true" with deep objects', async () => { |
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.
also added a deep equality test here to test the assign by reference in the code to make sure we don't get into some type of continual recursive loop. This looks to work as intended
Looks like this test is hanging? |
I will take a look at the hanging test. I think we should drop support for < Vue 2.5 sometime. |
Heh nice. I would not have thought about this :D |
@dobromir-hristov I almost wish I didn't think of this 😆 . It's pretty hacky, but wasn't sure of another way, especially since Watcher doesn't seem to do anything with the |
@lmiller1990 any luck with that hanging test? Let me know if I can help in any way! |
I spent a bit of time but I am not sure why is is hanging. There is some way to skip tests for old Vue versions, you could give that a shot (if that's the reason it's hanging). |
@lmiller1990 is there a config val in CI that handles that? Otherwise, I could just use |
@AtofStryker sorry, I mean you can use this helper:
|
setProps in certain cases was being blown away by nextTick intervals. If the property is not up to date, setProps will be called again to sync the changes. fix vuejs#1419
3b03990
to
fa669fa
Compare
@lmiller1990 I figured out why the test was hanging. I completely forgot the |
Co-authored-by: Bill Glesias <[email protected]>
Haha, so the test was actually correctly helping us out and catching the |
@AtofStryker if I may, did you happen to figure out why the next tick caused the |
this.vm[key] === data[key] || this.vm.$attrs[key] === data[key] | ||
) | ||
}) | ||
return !isUpdated ? this.setProps(data).then(resolve()) : resolve() |
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.
Shouldn't this be
.then(() => resolve())
instead of
.then(resolve())
?
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.
EDIT: ignore this, I forgot that this was overriding the method, so we know it's always returning a promise
Maybe the typedef could be updated
Additionally, the signature on setProps claims to potentially return void
interface BaseWrapper {
setProps (props: object): Promise<void> | void
}
so I'm getting warnings on
? this.setProps(data).then(`
property 'then' does not exist on type 'void | Promise<void>'.
Property 'then' does not exist on type 'void'
maybe I'm missing something, I'm just trying to backport the fix for my project
Janky backport function if anyone cares
/**
* Bug: setProps doesn't play nice when there exists a watcher with immediate:true
* https://github.com/vuejs/vue-test-utils/pull/1618
*/
function setPropsForSure(
wrapper: Wrapper<CombinedVueInstance<any, any, any, any, any>>,
data: any,
) {
return new Promise(resolve => {
wrapper.setProps(data);
wrapper.vm.$nextTick().then(() => {
const isUpdated = Object.keys(data).every(key => {
return (
// $FlowIgnore : Problem with possibly null this.vm
wrapper.vm[key] === data[key] || wrapper.vm.$attrs[key] === data[key]
);
});
if (isUpdated) {
return resolve();
}
let result = setPropsForSure(wrapper, data);
if (result) {
result.then(() => resolve());
} else {
resolve();
}
});
});
}
return nextTick() | ||
return new Promise(resolve => { | ||
nextTick().then(() => { | ||
const isUpdated = Object.keys(data).some(key => { |
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.
Shouldn't this use .every
?
Otherwise, setting new props where one but not all of the new values is the same as the old could falsely signal that the update succeeded.
Not sure if this is the culprit, but we have a test that appears to succeed, but never finishes. i.e the test reports success, but Not a full repro, but the test is something like it('should use foo\'s dates when bar hasn\'t been set', () => {
expect.assertions(2);
wrapper.setProps({
a: {
...a,
endTime: '2020-01-02',
startTime: '2020-01-01',
},
b: {
endTime: '2020-01-02',
startTime: '2020-01-01',
},
});
expect(wrapper.vm.bar).toBeTruthy();
wrapper.setProps({
a: {
...a,
endTime: '2020-01-02',
startTime: '2020-01-01',
},
b: {
endTime: '2020-01-01',
startTime: '2020-01-01',
},
});
expect(wrapper.vm.bar).toBeFalsy();
}); This test passes very quickly (about one second), but 10 minutes later and jest is still doing...something. This is fixed by doing it('should use foo\'s dates when bar hasn\'t been set', async () => {
expect.assertions(2);
await wrapper.setProps({
a: {
...a,
endTime: '2020-01-02',
startTime: '2020-01-01',
},
b: {
endTime: '2020-01-02',
startTime: '2020-01-01',
},
});
expect(wrapper.vm.bar).toBeTruthy();
await wrapper.setProps({
a: {
...a,
endTime: '2020-01-02',
startTime: '2020-01-01',
},
b: {
endTime: '2020-01-01',
startTime: '2020-01-01',
},
});
expect(wrapper.vm.bar).toBeFalsy();
}); |
We should update the docs to encourage people to always do Actually instead of using |
Well for me, using |
@vegerot, I can't solve the same issue with awaiting. Does anyone know more about this weird issue and why it's happening? |
setProps in certain cases was being blown away by nextTick intervals. If the property is not up to
date, setProps will be called again to sync the changes.
fix #1419
What kind of change does this PR introduce? (check at least one)
Does this PR introduce a breaking change? (check one)
If yes, please describe the impact and migration path for existing applications:
The PR fulfills these requirements:
dev
branch.fix #xxx[,#xxx]
, where "xxx" is the issue number)If adding a new feature, the PR's description includes:
Other information: