From 771075fd64757bba06dee7a75aa839472a09cc52 Mon Sep 17 00:00:00 2001 From: Victor van Poppelen Date: Wed, 18 Dec 2019 21:27:42 -0800 Subject: [PATCH 1/8] test: ensure Wrapper.setChecked() is a no-op for checked checkboxes --- test/specs/wrapper/setChecked.spec.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/specs/wrapper/setChecked.spec.js b/test/specs/wrapper/setChecked.spec.js index 571a218f5..33c1d9592 100644 --- a/test/specs/wrapper/setChecked.spec.js +++ b/test/specs/wrapper/setChecked.spec.js @@ -55,6 +55,28 @@ describeWithShallowAndMount('setChecked', mountingMethod => { expect(wrapper.find('.counter').text()).to.equal('4') }) + it('should trigger a change event when called on a checkbox', () => { + const listeners = { change: sinon.spy() } + const input = mountingMethod({ + template: ``, + }, { listeners }) + + input.setChecked() + + expect(listeners.change).to.have.been.called + }); + + it('should not trigger a change event if the checkbox is already checked', () => { + const listeners = { change: sinon.spy() } + const input = mountingMethod({ + template: ``, + }, { listeners }) + + input.setChecked() + + expect(listeners.change).not.to.have.been.called + }); + it('updates dom with radio v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) @@ -67,7 +89,7 @@ describeWithShallowAndMount('setChecked', mountingMethod => { expect(wrapper.text()).to.contain('radioFooResult') }) - it('changes state the right amount of times with checkbox v-model', async () => { + it('changes state the right amount of times with radio v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const radioBar = wrapper.find('#radioBar') const radioFoo = wrapper.find('#radioFoo') From 1ee1fa04f80fb797a5f3b4717c5ea19fa29c34b1 Mon Sep 17 00:00:00 2001 From: Victor van Poppelen Date: Wed, 18 Dec 2019 21:38:27 -0800 Subject: [PATCH 2/8] test: ensure Wrapper.setChecked() is a no-op for selected radios Selecting already-selected radio buttons or checking already-checked checkboxes should not trigger events. --- test/specs/wrapper/setChecked.spec.js | 38 +++++++++++++++++++++------ 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/test/specs/wrapper/setChecked.spec.js b/test/specs/wrapper/setChecked.spec.js index 33c1d9592..a6f536205 100644 --- a/test/specs/wrapper/setChecked.spec.js +++ b/test/specs/wrapper/setChecked.spec.js @@ -57,22 +57,22 @@ describeWithShallowAndMount('setChecked', mountingMethod => { it('should trigger a change event when called on a checkbox', () => { const listeners = { change: sinon.spy() } - const input = mountingMethod({ - template: ``, - }, { listeners }) - input.setChecked() + mountingMethod( + { template: `` }, + { listeners }, + ).setChecked() expect(listeners.change).to.have.been.called }); it('should not trigger a change event if the checkbox is already checked', () => { const listeners = { change: sinon.spy() } - const input = mountingMethod({ - template: ``, - }, { listeners }) - input.setChecked() + mountingMethod( + { template: `` }, + { listeners }, + ).setChecked() expect(listeners.change).not.to.have.been.called }); @@ -111,6 +111,28 @@ describeWithShallowAndMount('setChecked', mountingMethod => { expect(wrapper.find('.counter').text()).to.equal('4') }) + it('should trigger a change event when called on a radio button', () => { + const listeners = { change: sinon.spy() } + + mountingMethod( + { template: `` }, + { listeners }, + ).setChecked() + + expect(listeners.change).to.have.been.called + }); + + it('should not trigger a change event if the radio button is already selected', () => { + const listeners = { change: sinon.spy() } + + mountingMethod( + { template: `` }, + { listeners }, + ).setChecked() + + expect(listeners.change).not.to.have.been.called + }); + it('throws error if checked param is not boolean', () => { const message = 'wrapper.setChecked() must be passed a boolean' const wrapper = mountingMethod(ComponentWithInput) From 562bf11676f2d57f3272e9554fbf38ac7010a453 Mon Sep 17 00:00:00 2001 From: Victor van Poppelen Date: Wed, 18 Dec 2019 21:54:44 -0800 Subject: [PATCH 3/8] fix: ensure Wrapper.setChecked() idempotence --- packages/test-utils/src/wrapper.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index 4810e75da..866347e40 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -375,6 +375,10 @@ export default class Wrapper implements BaseWrapper { ) } + if (this.element.checked === checked) { + return + } + if (event !== 'click' || isPhantomJS) { // $FlowIgnore this.element.selected = true From f63eda294b30f25a223b9e50dca0bf782df6ef79 Mon Sep 17 00:00:00 2001 From: Victor van Poppelen Date: Wed, 18 Dec 2019 22:28:30 -0800 Subject: [PATCH 4/8] test: fix Wrapper.setChecked() test compatibility Older versions of Vue use the `click` DOM event for updating radio/checkbox `v-model`s. --- test/specs/wrapper/setChecked.spec.js | 102 ++++++++++++++++---------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/test/specs/wrapper/setChecked.spec.js b/test/specs/wrapper/setChecked.spec.js index a6f536205..ec5c9a344 100644 --- a/test/specs/wrapper/setChecked.spec.js +++ b/test/specs/wrapper/setChecked.spec.js @@ -56,26 +56,41 @@ describeWithShallowAndMount('setChecked', mountingMethod => { }) it('should trigger a change event when called on a checkbox', () => { - const listeners = { change: sinon.spy() } - - mountingMethod( - { template: `` }, - { listeners }, - ).setChecked() - - expect(listeners.change).to.have.been.called - }); + const listener = sinon.spy() + + mountingMethod({ + // For compatibility with earlier versions of Vue that use the `click` + // event for updating `v-model`. + template: ` + + `, + methods: { listener }, + }).setChecked() + + expect(listener).to.have.been.called + }) it('should not trigger a change event if the checkbox is already checked', () => { - const listeners = { change: sinon.spy() } - - mountingMethod( - { template: `` }, - { listeners }, - ).setChecked() - - expect(listeners.change).not.to.have.been.called - }); + const listener = sinon.spy() + + mountingMethod({ + template: ` + + `, + methods: { listener }, + }).setChecked() + + expect(listener).not.to.have.been.called + }) it('updates dom with radio v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) @@ -112,26 +127,39 @@ describeWithShallowAndMount('setChecked', mountingMethod => { }) it('should trigger a change event when called on a radio button', () => { - const listeners = { change: sinon.spy() } - - mountingMethod( - { template: `` }, - { listeners }, - ).setChecked() - - expect(listeners.change).to.have.been.called - }); - - it('should not trigger a change event if the radio button is already selected', () => { - const listeners = { change: sinon.spy() } - - mountingMethod( - { template: `` }, - { listeners }, - ).setChecked() + const listener = sinon.spy() + + mountingMethod({ + template: ` + + `, + methods: { listener }, + }).setChecked() + + expect(listener).to.have.been.called + }) - expect(listeners.change).not.to.have.been.called - }); + it('should not trigger a change event if the radio button is already checked', () => { + const listener = sinon.spy() + + mountingMethod({ + template: ` + + `, + methods: { listener }, + }).setChecked() + + expect(listener).not.to.have.been.called + }) it('throws error if checked param is not boolean', () => { const message = 'wrapper.setChecked() must be passed a boolean' From e229e372dc2d34086a0023bcdf7706011c82a18b Mon Sep 17 00:00:00 2001 From: Victor van Poppelen Date: Wed, 18 Dec 2019 22:40:09 -0800 Subject: [PATCH 5/8] test: ensure Wrapper.setSelected() idempotency --- test/specs/wrapper/setSelected.spec.js | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/specs/wrapper/setSelected.spec.js b/test/specs/wrapper/setSelected.spec.js index 102c9336a..b19d0a8da 100644 --- a/test/specs/wrapper/setSelected.spec.js +++ b/test/specs/wrapper/setSelected.spec.js @@ -39,6 +39,38 @@ describeWithShallowAndMount('setSelected', mountingMethod => { expect(wrapper.text()).to.contain('selectA') }) + it('should trigger a change event on the parent +