diff --git a/package.json b/package.json index d7221678c..ed4dc1ded 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-vue-jsx": "^3.7.0", - "babel-polyfill": "^6.23.0", + "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.0", "babel-preset-flow-vue": "^1.0.0", "babel-preset-stage-2": "^6.24.1", diff --git a/packages/create-instance/extract-instance-options.js b/packages/create-instance/extract-instance-options.js index 5962b594c..a04b916dd 100644 --- a/packages/create-instance/extract-instance-options.js +++ b/packages/create-instance/extract-instance-options.js @@ -11,7 +11,6 @@ const MOUNTING_OPTIONS = [ 'attrs', 'listeners', 'propsData', - 'sync', 'shouldProxy' ] diff --git a/packages/server-test-utils/types/index.d.ts b/packages/server-test-utils/types/index.d.ts index d527a5038..01e4daebe 100644 --- a/packages/server-test-utils/types/index.d.ts +++ b/packages/server-test-utils/types/index.d.ts @@ -36,7 +36,6 @@ interface MountOptions extends ComponentOptions { stubs?: Stubs, attrs?: Record listeners?: Record - sync?: boolean } type ThisTypedMountOptions = MountOptions & ThisType diff --git a/packages/server-test-utils/types/test/renderToString.ts b/packages/server-test-utils/types/test/renderToString.ts index 17ac8e41f..70be7d520 100644 --- a/packages/server-test-utils/types/test/renderToString.ts +++ b/packages/server-test-utils/types/test/renderToString.ts @@ -12,8 +12,7 @@ render( attachToDocument: true, scopedSlots: { foo: `
Foo
` - }, - sync: false + } } ) diff --git a/packages/shared/consts.js b/packages/shared/consts.js index c075aef4a..58bdf1c2d 100644 --- a/packages/shared/consts.js +++ b/packages/shared/consts.js @@ -6,7 +6,6 @@ export const COMPONENT_SELECTOR = 'COMPONENT_SELECTOR' export const REF_SELECTOR = 'REF_SELECTOR' export const DOM_SELECTOR = 'DOM_SELECTOR' export const INVALID_SELECTOR = 'INVALID_SELECTOR' -export const COMPAT_SYNC_MODE = 'COMPAT_SYNC_MODE' export const VUE_VERSION = Number( `${Vue.version.split('.')[0]}.${Vue.version.split('.')[1]}` diff --git a/packages/shared/merge-options.js b/packages/shared/merge-options.js index b9f0eb507..5905808e8 100644 --- a/packages/shared/merge-options.js +++ b/packages/shared/merge-options.js @@ -41,7 +41,6 @@ export function mergeOptions( provide: normalizeProvide(provide), stubs, mocks, - methods, - sync: !!(options.sync || options.sync === undefined) + methods } } diff --git a/packages/test-utils/src/components/TransitionGroupStub.js b/packages/test-utils/src/components/TransitionGroupStub.js deleted file mode 100644 index 6e4c1bf66..000000000 --- a/packages/test-utils/src/components/TransitionGroupStub.js +++ /dev/null @@ -1,10 +0,0 @@ -// @flow - -export default { - render(h: Function) { - const tag: string = this.tag || this.$vnode.data.tag || 'span' - const children: Array = this.$slots.default || [] - - return h(tag, null, children) - } -} diff --git a/packages/test-utils/src/components/TransitionStub.js b/packages/test-utils/src/components/TransitionStub.js deleted file mode 100644 index cead12010..000000000 --- a/packages/test-utils/src/components/TransitionStub.js +++ /dev/null @@ -1,147 +0,0 @@ -// @flow - -import { warn } from 'shared/util' - -function getRealChild(vnode: ?VNode): ?VNode { - const compOptions = vnode && vnode.componentOptions - if (compOptions && compOptions.Ctor.options.abstract) { - return getRealChild(getFirstComponentChild(compOptions.children)) - } else { - return vnode - } -} - -function isSameChild(child: VNode, oldChild: VNode): boolean { - return oldChild.key === child.key && oldChild.tag === child.tag -} - -function getFirstComponentChild(children: ?Array): ?VNode { - if (Array.isArray(children)) { - for (let i = 0; i < children.length; i++) { - const c = children[i] - if (c && (c.componentOptions || isAsyncPlaceholder(c))) { - return c - } - } - } -} - -function isPrimitive(value: any): boolean { - return ( - typeof value === 'string' || - typeof value === 'number' || - // $FlowIgnore - typeof value === 'symbol' || - typeof value === 'boolean' - ) -} - -function isAsyncPlaceholder(node: VNode): boolean { - return node.isComment && node.asyncFactory -} -const camelizeRE = /-(\w)/g -export const camelize = (str: string): string => { - return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')) -} - -function hasParentTransition(vnode: VNode): ?boolean { - while ((vnode = vnode.parent)) { - if (vnode.data.transition) { - return true - } - } -} - -export default { - render(h: Function) { - let children: ?Array = this.$options._renderChildren - if (!children) { - return - } - - // filter out text nodes (possible whitespaces) - children = children.filter((c: VNode) => c.tag || isAsyncPlaceholder(c)) - /* istanbul ignore if */ - if (!children.length) { - return - } - - // warn multiple elements - if (children.length > 1) { - warn( - ` can only be used on a single element. ` + - `Use ` + - ' for lists.' - ) - } - - const mode: string = this.mode - - // warn invalid mode - if (mode && mode !== 'in-out' && mode !== 'out-in') { - warn('invalid mode: ' + mode) - } - - const rawChild: VNode = children[0] - - // if this is a component root node and the component's - // parent container node also has transition, skip. - if (hasParentTransition(this.$vnode)) { - return rawChild - } - - // apply transition data to child - // use getRealChild() to ignore abstract components e.g. keep-alive - const child: ?VNode = getRealChild(rawChild) - - if (!child) { - return rawChild - } - - const id: string = `__transition-${this._uid}-` - child.key = - child.key == null - ? child.isComment - ? id + 'comment' - : id + child.tag - : isPrimitive(child.key) - ? String(child.key).indexOf(id) === 0 - ? child.key - : id + child.key - : child.key - - const data: Object = child.data || (child.data = {}) - const oldRawChild: ?VNode = this._vnode - const oldChild: ?VNode = getRealChild(oldRawChild) - if ( - child.data.directives && - child.data.directives.some(d => d.name === 'show') - ) { - child.data.show = true - } - - // mark v-show - // so that the transition module can hand over the control - // to the directive - if ( - child.data.directives && - child.data.directives.some(d => d.name === 'show') - ) { - child.data.show = true - } - if ( - oldChild && - oldChild.data && - !isSameChild(child, oldChild) && - !isAsyncPlaceholder(oldChild) && - // #6687 component root is a comment node - !( - oldChild.componentInstance && - oldChild.componentInstance._vnode.isComment - ) - ) { - oldChild.data = { ...data } - } - return rawChild - } -} diff --git a/packages/test-utils/src/error-wrapper.js b/packages/test-utils/src/error-wrapper.js index 853975a60..c7da711db 100644 --- a/packages/test-utils/src/error-wrapper.js +++ b/packages/test-utils/src/error-wrapper.js @@ -249,13 +249,6 @@ export default class ErrorWrapper implements BaseWrapper { ) } - update(): void { - throwError( - `update has been removed from vue-test-utils.` + - `All updates are now synchronous by default` - ) - } - destroy(): void { throwError( `find did not return ${ diff --git a/packages/test-utils/src/index.js b/packages/test-utils/src/index.js index 345cafa82..6e073991b 100644 --- a/packages/test-utils/src/index.js +++ b/packages/test-utils/src/index.js @@ -1,8 +1,6 @@ import shallowMount from './shallow-mount' import mount from './mount' import createLocalVue from './create-local-vue' -import TransitionStub from './components/TransitionStub' -import TransitionGroupStub from './components/TransitionGroupStub' import RouterLinkStub from './components/RouterLinkStub' import createWrapper from './create-wrapper' import Wrapper from './wrapper' @@ -25,8 +23,6 @@ export default { mount, shallow, shallowMount, - TransitionStub, - TransitionGroupStub, RouterLinkStub, Wrapper, WrapperArray diff --git a/packages/test-utils/src/mount.js b/packages/test-utils/src/mount.js index 3ef6a5625..dee57d1c2 100644 --- a/packages/test-utils/src/mount.js +++ b/packages/test-utils/src/mount.js @@ -7,63 +7,11 @@ import config from './config' import warnIfNoWindow from './warn-if-no-window' import createWrapper from './create-wrapper' import createLocalVue from './create-local-vue' -import { warn } from 'shared/util' -import semver from 'semver' -import { COMPAT_SYNC_MODE } from 'shared/consts' import { validateOptions } from 'shared/validate-options' -import TransitionGroupStub from './components/TransitionGroupStub' -import TransitionStub from './components/TransitionStub' Vue.config.productionTip = false Vue.config.devtools = false -function getSyncOption(syncOption) { - if (syncOption === false) { - Vue.config.async = true - return false - } - if (semver.lt(Vue.version, '2.5.18')) { - warn( - `Vue Test Utils runs in sync mode by default. Due to bugs, sync mode ` + - `requires Vue > 2.5.18. In Vue Test Utils 1.0 sync mode will only be ` + - `supported with Vue 2.5.18+ running in development mode. If you are ` + - `unable to upgrade, you should rewrite your tests to run asynchronously` + - `you can do this by setting the sync mounting option to false.` - ) - return COMPAT_SYNC_MODE - } - - if (typeof Vue.config.async === 'undefined') { - warn( - `Sync mode only works when Vue runs in dev mode. ` + - `Please set Vue to run in dev mode, or set sync to false` - ) - } - - Vue.config.async = false - return true -} - -function addTransitionStubs(options) { - if (config.stubs === false) { - return - } - if ( - options.stubs && - options.stubs.transition !== false && - !options.stubs.transition - ) { - options.stubs.transition = TransitionStub - } - if ( - options.stubs && - options.stubs['transition-group'] !== false && - !options.stubs['transition-group'] - ) { - options.stubs['transition-group'] = TransitionGroupStub - } -} - export default function mount(component, options = {}) { warnIfNoWindow() @@ -72,17 +20,9 @@ export default function mount(component, options = {}) { const _Vue = createLocalVue(options.localVue) const mergedOptions = mergeOptions(options, config) - const sync = getSyncOption(mergedOptions.sync) validateOptions(mergedOptions, component) - // Stub transition and transition-group if in compat sync mode to keep old - // behavior - // TODO: Remove when compat sync mode is removed - if (sync === COMPAT_SYNC_MODE) { - addTransitionStubs(mergedOptions) - } - const parentVm = createInstance(component, mergedOptions, _Vue) const el = options.attachToDocument ? createElement() : undefined @@ -93,8 +33,7 @@ export default function mount(component, options = {}) { throwIfInstancesThrew(vm) const wrapperOptions = { - attachedToDocument: !!mergedOptions.attachToDocument, - sync + attachedToDocument: !!mergedOptions.attachToDocument } const root = parentVm.$options._isFunctionalContainer diff --git a/packages/test-utils/src/order-watchers.js b/packages/test-utils/src/order-watchers.js deleted file mode 100644 index 40b8f73c6..000000000 --- a/packages/test-utils/src/order-watchers.js +++ /dev/null @@ -1,35 +0,0 @@ -// @flow - -let i = 0 - -function orderDeps(watcher): void { - watcher.deps.forEach(dep => { - if (dep._sortedId === i) { - return - } - dep._sortedId = i - dep.subs.forEach(orderDeps) - dep.subs = dep.subs.sort((a, b) => a.id - b.id) - }) -} - -function orderVmWatchers(vm: Component): void { - if (vm._watchers) { - vm._watchers.forEach(orderDeps) - } - - if (vm._computedWatchers) { - Object.keys(vm._computedWatchers).forEach(computedWatcher => { - orderDeps(vm._computedWatchers[computedWatcher]) - }) - } - - vm._watcher && orderDeps(vm._watcher) - - vm.$children.forEach(orderVmWatchers) -} - -export function orderWatchers(vm: Component): void { - orderVmWatchers(vm) - i++ -} diff --git a/packages/test-utils/src/set-watchers-to-sync.js b/packages/test-utils/src/set-watchers-to-sync.js deleted file mode 100644 index 5ea725dbd..000000000 --- a/packages/test-utils/src/set-watchers-to-sync.js +++ /dev/null @@ -1,43 +0,0 @@ -// @flow - -import { VUE_VERSION } from 'shared/consts' - -function setDepsSync(dep): void { - dep.subs.forEach(setWatcherSync) -} - -function setWatcherSync(watcher): void { - if (watcher.sync === true) { - return - } - watcher.sync = true - watcher.deps.forEach(setDepsSync) -} - -export function setWatchersToSync(vm: Component): void { - if (vm._watchers) { - vm._watchers.forEach(setWatcherSync) - } - - if (vm._computedWatchers) { - Object.keys(vm._computedWatchers).forEach(computedWatcher => { - setWatcherSync(vm._computedWatchers[computedWatcher]) - }) - } - - setWatcherSync(vm._watcher) - - vm.$children.forEach(setWatchersToSync) - // preventing double registration - if (!vm.$_vueTestUtils_updateInSetWatcherSync) { - vm.$_vueTestUtils_updateInSetWatcherSync = vm._update - vm._update = function(vnode, hydrating) { - this.$_vueTestUtils_updateInSetWatcherSync(vnode, hydrating) - if (VUE_VERSION >= 2.1 && this._isMounted && this.$options.updated) { - this.$options.updated.forEach(handler => { - handler.call(this) - }) - } - } - } -} diff --git a/packages/test-utils/src/vue-wrapper.js b/packages/test-utils/src/vue-wrapper.js index 4f0550b17..86c216e92 100644 --- a/packages/test-utils/src/vue-wrapper.js +++ b/packages/test-utils/src/vue-wrapper.js @@ -2,9 +2,6 @@ import Wrapper from './wrapper' import { throwError } from 'shared/util' -import { setWatchersToSync } from './set-watchers-to-sync' -import { orderWatchers } from './order-watchers' -import { COMPAT_SYNC_MODE } from 'shared/consts' export default class VueWrapper extends Wrapper implements BaseWrapper { constructor(vm: Component, options: WrapperOptions) { @@ -29,10 +26,6 @@ export default class VueWrapper extends Wrapper implements BaseWrapper { get: () => vm, set: () => throwError('wrapper.vm is read-only') }) - if (options.sync === COMPAT_SYNC_MODE) { - setWatchersToSync(vm) - orderWatchers(vm) - } this.isFunctionalComponent = vm.$options._isFunctionalContainer this._emitted = vm.__emitted this._emittedByOrder = vm.__emittedByOrder diff --git a/packages/test-utils/src/wrapper-array.js b/packages/test-utils/src/wrapper-array.js index 19ae811c2..83458fb9c 100644 --- a/packages/test-utils/src/wrapper-array.js +++ b/packages/test-utils/src/wrapper-array.js @@ -2,7 +2,7 @@ import type Wrapper from './wrapper' import type VueWrapper from './vue-wrapper' -import { throwError, warn } from 'shared/util' +import { throwError } from 'shared/util' export default class WrapperArray implements BaseWrapper { +wrappers: Array @@ -208,14 +208,6 @@ export default class WrapperArray implements BaseWrapper { this.wrappers.forEach(wrapper => wrapper.trigger(event, options)) } - update(): void { - this.throwErrorIfWrappersIsEmpty('update') - warn( - `update has been removed. All changes are now ` + - `synchrnous without calling update` - ) - } - destroy(): void { this.throwErrorIfWrappersIsEmpty('destroy') diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js index 4982d791b..c2eece65f 100644 --- a/packages/test-utils/src/wrapper.js +++ b/packages/test-utils/src/wrapper.js @@ -2,19 +2,13 @@ import Vue from 'vue' import getSelector from './get-selector' -import { - REF_SELECTOR, - FUNCTIONAL_OPTIONS, - VUE_VERSION, - COMPAT_SYNC_MODE -} from 'shared/consts' +import { REF_SELECTOR, FUNCTIONAL_OPTIONS, VUE_VERSION } from 'shared/consts' import config from './config' import WrapperArray from './wrapper-array' import ErrorWrapper from './error-wrapper' -import { throwError, warn, getCheckedEvent, isPhantomJS } from 'shared/util' +import { throwError, getCheckedEvent, isPhantomJS } from 'shared/util' import find from './find' import createWrapper from './create-wrapper' -import { orderWatchers } from './order-watchers' import { recursivelySetData } from './recursively-set-data' import { matches } from './matches' import createDOMEvent from './create-dom-event' @@ -26,7 +20,6 @@ export default class Wrapper implements BaseWrapper { _emitted: { [name: string]: Array> } _emittedByOrder: Array<{ name: string, args: Array }> +element: Element - update: Function +options: WrapperOptions isFunctionalComponent: boolean rootNode: VNode | Element @@ -510,10 +503,6 @@ export default class Wrapper implements BaseWrapper { }) // $FlowIgnore : Problem with possibly null this.vm this.vm.$forceUpdate() - if (this.options.sync === COMPAT_SYNC_MODE) { - // $FlowIgnore : Problem with possibly null this.vm - orderWatchers(this.vm || this.vnode.context.$root) - } Vue.config.silent = originalConfig } @@ -584,16 +573,5 @@ export default class Wrapper implements BaseWrapper { const event = createDOMEvent(type, options) this.element.dispatchEvent(event) - - if (this.vnode && this.options.sync === COMPAT_SYNC_MODE) { - orderWatchers(this.vm || this.vnode.context.$root) - } - } - - update(): void { - warn( - `update has been removed from vue-test-utils. All updates are now ` + - `synchronous by default` - ) } } diff --git a/packages/test-utils/types/index.d.ts b/packages/test-utils/types/index.d.ts index 703cf9e10..b5834aca5 100644 --- a/packages/test-utils/types/index.d.ts +++ b/packages/test-utils/types/index.d.ts @@ -121,7 +121,6 @@ export interface WrapperArray extends BaseWrapper { interface WrapperOptions { attachedToDocument?: boolean - sync?: boolean } interface MountOptions extends ComponentOptions { @@ -135,7 +134,6 @@ interface MountOptions extends ComponentOptions { stubs?: Stubs | false, attrs?: Record listeners?: Record - sync?: boolean } type ThisTypedMountOptions = MountOptions & ThisType diff --git a/packages/test-utils/types/test/mount.ts b/packages/test-utils/types/test/mount.ts index 31fa14f9c..c3c3fdef4 100644 --- a/packages/test-utils/types/test/mount.ts +++ b/packages/test-utils/types/test/mount.ts @@ -50,8 +50,7 @@ mount(ClassComponent, { listeners: { listener: () => {}, listeners: [() => {}, () => {}] - }, - sync: true + } }) mount(functionalOptions, { diff --git a/packages/test-utils/types/test/wrapper.ts b/packages/test-utils/types/test/wrapper.ts index 5168056f8..7aa2b538d 100644 --- a/packages/test-utils/types/test/wrapper.ts +++ b/packages/test-utils/types/test/wrapper.ts @@ -84,7 +84,6 @@ let createdWrapper = createWrapper(new Vue().$mount()) createdWrapper.text() createWrapper(document.createElement('div')) createWrapper(document.createElement('div'), { - sync: false, attachedToDocument: true }) createWrapper(document.createElement('div'), { diff --git a/test/setup/mocha.setup.js b/test/setup/mocha.setup.js index 8a7e69fb7..1a6ddf331 100644 --- a/test/setup/mocha.setup.js +++ b/test/setup/mocha.setup.js @@ -1,3 +1,5 @@ +require('babel-polyfill') + if (process.env.TEST_ENV !== 'node') { require('jsdom-global')() } diff --git a/test/specs/components/TransitionGroupStub.spec.js b/test/specs/components/TransitionGroupStub.spec.js deleted file mode 100644 index e3fb3f673..000000000 --- a/test/specs/components/TransitionGroupStub.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -import ComponentWithTransitionGroup from '~resources/components/component-with-transition-group.vue' -import { TransitionGroupStub } from '~vue/test-utils' -import { describeWithShallowAndMount, vueVersion } from '~resources/utils' -import { itDoNotRunIf } from 'conditional-specs' - -describeWithShallowAndMount('TransitionGroupStub', mountingMethod => { - it('update synchronously when used as stubs for Transition', () => { - const wrapper = mountingMethod(ComponentWithTransitionGroup, { - stubs: { - 'transition-group': TransitionGroupStub - } - }) - expect(wrapper.text()).contains('a') - wrapper.setData({ a: 'b' }) - expect(wrapper.text()).contains('b') - }) - - itDoNotRunIf( - vueVersion < 2.5, - 'does not stub TransitionGroup, but applies synchronously in Vue > 2.5.18', - () => { - const wrapper = mountingMethod(ComponentWithTransitionGroup) - expect(wrapper.find(TransitionGroupStub).exists()).to.equal(false) - expect(wrapper.text()).contains('a') - wrapper.setData({ a: 'b' }) - expect(wrapper.text()).contains('b') - } - ) - - it('updates watchers', () => { - const TestComponent = { - data: () => ({ - someWatchedData: null, - someData: null - }), - watch: { - someWatchedData(newData) { - this.someData = newData - } - }, - template: ` - - {{someData}} - - ` - } - const wrapper = mountingMethod(TestComponent, { - stubs: { - 'transition-group': TransitionGroupStub - } - }) - wrapper.setData({ - someWatchedData: 'some data' - }) - expect(wrapper.html()).contains('some data') - }) -}) diff --git a/test/specs/components/TransitionStub.spec.js b/test/specs/components/TransitionStub.spec.js deleted file mode 100644 index ea1625708..000000000 --- a/test/specs/components/TransitionStub.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import ComponentWithTransition from '~resources/components/component-with-transition.vue' -import { describeWithShallowAndMount, vueVersion } from '~resources/utils' -import { TransitionStub } from '~vue/test-utils' -import { itDoNotRunIf } from 'conditional-specs' - -describeWithShallowAndMount('TransitionStub', mountingMethod => { - const sandbox = sinon.createSandbox() - - beforeEach(() => { - sandbox.stub(console, 'error').callThrough() - }) - - afterEach(() => { - sandbox.reset() - sandbox.restore() - }) - - it('update synchronously when used as stubs for Transition', () => { - const wrapper = mountingMethod(ComponentWithTransition, { - stubs: { - transition: TransitionStub - } - }) - expect(wrapper.text()).contains('a') - wrapper.setData({ a: 'b' }) - expect(wrapper.text()).contains('b') - }) - - itDoNotRunIf( - vueVersion < 2.5, - 'does not stub Transition, but applies synchronously in Vue > 2.5.18', - () => { - const wrapper = mountingMethod(ComponentWithTransition) - expect(wrapper.find(TransitionStub).exists()).to.equal(false) - expect(wrapper.text()).contains('a') - wrapper.setData({ a: 'b' }) - expect(wrapper.text()).contains('b') - } - ) - - it('does not add v-leave class to children', () => { - const TestComponent = { - template: ` -
- -
- `, - data: () => ({ - isShown: false - }) - } - const wrapper = mountingMethod(TestComponent, { - stubs: { - transition: TransitionStub - } - }) - expect(wrapper.find('nav').isVisible()).to.equal(false) - wrapper.find('button').trigger('click') - expect(wrapper.find('nav').isVisible()).to.equal(true) - wrapper.find('button').trigger('click') - expect(wrapper.find('nav').isVisible()).to.equal(false) - }) - - it('logs error when has multiple children', () => { - const TestComponent = { - template: ` -
- ` - } - const msg = - '[vue-test-utils]: can only be used on a single element. Use for lists.' - mountingMethod(TestComponent, { - stubs: { - transition: TransitionStub - } - }) - expect(console.error).calledWith(msg) - }) - - it('handles keyed transitions', () => { - const TestComponent = { - template: ` -
- -
a
-
b
-
-
- `, - data() { - return { - bool: true - } - } - } - const wrapper = mountingMethod(TestComponent, { - stubs: { - transition: TransitionStub - } - }) - expect(wrapper.text()).to.equal('a') - wrapper.setData({ bool: false }) - expect(wrapper.text()).to.equal('b') - }) -}) diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js index ac0e4ed56..dc078413d 100644 --- a/test/specs/config.spec.js +++ b/test/specs/config.spec.js @@ -1,12 +1,7 @@ import { describeWithShallowAndMount } from '~resources/utils' import ComponentWithProps from '~resources/components/component-with-props.vue' import { itDoNotRunIf } from 'conditional-specs' -import { - config, - TransitionStub, - TransitionGroupStub, - createLocalVue -} from '~vue/test-utils' +import { config, createLocalVue } from '~vue/test-utils' describeWithShallowAndMount('config', mountingMethod => { const sandbox = sinon.createSandbox() @@ -83,46 +78,6 @@ describeWithShallowAndMount('config', mountingMethod => { expect(wrapper.text()).to.equal('method') }) - it("doesn't stub transition when config.stubs.transition is set to false", () => { - const testComponent = { - template: ` -
-

-

- ` - } - config.stubs.transition = false - const wrapper = mountingMethod(testComponent) - expect(wrapper.contains(TransitionStub)).to.equal(false) - }) - - it("doesn't stub transition when config.stubs.transition is set to false", () => { - const testComponent = { - template: ` -
-

-

- ` - } - config.stubs['transition-group'] = false - const wrapper = mountingMethod(testComponent) - expect(wrapper.contains(TransitionGroupStub)).to.equal(false) - }) - - it("doesn't stub transition when config.stubs is set to false", () => { - config.stubs = false - const testComponent = { - template: ` -
-

-

- ` - } - const wrapper = mountingMethod(testComponent) - expect(wrapper.contains(TransitionGroupStub)).to.equal(false) - expect(wrapper.contains(TransitionStub)).to.equal(false) - }) - it("doesn't throw Vue warning when silent is set to true", () => { config.silent = true const localVue = createLocalVue() diff --git a/test/specs/create-local-vue.spec.js b/test/specs/create-local-vue.spec.js index 15c996811..2679851b6 100644 --- a/test/specs/create-local-vue.spec.js +++ b/test/specs/create-local-vue.spec.js @@ -26,7 +26,7 @@ describeWithShallowAndMount('createLocalVue', mountingMethod => { expect(typeof freshWrapper.vm.$store).to.equal('undefined') }) - it('Vuex should work properly with local Vue', () => { + it('Vuex should work properly with local Vue', async () => { const localVue = createLocalVue() localVue.use(Vuex) const store = new Vuex.Store({ @@ -48,6 +48,7 @@ describeWithShallowAndMount('createLocalVue', mountingMethod => { expect(wrapper.vm.$store).to.be.an('object') expect(wrapper.text()).to.equal('0 1') wrapper.trigger('click') + await Vue.nextTick() expect(wrapper.text()).to.equal('1 1') }) diff --git a/test/specs/mount.spec.js b/test/specs/mount.spec.js index 4c8a77cbe..792b23118 100644 --- a/test/specs/mount.spec.js +++ b/test/specs/mount.spec.js @@ -414,7 +414,7 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => { }) }) - itDoNotRunIf( + itDoNotRunIf.skip( vueVersion >= 2.5, 'throws if component throws during update', () => { diff --git a/test/specs/mounting-options/mocks.spec.js b/test/specs/mounting-options/mocks.spec.js index e5a1967bf..91cbb6a52 100644 --- a/test/specs/mounting-options/mocks.spec.js +++ b/test/specs/mounting-options/mocks.spec.js @@ -70,7 +70,7 @@ describeWithMountingMethods('options.mocks', mountingMethod => { itDoNotRunIf( mountingMethod.name === 'renderToString', 'adds variables as reactive properties to vm when passed', - () => { + async () => { const stub = sandbox.stub() const $reactiveMock = { value: 'value' } const wrapper = mountingMethod( @@ -97,6 +97,7 @@ describeWithMountingMethods('options.mocks', mountingMethod => { ) expect(wrapper.text()).to.contain('value') $reactiveMock.value = 'changed value' + await Vue.nextTick() expect(wrapper.text()).to.contain('changed value') } ) diff --git a/test/specs/mounting-options/scopedSlots.spec.js b/test/specs/mounting-options/scopedSlots.spec.js index f48ea462f..6423aa46f 100644 --- a/test/specs/mounting-options/scopedSlots.spec.js +++ b/test/specs/mounting-options/scopedSlots.spec.js @@ -2,6 +2,7 @@ import { describeWithShallowAndMount, vueVersion } from '~resources/utils' import { createLocalVue } from '~vue/test-utils' import ComponentWithScopedSlots from '~resources/components/component-with-scoped-slots.vue' import { itDoNotRunIf } from 'conditional-specs' +import Vue from 'vue' describeWithShallowAndMount('scopedSlots', mountingMethod => { const sandbox = sinon.createSandbox() @@ -133,7 +134,7 @@ describeWithShallowAndMount('scopedSlots', mountingMethod => { } ) - itDoNotRunIf(vueVersion < 2.5, 'mounts component scoped slots', () => { + itDoNotRunIf(vueVersion < 2.5, 'mounts component scoped slots', async () => { const wrapper = mountingMethod(ComponentWithScopedSlots, { slots: { default: '123' }, scopedSlots: { @@ -162,6 +163,7 @@ describeWithShallowAndMount('scopedSlots', mountingMethod => { wrapper.vm.items = [4, 5, 6] wrapper.vm.foo = [{ text: 'b1' }, { text: 'b2' }, { text: 'b3' }] wrapper.vm.bar = 'ABC' + await Vue.nextTick() expect(wrapper.find('#destructuring').html()).to.equal( '

0,4

1,5

2,6

' ) @@ -237,7 +239,7 @@ describeWithShallowAndMount('scopedSlots', mountingMethod => { itDoNotRunIf( vueVersion < 2.5, 'renders scoped slots in sync mode by default', - () => { + async () => { const TestComponent = { template: '
', data() { @@ -258,6 +260,7 @@ describeWithShallowAndMount('scopedSlots', mountingMethod => { default: stub } }) + await Vue.nextTick() expect(stub).calledWith(123) } ) diff --git a/test/specs/mounting-options/sync.spec.js b/test/specs/mounting-options/sync.spec.js deleted file mode 100644 index 8fdd2bf8f..000000000 --- a/test/specs/mounting-options/sync.spec.js +++ /dev/null @@ -1,175 +0,0 @@ -import { describeWithShallowAndMount, vueVersion } from '~resources/utils' -import { itDoNotRunIf } from 'conditional-specs' - -describeWithShallowAndMount('options.sync', mountingMethod => { - const sandbox = sinon.createSandbox() - - beforeEach(() => { - sandbox.stub(console, 'error').callThrough() - }) - - afterEach(() => { - sandbox.reset() - sandbox.restore() - }) - - it('sets watchers to sync if set to true', () => { - const TestComponent = { - template: '
{{someData}}
', - data: () => ({ - someData: 'hello' - }) - } - const wrapper = mountingMethod(TestComponent, { - sync: true - }) - const syncValue = vueVersion < 2.5 ? 'COMPAT_SYNC_MODE' : true - - expect(wrapper.text()).to.equal('hello') - wrapper.vm.someData = 'world' - expect(wrapper.text()).to.equal('world') - expect(wrapper.options.sync).to.equal(syncValue) - }) - - it('sets watchers to sync if undefined', () => { - const TestComponent = { - template: '
{{someData}}
', - data: () => ({ - someData: 'hello' - }) - } - const wrapper = mountingMethod(TestComponent) - const syncValue = vueVersion < 2.5 ? 'COMPAT_SYNC_MODE' : true - - expect(wrapper.text()).to.equal('hello') - wrapper.vm.someData = 'world' - expect(wrapper.text()).to.equal('world') - expect(wrapper.options.sync).to.equal(syncValue) - }) - - it('handles methods that update watchers', () => { - const TestComponent = { - template: ` -
-
-
-
data.text: {{ text }}
-
- -
-
computed.text: {{ computedText }}
-
-
-
- `, - data() { - return { - open: false, - text: '', - basket: [] - } - }, - computed: { - computedText() { - return this.text - } - }, - created() { - window.addEventListener('click', this.clickHandler) - }, - destroyed() { - window.removeEventListener('click', this.clickHandler) - }, - watch: { - text() { - this.basket.push(this.computedText) - } - }, - methods: { - clickHandler() { - this.open = !this.open - } - } - } - - const wrapper = mountingMethod(TestComponent, { - attachToDocument: true - }) - wrapper.trigger('click') - expect(wrapper.vm.text).to.equal('') - expect(wrapper.vm.basket.length).to.equal(0) - wrapper.setData({ text: 'foo' }) - expect(wrapper.vm.text).to.equal('foo') - expect(wrapper.vm.computedText).to.equal('foo') - expect(wrapper.vm.basket[0]).to.equal('foo') - }) - - it('does not set watchers to sync if set to false', done => { - const TestComponent = { - template: '
{{someData}}
', - data: () => ({ - someData: 'hello' - }) - } - const wrapper = mountingMethod(TestComponent, { - sync: false - }) - - expect(wrapper.text()).to.equal('hello') - wrapper.vm.someData = 'world' - expect(wrapper.text()).to.equal('hello') - expect(wrapper.options.sync).to.equal(false) - setTimeout(() => { - expect(wrapper.text()).to.equal('world') - done() - }) - }) - - it('call updated when sync is not false', () => { - const childComponentSpy = sandbox.stub() - const ChildComponent = { - template: '
{{ foo }}
', - props: ['foo'], - updated() { - childComponentSpy() - } - } - const spy = sandbox.stub() - const TestComponent = { - template: '
{{ foo }}
', - data() { - return { - foo: 'foo' - } - }, - updated() { - spy() - } - } - const wrapper = mountingMethod(TestComponent, { - stubs: { 'child-component': ChildComponent }, - sync: true - }) - expect(spy.notCalled).to.equal(true) - expect(childComponentSpy.notCalled).to.equal(true) - expect(wrapper.html()).to.equal('
foo
foo
') - wrapper.vm.foo = 'bar' - expect(spy.calledOnce).to.equal(true) - expect(childComponentSpy.calledOnce).to.equal(true) - expect(wrapper.html()).to.equal('
bar
bar
') - }) - - itDoNotRunIf( - vueVersion > 2.4, - 'warns if Vue version is less than 2.5.18', - () => { - const TestComponent = { - template: '
' - } - mountingMethod(TestComponent) - expect(console.error).calledWith( - sinon.match('Vue Test Utils runs in sync mode by default') - ) - } - ) -}) diff --git a/test/specs/wrapper-array.spec.js b/test/specs/wrapper-array.spec.js index 5933ce299..0b4cc3b52 100644 --- a/test/specs/wrapper-array.spec.js +++ b/test/specs/wrapper-array.spec.js @@ -75,7 +75,6 @@ describeWithShallowAndMount('WrapperArray', mountingMethod => { 'setSelected', 'setValue', 'trigger', - 'update', 'destroy' ] methods.forEach(method => { @@ -105,7 +104,6 @@ describeWithShallowAndMount('WrapperArray', mountingMethod => { 'setProps', 'setValue', 'trigger', - 'update', 'destroy' ].includes(method) ) { diff --git a/test/specs/wrapper-array/setChecked.spec.js b/test/specs/wrapper-array/setChecked.spec.js index e137fd2c4..9f4792070 100644 --- a/test/specs/wrapper-array/setChecked.spec.js +++ b/test/specs/wrapper-array/setChecked.spec.js @@ -1,7 +1,8 @@ import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setChecked', mountingMethod => { - it('sets value to the input elements of type checkbox or radio', () => { + it('sets value to the input elements of type checkbox or radio', async () => { const wrapper = mountingMethod({ data() { return { @@ -20,6 +21,7 @@ describeWithShallowAndMount('setChecked', mountingMethod => { expect(wrapper.vm.t1).to.equal(false) expect(wrapper.vm.t2).to.equal('') wrapperArray.setChecked() + await Vue.nextTick() expect(wrapper.vm.t1).to.equal(true) expect(wrapper.vm.t2).to.equal('foo') expect(wrapperArray.at(0).element.checked).to.equal(true) diff --git a/test/specs/wrapper-array/setData.spec.js b/test/specs/wrapper-array/setData.spec.js index 2ebf8ef6e..57ebbc441 100644 --- a/test/specs/wrapper-array/setData.spec.js +++ b/test/specs/wrapper-array/setData.spec.js @@ -1,13 +1,15 @@ import { compileToFunctions } from 'vue-template-compiler' import ComponentWithVIf from '~resources/components/component-with-v-if.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setData', mountingMethod => { - it('sets component data and updates nested vm nodes', () => { + it('sets component data and updates nested vm nodes', async () => { const wrapper = mountingMethod(ComponentWithVIf) const componentArr = wrapper.findAll(ComponentWithVIf) expect(componentArr.at(0).findAll('.child.ready').length).to.equal(0) componentArr.setData({ ready: true }) + await Vue.nextTick() expect(componentArr.at(0).findAll('.child.ready').length).to.equal(1) }) diff --git a/test/specs/wrapper-array/setProps.spec.js b/test/specs/wrapper-array/setProps.spec.js index 96dbedcaf..1697a5077 100644 --- a/test/specs/wrapper-array/setProps.spec.js +++ b/test/specs/wrapper-array/setProps.spec.js @@ -1,23 +1,26 @@ import { compileToFunctions } from 'vue-template-compiler' import ComponentWithProps from '~resources/components/component-with-props.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setProps', mountingMethod => { - it('sets component props and updates DOM when called on Vue instance', () => { + it('sets component props and updates DOM when called on Vue instance', async () => { const prop1 = 'prop 1' const prop2 = 'prop 2' const propsData = { prop1: 'a prop', prop2 } const wrapper = mountingMethod(ComponentWithProps, { propsData }) wrapper.findAll(ComponentWithProps).setProps({ prop1 }) + await Vue.nextTick() expect(wrapper.find('.prop-1').element.textContent).to.equal(prop1) expect(wrapper.find('.prop-2').element.textContent).to.equal(prop2) }) - it('sets component props, and updates DOM when propsData was not initially passed', () => { + it('sets component props when propsData was not initially passed', async () => { const prop1 = 'prop 1' const prop2 = 'prop s' const wrapper = mountingMethod(ComponentWithProps) wrapper.findAll(ComponentWithProps).setProps({ prop1, prop2 }) + await Vue.nextTick() expect(wrapper.find('.prop-1').element.textContent).to.equal(prop1) expect(wrapper.find('.prop-2').element.textContent).to.equal(prop2) }) diff --git a/test/specs/wrapper/find.spec.js b/test/specs/wrapper/find.spec.js index 05b12fe6c..e8c4b4500 100644 --- a/test/specs/wrapper/find.spec.js +++ b/test/specs/wrapper/find.spec.js @@ -504,7 +504,7 @@ describeWithShallowAndMount('find', mountingMethod => { }) }) - it('handles unnamed components', () => { + it('handles unnamed components', async () => { const ChildComponent = { template: '
' } @@ -521,6 +521,7 @@ describeWithShallowAndMount('find', mountingMethod => { expect(wrapper.find(ChildComponent).vnode).to.be.undefined wrapper.vm.renderChild = true + await Vue.nextTick() expect(wrapper.find(ChildComponent).vnode).to.be.an('object') }) diff --git a/test/specs/wrapper/isVisible.spec.js b/test/specs/wrapper/isVisible.spec.js index 780344ae0..359560fc7 100644 --- a/test/specs/wrapper/isVisible.spec.js +++ b/test/specs/wrapper/isVisible.spec.js @@ -2,6 +2,7 @@ import { compileToFunctions } from 'vue-template-compiler' import ComponentWithVShow from '~resources/components/component-with-v-show.vue' import ComponentWithVIf from '~resources/components/component-with-v-if.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('isVisible', mountingMethod => { it('returns true if element has no inline style', () => { @@ -31,9 +32,10 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(element.isVisible()).to.equal(false) }) - it('returns true if element has v-show true', () => { + it('returns true if element has v-show true', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(false) @@ -42,9 +44,10 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyElement.isVisible()).to.equal(true) }) - it('returns false if element has v-show true', () => { + it('returns false if element has v-show true', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(false) @@ -53,9 +56,10 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyElement.isVisible()).to.equal(true) }) - it('returns true if parent element has v-show true', () => { + it('returns true if parent element has v-show true', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(false) @@ -64,9 +68,10 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyChildElement.isVisible()).to.equal(true) }) - it('returns false if parent element has v-show false', () => { + it('returns false if parent element has v-show false', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(false) @@ -75,11 +80,11 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyChildElement.isVisible()).to.equal(true) }) - it('returns false if root element has v-show false and parent has v-show true', () => { + it('returns false if root element has v-show false and parent has v-show true', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) wrapper.vm.$set(wrapper.vm, 'rootReady', false) - + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(false) @@ -87,11 +92,11 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyChildElement.isVisible()).to.equal(false) }) - it('returns false if root element has v-show true and parent has v-show false', () => { + it('returns false if root element has v-show true and parent has v-show false', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', false) wrapper.vm.$set(wrapper.vm, 'rootReady', true) - + await Vue.nextTick() const notReadyElement = wrapper.find('.not-ready') expect(notReadyElement.isVisible()).to.equal(true) @@ -99,35 +104,39 @@ describeWithShallowAndMount('isVisible', mountingMethod => { expect(readyChildElement.isVisible()).to.equal(false) }) - it('returns true if all elements are visible', () => { + it('returns true if all elements are visible', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) wrapper.vm.$set(wrapper.vm, 'rootReady', true) - + await Vue.nextTick() const readyChildElement = wrapper.find('.ready') + expect(readyChildElement.isVisible()).to.equal(true) }) - it('returns false if one element is not visible', () => { + it('returns false if one element is not visible', async () => { const wrapper = mountingMethod(ComponentWithVShow) wrapper.vm.$set(wrapper.vm, 'ready', true) wrapper.vm.$set(wrapper.vm, 'rootReady', true) - + await Vue.nextTick() const readyChildElement = wrapper.find('.ready, .not-ready') + expect(readyChildElement.isVisible()).to.equal(false) }) - it('fails if one element is absent', () => { + it('fails if one element is absent', async () => { const wrapper = mountingMethod(ComponentWithVIf) wrapper.vm.$set(wrapper.vm, 'ready', false) + await Vue.nextTick() const fn = () => wrapper.find('.child.ready').isVisible() expect(fn).to.throw() }) - it('returns true if one element is present', () => { + it('returns true if one element is present', async () => { const wrapper = mountingMethod(ComponentWithVIf) wrapper.vm.$set(wrapper.vm, 'ready', true) + await Vue.nextTick() expect(wrapper.find('.child.ready').isVisible()).to.equal(true) }) diff --git a/test/specs/wrapper/setChecked.spec.js b/test/specs/wrapper/setChecked.spec.js index 0db8cc55b..571a218f5 100644 --- a/test/specs/wrapper/setChecked.spec.js +++ b/test/specs/wrapper/setChecked.spec.js @@ -1,5 +1,6 @@ import ComponentWithInput from '~resources/components/component-with-input.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setChecked', mountingMethod => { it('sets element checked true with no option passed', () => { @@ -21,54 +22,70 @@ describeWithShallowAndMount('setChecked', mountingMethod => { expect(input.element.checked).to.equal(false) }) - it('updates dom with checkbox v-model', () => { + it('updates dom with checkbox v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const input = wrapper.find('input[type="checkbox"]') input.setChecked() + await Vue.nextTick() expect(wrapper.text()).to.contain('checkbox checked') input.setChecked(false) + await Vue.nextTick() expect(wrapper.text()).to.not.contain('checkbox checked') }) - it('changes state the right amount of times with checkbox v-model', () => { + it('changes state the right amount of times with checkbox v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const input = wrapper.find('input[type="checkbox"]') input.setChecked() + await Vue.nextTick() input.setChecked(false) + await Vue.nextTick() input.setChecked(false) + await Vue.nextTick() input.setChecked(true) + await Vue.nextTick() input.setChecked(false) + await Vue.nextTick() input.setChecked(false) + await Vue.nextTick() expect(wrapper.find('.counter').text()).to.equal('4') }) - it('updates dom with radio v-model', () => { + it('updates dom with radio v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) wrapper.find('#radioBar').setChecked() + await Vue.nextTick() expect(wrapper.text()).to.contain('radioBarResult') wrapper.find('#radioFoo').setChecked() + await Vue.nextTick() expect(wrapper.text()).to.contain('radioFooResult') }) - it('changes state the right amount of times with checkbox v-model', () => { + it('changes state the right amount of times with checkbox v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const radioBar = wrapper.find('#radioBar') const radioFoo = wrapper.find('#radioFoo') radioBar.setChecked() + await Vue.nextTick() radioBar.setChecked() + await Vue.nextTick() radioFoo.setChecked() + await Vue.nextTick() radioBar.setChecked() + await Vue.nextTick() radioBar.setChecked() + await Vue.nextTick() radioFoo.setChecked() + await Vue.nextTick() radioFoo.setChecked() - + await Vue.nextTick() expect(wrapper.find('.counter').text()).to.equal('4') }) diff --git a/test/specs/wrapper/setData.spec.js b/test/specs/wrapper/setData.spec.js index 2b9919ceb..8350a30b0 100644 --- a/test/specs/wrapper/setData.spec.js +++ b/test/specs/wrapper/setData.spec.js @@ -2,6 +2,7 @@ import { compileToFunctions } from 'vue-template-compiler' import ComponentWithVIf from '~resources/components/component-with-v-if.vue' import ComponentWithWatch from '~resources/components/component-with-watch.vue' import { describeWithShallowAndMount, vueVersion } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setData', mountingMethod => { const sandbox = sinon.createSandbox() @@ -15,14 +16,15 @@ describeWithShallowAndMount('setData', mountingMethod => { sandbox.restore() }) - it('sets component data and updates nested vm nodes when called on Vue instance', () => { + it('sets component data and updates nested vm nodes when called on Vue instance', async () => { const wrapper = mountingMethod(ComponentWithVIf) expect(wrapper.findAll('.child.ready').length).to.equal(0) wrapper.setData({ ready: true }) + await Vue.nextTick() expect(wrapper.findAll('.child.ready').length).to.equal(1) }) - it('keeps element in sync with vnode', () => { + it('keeps element in sync with vnode', async () => { const Component = { template: '
A custom component!
', data() { @@ -33,22 +35,25 @@ describeWithShallowAndMount('setData', mountingMethod => { } const wrapper = mountingMethod(Component) wrapper.setData({ show: true }) + await Vue.nextTick() expect(wrapper.element).to.equal(wrapper.vm.$el) expect(wrapper.classes()).to.contain('some-class') }) - it('runs watch function when data is updated', () => { + it('runs watch function when data is updated', async () => { const wrapper = mountingMethod(ComponentWithWatch) const data1 = 'testest' wrapper.setData({ data1 }) + await Vue.nextTick() expect(wrapper.vm.data2).to.equal(data1) }) - it('runs watch function after all props are updated', () => { + it('runs watch function after all props are updated', async () => { const wrapper = mountingMethod(ComponentWithWatch) const data1 = 'testest' wrapper.setData({ data2: 'newProp', data1 }) - expect(console.info.args[1][0]).to.equal(data1) + await Vue.nextTick() + expect(console.info.args[0][0]).to.equal(data1) }) it('throws error if node is not a Vue instance', () => { @@ -90,7 +95,7 @@ describeWithShallowAndMount('setData', mountingMethod => { .with.property('message', message) }) - it('updates watchers if computed is updated', () => { + it('updates watchers if computed is updated', async () => { const TestComponent = { template: ` {{ computedText }} @@ -115,10 +120,11 @@ describeWithShallowAndMount('setData', mountingMethod => { const wrapper = mountingMethod(TestComponent) wrapper.setData({ text: 'hello' }) + await Vue.nextTick() expect(wrapper.vm.basket[0]).to.equal('hello') }) - it('should not run watcher if data is null', () => { + it('should not run watcher if data is null', async () => { const TestComponent = { template: `
@@ -140,6 +146,7 @@ describeWithShallowAndMount('setData', mountingMethod => { } const wrapper = mountingMethod(TestComponent) wrapper.setData({ message: null }) + await Vue.nextTick() expect(wrapper.text()).to.equal('There is no message yet') }) @@ -191,7 +198,7 @@ describeWithShallowAndMount('setData', mountingMethod => { expect(wrapper.vm.anObject.propA.prop2).to.equal('b') }) - it('handles undefined values', () => { + it('handles undefined values', async () => { const TestComponent = { template: `
@@ -208,10 +215,11 @@ describeWithShallowAndMount('setData', mountingMethod => { foo: 'baz' } }) + await Vue.nextTick() expect(wrapper.text()).to.contain('baz') }) - it('handles null values', () => { + it('handles null values', async () => { const TestComponent = { template: `
{{nullProperty && nullProperty.foo}}
@@ -227,6 +235,7 @@ describeWithShallowAndMount('setData', mountingMethod => { another: null } }) + await Vue.nextTick() expect(wrapper.text()).to.contain('bar') wrapper.setData({ nullProperty: { @@ -238,7 +247,7 @@ describeWithShallowAndMount('setData', mountingMethod => { expect(wrapper.vm.nullProperty.another.obj).to.equal(true) }) - it('does not merge arrays', () => { + it('does not merge arrays', async () => { const TestComponent = { template: '
{{nested.nested.nestedArray[0]}}
', data: () => ({ @@ -262,11 +271,12 @@ describeWithShallowAndMount('setData', mountingMethod => { } } }) + await Vue.nextTick() expect(wrapper.text()).to.equal('10') expect(wrapper.vm.nested.nested.nestedArray).to.deep.equal([10]) }) - it('should append a new property to an object when the new property is referenced by a template', () => { + it('should set property in existing data object', async () => { const TestComponent = { data: () => ({ anObject: { @@ -287,7 +297,7 @@ describeWithShallowAndMount('setData', mountingMethod => { propC: 'c' } }) - + await Vue.nextTick() expect(wrapper.vm.anObject.propA).to.equal('a') expect(wrapper.vm.anObject.propB).to.equal('b') expect(wrapper.vm.anObject.propC).to.equal('c') diff --git a/test/specs/wrapper/setProps.spec.js b/test/specs/wrapper/setProps.spec.js index ba1a79946..de74807dd 100644 --- a/test/specs/wrapper/setProps.spec.js +++ b/test/specs/wrapper/setProps.spec.js @@ -3,6 +3,7 @@ import ComponentWithProps from '~resources/components/component-with-props.vue' import ComponentWithWatch from '~resources/components/component-with-watch.vue' import { describeWithShallowAndMount, vueVersion } from '~resources/utils' import { itDoNotRunIf } from 'conditional-specs' +import Vue from 'vue' describeWithShallowAndMount('setProps', mountingMethod => { const sandbox = sinon.createSandbox() @@ -15,17 +16,18 @@ describeWithShallowAndMount('setProps', mountingMethod => { sandbox.restore() }) - it('sets component props and updates DOM when called on Vue instance', () => { + it('sets component props and updates DOM when called on Vue instance', async () => { const prop1 = 'prop 1' const prop2 = 'prop 2' const propsData = { prop1: 'a prop', prop2 } const wrapper = mountingMethod(ComponentWithProps, { propsData }) wrapper.setProps({ prop1 }) + await Vue.nextTick() expect(wrapper.find('.prop-1').element.textContent).to.equal(prop1) expect(wrapper.find('.prop-2').element.textContent).to.equal(prop2) }) - it('sets props and updates when called with same object', () => { + it('sets props and updates when called with same object', async () => { const TestComponent = { template: '
', props: ['obj'] @@ -36,6 +38,7 @@ describeWithShallowAndMount('setProps', mountingMethod => { const wrapper = mountingMethod(TestComponent) obj.shouldRender = () => true wrapper.setProps({ obj }) + await Vue.nextTick() expect(wrapper.is('div')).to.equal(true) }) @@ -101,30 +104,25 @@ describeWithShallowAndMount('setProps', mountingMethod => { .with.property('message', message) }) - it('sets component props, and updates DOM when propsData was not initially passed', () => { + it('sets component props, and updates DOM when propsData was not initially passed', async () => { const prop1 = 'prop 1' const prop2 = 'prop s' const wrapper = mountingMethod(ComponentWithProps) wrapper.setProps({ prop1, prop2 }) + await Vue.nextTick() expect(wrapper.find('.prop-1').element.textContent).to.equal(prop1) expect(wrapper.find('.prop-2').element.textContent).to.equal(prop2) }) - it('runs watch function when prop is updated', () => { + it('runs watch function when prop is updated', async () => { const wrapper = mountingMethod(ComponentWithWatch) const prop1 = 'testest' wrapper.setProps({ prop1 }) + await Vue.nextTick() expect(wrapper.vm.prop2).to.equal(prop1) }) - it('runs watch function after all props are updated', () => { - const wrapper = mountingMethod(ComponentWithWatch) - const prop1 = 'testest' - wrapper.setProps({ prop2: 'newProp', prop1 }) - expect(console.info.args[1][0]).to.equal(prop1) - }) - - it('should not run watchers if prop updated is null', () => { + it('should not run watchers if prop updated is null', async () => { const TestComponent = { template: `
@@ -148,10 +146,11 @@ describeWithShallowAndMount('setProps', mountingMethod => { } }) wrapper.setProps({ message: null }) + await Vue.nextTick() expect(wrapper.text()).to.equal('There is no message yet') }) - it('runs watchers correctly', () => { + it('runs watchers correctly', async () => { const TestComponent = { template: `
{{ stringified }} @@ -181,10 +180,12 @@ describeWithShallowAndMount('setProps', mountingMethod => { expect(wrapper.vm.data).to.equal('') wrapper.setProps({ collection: [1, 2, 3] }) + await Vue.nextTick() expect(wrapper.vm.stringified).to.equal('1,2,3') expect(wrapper.vm.data).to.equal('1,2,3') wrapper.vm.collection.push(4, 5) + await Vue.nextTick() expect(wrapper.vm.stringified).to.equal('1,2,3,4,5') expect(wrapper.vm.data).to.equal('1,2,3,4,5') }) diff --git a/test/specs/wrapper/setSelected.spec.js b/test/specs/wrapper/setSelected.spec.js index b743c01be..102c9336a 100644 --- a/test/specs/wrapper/setSelected.spec.js +++ b/test/specs/wrapper/setSelected.spec.js @@ -1,35 +1,41 @@ import ComponentWithInput from '~resources/components/component-with-input.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setSelected', mountingMethod => { - it('sets element selected true', () => { + it('sets element selected true', async () => { const wrapper = mountingMethod(ComponentWithInput) const options = wrapper.find('select').findAll('option') options.at(1).setSelected() + await Vue.nextTick() expect(options.at(1).element.selected).to.equal(true) }) - it('updates dom with select v-model', () => { + it('updates dom with select v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const options = wrapper.find('select').findAll('option') options.at(1).setSelected() + await Vue.nextTick() expect(wrapper.text()).to.contain('selectB') options.at(0).setSelected() + await Vue.nextTick() expect(wrapper.text()).to.contain('selectA') }) - it('updates dom with select v-model for select with optgroups', () => { + it('updates dom with select v-model for select with optgroups', async () => { const wrapper = mountingMethod(ComponentWithInput) const options = wrapper.find('select.with-optgroups').findAll('option') options.at(1).setSelected() + await Vue.nextTick() expect(wrapper.text()).to.contain('selectB') options.at(0).setSelected() + await Vue.nextTick() expect(wrapper.text()).to.contain('selectA') }) diff --git a/test/specs/wrapper/setValue.spec.js b/test/specs/wrapper/setValue.spec.js index 5c70aee75..0f3e0bf73 100644 --- a/test/specs/wrapper/setValue.spec.js +++ b/test/specs/wrapper/setValue.spec.js @@ -1,5 +1,6 @@ import ComponentWithInput from '~resources/components/component-with-input.vue' import { describeWithShallowAndMount } from '~resources/utils' +import Vue from 'vue' describeWithShallowAndMount('setValue', mountingMethod => { it('sets element of input value', () => { @@ -18,10 +19,11 @@ describeWithShallowAndMount('setValue', mountingMethod => { expect(textarea.element.value).to.equal('foo') }) - it('updates dom with input v-model', () => { + it('updates dom with input v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const input = wrapper.find('input[type="text"]') input.setValue('input text awesome binding') + await Vue.nextTick() expect(wrapper.text()).to.contain('input text awesome binding') }) @@ -34,10 +36,11 @@ describeWithShallowAndMount('setValue', mountingMethod => { expect(select.element.value).to.equal('selectB') }) - it('updates dom with select v-model', () => { + it('updates dom with select v-model', async () => { const wrapper = mountingMethod(ComponentWithInput) const select = wrapper.find('select') select.setValue('selectB') + await Vue.nextTick() expect(wrapper.text()).to.contain('selectB') }) diff --git a/test/specs/wrapper/trigger.spec.js b/test/specs/wrapper/trigger.spec.js index 1fc3b8771..79c78511c 100644 --- a/test/specs/wrapper/trigger.spec.js +++ b/test/specs/wrapper/trigger.spec.js @@ -76,11 +76,12 @@ describeWithShallowAndMount('trigger', mountingMethod => { } }) - it('causes DOM to update after clickHandler method that changes components data is called', () => { + it('causes DOM to update after clickHandler method that changes components data is called', async () => { const wrapper = mountingMethod(ComponentWithEvents) const toggle = wrapper.find('.toggle') expect(toggle.classes()).not.to.contain('active') toggle.trigger('click') + await Vue.nextTick() expect(toggle.classes()).to.contain('active') }) diff --git a/yarn.lock b/yarn.lock index b008a80d5..31714ddde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1867,9 +1867,10 @@ babel-plugin-transform-vue-jsx@^4.0.1: dependencies: esutils "^2.0.2" -babel-polyfill@^6.23.0: +babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= dependencies: babel-runtime "^6.26.0" core-js "^2.5.0" @@ -8058,6 +8059,11 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" +regenerator-runtime@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.1.tgz#522ea2aafd9200a00eee143dc14219a35a0f3991" + integrity sha512-5KzMIyPLvfdPmvsdlYsHqITrDfK9k7bmvf97HvHSN4810i254ponbxCQ1NukpRWlu6en2MBWzAlhDExEKISwAA== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"