From 5cc39cd084e3c4e5a0e00adc338fcbea8fd3556f Mon Sep 17 00:00:00 2001 From: eddyerburgh Date: Mon, 15 Oct 2018 19:37:18 +0100 Subject: [PATCH 1/3] fix: stub lazily added components --- packages/create-instance/add-stubs.js | 17 +++++++++++++++-- packages/create-instance/create-instance.js | 2 +- .../create-instance/extract-instance-options.js | 3 ++- packages/shared/create-component-stubs.js | 2 +- packages/test-utils/src/shallow-mount.js | 1 + test/specs/shallow-mount.spec.js | 17 +++++++++++++++++ 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/packages/create-instance/add-stubs.js b/packages/create-instance/add-stubs.js index dbf5ded21..52131cfbc 100644 --- a/packages/create-instance/add-stubs.js +++ b/packages/create-instance/add-stubs.js @@ -1,7 +1,10 @@ -import { createStubsFromStubsObject } from 'shared/create-component-stubs' +import { + createStubsFromStubsObject, + createStubFromComponent +} from 'shared/create-component-stubs' import { addHook } from './add-hook' -export function addStubs (component, stubs, _Vue) { +export function addStubs (component, stubs, _Vue, shouldProxy) { const stubComponents = createStubsFromStubsObject( component.components, stubs @@ -12,6 +15,16 @@ export function addStubs (component, stubs, _Vue) { this.$options.components, stubComponents ) + if (shouldProxy) { + this.$options.components = new Proxy(this.$options.components, { + set (target, prop, value) { + if (!target[prop]) { + target[prop] = createStubFromComponent(value, prop) + } + return true + } + }) + } } addHook(_Vue.options, 'beforeMount', addStubComponentsMixin) diff --git a/packages/create-instance/create-instance.js b/packages/create-instance/create-instance.js index 641d92b61..604c76d45 100644 --- a/packages/create-instance/create-instance.js +++ b/packages/create-instance/create-instance.js @@ -59,7 +59,7 @@ export default function createInstance ( addEventLogger(_Vue) addMocks(options.mocks, _Vue) - addStubs(component, options.stubs, _Vue) + addStubs(component, options.stubs, _Vue, options.shouldProxy) if ( (component.options && component.options.functional) || diff --git a/packages/create-instance/extract-instance-options.js b/packages/create-instance/extract-instance-options.js index 39ce86d85..5d7d3b5e5 100644 --- a/packages/create-instance/extract-instance-options.js +++ b/packages/create-instance/extract-instance-options.js @@ -12,7 +12,8 @@ const MOUNTING_OPTIONS = [ 'listeners', 'propsData', 'logModifiedComponents', - 'sync' + 'sync', + 'shouldProxy' ] export default function extractInstanceOptions ( diff --git a/packages/shared/create-component-stubs.js b/packages/shared/create-component-stubs.js index e4d93aa8d..3396d2b22 100644 --- a/packages/shared/create-component-stubs.js +++ b/packages/shared/create-component-stubs.js @@ -102,7 +102,7 @@ export function createStubFromComponent ( } } -function createStubFromString ( +export function createStubFromString ( templateString: string, originalComponent: Component = {}, name: string diff --git a/packages/test-utils/src/shallow-mount.js b/packages/test-utils/src/shallow-mount.js index 8d34d4be3..dd77dbd2b 100644 --- a/packages/test-utils/src/shallow-mount.js +++ b/packages/test-utils/src/shallow-mount.js @@ -31,6 +31,7 @@ export default function shallowMount ( return mount(component, { ...options, + shouldProxy: true, components: { ...createStubsForComponent(_Vue), ...createStubsForComponent(component) diff --git a/test/specs/shallow-mount.spec.js b/test/specs/shallow-mount.spec.js index a64da4aef..31c8f639d 100644 --- a/test/specs/shallow-mount.spec.js +++ b/test/specs/shallow-mount.spec.js @@ -389,6 +389,23 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => { .to.equal('hey') }) + it('stubs lazy registered components', () => { + const Child = { + render: h => h('p') + } + const TestComponent = { + template: '
', + beforeCreate () { + this.$options.components.Child = Child + } + } + const wrapper = shallowMount(TestComponent) + + expect(wrapper.findAll('p').length) + .to.equal(0) + expect(wrapper.findAll(Child).length).to.equal(1) + }) + itDoNotRunIf( vueVersion < 2.4, // auto resolve of default export added in 2.4 'handles component as dynamic import', () => { From a84ab14b896a1ca3dde03eba4fd8a613b908eb91 Mon Sep 17 00:00:00 2001 From: eddyerburgh Date: Mon, 15 Oct 2018 19:45:20 +0100 Subject: [PATCH 2/3] fix: add missing types --- flow/options.flow.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flow/options.flow.js b/flow/options.flow.js index c95fb78bf..b98c3d3d6 100644 --- a/flow/options.flow.js +++ b/flow/options.flow.js @@ -14,7 +14,8 @@ declare type Options = { listeners?: { [key: string]: Function | Array }, parentComponent?: Object, logModifiedComponents?: boolean, - sync?: boolean + sync?: boolean, + shouldProxy?: boolean }; declare type SlotValue = Component | string | Array; From 7a6a6fa962d4dcdfb565e130e21b72cb21da6b8e Mon Sep 17 00:00:00 2001 From: eddyerburgh Date: Mon, 15 Oct 2018 20:59:43 +0100 Subject: [PATCH 3/3] fix: only use Proxy if its supported --- packages/create-instance/add-stubs.js | 2 +- test/specs/shallow-mount.spec.js | 32 ++++++++++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/create-instance/add-stubs.js b/packages/create-instance/add-stubs.js index 52131cfbc..591db4b89 100644 --- a/packages/create-instance/add-stubs.js +++ b/packages/create-instance/add-stubs.js @@ -15,7 +15,7 @@ export function addStubs (component, stubs, _Vue, shouldProxy) { this.$options.components, stubComponents ) - if (shouldProxy) { + if (typeof Proxy !== 'undefined' && shouldProxy) { this.$options.components = new Proxy(this.$options.components, { set (target, prop, value) { if (!target[prop]) { diff --git a/test/specs/shallow-mount.spec.js b/test/specs/shallow-mount.spec.js index 31c8f639d..9568ef30e 100644 --- a/test/specs/shallow-mount.spec.js +++ b/test/specs/shallow-mount.spec.js @@ -9,7 +9,7 @@ import ComponentWithoutName from '~resources/components/component-without-name.v import ComponentAsAClassWithChild from '~resources/components/component-as-a-class-with-child.vue' import RecursiveComponent from '~resources/components/recursive-component.vue' import { vueVersion } from '~resources/utils' -import { describeRunIf, itDoNotRunIf } from 'conditional-specs' +import { describeRunIf, itDoNotRunIf, itSkipIf } from 'conditional-specs' describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => { beforeEach(() => { @@ -389,22 +389,24 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => { .to.equal('hey') }) - it('stubs lazy registered components', () => { - const Child = { - render: h => h('p') - } - const TestComponent = { - template: '
', - beforeCreate () { - this.$options.components.Child = Child + itSkipIf( + typeof Proxy === 'undefined', + 'stubs lazily registered components', () => { + const Child = { + render: h => h('p') } - } - const wrapper = shallowMount(TestComponent) + const TestComponent = { + template: '
', + beforeCreate () { + this.$options.components.Child = Child + } + } + const wrapper = shallowMount(TestComponent) - expect(wrapper.findAll('p').length) - .to.equal(0) - expect(wrapper.findAll(Child).length).to.equal(1) - }) + expect(wrapper.findAll('p').length) + .to.equal(0) + expect(wrapper.findAll(Child).length).to.equal(1) + }) itDoNotRunIf( vueVersion < 2.4, // auto resolve of default export added in 2.4