diff --git a/docs/api/options.md b/docs/api/options.md
index 35eaebae2..de35e147b 100644
--- a/docs/api/options.md
+++ b/docs/api/options.md
@@ -292,29 +292,21 @@ When `sync` is `false`, the Vue component is rendered asynchronously.
## Other options
-When the options for `mount` and `shallowMount` contain the options other than the mounting options, the component options are overwritten with those using [extends](https://vuejs.org/v2/api/#extends).
+When the options for `mount` and `shallowMount` contain the options other than the mounting options, the options are added used when the Vue instance is initialized.
```js
const Component = {
- template: '
{{ foo() }}{{ bar() }}{{ baz() }}
',
- methods: {
- foo () {
- return 'a'
- },
- bar () {
- return 'b'
- }
- }
+ template: `
+
+ id: {$route.params.id}
+ username: {$store.state.username}
+
+ `
}
+
const options = {
- methods: {
- bar () {
- return 'B'
- },
- baz () {
- return 'C'
- }
- }
+ store,
+ route
}
const wrapper = mount(Component, options)
expect(wrapper.text()).toBe('aBC')
diff --git a/packages/create-instance/create-instance.js b/packages/create-instance/create-instance.js
index d895af758..7ae2aa91f 100644
--- a/packages/create-instance/create-instance.js
+++ b/packages/create-instance/create-instance.js
@@ -90,8 +90,8 @@ export default function createInstance (
// extend component from _Vue to add properties and mixins
// extend does not work correctly for sub class components in Vue < 2.2
const Constructor = typeof component === 'function'
- ? _Vue.extend(component.options).extend(instanceOptions)
- : _Vue.extend(component).extend(instanceOptions)
+ ? _Vue.extend(component.options)
+ : _Vue.extend(component)
// used to identify extended component using constructor
Constructor.options.$_vueTestUtils_original = component
@@ -151,5 +151,5 @@ export default function createInstance (
}
const Parent = _Vue.extend(parentComponentOptions)
- return new Parent()
+ return new Parent(instanceOptions)
}
diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js
index 4d13e0c25..2e1532191 100644
--- a/packages/test-utils/src/wrapper.js
+++ b/packages/test-utils/src/wrapper.js
@@ -675,11 +675,15 @@ export default class Wrapper implements BaseWrapper {
*/
setMethods (methods: Object): void {
if (!this.isVueInstance()) {
- throwError(
- `wrapper.setMethods() can only be called on a Vue ` +
- `instance`
- )
+ throwError(`wrapper.setMethods() can only be called on a Vue instance`)
}
+ // the methods object is a reference to the original component methods
+ // object. So before making any changes we need to replace vm.methods with
+ // an object that we can change safely.
+
+ // $FlowIgnore
+ this.vm.$options.methods = Object.create(this.vm.$options.methods)
+
Object.keys(methods).forEach(key => {
// $FlowIgnore : Problem with possibly null this.vm
this.vm[key] = methods[key]
diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js
index 5dacf4adb..d4e5ac275 100644
--- a/test/specs/config.spec.js
+++ b/test/specs/config.spec.js
@@ -68,21 +68,6 @@ describeWithShallowAndMount('config', mountingMethod => {
localVue.prototype.$t = undefined
})
- it('overrides a method', () => {
- const testComponent = {
- template: `
- {{ val() }}
- `
- }
-
- config.methods['val'] = () => 'method'
-
- const wrapper = mountingMethod(testComponent)
-
- expect(wrapper.vm.val()).to.equal('method')
- expect(wrapper.text()).to.equal('method')
- })
-
it("doesn't stub transition when config.stubs.transition is set to false", () => {
const testComponent = {
template: `
diff --git a/test/specs/mount.spec.js b/test/specs/mount.spec.js
index cdbdfcef4..743b6bfea 100644
--- a/test/specs/mount.spec.js
+++ b/test/specs/mount.spec.js
@@ -5,7 +5,7 @@ import Component from '~resources/components/component.vue'
import ComponentWithProps from '~resources/components/component-with-props.vue'
import ComponentWithMixin from '~resources/components/component-with-mixin.vue'
import ComponentAsAClass from '~resources/components/component-as-a-class.vue'
-import { injectSupported, vueVersion } from '~resources/utils'
+import { vueVersion } from '~resources/utils'
import { describeRunIf, itDoNotRunIf, itSkipIf } from 'conditional-specs'
import Vuex from 'vuex'
@@ -161,27 +161,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
expect(wrapper.html()).to.equal(`foo
`)
})
- itDoNotRunIf(
- vueVersion < 2.3,
- 'overrides methods', () => {
- const stub = sinon.stub()
- const TestComponent = Vue.extend({
- template: '',
- methods: {
- callStub () {
- stub()
- }
- }
- })
- mount(TestComponent, {
- methods: {
- callStub () {}
- }
- }).vm.callStub()
-
- expect(stub).not.called
- })
-
it.skip('overrides component prototype', () => {
const mountSpy = sinon.spy()
const destroySpy = sinon.spy()
@@ -235,9 +214,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
render: h => h('div')
},
{
- provide: {
- prop: 'val'
- },
attachToDocument: 'attachToDocument',
mocks: {
prop: 'val'
@@ -257,9 +233,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
}
}
)
- if (injectSupported) {
- expect(typeof wrapper.vm.$options.provide).to.equal('object')
- }
expect(wrapper.vm.$options.attachToDocument).to.equal(undefined)
expect(wrapper.vm.$options.mocks).to.equal(undefined)
@@ -373,32 +346,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
expect(wrapper.html()).to.equal(``)
})
- it('overwrites the component options with the instance options', () => {
- const Component = {
- template: '{{ foo() }}{{ bar() }}{{ baz() }}
',
- methods: {
- foo () {
- return 'a'
- },
- bar () {
- return 'b'
- }
- }
- }
- const options = {
- methods: {
- bar () {
- return 'B'
- },
- baz () {
- return 'C'
- }
- }
- }
- const wrapper = mount(Component, options)
- expect(wrapper.text()).to.equal('aBC')
- })
-
it('handles inline components', () => {
const ChildComponent = {
render (h) {
@@ -415,4 +362,18 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
})
expect(wrapper.findAll(ChildComponent).length).to.equal(1)
})
+
+ it('has correct own properties in options.components', () => {
+ const ChildComponent = {
+ template: ''
+ }
+ const TestComponent = {
+ template: '',
+ components: {
+ ChildComponent
+ }
+ }
+ const { vm } = mount(TestComponent)
+ expect(Object.keys(vm.$options.components)).to.contain('ChildComponent')
+ })
})
diff --git a/test/specs/mounting-options/methods.spec.js b/test/specs/mounting-options/methods.spec.js
deleted file mode 100644
index 04524c1ee..000000000
--- a/test/specs/mounting-options/methods.spec.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { config } from '~vue/test-utils'
-import { describeWithMountingMethods } from '~resources/utils'
-
-describeWithMountingMethods('options.methods', mountingMethod => {
- it('prioritize mounting options over config', () => {
- config.methods['val'] = () => 'methodFromConfig'
-
- const TestComponent = {
- template: `
- {{ val() }}
- `
- }
-
- const wrapper = mountingMethod(TestComponent, {
- methods: {
- val () {
- return 'methodFromOptions'
- }
- }
- })
- const HTML =
- mountingMethod.name === 'renderToString' ? wrapper : wrapper.html()
- expect(HTML).to.contain('methodFromOptions')
- })
-})
diff --git a/test/specs/wrapper/setComputed.spec.js b/test/specs/wrapper/setComputed.spec.js
index 6744234e3..bc39528ca 100644
--- a/test/specs/wrapper/setComputed.spec.js
+++ b/test/specs/wrapper/setComputed.spec.js
@@ -58,7 +58,7 @@ describeWithShallowAndMount('setComputed', mountingMethod => {
expect(wrapper.vm.b).to.equal(3)
})
- it('works correctly with mapGetters', () => {
+ it.skip('works correctly with mapGetters', () => {
const localVue = createLocalVue()
localVue.use(Vuex)
const store = new Vuex.Store({