diff --git a/.circleci/config.yml b/.circleci/config.yml
index 0f17bf84d..b85fddcd9 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -60,48 +60,13 @@ jobs:
- run:
name: yarn test
command: yarn test
- test_version_2.0.8:
+ test_compat:
<<: *defaults
steps:
- attach_workspace:
at: ~/repo
- *restore_node_modules
- - run: yarn test:compat "2.0.8"
- test_version_2.1.10:
- <<: *defaults
- steps:
- - attach_workspace:
- at: ~/repo
- - *restore_node_modules
- - run: yarn test:compat "2.1.10"
- test_version_2.2.6:
- <<: *defaults
- steps:
- - attach_workspace:
- at: ~/repo
- - *restore_node_modules
- - run: yarn test:compat "2.2.6"
- test_version_2.3.4:
- <<: *defaults
- steps:
- - attach_workspace:
- at: ~/repo
- - *restore_node_modules
- - run: yarn test:compat "2.3.4"
- test_version_2.4.2:
- <<: *defaults
- steps:
- - attach_workspace:
- at: ~/repo
- - *restore_node_modules
- - run: yarn test:compat "2.4.2"
- test_version_2.5.13:
- <<: *defaults
- steps:
- - attach_workspace:
- at: ~/repo
- - *restore_node_modules
- - run: yarn test:compat "2.5.16"
+ - run: yarn test:compat
workflows:
version: 2
install-tests:
@@ -116,32 +81,7 @@ workflows:
- test:
requires:
- install
- - test_version_2.0.8:
- requires:
- - install
- - build_test
- - test
- - test_version_2.1.10:
- requires:
- - install
- - build_test
- - test
- - test_version_2.2.6:
- requires:
- - install
- - build_test
- - test
- - test_version_2.3.4:
- requires:
- - install
- - build_test
- - test
- - test_version_2.4.2:
- requires:
- - install
- - build_test
- - test
- - test_version_2.5.13:
+ - test_compat:
requires:
- install
- build_test
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 225067c4e..33e62594e 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -38,7 +38,7 @@ Hi! I’m really excited that you are interested in contributing to Vue Test Uti
You will need [Node.js](http://nodejs.org) **version 6+**
-Vue Test Utils is a monorepo. It contains a root package.json for running scripts across the project. The code is inside separate packages in the `packages` directory. The project uses [lerna](https://lernajs.io/) to manage the workspaces.
+Vue Test Utils is a monorepo. It contains a root package.json for running scripts across the project. The code is inside separate packages in the `packages` directory. The project uses [lerna](https://lerna.js.org/) to manage the workspaces.
After cloning the repo, run:
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 000000000..b2095be81
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..9cc43d98e
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "javascript.validate.enable": false,
+ "flow.pathToFlow": "${workspaceFolder}/node_modules/.bin/flow"
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 356535ec6..6bc80061c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,45 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+
+# [1.0.0-beta.30](https://github.com/vuejs/vue-test-utils/compare/v1.0.0-beta.29...v1.0.0-beta.30) (2019-11-28)
+
+
+### Bug Fixes
+
+* **types:** allow `false` as a component stub value ([#1231](https://github.com/vuejs/vue-test-utils/issues/1231)) ([2a4c6ef](https://github.com/vuejs/vue-test-utils/commit/2a4c6ef))
+* add $set scoped slot helper ([#1287](https://github.com/vuejs/vue-test-utils/issues/1287)) ([a9eea7b](https://github.com/vuejs/vue-test-utils/commit/a9eea7b)), closes [#1253](https://github.com/vuejs/vue-test-utils/issues/1253)
+* polyfill Element.matches for IE < 11 ([#1230](https://github.com/vuejs/vue-test-utils/issues/1230)) ([5e04331](https://github.com/vuejs/vue-test-utils/commit/5e04331)), closes [#1223](https://github.com/vuejs/vue-test-utils/issues/1223)
+* respect "hidden" attributes in isVisible() ([#1257](https://github.com/vuejs/vue-test-utils/issues/1257)) ([950763f](https://github.com/vuejs/vue-test-utils/commit/950763f))
+* return promise from render and renderToString ([#1164](https://github.com/vuejs/vue-test-utils/issues/1164)) ([3c597d3](https://github.com/vuejs/vue-test-utils/commit/3c597d3))
+* stub model option ([#1166](https://github.com/vuejs/vue-test-utils/issues/1166)) ([f81695b](https://github.com/vuejs/vue-test-utils/commit/f81695b))
+* typo. ([#1312](https://github.com/vuejs/vue-test-utils/issues/1312)) ([90b2af7](https://github.com/vuejs/vue-test-utils/commit/90b2af7))
+
+
+### Code Refactoring
+
+* remove sync mode ([#1141](https://github.com/vuejs/vue-test-utils/issues/1141)) ([ef613de](https://github.com/vuejs/vue-test-utils/commit/ef613de))
+
+
+### Features
+
+* add correct render type ([#1143](https://github.com/vuejs/vue-test-utils/issues/1143)) ([8a9757c](https://github.com/vuejs/vue-test-utils/commit/8a9757c))
+* **wrapper:** allow destroy() method to work with functional components ([#1188](https://github.com/vuejs/vue-test-utils/issues/1188)) ([f4ea3fd](https://github.com/vuejs/vue-test-utils/commit/f4ea3fd))
+* add option to pretty print html components ([#1229](https://github.com/vuejs/vue-test-utils/issues/1229)) ([99336c4](https://github.com/vuejs/vue-test-utils/commit/99336c4))
+* stop auto stubbing transition and transition-group ([#1127](https://github.com/vuejs/vue-test-utils/issues/1127)) ([85a972c](https://github.com/vuejs/vue-test-utils/commit/85a972c))
+
+
+### BREAKING CHANGES
+
+* html output will now be formatted
+* render and renderToString are now async
+* * Remove `sync` mode
+* Remove TransitionStub
+* Remove Transition
+
+
+
+
# [1.0.0-beta.29](https://github.com/vuejs/vue-test-utils/compare/v1.0.0-beta.28...v1.0.0-beta.29) (2019-02-02)
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index e5cf587d3..21520c954 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -22,6 +22,7 @@ module.exports = {
}
},
serviceWorker: true,
+ head: [['link', { rel: 'icon', href: '/favicon.png' }]],
theme: 'vue',
themeConfig: {
algolia: {
diff --git a/docs/.vuepress/public/favicon.png b/docs/.vuepress/public/favicon.png
new file mode 100644
index 000000000..60e17006a
Binary files /dev/null and b/docs/.vuepress/public/favicon.png differ
diff --git a/docs/README.md b/docs/README.md
index c5baa3ff7..88828b481 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -10,10 +10,12 @@ Vue Test Utils is the official unit testing utility library for Vue.js.
- [Testing Single-File Components with Jest](guides/testing-single-file-components-with-jest.md)
- [Testing Single-File Components with Mocha + webpack](guides/testing-single-file-components-with-mocha-webpack.md)
- [Testing Single-File Components with Karma](guides/testing-single-file-components-with-karma.md)
+ - [Testing in Node.js Without a Build Step](guides/usage-without-a-build-step-node.md)
- [Testing Asynchronous Behavior](guides/testing-async-components.md)
- [Using with TypeScript](guides/using-with-typescript.md)
- [Using with Vue Router](guides/using-with-vue-router.md)
- [Using with Vuex](guides/using-with-vuex.md)
+ - [Useful Libraries for Testing](guides/useful-libraries-for-testing.md)
- [API](api/)
- [mount](api/mount.md)
- [shallowMount](api/shallowMount.md)
@@ -32,7 +34,6 @@ Vue Test Utils is the official unit testing utility library for Vue.js.
- [listeners](api/options.md#listeners)
- [parentComponent](api/options.md#parentComponent)
- [provide](api/options.md#provide)
- - [sync](api/options.md#sync)
- [other options](api/options.md#other-options)
- [Wrapper](api/wrapper/)
- [attributes](api/wrapper/attributes.md)
@@ -76,8 +77,6 @@ Vue Test Utils is the official unit testing utility library for Vue.js.
- [trigger](api/wrapper-array/trigger.md)
- [isVisible](api/wrapper-array/isVisible.md)
- [components](api/components/)
- - [TransitionStub](api/components/TransitionStub.md)
- - [TransitionGroupStub](api/components/TransitionGroupStub.md)
- [RouterLinkStub](api/components/RouterLinkStub.md)
- [Selectors](api/selectors.md)
- [createWrapper](api/createWrapper.md)
diff --git a/docs/api/components/README.md b/docs/api/components/README.md
index fde3fe9df..b6989e287 100644
--- a/docs/api/components/README.md
+++ b/docs/api/components/README.md
@@ -3,5 +3,3 @@
Vue Test Utils includes utility components you can use to stub components.
!!!include(docs/api/components/RouterLinkStub.md)!!!
-!!!include(docs/api/components/TransitionStub.md)!!!
-!!!include(docs/api/components/TransitionGroupStub.md)!!!
diff --git a/docs/api/components/TransitionGroupStub.md b/docs/api/components/TransitionGroupStub.md
deleted file mode 100644
index 8b1064968..000000000
--- a/docs/api/components/TransitionGroupStub.md
+++ /dev/null
@@ -1,31 +0,0 @@
-## TransitionGroupStub
-
-A component to stub the `transition-group` component. Instead of performing transitions asynchronously, it returns the child components synchronously.
-
-This is set to stub all `transition-group` components by default in the Vue Test Utils config. To use the built-in `transition-group` component set `config.stubs['transition-group']` to false:
-
-```js
-import { config } from '@vue/test-utils'
-
-config.stubs['transition-group'] = false
-```
-
-To reset it to stub `transition-group` components:
-
-```js
-import { config, TransitionGroupStub } from '@vue/test-utils'
-
-config.stubs['transition-group'] = TransitionGroupStub
-```
-
-To set it as a stub in mounting options:
-
-```js
-import { mount, TransitionGroupStub } from '@vue/test-utils'
-
-mount(Component, {
- stubs: {
- 'transition-group': TransitionGroupStub
- }
-})
-```
diff --git a/docs/api/components/TransitionStub.md b/docs/api/components/TransitionStub.md
deleted file mode 100644
index 4c2b4dfee..000000000
--- a/docs/api/components/TransitionStub.md
+++ /dev/null
@@ -1,31 +0,0 @@
-## TransitionStub
-
-A component to stub the `transition` component. Instead of performing transitions asynchronously, it returns the child component synchronously.
-
-This is set to stub all `transition` components by default in the Vue Test Utils config. To use the built-in `transition` component set `config.stubs.transition` to false:
-
-```js
-import { config } from '@vue/test-utils'
-
-config.stubs.transition = false
-```
-
-To reset it to stub `transition` components:
-
-```js
-import { config, TransitionStub } from '@vue/test-utils'
-
-config.stubs.transition = TransitionStub
-```
-
-To set it as a stub in mounting options:
-
-```js
-import { mount, TransitionStub } from '@vue/test-utils'
-
-mount(Component, {
- stubs: {
- transition: TransitionStub
- }
-})
-```
diff --git a/docs/api/config.md b/docs/api/config.md
index 23a83c784..d07a86d49 100644
--- a/docs/api/config.md
+++ b/docs/api/config.md
@@ -7,7 +7,7 @@ Vue Test Utils includes a config object to defined options used by Vue Test Util
### `stubs`
- type: `{ [name: string]: Component | boolean | string }`
-- default: `{ transition: TransitionStub, 'transition-group': TransitionGroupStub }`
+- default: `{}`
The stub stored in `config.stubs` is used by default.
Stubs to use in components. These are overwritten by `stubs` passed in the mounting options.
diff --git a/docs/api/createLocalVue.md b/docs/api/createLocalVue.md
index 9b9b6f56b..d7066a99f 100644
--- a/docs/api/createLocalVue.md
+++ b/docs/api/createLocalVue.md
@@ -12,9 +12,11 @@ Use it with `options.localVue`:
```js
import { createLocalVue, shallowMount } from '@vue/test-utils'
+import MyPlugin from 'my-plugin'
import Foo from './Foo.vue'
const localVue = createLocalVue()
+localVue.use(MyPlugin)
const wrapper = shallowMount(Foo, {
localVue,
mocks: { foo: true }
diff --git a/docs/api/createWrapper.md b/docs/api/createWrapper.md
index 9e50c42ec..fc49d9d39 100644
--- a/docs/api/createWrapper.md
+++ b/docs/api/createWrapper.md
@@ -4,7 +4,6 @@
- `{vm|HTMLElement} node`
- `{Object} options`
- - `{Boolean} sync`
- `{Boolean} attachedToDocument`
- **Returns:**
diff --git a/docs/api/options.md b/docs/api/options.md
index 13f9f7788..d385d3047 100644
--- a/docs/api/options.md
+++ b/docs/api/options.md
@@ -21,7 +21,6 @@ These options will be merged with the component's existing options when mounted
- [`listeners`](#listeners)
- [`parentComponent`](#parentcomponent)
- [`provide`](#provide)
-- [`sync`](#sync)
## context
@@ -55,12 +54,25 @@ Example:
```js
import Foo from './Foo.vue'
+import MyComponent from './MyComponent.vue'
const bazComponent = {
name: 'baz-component',
template: '
baz
'
}
+const yourComponent = {
+ props: {
+ foo: {
+ type: String,
+ required: true
+ }
+ },
+ render(h) {
+ return h('p', this.foo)
+ }
+}
+
const wrapper = shallowMount(Component, {
slots: {
default: [Foo, '', 'text'],
@@ -68,7 +80,17 @@ const wrapper = shallowMount(Component, {
foo: '',
bar: 'bar',
baz: bazComponent,
- qux: ''
+ qux: '',
+ quux: ''
+ },
+ stubs: {
+ // used to register custom components
+ 'my-component': MyComponent,
+ 'your-component': yourComponent
+ },
+ mocks: {
+ // used to add properties to the rendering context
+ yourProperty: 'ipsum'
}
})
@@ -125,6 +147,27 @@ shallowMount(Component, {
})
```
+::: warning Root Element required
+Due to the internal implementation of this feature, the slot content has to return a root element, even though a scoped slot is allowed to return an array of elements.
+
+If you ever need this in a test, the recommended workaround is to wrap the component under test in another component and mount that one:
+:::
+
+```javascript
+const WrapperComp = {
+ template: `
+
+
Using the {{props.a}}
+
Using the {{props.a}}
+
+ `,
+ components: {
+ ComponentUnderTest
+ }
+}
+const wrapper = mount(WrapperComp).find(ComponentUnderTest)
+```
+
## stubs
- type: `{ [name: string]: Component | boolean } | Array`
@@ -248,6 +291,23 @@ Please see [Other options](#other-options).
Set the component instance's `$listeners` object.
+Example:
+
+```js
+const Component = {
+ template: ''
+}
+const onClick = jest.fn()
+const wrapper = mount(Component, {
+ listeners: {
+ click: onClick
+ }
+})
+
+wrapper.trigger('click')
+expect(onClick).toHaveBeenCalled()
+```
+
## parentComponent
- type: `Object`
@@ -290,14 +350,6 @@ const wrapper = shallowMount(Component, {
expect(wrapper.text()).toBe('fooValue')
```
-## sync
-
-- type: `boolean`
-- default: `true`
-
-When `sync` is `true`, the Vue component is rendered synchronously.
-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).
diff --git a/docs/api/wrapper-array/trigger.md b/docs/api/wrapper-array/trigger.md
index 374e25984..167d258eb 100644
--- a/docs/api/wrapper-array/trigger.md
+++ b/docs/api/wrapper-array/trigger.md
@@ -1,6 +1,6 @@
## trigger
-Triggers an event on every `Wrapper` in the `WrapperArray` DOM node.
+Triggers an [event](../../guides/dom-events.md#trigger-events) on every `Wrapper` in the `WrapperArray` DOM node.
**Note every `Wrapper` must contain a Vue instance.**
diff --git a/docs/api/wrapper/README.md b/docs/api/wrapper/README.md
index 6e726f624..80346d1d1 100644
--- a/docs/api/wrapper/README.md
+++ b/docs/api/wrapper/README.md
@@ -18,11 +18,11 @@ A `Wrapper` is an object that contains a mounted component or vnode and methods
#### `options.attachedToDocument`
-`Boolean` (read-only): True if `attachToDocument` in mounting options was `true`
+`Boolean` (read-only): True if component is attached to document when rendered.
-#### `options.sync`
+### `selector`
-`Boolean` (read-only): True if `sync` in mounting options was not `false`
+`Selector`: the selector that was used by [`find()`](./find.md) or [`findAll()`](./findAll.md) to create this wrapper
## Methods
diff --git a/docs/api/wrapper/setSelected.md b/docs/api/wrapper/setSelected.md
index 7f592c26f..85767740a 100644
--- a/docs/api/wrapper/setSelected.md
+++ b/docs/api/wrapper/setSelected.md
@@ -8,7 +8,7 @@ Selects an option element and updates `v-model` bound data.
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
-const wrapper = shallowMount(Foo)
+const wrapper = mount(Foo)
const options = wrapper.find('select').findAll('option')
options.at(1).setSelected()
diff --git a/docs/api/wrapper/trigger.md b/docs/api/wrapper/trigger.md
index 21a2712fd..f7cb9b5f7 100644
--- a/docs/api/wrapper/trigger.md
+++ b/docs/api/wrapper/trigger.md
@@ -27,6 +27,10 @@ wrapper.trigger('click', {
button: 0
})
+wrapper.trigger('click', {
+ ctrlKey: true // For testing @click.ctrl handlers
+})
+
expect(clickHandler.called).toBe(true)
```
diff --git a/docs/assets/CNAME b/docs/assets/CNAME
deleted file mode 100644
index 8a37c3fc4..000000000
--- a/docs/assets/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-vue-test-utils.vuejs.org
diff --git a/docs/assets/circle.yml b/docs/assets/circle.yml
deleted file mode 100644
index 56ad41b2f..000000000
--- a/docs/assets/circle.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-general:
- branches:
- ignore:
- - gh-pages
diff --git a/docs/guides/README.md b/docs/guides/README.md
index b4a54d949..1792ea228 100644
--- a/docs/guides/README.md
+++ b/docs/guides/README.md
@@ -7,6 +7,7 @@
!!!include(docs/guides/testing-single-file-components-with-jest.md)!!!
!!!include(docs/guides/testing-single-file-components-with-mocha-webpack.md)!!!
!!!include(docs/guides/testing-single-file-components-with-karma.md)!!!
+!!!include(docs/guides/usage-without-a-build-step-node.md)!!!
!!!include(docs/guides/testing-async-components.md)!!!
!!!include(docs/guides/using-with-typescript.md)!!!
!!!include(docs/guides/using-with-vue-router.md)!!!
diff --git a/docs/guides/common-tips.md b/docs/guides/common-tips.md
index d3d1a0d32..7f4766707 100644
--- a/docs/guides/common-tips.md
+++ b/docs/guides/common-tips.md
@@ -27,6 +27,44 @@ const wrapper = shallowMount(Component)
wrapper.vm // the mounted Vue instance
```
+### Writing asynchronous tests using `nextTick` (new)
+
+By default, Vue batches updates to run asynchronously (on the next "tick"). This is to prevent unnecessary DOM re-renders, and watcher computations ([see the docs](https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue) for more details).
+
+This means you **must** wait for updates to run after you set a reactive property. You can wait for updates with `Vue.nextTick()`:
+
+```js
+it('updates text', async () => {
+ const wrapper = mount(Component)
+ wrapper.trigger('click')
+ await Vue.nextTick()
+ expect(wrapper.text()).toContain('updated')
+})
+
+// Or if you're without async/await
+it('render text', done => {
+ const wrapper = mount(TestComponent)
+ wrapper.trigger('click')
+ Vue.nextTick(() => {
+ wrapper.text().toContain('some text')
+ wrapper.trigger('click')
+ Vue.nextTick(() => {
+ wrapper.text().toContain('some different text')
+ done()
+ })
+ })
+})
+```
+
+The following methods often cause watcher updates that require you to wait for the next tick:
+
+- `setChecked`
+- `setData`
+- `setSelected`
+- `setProps`
+- `setValue`
+- `trigger`
+
### Asserting Emitted Events
Each mounted wrapper automatically records all events emitted by the underlying Vue instance. You can retrieve the recorded events using the `wrapper.emitted()` method:
@@ -95,13 +133,13 @@ You can emit a custom event from a child component by accessing the instance.
**Test**
```js
-import { shallowMount } from '@vue/test-utils'
+import { mount } from '@vue/test-utils'
import ParentComponent from '@/components/ParentComponent'
import ChildComponent from '@/components/ChildComponent'
describe('ParentComponent', () => {
it("displays 'Emitted!' when custom event is emitted", () => {
- const wrapper = shallowMount(ParentComponent)
+ const wrapper = mount(ParentComponent)
wrapper.find(ChildComponent).vm.$emit('custom')
expect(wrapper.html()).toContain('Emitted!')
})
@@ -136,6 +174,106 @@ You can also update the props of an already-mounted component with the `wrapper.
_For a full list of options, please see the [mount options section](../api/options.md) of the docs._
+### Mocking Transitions
+
+Although calling `await Vue.nextTick()` works well for most use cases, there are some situations where additional workarounds are required. These issues will be solved before the `vue-test-utils` library moves out of beta. One such example is unit testing components with the `` wrapper provided by Vue.
+
+```vue
+
+
+
+
Foo
+
+
+
+
+
+```
+
+You might want to write a test that verifies that Foo is shown, then when `show` is set to `false`, Foo is no longer rendered. Such a test could be written as follows:
+
+```js
+test('should render Foo, then hide it', async () => {
+ const wrapper = mount(Foo)
+ expect(wrapper.text()).toMatch(/Foo/)
+
+ wrapper.setData({
+ show: false
+ })
+ await wrapper.vm.$nextTick()
+
+ expect(wrapper.text()).not.toMatch(/Foo/)
+})
+```
+
+In practice, although we are calling `setData` then waiting for the `nextTick` to ensure the DOM is updated, this test fails. This is an ongoing issue related to show Vue implements the `` component, that we would like to solve before version 1.0. For now, there are some workarounds:
+
+#### Using a `transitionStub` helper
+
+```js
+const transitionStub = () => ({
+ render: function(h) {
+ return this.$options._renderChildren
+ }
+})
+
+test('should render Foo, then hide it', async () => {
+ const wrapper = mount(Foo, {
+ stubs: {
+ transition: transitionStub()
+ }
+ })
+ expect(wrapper.text()).toMatch(/Foo/)
+
+ wrapper.setData({
+ show: false
+ })
+ await wrapper.vm.$nextTick()
+
+ expect(wrapper.text()).not.toMatch(/Foo/)
+})
+```
+
+This overrides the default behavior of the `` component and renders the children as soon as the relevant boolean condition changes, as opposed to applying CSS classes, which is how Vue's `` component works.
+
+#### Avoid `setData`
+
+Another alternative is to simply avoid using `setData` by writing two tests, with the required setup performed using `mount` or `shallowMount` options:
+
+```js
+test('should render Foo', async () => {
+ const wrapper = mount(Foo, {
+ data() {
+ return {
+ show: true
+ }
+ }
+ })
+
+ expect(wrapper.text()).toMatch(/Foo/)
+})
+
+test('should not render Foo', async () => {
+ const wrapper = mount(Foo, {
+ data() {
+ return {
+ show: false
+ }
+ }
+ })
+
+ expect(wrapper.text()).not.toMatch(/Foo/)
+})
+```
+
### Applying Global Plugins and Mixins
Some of the components may rely on features injected by a global plugin or mixin, for example `vuex` and `vue-router`.
@@ -143,7 +281,7 @@ Some of the components may rely on features injected by a global plugin or mixin
If you are writing tests for components in a specific app, you can setup the same global plugins and mixins once in the entry of your tests. But in some cases, for example testing a generic component suite that may get shared across different apps, it's better to test your components in a more isolated setup, without polluting the global `Vue` constructor. We can use the [`createLocalVue`](../api/createLocalVue.md) method to achieve that:
```js
-import { createLocalVue } from '@vue/test-utils'
+import { createLocalVue, mount } from '@vue/test-utils'
// create an extended `Vue` constructor
const localVue = createLocalVue()
diff --git a/docs/guides/dom-events.md b/docs/guides/dom-events.md
index dc99cd3c2..945543ca5 100644
--- a/docs/guides/dom-events.md
+++ b/docs/guides/dom-events.md
@@ -207,7 +207,3 @@ A key name after the dot `keydown.up` is translated to a `keyCode`. This is supp
| home | 36 |
| pageup | 33 |
| pagedown | 34 |
-
-### Important
-
-Vue Test Utils triggers event synchronously. Consequently, `Vue.nextTick` is not required.
diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md
index d9179df3c..634b9c566 100644
--- a/docs/guides/getting-started.md
+++ b/docs/guides/getting-started.md
@@ -102,15 +102,29 @@ it('button click should increment the count', () => {
})
```
-### What about `nextTick`?
+In order to test that the counter text has updated, we need to learn about `nextTick`.
-Vue batches pending DOM updates and applies them asynchronously to prevent unnecessary re-renders caused by multiple data mutations. This is why in practice we often have to use `Vue.nextTick` to wait until Vue has performed the actual DOM update after we trigger some state change.
+### Using `nextTick`
-To simplify usage, Vue Test Utils applies all updates synchronously so you don't need to use `Vue.nextTick` to wait for DOM updates in your tests.
+Vue batches pending DOM updates and applies them asynchronously to prevent unnecessary re-renders caused by multiple data mutations.
-_Note: `nextTick` is still necessary when you need to explictly advance the event loop, for operations such as asynchronous callbacks or promise resolution._
+_You can read more about asynchronous updates in the [Vue docs](https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue)_
-If you do still need to use `nextTick` in your test files, be aware that any errors thrown inside it may not be caught by your test runner as it uses promises internally. There are two approaches to fixing this: either you can set the `done` callback as Vue's global error handler at the start of the test, or you can call `nextTick` without an argument and return it as a promise:
+We need to use `Vue.nextTick()` to wait until Vue has performed the DOM update after we set a reactive property. In the counter example, setting the `count` property schedules a DOM update to run on the next tick.
+
+We can `await` `Vue.nextTick()` by writing the tests in an async function:
+
+```js
+it('button click should increment the count text', async () => {
+ expect(wrapper.text()).toContain('0')
+ const button = wrapper.find('button')
+ button.trigger('click')
+ await Vue.nextTick()
+ expect(wrapper.text()).toContain('1')
+})
+```
+
+When you use `nextTick` in your test files, be aware that any errors thrown inside it may not be caught by your test runner as it uses promises internally. There are two approaches to fixing this: either you can set the `done` callback as Vue's global error handler at the start of the test, or you can call `nextTick` without an argument and return it as a promise:
```js
// this will not be caught
@@ -121,7 +135,7 @@ it('will time out', done => {
})
})
-// the two following tests will work as expected
+// the three following tests will work as expected
it('will catch the error using done', done => {
Vue.config.errorHandler = done
Vue.nextTick(() => {
@@ -135,6 +149,11 @@ it('will catch the error using a promise', () => {
expect(true).toBe(false)
})
})
+
+it('will catch the error using async/await', async () => {
+ await Vue.nextTick()
+ expect(true).toBe(false)
+})
```
### What's Next
diff --git a/docs/guides/testing-async-components.md b/docs/guides/testing-async-components.md
index db977ffbb..d9bcb9bf4 100644
--- a/docs/guides/testing-async-components.md
+++ b/docs/guides/testing-async-components.md
@@ -1,8 +1,33 @@
## Testing Asynchronous Behavior
-To simplify testing, Vue Test Utils applies DOM updates _synchronously_. However, there are some techniques you need to be aware of when testing a component with asynchronous behavior such as callbacks or promises.
+There are two types of asynchronous behavior you will encounter in your tests:
-One of the most common asynchronous behaviors is API calls and Vuex actions. The following examples shows how to test a method that makes an API call. This example uses Jest to run the test and to mock the HTTP library `axios`. More about Jest manual mocks can be found [here](https://jestjs.io/docs/en/manual-mocks#content).
+1. Updates applied by Vue
+2. Asynchronous behavior outside of Vue
+
+## Updates applied by Vue
+
+Vue batches pending DOM updates and applies them asynchronously to prevent unnecessary re-renders caused by multiple data mutations.
+
+_You can read more about asynchronous updates in the [Vue docs](https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue)_
+
+In practice, this means you have to use `Vue.nextTick()` to wait until Vue has performed updates after you set a reactive property.
+
+The easiest way to use `Vue.nextTick()` is to write your tests in an async function:
+
+```js
+it('button click should increment the count text', async () => {
+ expect(wrapper.text()).toContain('0')
+ const button = wrapper.find('button')
+ button.trigger('click')
+ await Vue.nextTick()
+ expect(wrapper.text()).toContain('1')
+})
+```
+
+## Asynchronous behavior outside of Vue
+
+One of the most common asynchronous behaviors outside of Vue is API calls in Vuex actions. The following examples shows how to test a method that makes an API call. This example uses Jest to run the test and to mock the HTTP library `axios`. More about Jest manual mocks can be found [here](https://jestjs.io/docs/en/manual-mocks.html#content).
The implementation of the `axios` mock looks like this:
diff --git a/docs/guides/testing-single-file-components-with-karma.md b/docs/guides/testing-single-file-components-with-karma.md
index e41468784..9d09b3a7b 100644
--- a/docs/guides/testing-single-file-components-with-karma.md
+++ b/docs/guides/testing-single-file-components-with-karma.md
@@ -59,7 +59,7 @@ This file is used to configure Karma.
We need to preprocess our files with webpack. to do that, we add webpack as a preprocessor, and include our webpack config. We can use the webpack config file in the base of the project without changing anything.
-In our configuration, we run the tests in Chrome. To add extra browsers, see [the Browsers section in the Karma docs](http://karma-runner.github.io/2.0/config/browsers.html).
+In our configuration, we run the tests in Chrome. To add extra browsers, see [the Browsers section in the Karma docs](http://karma-runner.github.io/3.0/config/browsers.html).
### Picking an Assertion Library
diff --git a/docs/guides/testing-single-file-components-with-mocha-webpack.md b/docs/guides/testing-single-file-components-with-mocha-webpack.md
index 16bccb5d1..ad2777972 100644
--- a/docs/guides/testing-single-file-components-with-mocha-webpack.md
+++ b/docs/guides/testing-single-file-components-with-mocha-webpack.md
@@ -1,19 +1,17 @@
## Testing Single-File Components with Mocha + webpack
-> An example project for this setup is available on [GitHub](https://github.com/vuejs/vue-test-utils-mocha-webpack-example).
-
Another strategy for testing SFCs is compiling all our tests via webpack and then run it in a test runner. The advantage of this approach is that it gives us full support for all webpack and `vue-loader` features, so we don't have to make compromises in our source code.
-You can technically use any test runner you like and manually wire things together, but we've found [`mocha-webpack`](https://github.com/zinserjan/mocha-webpack) to provide a very streamlined experience for this particular task.
+You can technically use any test runner you like and manually wire things together, but we've found [`mochapack`](https://github.com/sysgears/mochapack) to provide a very streamlined experience for this particular task.
-### Setting Up `mocha-webpack`
+### Setting Up `mochapack`
We will assume you are starting with a setup that already has webpack, vue-loader and Babel properly configured - e.g. the `webpack-simple` template scaffolded by `vue-cli`.
The first thing to do is installing test dependencies:
```bash
-npm install --save-dev @vue/test-utils mocha mocha-webpack
+npm install --save-dev @vue/test-utils mocha mochapack
```
Next we need to define a test script in our `package.json`.
@@ -22,7 +20,7 @@ Next we need to define a test script in our `package.json`.
// package.json
{
"scripts": {
- "test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
+ "test": "mochapack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
}
}
```
@@ -53,7 +51,7 @@ module.exports = {
#### Source Maps
-Source maps need to be inlined to be picked up by `mocha-webpack`. The recommended config is:
+Source maps need to be inlined to be picked up by `mochapack`. The recommended config is:
```js
module.exports = {
@@ -172,13 +170,12 @@ Woohoo, we got our tests running!
### Coverage
-To setup code coverage to `mocha-webpack`, follow [the `mocha-webpack` code coverage guide](https://github.com/zinserjan/mocha-webpack/blob/master/docs/guides/code-coverage.md).
+To setup code coverage to `mochapack`, follow [the `mochapack` code coverage guide](https://github.com/sysgears/mochapack/blob/master/docs/guides/code-coverage.md).
### Resources
-- [Example project for this setup](https://github.com/vuejs/vue-test-utils-mocha-webpack-example)
- [Mocha](https://mochajs.org/)
-- [mocha-webpack](http://zinserjan.github.io/mocha-webpack/)
+- [mochapack](https://github.com/sysgears/mochapack/)
- [Chai](http://chaijs.com/)
- [Sinon](http://sinonjs.org/)
- [jest/expect](https://jestjs.io/docs/en/expect#content)
diff --git a/docs/guides/usage-without-a-build-step-node.md b/docs/guides/usage-without-a-build-step-node.md
new file mode 100644
index 000000000..1f1cf018d
--- /dev/null
+++ b/docs/guides/usage-without-a-build-step-node.md
@@ -0,0 +1,55 @@
+## Usage Without a Build Step
+
+While it is common to build Vue applications using tools [Webpack](https://webpack.js.org/) to bundle the application, `vue-loader` to leverage Single File Components, and [Jest](https://jestjs.io/) to write expressive tests, it is possible to use Vue Test Utils with much less. The minimal requirements for Vue Test Utils, aside from the library itself are:
+
+- Vue
+- vue-template-compiler
+- a DOM (be it [jsdom](https://github.com/jsdom/jsdom) in a Node environment, or the DOM in a real browser)
+
+In this example, we will demonstrate how to write a simple test using nothing but the minimal dependencies described above. The final code can be found [here](https://github.com/lmiller1990/vue-test-utils-node-basic).
+
+## Installing the Dependencies
+
+We need to install some dependencies, as explained above: `npm install vue vue-template-complier jsdom jsdom-global @vue/test-utils`. No test runner or bundler is needed for this example.
+
+## Requiring the Libraries
+
+Now we need to require the libraries. There is a slight caveat, explained in a comment, and in depth below the snippet.
+
+```js
+// jsdom-global must be required before vue-test-utils,
+// because vue-test-utils expects a DOM (real DOM, or JSDOM)
+// to exist.
+require('jsdom-global')()
+
+const assert = require('assert')
+
+const Vue = require('vue')
+const VueTestUtils = require('@vue/test-utils')
+```
+
+As the comment says, `jsdom-global` must be required before `@vue/test-utils`. This is because Vue Test Utils expects a DOM to be present to render the Vue components. If you are running the tests in a real browser, you will not need `jsdom` at all. `Vue` must also be required before `@vue/test-utils` for obvious reasons - Vue Test Utils expects to be available, as well. We also require `assert` from the node standard library. Normally we would use the matchers provided by a test runner, often in the format of an `expect(...).toEqual(...)` assertion, but `assert` will serve this purpose for this example.
+
+## Writing a Test
+
+Now everything is set up, all we need is a component and a test. To keep things simple, we will just render some text and assert it is present in the rendered component.
+
+```js
+const App = Vue.component('app', {
+ data() {
+ return {
+ msg: 'Hello Vue Test Utils'
+ }
+ },
+
+ template: `
+
{{ msg }}
+ `
+})
+
+const wrapper = VueTestUtils.shallowMount(App)
+
+assert.strictEqual('Hello Vue Test Utils', wrapper.text())
+```
+
+It's as simple as it looks. Since we do not have a build step, we cannot use Single File Components. There is nothing to stop us using Vue in the same style you would when including it from a CDN via a `
+```
+
+**Тест**
+
+```js
+import { shallowMount } from '@vue/test-utils'
+import ParentComponent from '@/components/ParentComponent'
+import ChildComponent from '@/components/ChildComponent'
+
+describe('ParentComponent', () => {
+ it("displays 'Emitted!' when custom event is emitted", () => {
+ const wrapper = shallowMount(ParentComponent)
+ wrapper.find(ChildComponent).vm.$emit('custom')
+ expect(wrapper.html()).toContain('Emitted!')
+ })
+})
+```
+
### Манипулирование состоянием компонента
Вы можете напрямую манипулировать состоянием компонента с помощью методов `setData` или `setProps` на обёртке:
diff --git a/docs/ru/guides/dom-events.md b/docs/ru/guides/dom-events.md
index be49eaabe..b3ce272cb 100644
--- a/docs/ru/guides/dom-events.md
+++ b/docs/ru/guides/dom-events.md
@@ -41,14 +41,17 @@ wrapper.trigger('click', { button: 0 })
+
diff --git a/test/resources/components/component-with-transition-group.vue b/test/resources/components/component-with-transition-group.vue
deleted file mode 100644
index 0c1163b4e..000000000
--- a/test/resources/components/component-with-transition-group.vue
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-