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 7bef579

Browse files
authored
chore: Cleanup structure (testing-library#209)
* Split index into focused files * Update deps * Add missing quotes
1 parent d05b77d commit 7bef579

File tree

7 files changed

+216
-210
lines changed

7 files changed

+216
-210
lines changed

‎jest.config.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = merge(config, {
55
testEnvironment: 'jsdom',
66
moduleFileExtensions: ['js', 'vue'],
77
moduleNameMapper: {
8-
'@testing-library/vue': '<rootDir>/src/vue-testing-library.js',
8+
'@testing-library/vue': '<rootDir>/src/index.js',
99
},
1010
coverageDirectory: './coverage',
1111
collectCoverageFrom: ['**/src/**/*.js', '!**/src/__tests__/**'],

‎package.json‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@testing-library/vue",
33
"version": "0.0.0-semantically-released",
44
"description": "Simple and complete Vue DOM testing utilities that encourage good testing practices.",
5-
"main": "dist/vue-testing-library.js",
5+
"main": "dist/index.js",
66
"types": "types/index.d.ts",
77
"scripts": {
88
"format": "kcd-scripts format",
@@ -50,21 +50,21 @@
5050
"devDependencies": {
5151
"@babel/plugin-transform-runtime": "^7.11.5",
5252
"@testing-library/jest-dom": "^5.11.6",
53-
"@types/estree": "0.0.45",
5453
"@testing-library/user-event": "^12.1.10",
54+
"@types/estree": "0.0.46",
5555
"apollo-boost": "^0.4.9",
5656
"apollo-cache-inmemory": "^1.6.6",
57-
"axios": "^0.20.0",
57+
"axios": "^0.21.1",
5858
"dtslint": "^4.0.5",
5959
"eslint": "^7.13.0",
60-
"eslint-plugin-vue": "^7.1.0",
60+
"eslint-plugin-vue": "^7.6.0",
6161
"graphql": "^15.3.0",
6262
"graphql-tag": "^2.11.0",
6363
"isomorphic-unfetch": "^3.0.0",
6464
"jest-serializer-vue": "^2.0.2",
6565
"kcd-scripts": "^7.0.3",
6666
"lodash.merge": "^4.6.2",
67-
"msw": "^0.21.2",
67+
"msw": "^0.26.2",
6868
"portal-vue": "^2.1.7",
6969
"typescript": "^4.0.5",
7070
"vee-validate": "^2.2.15",

‎src/__tests__/fire-event.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ typingEvents.forEach(event => {
201201
expect(console.warn).toHaveBeenCalledTimes(1)
202202
expect(console.warn).toHaveBeenCalledWith(
203203
expect.stringContaining(
204-
`Using "fireEvent.${event} may lead to unexpected results. Please use fireEvent.update() instead.`,
204+
`Using "fireEvent.${event}" may lead to unexpected results. Please use fireEvent.update() instead.`,
205205
),
206206
)
207207
})

‎src/fire-event.js‎

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/* eslint-disable testing-library/no-wait-for-empty-callback */
2+
import {waitFor, fireEvent as dtlFireEvent} from '@testing-library/dom'
3+
4+
// Vue Testing Lib's version of fireEvent will call DOM Testing Lib's
5+
// version of fireEvent. The reason is because we need to wait another
6+
// event loop tick to allow Vue to flush and update the DOM
7+
// More info: https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue
8+
9+
async function fireEvent(...args) {
10+
dtlFireEvent(...args)
11+
await waitFor(() => {})
12+
}
13+
14+
Object.keys(dtlFireEvent).forEach(key => {
15+
fireEvent[key] = async (...args) => {
16+
warnOnChangeOrInputEventCalledDirectly(args[1], key)
17+
18+
dtlFireEvent[key](...args)
19+
await waitFor(() => {})
20+
}
21+
})
22+
23+
fireEvent.touch = async elem => {
24+
await fireEvent.focus(elem)
25+
await fireEvent.blur(elem)
26+
}
27+
28+
// fireEvent.update is a small utility to provide a better experience when
29+
// working with v-model.
30+
// Related upstream issue: https://github.com/vuejs/vue-test-utils/issues/345#issuecomment-380588199
31+
// Examples: https://github.com/testing-library/vue-testing-library/blob/master/src/__tests__/form.js
32+
fireEvent.update = (elem, value) => {
33+
const tagName = elem.tagName
34+
const type = elem.type
35+
36+
switch (tagName) {
37+
case 'OPTION': {
38+
elem.selected = true
39+
40+
const parentSelectElement =
41+
elem.parentElement.tagName === 'OPTGROUP'
42+
? elem.parentElement.parentElement
43+
: elem.parentElement
44+
45+
return fireEvent.change(parentSelectElement)
46+
}
47+
48+
case 'INPUT': {
49+
if (['checkbox', 'radio'].includes(type)) {
50+
elem.checked = true
51+
return fireEvent.change(elem)
52+
} else if (type === 'file') {
53+
return fireEvent.change(elem)
54+
} else {
55+
elem.value = value
56+
if (elem._vModifiers?.lazy) {
57+
return fireEvent.change(elem)
58+
}
59+
return fireEvent.input(elem)
60+
}
61+
}
62+
63+
case 'TEXTAREA': {
64+
elem.value = value
65+
if (elem._vModifiers?.lazy) {
66+
return fireEvent.change(elem)
67+
}
68+
return fireEvent.input(elem)
69+
}
70+
71+
case 'SELECT': {
72+
elem.value = value
73+
return fireEvent.change(elem)
74+
}
75+
76+
default:
77+
// do nothing
78+
}
79+
80+
return null
81+
}
82+
83+
function warnOnChangeOrInputEventCalledDirectly(eventValue, eventKey) {
84+
if (process.env.VTL_SKIP_WARN_EVENT_UPDATE) return
85+
86+
if (eventValue && (eventKey === 'change' || eventKey === 'input')) {
87+
console.warn(
88+
`Using "fireEvent.${eventKey}" may lead to unexpected results. Please use fireEvent.update() instead.`,
89+
)
90+
}
91+
}
92+
93+
export {fireEvent}

‎src/index.js‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {cleanup} from './render'
2+
3+
// If we're running in a test runner that supports afterEach then we'll
4+
// automatically run cleanup after each test.
5+
// This ensures that tests run in isolation from each other.
6+
// If you don't like this, set the VTL_SKIP_AUTO_CLEANUP variable to 'true'.
7+
if (typeof afterEach === 'function' && !process.env.VTL_SKIP_AUTO_CLEANUP) {
8+
afterEach(() => {
9+
cleanup()
10+
})
11+
}
12+
13+
export * from '@testing-library/dom'
14+
export {cleanup, render} from './render'
15+
export {fireEvent} from './fire-event'

‎src/render.js‎

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import {createLocalVue, mount} from '@vue/test-utils'
2+
3+
import {getQueriesForElement, prettyDOM} from '@testing-library/dom'
4+
5+
const mountedWrappers = new Set()
6+
7+
function render(
8+
Component,
9+
{
10+
store = null,
11+
routes = null,
12+
container: customContainer,
13+
baseElement: customBaseElement,
14+
...mountOptions
15+
} = {},
16+
configurationCb,
17+
) {
18+
const div = document.createElement('div')
19+
const baseElement = customBaseElement || customContainer || document.body
20+
const container = customContainer || baseElement.appendChild(div)
21+
22+
const attachTo = document.createElement('div')
23+
container.appendChild(attachTo)
24+
25+
const localVue = createLocalVue()
26+
let vuexStore = null
27+
let router = null
28+
let callbackOptions = {}
29+
30+
if (store) {
31+
const Vuex = require('vuex')
32+
localVue.use(Vuex)
33+
34+
vuexStore = new Vuex.Store(store)
35+
}
36+
37+
if (routes) {
38+
const requiredRouter = require('vue-router')
39+
const VueRouter = requiredRouter.default || requiredRouter
40+
localVue.use(VueRouter)
41+
42+
router = new VueRouter({routes})
43+
}
44+
45+
if (configurationCb && typeof configurationCb === 'function') {
46+
callbackOptions = configurationCb(localVue, vuexStore, router)
47+
}
48+
49+
if (!mountOptions.propsData && !!mountOptions.props) {
50+
mountOptions.propsData = mountOptions.props
51+
delete mountOptions.props
52+
}
53+
54+
const wrapper = mount(Component, {
55+
attachTo,
56+
localVue,
57+
router,
58+
store: vuexStore,
59+
...mountOptions,
60+
...callbackOptions,
61+
})
62+
63+
mountedWrappers.add(wrapper)
64+
container.appendChild(wrapper.element)
65+
66+
return {
67+
container,
68+
baseElement,
69+
debug: (el = baseElement, ...args) =>
70+
Array.isArray(el)
71+
? el.forEach(e => console.log(prettyDOM(e, ...args)))
72+
: console.log(prettyDOM(el, ...args)),
73+
unmount: () => wrapper.destroy(),
74+
isUnmounted: () => wrapper.vm._isDestroyed,
75+
html: () => wrapper.html(),
76+
emitted: () => wrapper.emitted(),
77+
updateProps: _ => wrapper.setProps(_),
78+
...getQueriesForElement(baseElement),
79+
}
80+
}
81+
82+
function cleanup() {
83+
mountedWrappers.forEach(cleanupAtWrapper)
84+
}
85+
86+
function cleanupAtWrapper(wrapper) {
87+
if (
88+
wrapper.element.parentNode &&
89+
wrapper.element.parentNode.parentNode === document.body
90+
) {
91+
document.body.removeChild(wrapper.element.parentNode)
92+
}
93+
94+
try {
95+
wrapper.destroy()
96+
} finally {
97+
mountedWrappers.delete(wrapper)
98+
}
99+
}
100+
101+
export {cleanup, render}

0 commit comments

Comments
(0)

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