-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #332 from palmcivet/test/image-viewer/unit
test(image-viewer): add unit test for image-viewer
- Loading branch information
Showing
7 changed files
with
315 additions
and
11 deletions.
There are no files selected for viewing
Submodule _common
updated
22 files
109 changes: 109 additions & 0 deletions
109
src/image-viewer/__test__/__snapshots__/index.test.jsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Vitest Snapshot v1 | ||
|
||
exports[`ImageViewer > function > : onIndexChange 1`] = ` | ||
<transition-stub | ||
class="t-image-viewer" | ||
> | ||
<div | ||
class="t-overlay t-overlay--active" | ||
style="z-index: 1000; transition-duration: 300ms;" | ||
> | ||
<div | ||
class="t-image-viewer__close-icon" | ||
> | ||
<svg | ||
class="t-icon t-icon-close-circle-filled" | ||
fill="none" | ||
height="1em" | ||
viewBox="0 0 16 16" | ||
width="1em" | ||
> | ||
<path | ||
d="M15 8A7 7 0 101 8a7 7 0 0014 0zM5.67 4.95L8 7.29l2.33-2.34.7.7L8.7 8l2.34 2.35-.71.7L8 8.71l-2.33 2.34-.7-.7L7.3 8 4.96 5.65l.71-.7z" | ||
fill="currentColor" | ||
fill-opacity="0.9" | ||
/> | ||
</svg> | ||
</div> | ||
<div | ||
class="t-swiper t-image-viewer__swipe" | ||
style="overflow: hidden;" | ||
> | ||
<div | ||
class="t-swiper__container" | ||
data-is-trust="true" | ||
style="flex-direction: row; transform: translateX(-0px); transition: transform 300ms;" | ||
> | ||
<div | ||
class="t-swiper-item t-image-viewer__swipe-item copy-item" | ||
> | ||
<img | ||
class="t-image-viewer__image" | ||
src="https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png" | ||
style="transition-duration: .3s;" | ||
/> | ||
</div> | ||
<div | ||
class="t-swiper-item t-image-viewer__swipe-item" | ||
> | ||
<img | ||
class="t-image-viewer__image" | ||
src="https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png" | ||
style="transition-duration: .3s;" | ||
/> | ||
</div> | ||
<div | ||
class="t-swiper-item t-image-viewer__swipe-item" | ||
> | ||
<img | ||
class="t-image-viewer__image" | ||
src="https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png" | ||
style="transition-duration: .3s;" | ||
/> | ||
</div> | ||
<div | ||
class="t-swiper-item t-image-viewer__swipe-item copy-item" | ||
> | ||
<img | ||
class="t-image-viewer__image" | ||
src="https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png" | ||
style="transition-duration: .3s;" | ||
/> | ||
</div> | ||
</div> | ||
<!--v-if--> | ||
<span | ||
class="t-swiper__pagination t-swiper__pagination-dots t-swiper__pagination-bottom" | ||
> | ||
<span | ||
class="t-swiper-dot" | ||
/> | ||
<span | ||
class="t-swiper-dot" | ||
/> | ||
<!--v-if--> | ||
</span> | ||
</div> | ||
</div> | ||
</transition-stub> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { nextTick, ref } from 'vue'; | ||
import { mount } from '@vue/test-utils'; | ||
import { CloseCircleFilledIcon, AddCircleIcon } from 'tdesign-icons-vue-next'; | ||
import { describe, it, vi } from 'vitest'; | ||
import ImageViewer from '../image-viewer.vue'; | ||
import { Swiper } from '../../swiper'; | ||
import { trigger, triggerZoom } from './touch'; | ||
|
||
const images = ref([ | ||
'https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png', | ||
'https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png', | ||
'https://imgcache.qq.com/open_proj/proj_qcloud_v2/rocket_images/1606728019829_yw760ok1jmpbep14i.png', | ||
]); | ||
|
||
describe('ImageViewer', () => { | ||
describe('props', () => { | ||
it(': closeBtn', async () => { | ||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} closeBtn={false} />); | ||
|
||
expect(wrapper.findComponent(CloseCircleFilledIcon).exists()).toBe(false); | ||
}); | ||
|
||
it(': images', async () => { | ||
const emptyImages = mount(<ImageViewer visible={true} />); | ||
expect(emptyImages.find('.t-swiper-item').exists()).toBe(false); | ||
|
||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} />); | ||
|
||
await nextTick(); | ||
expect(wrapper.findAll('.t-swiper-item').length - 2).toBe(images.value.length); | ||
|
||
images.value.pop(); | ||
await nextTick(); | ||
expect(wrapper.findAll('.t-swiper-item').length - 2).toBe(images.value.length); | ||
}); | ||
|
||
it(': maxZoom', async () => { | ||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} maxZoom={2} />); | ||
|
||
const target = wrapper.find('.t-swiper-item'); | ||
triggerZoom(target, 200, 200, 'in'); | ||
expect(wrapper.vm.imageStyle).toMatchObject({ transform: `scale(${2}, ${2})` }); | ||
|
||
triggerZoom(target, 200, 200, 'out'); | ||
expect(wrapper.vm.imageStyle).not.toHaveProperty('transform'); | ||
|
||
// 测试 toggleScale | ||
trigger(target, 'touchstart', 50, 50); | ||
trigger(target, 'touchend', 50, 50); | ||
|
||
await new Promise((resolve, reject) => { | ||
setTimeout(() => { | ||
resolve(); | ||
}, 100); // 小于 TAP_TIME | ||
}); | ||
trigger(target, 'touchstart', 50, 50); | ||
trigger(target, 'touchend', 50, 50); | ||
}); | ||
|
||
it(': showIndex', async () => { | ||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} showIndex={true} />); | ||
|
||
expect(wrapper.find('.t-swiper__pagination-fraction').exists()).toBe(true); | ||
}); | ||
|
||
it(': visible', async () => { | ||
const visible = ref(false); | ||
const wrapper = mount(<ImageViewer v-model:images={images.value} v-model:visible={visible.value} />); | ||
|
||
expect(wrapper.findComponent(Swiper).exists()).toBe(false); | ||
visible.value = true; | ||
}); | ||
}); | ||
|
||
describe('slots', () => { | ||
it(': closeBtn', () => { | ||
const wrapper = mount( | ||
<ImageViewer v-model:images={images.value} visible={true} closeBtn={() => <AddCircleIcon />} />, | ||
); | ||
|
||
expect(wrapper.findComponent(AddCircleIcon).exists()).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('event', () => { | ||
it(': close', async () => { | ||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} />); | ||
|
||
await wrapper.findComponent(CloseCircleFilledIcon).trigger('click'); | ||
expect(wrapper.emitted()).toHaveProperty('close'); | ||
}); | ||
}); | ||
|
||
describe('function', () => { | ||
it(': onClose', async () => { | ||
const onClose = vi.fn(); | ||
|
||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} onClose={onClose} />); | ||
|
||
await wrapper.findComponent(CloseCircleFilledIcon).trigger('click'); | ||
expect(onClose).toHaveBeenCalled(); | ||
}); | ||
|
||
it(': onIndexChange', async () => { | ||
const onIndexChange = vi.fn(); | ||
|
||
const wrapper = mount(<ImageViewer v-model:images={images.value} visible={true} onIndexChange={onIndexChange} />); | ||
|
||
const target = wrapper.find('.t-swiper__container'); | ||
|
||
await trigger(target, 'touchstart', 0, 0); | ||
await trigger(target, 'touchmove', 30, 0); | ||
await trigger(target, 'touchmove', 60, 0); | ||
await trigger(target, 'touchmove', 120, 0); | ||
await trigger(target, 'touchend', 120, 0); | ||
|
||
expect(wrapper.element).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* https://github.com/vant-ui/vant/blob/dev/packages/vant/test/event.ts | ||
*/ | ||
|
||
import { ComponentPublicInstance, nextTick } from 'vue'; | ||
import { VueWrapper, DOMWrapper } from '@vue/test-utils'; | ||
|
||
function getTouch(el: Element | Window, x: number, y: number) { | ||
return { | ||
identifier: Date.now(), | ||
target: el, | ||
pageX: x, | ||
pageY: y, | ||
clientX: x, | ||
clientY: y, | ||
radiusX: 2.5, | ||
radiusY: 2.5, | ||
rotationAngle: 10, | ||
force: 0.5, | ||
}; | ||
} | ||
|
||
// trigger pointer/touch event | ||
export function trigger( | ||
wrapper: VueWrapper<ComponentPublicInstance<any, any, any>> | DOMWrapper<Element> | Element | Window, | ||
eventName: string, | ||
x = 0, | ||
y = 0, | ||
options: any = {}, | ||
) { | ||
const el = 'element' in wrapper ? wrapper.element : wrapper; | ||
const touchList = options.touchList || [getTouch(el, x, y)]; | ||
|
||
if (options.x || options.y) { | ||
touchList.push(getTouch(el, options.x, options.y)); | ||
} | ||
|
||
const event = document.createEvent('CustomEvent'); | ||
event.initCustomEvent(eventName, true, true, {}); | ||
|
||
Object.assign(event, { | ||
clientX: x, | ||
clientY: y, | ||
touches: touchList, | ||
targetTouches: touchList, | ||
changedTouches: touchList, | ||
}); | ||
|
||
el.dispatchEvent(event); | ||
|
||
return nextTick(); | ||
} | ||
|
||
function triggerTwoFingerTouchmove(el: Element | DOMWrapper<Element>, x: number, y: number) { | ||
trigger(el, 'touchmove', -x, -y, { x, y }); | ||
} | ||
|
||
// simulate zoom | ||
export function triggerZoom(el: Element | DOMWrapper<Element>, x: number, y: number, direction: 'in' | 'out' = 'in') { | ||
trigger(el, 'touchstart', 0, 0, { x, y }); | ||
|
||
if (direction === 'in') { | ||
triggerTwoFingerTouchmove(el, x / 4, y / 4); | ||
triggerTwoFingerTouchmove(el, x / 3, y / 3); | ||
triggerTwoFingerTouchmove(el, x / 2, y / 2); | ||
triggerTwoFingerTouchmove(el, x, y); | ||
} else if (direction === 'out') { | ||
triggerTwoFingerTouchmove(el, x, y); | ||
triggerTwoFingerTouchmove(el, x / 2, y / 2); | ||
triggerTwoFingerTouchmove(el, x / 3, y / 3); | ||
triggerTwoFingerTouchmove(el, x / 4, y / 4); | ||
} | ||
|
||
trigger(el, 'touchend', 0, 0, { touchList: [] }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters