From ecd4bcf983422189e903c3e466f07020203835c1 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Vitullo Date: Thu, 7 Jun 2018 08:26:53 +0200 Subject: [PATCH 1/4] initial implementation --- packages/test-utils/src/config.js | 3 +- packages/test-utils/src/wrapper.js | 70 +++++++++++++++++------------- test/specs/config.spec.js | 33 ++++++++++++++ 3 files changed, 75 insertions(+), 31 deletions(-) diff --git a/packages/test-utils/src/config.js b/packages/test-utils/src/config.js index 4271c8ec6..6e8959c47 100644 --- a/packages/test-utils/src/config.js +++ b/packages/test-utils/src/config.js @@ -9,5 +9,6 @@ export default { mocks: {}, methods: {}, provide: {}, - logModifiedComponents: true + logModifiedComponents: true, + silentWarning: true } diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index d95678e33..9d9856f42 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -9,6 +9,7 @@ import { NAME_SELECTOR, FUNCTIONAL_OPTIONS } from './consts' +import config from './config' import { vmCtorMatchesName, vmCtorMatchesSelector, @@ -26,6 +27,13 @@ import { orderWatchers } from './order-watchers' +const silent = function (fn) { + const originalConfig = Vue.config.silent + Vue.config.silent = config.silentWarning + fn.apply(this) + Vue.config.silent = originalConfig +} + export default class Wrapper implements BaseWrapper { vnode: VNode | null; vm: Component | null; @@ -507,40 +515,42 @@ export default class Wrapper implements BaseWrapper { * Sets vm props */ setProps (data: Object) { - if (this.isFunctionalComponent) { - throwError('wrapper.setProps() cannot be called on a functional component') - } - if (!this.isVueInstance() || !this.vm) { - throwError('wrapper.setProps() can only be called on a Vue instance') - } - if (this.vm && this.vm.$options && !this.vm.$options.propsData) { - this.vm.$options.propsData = {} - } - Object.keys(data).forEach((key) => { - // Ignore properties that were not specified in the component options - // $FlowIgnore : Problem with possibly null this.vm - if (!this.vm.$options._propKeys || !this.vm.$options._propKeys.some(prop => prop === key)) { - throwError(`wrapper.setProps() called with ${key} property which is not defined on component`) + silent(() => { + if (this.isFunctionalComponent) { + throwError('wrapper.setProps() cannot be called on a functional component') + } + if (!this.isVueInstance() || !this.vm) { + throwError('wrapper.setProps() can only be called on a Vue instance') } + if (this.vm && this.vm.$options && !this.vm.$options.propsData) { + this.vm.$options.propsData = {} + } + Object.keys(data).forEach((key) => { + // Ignore properties that were not specified in the component options + // $FlowIgnore : Problem with possibly null this.vm + if (!this.vm.$options._propKeys || !this.vm.$options._propKeys.some(prop => prop === key)) { + throwError(`wrapper.setProps() called with ${key} property which is not defined on component`) + } - // $FlowIgnore : Problem with possibly null this.vm - if (this.vm._props) { - this.vm._props[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$props - this.vm.$props[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$options - this.vm.$options.propsData[key] = data[key] - } else { // $FlowIgnore : Problem with possibly null this.vm - this.vm[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$options - this.vm.$options.propsData[key] = data[key] - } - }) + if (this.vm._props) { + this.vm._props[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$props + this.vm.$props[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$options + this.vm.$options.propsData[key] = data[key] + } else { + // $FlowIgnore : Problem with possibly null this.vm + this.vm[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$options + this.vm.$options.propsData[key] = data[key] + } + }) - // $FlowIgnore : Problem with possibly null this.vm - this.vnode = this.vm._vnode - orderWatchers(this.vm || this.vnode.context.$root) + // $FlowIgnore : Problem with possibly null this.vm + this.vnode = this.vm._vnode + orderWatchers(this.vm || this.vnode.context.$root) + }) } /** diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js index 94820285e..7f0ae19c3 100644 --- a/test/specs/config.spec.js +++ b/test/specs/config.spec.js @@ -2,6 +2,7 @@ import { describeWithShallowAndMount, vueVersion } from '~resources/utils' +import ComponentWithProps from '~resources/components/component-with-props.vue' import { itDoNotRunIf, itSkipIf @@ -137,6 +138,38 @@ describeWithShallowAndMount('config', (mountingMethod) => { expect(wrapper.contains(TransitionStub)).to.equal(false) }) + it('doesn\'t throw Vue warning when silentWarning is set to true', () => { + config.silentWarning = true + const localVue = createLocalVue() + const wrapper = mountingMethod(ComponentWithProps, { + propsData: { + prop1: 'example' + }, + localVue + }) + expect(wrapper.vm.prop1).to.equal('example') + wrapper.setProps({ + prop1: 'new value' + }) + expect(consoleError.called).to.equal(false) + }) + + it('does throw Vue warning when silentWarning is set to false', () => { + config.silentWarning = false + const localVue = createLocalVue() + const wrapper = mountingMethod(ComponentWithProps, { + propsData: { + prop1: 'example' + }, + localVue + }) + expect(wrapper.vm.prop1).to.equal('example') + wrapper.setProps({ + prop1: 'new value' + }) + expect(consoleError.called).to.equal(true) + }) + itSkipIf( vueVersion < 2.3, 'does not log when component is extended if logModifiedComponents is false', () => { From 35c39273aff172b8295ecd0f2f730decd2bcee0c Mon Sep 17 00:00:00 2001 From: Francesco Paolo Vitullo Date: Thu, 7 Jun 2018 08:28:31 +0200 Subject: [PATCH 2/4] simple procedure --- packages/test-utils/src/wrapper.js | 72 ++++++++++++++---------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index 9d9856f42..470cf08f5 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -27,13 +27,6 @@ import { orderWatchers } from './order-watchers' -const silent = function (fn) { - const originalConfig = Vue.config.silent - Vue.config.silent = config.silentWarning - fn.apply(this) - Vue.config.silent = originalConfig -} - export default class Wrapper implements BaseWrapper { vnode: VNode | null; vm: Component | null; @@ -515,42 +508,43 @@ export default class Wrapper implements BaseWrapper { * Sets vm props */ setProps (data: Object) { - silent(() => { - if (this.isFunctionalComponent) { - throwError('wrapper.setProps() cannot be called on a functional component') - } - if (!this.isVueInstance() || !this.vm) { - throwError('wrapper.setProps() can only be called on a Vue instance') - } - if (this.vm && this.vm.$options && !this.vm.$options.propsData) { - this.vm.$options.propsData = {} + const originalConfig = Vue.config.silent + Vue.config.silent = config.silentWarning + if (this.isFunctionalComponent) { + throwError('wrapper.setProps() cannot be called on a functional component') + } + if (!this.isVueInstance() || !this.vm) { + throwError('wrapper.setProps() can only be called on a Vue instance') + } + if (this.vm && this.vm.$options && !this.vm.$options.propsData) { + this.vm.$options.propsData = {} + } + Object.keys(data).forEach((key) => { + // Ignore properties that were not specified in the component options + // $FlowIgnore : Problem with possibly null this.vm + if (!this.vm.$options._propKeys || !this.vm.$options._propKeys.some(prop => prop === key)) { + throwError(`wrapper.setProps() called with ${key} property which is not defined on component`) } - Object.keys(data).forEach((key) => { - // Ignore properties that were not specified in the component options - // $FlowIgnore : Problem with possibly null this.vm - if (!this.vm.$options._propKeys || !this.vm.$options._propKeys.some(prop => prop === key)) { - throwError(`wrapper.setProps() called with ${key} property which is not defined on component`) - } - - // $FlowIgnore : Problem with possibly null this.vm - if (this.vm._props) { - this.vm._props[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$props - this.vm.$props[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$options - this.vm.$options.propsData[key] = data[key] - } else { - // $FlowIgnore : Problem with possibly null this.vm - this.vm[key] = data[key] - // $FlowIgnore : Problem with possibly null this.vm.$options - this.vm.$options.propsData[key] = data[key] - } - }) // $FlowIgnore : Problem with possibly null this.vm - this.vnode = this.vm._vnode - orderWatchers(this.vm || this.vnode.context.$root) + if (this.vm._props) { + this.vm._props[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$props + this.vm.$props[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$options + this.vm.$options.propsData[key] = data[key] + } else { + // $FlowIgnore : Problem with possibly null this.vm + this.vm[key] = data[key] + // $FlowIgnore : Problem with possibly null this.vm.$options + this.vm.$options.propsData[key] = data[key] + } }) + + // $FlowIgnore : Problem with possibly null this.vm + this.vnode = this.vm._vnode + orderWatchers(this.vm || this.vnode.context.$root) + Vue.config.silent = originalConfig } /** From e0bd7c78cf4ccd438241a2c71ac9b60a14e45d4f Mon Sep 17 00:00:00 2001 From: Francesco Paolo Vitullo Date: Thu, 7 Jun 2018 08:50:34 +0200 Subject: [PATCH 3/4] changing config name --- packages/test-utils/src/config.js | 2 +- packages/test-utils/src/wrapper.js | 2 +- test/specs/config.spec.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/test-utils/src/config.js b/packages/test-utils/src/config.js index 6e8959c47..d31342b0b 100644 --- a/packages/test-utils/src/config.js +++ b/packages/test-utils/src/config.js @@ -10,5 +10,5 @@ export default { methods: {}, provide: {}, logModifiedComponents: true, - silentWarning: true + silentWarnings: true } diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index 470cf08f5..6a4f269f0 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -509,7 +509,7 @@ export default class Wrapper implements BaseWrapper { */ setProps (data: Object) { const originalConfig = Vue.config.silent - Vue.config.silent = config.silentWarning + Vue.config.silent = config.silentWarnings if (this.isFunctionalComponent) { throwError('wrapper.setProps() cannot be called on a functional component') } diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js index 7f0ae19c3..aa60fef37 100644 --- a/test/specs/config.spec.js +++ b/test/specs/config.spec.js @@ -138,8 +138,8 @@ describeWithShallowAndMount('config', (mountingMethod) => { expect(wrapper.contains(TransitionStub)).to.equal(false) }) - it('doesn\'t throw Vue warning when silentWarning is set to true', () => { - config.silentWarning = true + it('doesn\'t throw Vue warning when silentWarnings is set to true', () => { + config.silentWarnings = true const localVue = createLocalVue() const wrapper = mountingMethod(ComponentWithProps, { propsData: { @@ -154,8 +154,8 @@ describeWithShallowAndMount('config', (mountingMethod) => { expect(consoleError.called).to.equal(false) }) - it('does throw Vue warning when silentWarning is set to false', () => { - config.silentWarning = false + it('does throw Vue warning when silentWarnings is set to false', () => { + config.silentWarnings = false const localVue = createLocalVue() const wrapper = mountingMethod(ComponentWithProps, { propsData: { From 7aa7c85b4562363ffdcc5fadbec8cb9b24a16572 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Vitullo Date: Sat, 9 Jun 2018 12:38:58 +0200 Subject: [PATCH 4/4] adding better test handling and documentation to the config for silentWarnings --- docs/api/config.md | 14 ++++++++++++++ test/specs/config.spec.js | 9 ++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/api/config.md b/docs/api/config.md index 3b33cf758..74b35b006 100644 --- a/docs/api/config.md +++ b/docs/api/config.md @@ -94,3 +94,17 @@ import VueTestUtils from '@vue/test-utils' VueTestUtils.config.logModifiedComponents = false ``` + +### `silentWarnings` + +- type: `Boolean` +- default: `true` + +It suppresses warnings triggered by Vue while mutating component's observables (e.g. props). When set to `false`, all warnings are visible in the console. This is a configurable way which relies on `Vue.config.silent`. +Example: + +```js +import VueTestUtils from '@vue/test-utils' + +VueTestUtils.config.silentWarnings = false +``` diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js index aa60fef37..2e094ca7e 100644 --- a/test/specs/config.spec.js +++ b/test/specs/config.spec.js @@ -11,15 +11,17 @@ import { config, TransitionStub, TransitionGroupStub, createLocalVue } from '~vu import Vue from 'vue' describeWithShallowAndMount('config', (mountingMethod) => { - let configStubsSave - let consoleError - let configLogSave + let configStubsSave, + consoleError, + configLogSave, + configSilentWarningsSave beforeEach(() => { TransitionGroupStub.name = 'another-temp-name' TransitionStub.name = 'a-temp-name' configStubsSave = config.stubs configLogSave = config.logModifiedComponents + configSilentWarningsSave = config.silentWarnings consoleError = sinon.stub(console, 'error') }) @@ -28,6 +30,7 @@ describeWithShallowAndMount('config', (mountingMethod) => { TransitionStub.name = 'transition' config.stubs = configStubsSave config.logModifiedComponents = configLogSave + config.silentWarnings = configSilentWarningsSave consoleError.restore() })