Skip to content
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: no unnecessary extend #1084

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions docs/api/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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: '<div>{{ foo() }}{{ bar() }}{{ baz() }}</div>',
methods: {
foo () {
return 'a'
},
bar () {
return 'b'
}
}
template: `
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example could be improved to make context more clear.
expect(wrapper.text()).toBe('aBC') would fail?

<div>
id: {$route.params.id}
username: {$store.state.username}
</div>
`
}

const options = {
methods: {
bar () {
return 'B'
},
baz () {
return 'C'
}
}
store,
route
}
const wrapper = mount(Component, options)
expect(wrapper.text()).toBe('aBC')
Expand Down
6 changes: 3 additions & 3 deletions packages/create-instance/create-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

: _Vue.extend(component)

// used to identify extended component using constructor
Constructor.options.$_vueTestUtils_original = component
Expand Down Expand Up @@ -151,5 +151,5 @@ export default function createInstance (
}
const Parent = _Vue.extend(parentComponentOptions)

return new Parent()
return new Parent(instanceOptions)
}
12 changes: 8 additions & 4 deletions packages/test-utils/src/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
15 changes: 0 additions & 15 deletions test/specs/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,6 @@ describeWithShallowAndMount('config', mountingMethod => {
localVue.prototype.$t = undefined
})

it('overrides a method', () => {
const testComponent = {
template: `
<div>{{ val() }}</div>
`
}

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: `
Expand Down
69 changes: 15 additions & 54 deletions test/specs/mount.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -161,27 +161,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
expect(wrapper.html()).to.equal(`<div>foo</div>`)
})

itDoNotRunIf(
vueVersion < 2.3,
'overrides methods', () => {
const stub = sinon.stub()
const TestComponent = Vue.extend({
template: '<div />',
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()
Expand Down Expand Up @@ -235,9 +214,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
render: h => h('div')
},
{
provide: {
prop: 'val'
},
attachToDocument: 'attachToDocument',
mocks: {
prop: 'val'
Expand All @@ -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)
Expand Down Expand Up @@ -373,32 +346,6 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => {
expect(wrapper.html()).to.equal(`<div height="50px" extra="attr"><p class="prop-1">prop1</p> <p class="prop-2"></p></div>`)
})

it('overwrites the component options with the instance options', () => {
const Component = {
template: '<div>{{ foo() }}{{ bar() }}{{ baz() }}</div>',
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) {
Expand All @@ -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: '<div />'
}
const TestComponent = {
template: '<div />',
components: {
ChildComponent
}
}
const { vm } = mount(TestComponent)
expect(Object.keys(vm.$options.components)).to.contain('ChildComponent')
})
})
25 changes: 0 additions & 25 deletions test/specs/mounting-options/methods.spec.js

This file was deleted.

2 changes: 1 addition & 1 deletion test/specs/wrapper/setComputed.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down