diff --git a/docs/api/wrapper-array/README.md b/docs/api/wrapper-array/README.md index 9ad5dbde0..fa6c745cf 100644 --- a/docs/api/wrapper-array/README.md +++ b/docs/api/wrapper-array/README.md @@ -4,13 +4,13 @@ A `WrapperArray` is an object that contains an array of [`Wrappers`](../wrapper/ ## Properties -### `wrappers` +### `wrappers` -`array`: the `Wrappers` contained in the `WrapperArray` +`array` (read-only): the `Wrappers` contained in the `WrapperArray` -### `length` +### `length` -`number`: the number of `Wrappers` contained in the `WrapperArray` +`number` (read-only): the number of `Wrappers` contained in the `WrapperArray` ## Methods diff --git a/docs/api/wrapper/README.md b/docs/api/wrapper/README.md index b4765b6f4..7f4c5f012 100644 --- a/docs/api/wrapper/README.md +++ b/docs/api/wrapper/README.md @@ -14,13 +14,13 @@ A `Wrapper` is an object that contains a mounted component or vnode and methods `HTMLElement` (read-only): the root DOM node of the wrapper -### `options` +### `options` #### `options.attachedToDocument` `Boolean` (read-only): True if `attachedToDocument` in mounting options was `true` -#### `options.sync` +#### `options.sync` `Boolean` (read-only): True if `sync` in mounting options was not `false` diff --git a/packages/test-utils/src/vue-wrapper.js b/packages/test-utils/src/vue-wrapper.js index 289790a6b..6db1de2d9 100644 --- a/packages/test-utils/src/vue-wrapper.js +++ b/packages/test-utils/src/vue-wrapper.js @@ -1,6 +1,7 @@ // @flow import Wrapper from './wrapper' +import { throwError } from 'shared/util' import { setWatchersToSync } from './set-watchers-to-sync' import { orderWatchers } from './order-watchers' @@ -11,17 +12,17 @@ export default class VueWrapper extends Wrapper implements BaseWrapper { // $FlowIgnore : issue with defineProperty Object.defineProperty(this, 'vnode', { get: () => vm._vnode, - set: () => {} + set: () => throwError('wrapper.vnode is read-only') }) // $FlowIgnore Object.defineProperty(this, 'element', { get: () => vm.$el, - set: () => {} + set: () => throwError('wrapper.element is read-only') }) // $FlowIgnore Object.defineProperty(this, 'vm', { get: () => vm, - set: () => {} + set: () => throwError('wrapper.vm is read-only') }) if (options.sync) { setWatchersToSync(vm) diff --git a/packages/test-utils/src/wrapper-array.js b/packages/test-utils/src/wrapper-array.js index 4bf9d2ccf..30e2c76e6 100644 --- a/packages/test-utils/src/wrapper-array.js +++ b/packages/test-utils/src/wrapper-array.js @@ -5,12 +5,21 @@ import type VueWrapper from './vue-wrapper' import { throwError, warn } from 'shared/util' export default class WrapperArray implements BaseWrapper { - wrappers: Array; - length: number; + +wrappers: Array; + +length: number; constructor (wrappers: Array) { - this.wrappers = wrappers || [] - this.length = this.wrappers.length + const length = wrappers.length + // $FlowIgnore + Object.defineProperty(this, 'wrappers', { + get: () => wrappers, + set: () => throwError('wrapperArray.wrappers is read-only') + }) + // $FlowIgnore + Object.defineProperty(this, 'length', { + get: () => length, + set: () => throwError('wrapperArray.length is read-only') + }) } at (index: number): Wrapper | VueWrapper { diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index a69fd7ff9..8091ea04b 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -42,24 +42,24 @@ export default class Wrapper implements BaseWrapper { // $FlowIgnore Object.defineProperty(this, 'vnode', { get: () => vnode, - set: () => {} + set: () => throwError('wrapper.vnode is read-only') }) // $FlowIgnore Object.defineProperty(this, 'element', { get: () => element, - set: () => {} + set: () => throwError('wrapper.element is read-only') }) // $FlowIgnore Object.defineProperty(this, 'vm', { get: () => undefined, - set: () => {} + set: () => throwError('wrapper.vm is read-only') }) } const frozenOptions = Object.freeze(options) // $FlowIgnore Object.defineProperty(this, 'options', { get: () => frozenOptions, - set: () => {} + set: () => throwError('wrapper.options is read-only') }) if ( this.vnode && @@ -399,7 +399,6 @@ export default class Wrapper implements BaseWrapper { } return !!( - this.element && this.element.getAttribute && this.element.matches(selector) ) @@ -667,7 +666,6 @@ export default class Wrapper implements BaseWrapper { }) // $FlowIgnore : Problem with possibly null this.vm - this.vnode = this.vm._vnode orderWatchers(this.vm || this.vnode.context.$root) Vue.config.silent = originalConfig } @@ -814,7 +812,7 @@ export default class Wrapper implements BaseWrapper { */ destroy () { if (!this.isVueInstance()) { - throwError(`wrapper.destroy() can only be called on a Vue ` + `instance`) + throwError(`wrapper.destroy() can only be called on a Vue instance`) } if (this.element.parentNode) { diff --git a/test/specs/vuewrapper.js b/test/specs/vue-wrapper.spec.js similarity index 68% rename from test/specs/vuewrapper.js rename to test/specs/vue-wrapper.spec.js index b909d9e31..4b6cb60b7 100644 --- a/test/specs/vuewrapper.js +++ b/test/specs/vue-wrapper.spec.js @@ -5,9 +5,10 @@ describeWithShallowAndMount('VueWrapper', mountingMethod => { it(`has the ${property} property which is read-only`, () => { const wrapper = mountingMethod({ template: '

' }) expect(wrapper.constructor.name).to.equal('VueWrapper') - const originalProperty = wrapper[property] - wrapper[property] = 'foo' - expect(wrapper[property]).to.equal(originalProperty) + const message = `[vue-test-utils]: wrapper.${property} is read-only` + expect(() => { wrapper[property] = 'foo' }) + .to.throw() + .with.property('message', message) }) }) }) diff --git a/test/specs/wrapper-array.spec.js b/test/specs/wrapper-array.spec.js index dbd0217e2..590210a6d 100644 --- a/test/specs/wrapper-array.spec.js +++ b/test/specs/wrapper-array.spec.js @@ -7,13 +7,19 @@ describeWithShallowAndMount('WrapperArray', mountingMethod => { const wrapper = mountingMethod(compiled) const wrapperArray = wrapper.findAll('p') expect(wrapperArray.constructor.name).to.equal('WrapperArray') - if (wrappers) { - wrapperArray.wrappers = wrappers - wrapperArray.length = wrappers.length - } - return wrapperArray + return wrappers ? new wrapperArray.constructor(wrappers) : wrapperArray } + ['wrappers', 'length'].forEach(property => { + it(`has the ${property} property which is read-only`, () => { + const wrapperArray = getWrapperArray() + const message = `[vue-test-utils]: wrapperArray.${property} is read-only` + expect(() => { wrapperArray[property] = 'foo' }) + .to.throw() + .with.property('message', message) + }) + }) + it('returns class with length equal to length of wrappers passed in constructor', () => { const wrapperArray = getWrapperArray() expect(wrapperArray.length).to.equal(3) @@ -67,8 +73,7 @@ describeWithShallowAndMount('WrapperArray', mountingMethod => { if (method === 'at') { return } - const wrapperArray = getWrapperArray() - wrapperArray.wrappers = [] + const wrapperArray = getWrapperArray([]) const message = `[vue-test-utils]: ${method} cannot be called on 0 items` expect(() => wrapperArray[method]()) .to.throw() @@ -99,8 +104,7 @@ describeWithShallowAndMount('WrapperArray', mountingMethod => { ) { return } - const wrapperArray = getWrapperArray() - wrapperArray.wrappers = [1, 2, 3] + const wrapperArray = getWrapperArray([1, 2, 3]) const message = `[vue-test-utils]: ${method} must be called on a single wrapper, use at(i) to access a wrapper` expect(() => wrapperArray[method]()) .to.throw() diff --git a/test/specs/wrapper.spec.js b/test/specs/wrapper.spec.js index 38fec40f0..82848ab74 100644 --- a/test/specs/wrapper.spec.js +++ b/test/specs/wrapper.spec.js @@ -6,9 +6,10 @@ describeWithShallowAndMount('Wrapper', mountingMethod => { const wrapper = mountingMethod({ template: '

' }) .find('p') expect(wrapper.constructor.name).to.equal('Wrapper') - const originalProperty = wrapper[property] - wrapper[property] = 'foo' - expect(wrapper[property]).to.equal(originalProperty) + const message = `[vue-test-utils]: wrapper.${property} is read-only` + expect(() => { wrapper[property] = 'foo' }) + .to.throw() + .with.property('message', message) }) }) }) diff --git a/test/specs/wrapper/attributes.spec.js b/test/specs/wrapper/attributes.spec.js index e93b91bfb..45af0851d 100644 --- a/test/specs/wrapper/attributes.spec.js +++ b/test/specs/wrapper/attributes.spec.js @@ -15,11 +15,4 @@ describeWithShallowAndMount('attributes', mountingMethod => { const wrapper = mountingMethod(compiled) expect(wrapper.attributes()).to.eql({}) }) - - it('returns empty object if wrapper element is null', () => { - const compiled = compileToFunctions('
') - const wrapper = mountingMethod(compiled) - wrapper.element = null - expect(wrapper.attributes()).to.eql({}) - }) }) diff --git a/test/specs/wrapper/is.spec.js b/test/specs/wrapper/is.spec.js index ca1cc83bd..606b2f32b 100644 --- a/test/specs/wrapper/is.spec.js +++ b/test/specs/wrapper/is.spec.js @@ -28,12 +28,6 @@ describeWithShallowAndMount('is', mountingMethod => { expect(wrapper.is('#div')).to.equal(true) }) - it('returns false if wrapper does not contain element', () => { - const wrapper = mountingMethod(ComponentWithChild) - wrapper.element = null - expect(wrapper.is('a')).to.equal(false) - }) - it('returns true if root node matches Vue Component selector', () => { const wrapper = mountingMethod(ComponentWithChild) const component = wrapper.findAll(Component).at(0)