Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fc27014

Browse files
committed
Improve messaging
1 parent 3eff52f commit fc27014

File tree

4 files changed

+167
-6
lines changed

4 files changed

+167
-6
lines changed

‎src/__tests__/deprecated-options.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('warns on deprecated store option', () => {
1818
expect(console.warn).toHaveBeenCalledTimes(1)
1919
expect(console.warn).toHaveBeenCalledWith(
2020
expect.stringContaining(
21-
`Providing 'store' or 'routes' options is now deprecated`,
21+
`Providing 'store' or 'routes' options is no longer available`,
2222
),
2323
)
2424
})
@@ -33,7 +33,7 @@ test('warns on deprecated routes option', () => {
3333
expect(console.warn).toHaveBeenCalledTimes(1)
3434
expect(console.warn).toHaveBeenCalledWith(
3535
expect.stringContaining(
36-
`Providing 'store' or 'routes' options is now deprecated`,
36+
`Providing 'store' or 'routes' options is no longer available`,
3737
),
3838
)
3939
})

‎src/index.js‎

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,165 @@
1+
<<<<<<< HEAD
12
import {cleanup} from './render'
3+
=======
4+
/* eslint-disable testing-library/no-wait-for-empty-callback */
5+
import {mount} from '@vue/test-utils'
6+
7+
import {
8+
getQueriesForElement,
9+
prettyDOM,
10+
waitFor,
11+
fireEvent as dtlFireEvent,
12+
} from '@testing-library/dom'
13+
14+
const mountedWrappers = new Set()
15+
16+
function render(
17+
Component,
18+
{
19+
store = null,
20+
routes = null,
21+
container: customContainer,
22+
baseElement: customBaseElement,
23+
...mountOptions
24+
} = {},
25+
) {
26+
const div = document.createElement('div')
27+
const baseElement = customBaseElement || customContainer || document.body
28+
const container = customContainer || baseElement.appendChild(div)
29+
30+
if (store || routes) {
31+
console.warn(`Providing 'store' or 'routes' options is no longer available.
32+
You need to create a router/vuex instance and provide it through 'global.plugins'.
33+
Check out the test examples on GitHub for further details.`)
34+
}
35+
36+
const wrapper = mount(Component, {
37+
...mountOptions,
38+
attachTo: container,
39+
})
40+
41+
// this removes the additional "data-v-app" div node from VTU:
42+
// https://github.com/vuejs/vue-test-utils-next/blob/master/src/mount.ts#L196-L213
43+
unwrapNode(wrapper.parentElement)
44+
45+
mountedWrappers.add(wrapper)
46+
47+
return {
48+
container,
49+
baseElement,
50+
debug: (el = baseElement, maxLength, options) =>
51+
Array.isArray(el)
52+
? el.forEach(e => console.log(prettyDOM(e, maxLength, options)))
53+
: console.log(prettyDOM(el, maxLength, options)),
54+
unmount: () => wrapper.unmount(),
55+
html: () => wrapper.html(),
56+
emitted: () => wrapper.emitted(),
57+
rerender: props => wrapper.setProps(props),
58+
...getQueriesForElement(baseElement),
59+
}
60+
}
61+
62+
function unwrapNode(node) {
63+
node.replaceWith(...node.childNodes)
64+
}
65+
66+
function cleanup() {
67+
mountedWrappers.forEach(cleanupAtWrapper)
68+
}
69+
70+
function cleanupAtWrapper(wrapper) {
71+
if (
72+
wrapper.element.parentNode &&
73+
wrapper.element.parentNode.parentNode === document.body
74+
) {
75+
document.body.removeChild(wrapper.element.parentNode)
76+
}
77+
78+
wrapper.unmount()
79+
mountedWrappers.delete(wrapper)
80+
}
81+
82+
// Vue Testing Library's version of fireEvent will call DOM Testing Library's
83+
// version of fireEvent plus wait for one tick of the event loop to allow Vue
84+
// to asynchronously handle the event.
85+
// More info: https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue
86+
async function fireEvent(...args) {
87+
dtlFireEvent(...args)
88+
await waitFor(() => {})
89+
}
90+
91+
function suggestUpdateIfNecessary(eventValue, eventKey) {
92+
const changeOrInputEventCalledDirectly =
93+
eventValue && (eventKey === 'change' || eventKey === 'input')
94+
95+
if (changeOrInputEventCalledDirectly) {
96+
console.warn(
97+
`Using fireEvent.${eventKey}() may lead to unexpected results. Please use fireEvent.update() instead.`,
98+
)
99+
}
100+
}
101+
102+
Object.keys(dtlFireEvent).forEach(key => {
103+
fireEvent[key] = async (...args) => {
104+
suggestUpdateIfNecessary(args[1], key)
105+
dtlFireEvent[key](...args)
106+
await waitFor(() => {})
107+
}
108+
})
109+
110+
fireEvent.touch = async elem => {
111+
await fireEvent.focus(elem)
112+
await fireEvent.blur(elem)
113+
}
114+
115+
// Small utility to provide a better experience when working with v-model.
116+
// Related upstream issue: https://github.com/vuejs/vue-test-utils/issues/345#issuecomment-380588199
117+
// Examples: https://github.com/testing-library/vue-testing-library/blob/master/src/__tests__/form.js
118+
fireEvent.update = (elem, value) => {
119+
const tagName = elem.tagName
120+
const type = elem.type
121+
122+
switch (tagName) {
123+
case 'OPTION': {
124+
elem.selected = true
125+
126+
const parentSelectElement =
127+
elem.parentElement.tagName === 'OPTGROUP'
128+
? elem.parentElement.parentElement
129+
: elem.parentElement
130+
131+
return fireEvent.change(parentSelectElement)
132+
}
133+
134+
case 'INPUT': {
135+
if (['checkbox', 'radio'].includes(type)) {
136+
elem.checked = true
137+
return fireEvent.change(elem)
138+
} else if (type === 'file') {
139+
return fireEvent.change(elem)
140+
} else {
141+
elem.value = value
142+
return fireEvent.input(elem)
143+
}
144+
}
145+
146+
case 'TEXTAREA': {
147+
elem.value = value
148+
return fireEvent.input(elem)
149+
}
150+
151+
case 'SELECT': {
152+
elem.value = value
153+
return fireEvent.change(elem)
154+
}
155+
156+
default:
157+
// do nothing
158+
}
159+
160+
return null
161+
}
162+
>>>>>>> 544c49d... Improve messaging
2163

3164
// If we're running in a test runner that supports afterEach then we'll
4165
// automatically run cleanup after each test.

‎src/render.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ function render(
2020
const container = customContainer || baseElement.appendChild(div)
2121

2222
if (store || routes) {
23-
console.warn(`Providing 'store' or 'routes' options is now deprecated.
24-
You need to create a router/vuex plugin and provide it through 'global.plugins'.
23+
console.warn(`Providing 'store' or 'routes' options is no longer available.
24+
You need to create a router/vuex instance and provide it through 'global.plugins'.
2525
Check out the test examples on GitHub for further details.`)
2626
}
2727

‎types/index.d.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ type VueTestUtilsRenderOptions = Omit<
3232
>
3333
type VueTestingLibraryRenderOptions = {
3434
/**
35-
* @deprecated Use `global.plugins` array instead.
35+
* @deprecated Add a Vuex instance through `global.plugins` array instead.
3636
*/
3737
store: any
3838
/**
39-
* @deprecated Use `global.plugins` array instead.
39+
* @deprecated Add a Router instance through `global.plugins` array instead.
4040
*/
4141
routes?: any
4242
container?: Element

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /