Skip to content

Commit 0ecbc6e

Browse files
committed
fix(test): 1. Bump @vue/test-utils 2. add unit test for drag & resize
1 parent a980962 commit 0ecbc6e

File tree

5 files changed

+261
-16
lines changed

5 files changed

+261
-16
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"@vue/cli-plugin-babel": "^4.5.11",
3636
"@vue/compiler-sfc": "^3.0.11",
3737
"@vue/eslint-config-prettier": "^6.0.0",
38-
"@vue/test-utils": "^2.0.0-0",
38+
"@vue/test-utils": "^2.0.0-rc.6",
3939
"autoprefixer": "^9.8.6",
4040
"babel-core": "^7.0.0-bridge.0",
4141
"babel-eslint": "^10.1.0",

tests/unit/VueFinalModal.spec.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ describe('VueFinalModal.vue', () => {
7373
wrapper.unmount()
7474
})
7575
it('styles', async () => {
76-
const testStyle = 'background: rgb(255, 255, 255);'
76+
const testStyle = { background: 'rgb(255, 255, 255)' }
7777
const { wrapper } = await createClosedModal({
7878
styles: testStyle
7979
})
80-
expect(wrapper.find('.vfm__container').attributes('style')).toContain(testStyle)
80+
expect(wrapper.find('.vfm__container').attributes('style')).toContain('background: rgb(255, 255, 255)')
8181
wrapper.unmount()
8282
})
8383
it('overlayClass', async () => {
@@ -89,11 +89,11 @@ describe('VueFinalModal.vue', () => {
8989
wrapper.unmount()
9090
})
9191
it('overlayStyle', async () => {
92-
const testStyle = 'background: rgb(255, 255, 255);'
92+
const testStyle = { background: 'rgb(255, 255, 255)' }
9393
const { wrapper } = await createOpenedModal({
9494
overlayStyle: testStyle
9595
})
96-
expect(wrapper.find('.vfm__overlay').attributes('style')).toContain(testStyle)
96+
expect(wrapper.find('.vfm__overlay').attributes('style')).toContain('background: rgb(255, 255, 255)')
9797
wrapper.unmount()
9898
})
9999
it('contentClass', async () => {
@@ -104,12 +104,28 @@ describe('VueFinalModal.vue', () => {
104104
expect(wrapper.find('.vfm__content').classes()).toContain(testClass)
105105
wrapper.unmount()
106106
})
107-
it('contentStyle', async () => {
108-
const testStyle = 'background: rgb(255, 255, 255);'
107+
it('contentStyle with object', async () => {
108+
const testStyle = { background: 'rgb(255, 255, 255)' }
109109
const { wrapper } = await createClosedModal({
110110
contentStyle: testStyle
111111
})
112-
expect(wrapper.find('.vfm__content').attributes('style')).toContain(testStyle)
112+
const style = wrapper.find('.vfm__content').attributes('style')
113+
Object.keys(testStyle).forEach(key => {
114+
expect(style).toContain(`${key}: ${testStyle[key]};`)
115+
})
116+
wrapper.unmount()
117+
})
118+
it('contentStyle with array object', async () => {
119+
const testStyle = [{ background: 'rgb(255, 255, 255)' }]
120+
const { wrapper } = await createOpenedModal({
121+
contentStyle: testStyle
122+
})
123+
const style = wrapper.find('.vfm__content').attributes('style')
124+
testStyle.forEach(item => {
125+
Object.keys(item).forEach(key => {
126+
expect(style).toContain(`${key}: ${item[key]};`)
127+
})
128+
})
113129
wrapper.unmount()
114130
})
115131
it('hideOverlay: true', async () => {
@@ -426,6 +442,7 @@ describe('VueFinalModal.vue', () => {
426442
await $vfm.show('testModal', params)
427443
await $vfm.hide('testModal')
428444
expect(isEqual(wrapper.findComponent('.vfm').vm.params, params)).toBe(true)
445+
wrapper.unmount()
429446
})
430447
})
431448
})

tests/unit/dragResize.spec.js

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import { setStyle, getPosition, clamp, trimPx, addListener, removeListener } from '../../lib/utils/dragResize'
2+
import { afterTransition, createOpenedModal } from './utils'
3+
import { h } from 'vue'
4+
5+
function dispatchEvents(el) {
6+
const mousedownEvent = new MouseEvent('mousedown', { bubbles: true })
7+
const mousemoveEvent = new MouseEvent('mousemove', { bubbles: true })
8+
const mouseupEvent = new MouseEvent('mouseup', { bubbles: true })
9+
el.dispatchEvent(mousedownEvent)
10+
el.dispatchEvent(mousemoveEvent)
11+
el.dispatchEvent(mouseupEvent)
12+
return new Promise(resolve => {
13+
setTimeout(() => resolve())
14+
})
15+
}
16+
function getEmittedEvents(type, wrapper) {
17+
return ['start', 'move', 'end'].reduce((events, event) => {
18+
const _event = wrapper.emitted(`${type}:${event}`)
19+
if (_event) {
20+
events.push(..._event)
21+
}
22+
return events
23+
}, [])
24+
}
25+
26+
describe('drag & resize', () => {
27+
it('drag', async () => {
28+
const { wrapper } = await createOpenedModal({ drag: true })
29+
await wrapper.setProps({ drag: false })
30+
await dispatchEvents(wrapper.find('.vfm__content').element)
31+
expect(getEmittedEvents('drag', wrapper.findComponent('.vfm')).length).toBe(0)
32+
await wrapper.setProps({ drag: true })
33+
await dispatchEvents(wrapper.find('.vfm__content').element)
34+
expect(getEmittedEvents('drag', wrapper.findComponent('.vfm')).length).toBe(3)
35+
await wrapper.setProps({ modelValue: false })
36+
await afterTransition()
37+
expect(wrapper.find('.vfm').isVisible()).toBe(false)
38+
wrapper.unmount()
39+
})
40+
it('dragSelector', async () => {
41+
const { wrapper } = await createOpenedModal(
42+
{ drag: true, fitParant: false, dragSelector: '.modal-content' },
43+
{},
44+
{
45+
slots: {
46+
default: () => h('div', { class: 'modal-content' }, h('div', { class: 'modal-disabled-drag' }))
47+
}
48+
}
49+
)
50+
51+
await dispatchEvents(wrapper.find('.modal-disabled-drag').element)
52+
expect(getEmittedEvents('drag', wrapper.findComponent('.vfm')).length).toBe(0)
53+
await dispatchEvents(wrapper.find('.modal-content').element)
54+
expect(getEmittedEvents('drag', wrapper.findComponent('.vfm')).length).toBe(3)
55+
wrapper.unmount()
56+
})
57+
it('resize', async () => {
58+
const resizeDirections = ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']
59+
const { wrapper } = await createOpenedModal({
60+
resize: true,
61+
resizeDirections,
62+
fitParant: false
63+
})
64+
await wrapper.setProps({ resize: false })
65+
await afterTransition()
66+
await wrapper.setProps({ resize: true })
67+
await afterTransition()
68+
await Promise.allSettled(
69+
resizeDirections.map(direction => {
70+
return dispatchEvents(wrapper.find(`.vfm--resize-${direction}`).element)
71+
})
72+
)
73+
expect(getEmittedEvents('resize', wrapper.findComponent('.vfm')).length).toBe(resizeDirections.length * 3)
74+
await wrapper.setProps({ modelValue: false })
75+
await afterTransition()
76+
expect(wrapper.find('.vfm').isVisible()).toBe(false)
77+
wrapper.unmount()
78+
})
79+
it('resize with absolute vfmContent', async () => {
80+
const resizeDirections = ['t', 'tr', 'r', 'br']
81+
const { wrapper } = await createOpenedModal({
82+
resize: true,
83+
resizeDirections,
84+
fitParent: true,
85+
contentStyle: { position: 'absolute' }
86+
})
87+
await wrapper.setProps({ resize: false })
88+
await afterTransition()
89+
await wrapper.setProps({ resize: true })
90+
await afterTransition()
91+
await Promise.allSettled(
92+
resizeDirections.map(direction => {
93+
return dispatchEvents(wrapper.find(`.vfm--resize-${direction}`).element)
94+
})
95+
)
96+
expect(getEmittedEvents('resize', wrapper.findComponent('.vfm')).length).toBe(resizeDirections.length * 3)
97+
wrapper.unmount()
98+
})
99+
it('resize with absolute vfmContent', async () => {
100+
const resizeDirections = ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']
101+
const { wrapper } = await createOpenedModal({
102+
resize: true,
103+
resizeDirections,
104+
fitParent: false,
105+
contentStyle: { position: 'absolute' }
106+
})
107+
await wrapper.setProps({ resize: false })
108+
await afterTransition()
109+
await wrapper.setProps({ resize: true })
110+
await afterTransition()
111+
await Promise.allSettled(
112+
resizeDirections.map(direction => {
113+
return dispatchEvents(wrapper.find(`.vfm--resize-${direction}`).element)
114+
})
115+
)
116+
expect(getEmittedEvents('resize', wrapper.findComponent('.vfm')).length).toBe(resizeDirections.length * 3)
117+
wrapper.unmount()
118+
})
119+
it('keepChangedStyle', async () => {
120+
const { wrapper } = await createOpenedModal({ drag: true, keepChangedStyle: true })
121+
await wrapper.setProps({ keepChangedStyle: false })
122+
expect(wrapper.findComponent('.vfm').props().keepChangedStyle).toBe(false)
123+
wrapper.unmount()
124+
})
125+
})
126+
127+
describe('utils: dragResize', () => {
128+
it('setStyle', () => {
129+
const resizeCursor = {
130+
t: 'ns-resize',
131+
tr: 'nesw-resize',
132+
r: 'ew-resize',
133+
br: 'nwse-resize',
134+
b: 'ns-resize',
135+
bl: 'nesw-resize',
136+
l: 'ew-resize',
137+
tl: 'nwse-resize'
138+
}
139+
140+
Object.values(resizeCursor).forEach(cursor => {
141+
const elem = document.createElement('div')
142+
const defaultCursor = elem.style.cursor
143+
const resetStyle = setStyle(elem, 'cursor', cursor)
144+
expect(elem.style.cursor).toBe(cursor)
145+
resetStyle()
146+
expect(elem.style.cursor).toBe(defaultCursor)
147+
})
148+
})
149+
150+
it('getPosition', () => {
151+
const result = { x: 0, y: 0 }
152+
const touchesEvent = {
153+
targetTouches: [{ clientX: 0, clientY: 0 }]
154+
}
155+
const clickEvent = {
156+
clientX: 0,
157+
clientY: 0
158+
}
159+
expect(getPosition(touchesEvent)).toEqual(result)
160+
expect(getPosition(clickEvent)).toEqual(result)
161+
})
162+
163+
it('clamp', () => {
164+
expect(clamp(undefined, -20, undefined)).toBe(-20)
165+
expect(clamp(10, -20, undefined)).toBe(10)
166+
expect(clamp(10, 20, undefined)).toBe(20)
167+
expect(clamp(10, 20, 15)).toBe(15)
168+
expect(clamp(10, 2, 15)).toBe(10)
169+
expect(clamp(10, 20, 30)).toBe(20)
170+
})
171+
172+
it('trimPx', () => {
173+
expect(trimPx('100px')).toBe(100)
174+
expect(trimPx('100%')).toBe(0)
175+
expect(trimPx('100')).toBe(100)
176+
expect(trimPx('0px')).toBe(0)
177+
expect(trimPx('0%')).toBe(0)
178+
expect(trimPx('0')).toBe(0)
179+
expect(trimPx('')).toBe(0)
180+
})
181+
182+
it('add & remove EventListener', () => {
183+
const downElem = document.createElement('div')
184+
const downFn = jest.fn()
185+
addListener('down', downElem, downFn)
186+
const mousedownEvent = new CustomEvent('mousedown')
187+
const touchstartEvent = new CustomEvent('touchstart')
188+
downElem.dispatchEvent(mousedownEvent)
189+
downElem.dispatchEvent(touchstartEvent)
190+
expect(downFn).toHaveBeenCalledTimes(2)
191+
192+
removeListener('down', downElem, downFn)
193+
downElem.dispatchEvent(mousedownEvent)
194+
downElem.dispatchEvent(touchstartEvent)
195+
expect(downFn).toHaveBeenCalledTimes(2)
196+
197+
const moveElem = document.createElement('div')
198+
const moveFn = jest.fn()
199+
addListener('move', moveElem, moveFn)
200+
const mousemoveEvent = new CustomEvent('mousemove')
201+
const touchmoveEvent = new CustomEvent('touchmove')
202+
moveElem.dispatchEvent(mousemoveEvent)
203+
moveElem.dispatchEvent(touchmoveEvent)
204+
expect(moveFn).toHaveBeenCalledTimes(2)
205+
206+
removeListener('move', moveElem, moveFn)
207+
moveElem.dispatchEvent(mousemoveEvent)
208+
moveElem.dispatchEvent(touchmoveEvent)
209+
expect(moveFn).toHaveBeenCalledTimes(2)
210+
211+
const upElem = document.createElement('div')
212+
const upFn = jest.fn()
213+
addListener('up', upElem, upFn)
214+
const mouseupEvent = new CustomEvent('mouseup')
215+
const touchendEvent = new CustomEvent('touchend')
216+
upElem.dispatchEvent(mouseupEvent)
217+
upElem.dispatchEvent(touchendEvent)
218+
expect(upFn).toHaveBeenCalledTimes(2)
219+
220+
removeListener('up', upElem, upFn)
221+
upElem.dispatchEvent(mouseupEvent)
222+
upElem.dispatchEvent(touchendEvent)
223+
expect(upFn).toHaveBeenCalledTimes(2)
224+
})
225+
})

tests/unit/utils.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function afterTransition(transitionDelay = 65) {
1010
}
1111

1212
const vfm = {
13-
template: `<vue-final-modal v-bind="$attrs"></vue-final-modal>`,
13+
template: `<vue-final-modal v-bind="$attrs"><slot></slot></vue-final-modal>`,
1414
inheritAttrs: false
1515
}
1616

@@ -23,12 +23,12 @@ export function createOpenedModal(props = {}, attrs = {}, mountingOptions = {})
2323
const wrapper = mount(vfm, {
2424
props: {
2525
modelValue: true,
26+
'onUpdate:modelValue': val => {
27+
wrapper.setProps({ modelValue: val })
28+
},
2629
...props
2730
},
2831
attrs: {
29-
input: val => {
30-
wrapper.setProps({ modelValue: val })
31-
},
3232
...attrs,
3333
onOpened() {
3434
if (attrs.onOpened) {
@@ -58,6 +58,9 @@ export function createClosedModal(props = {}, attrs = {}, mountingOptions = {})
5858
const wrapper = mount(vfm, {
5959
props: {
6060
modelValue: false,
61+
'onUpdate:modelValue': val => {
62+
wrapper.setProps({ modelValue: val })
63+
},
6164
...props
6265
},
6366
global: {

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,10 +1494,10 @@
14941494
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.11.tgz#20d22dd0da7d358bb21c17f9bde8628152642c77"
14951495
integrity sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==
14961496

1497-
"@vue/test-utils@^2.0.0-0":
1498-
version "2.0.0-rc.3"
1499-
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0-rc.3.tgz#11b97d56d786bec60431b00888b3264e334b83c8"
1500-
integrity sha512-f2/RtXp0IZgyAL/X3N9dBlobcL3VMZ336nw/gKBIQWXPMC9dbZvC7C4F7bQNI5235fjAEO6zeMK2L7MwsHlKBw==
1497+
"@vue/test-utils@^2.0.0-rc.6":
1498+
version "2.0.0-rc.6"
1499+
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0-rc.6.tgz#d0aac24d20450d379e183f70542c0822670b8783"
1500+
integrity sha512-0cnQBVH589PwgqWpyv1fgCAz+9Ram/MsvN3ZEAEVXi1aPuhUa22EudGc0WezQ9PKwR+L40NrBmt3JBXE2tSRRQ==
15011501

15021502
"@webassemblyjs/[email protected]":
15031503
version "1.9.0"

0 commit comments

Comments
 (0)