130 lines
3.9 KiB
JavaScript
130 lines
3.9 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { useContentMarkdownLightbox } from '../composables/useContentMarkdownLightbox.js'
|
|
|
|
/**
|
|
* 라이트박스 키보드 이벤트 테스트용 대상을 만든다.
|
|
* @returns {{ target: { addEventListener: Function, removeEventListener: Function }, listeners: Set<Function>, addCount: () => number, removeCount: () => number }} 이벤트 대상
|
|
*/
|
|
const createKeyboardTarget = () => {
|
|
const listeners = new Set()
|
|
let added = 0
|
|
let removed = 0
|
|
|
|
return {
|
|
listeners,
|
|
addCount: () => added,
|
|
removeCount: () => removed,
|
|
target: {
|
|
addEventListener: (type, handler) => {
|
|
if (type !== 'keydown') {
|
|
return
|
|
}
|
|
|
|
added += 1
|
|
listeners.add(handler)
|
|
},
|
|
removeEventListener: (type, handler) => {
|
|
if (type !== 'keydown') {
|
|
return
|
|
}
|
|
|
|
removed += 1
|
|
listeners.delete(handler)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키보드 이벤트 스텁을 만든다.
|
|
* @param {string} key - 키 이름
|
|
* @returns {{ key: string, prevented: boolean, preventDefault: Function }} 이벤트 스텁
|
|
*/
|
|
const createKeyboardEvent = (key) => ({
|
|
key,
|
|
prevented: false,
|
|
preventDefault () {
|
|
this.prevented = true
|
|
}
|
|
})
|
|
|
|
test('본문 라이트박스는 키로 이미지를 열고 순환 이동한다', () => {
|
|
const { target } = createKeyboardTarget()
|
|
const lightbox = useContentMarkdownLightbox({ getKeyboardTarget: () => target })
|
|
const images = [
|
|
{ lightboxKey: 'a', url: '/a.jpg' },
|
|
{ lightboxKey: 'b', url: '/b.jpg' },
|
|
{ lightboxKey: 'c', url: '/c.jpg' }
|
|
]
|
|
|
|
lightbox.openContentLightbox(images, 'b')
|
|
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg')
|
|
|
|
lightbox.showNextImage()
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/c.jpg')
|
|
|
|
lightbox.showNextImage()
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/a.jpg')
|
|
|
|
lightbox.showPreviousImage()
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/c.jpg')
|
|
})
|
|
|
|
test('본문 라이트박스는 열릴 때 키보드 이벤트를 한 번만 연결하고 닫힐 때 해제한다', () => {
|
|
const keyboard = createKeyboardTarget()
|
|
const lightbox = useContentMarkdownLightbox({ getKeyboardTarget: () => keyboard.target })
|
|
const images = [
|
|
{ lightboxKey: 'a', url: '/a.jpg' },
|
|
{ lightboxKey: 'b', url: '/b.jpg' }
|
|
]
|
|
|
|
lightbox.openLightbox(images, 0)
|
|
lightbox.openLightbox(images, 1)
|
|
|
|
assert.equal(keyboard.addCount(), 1)
|
|
assert.equal(keyboard.listeners.size, 1)
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg')
|
|
|
|
const event = createKeyboardEvent('Escape')
|
|
const [handler] = keyboard.listeners
|
|
|
|
handler(event)
|
|
|
|
assert.equal(event.prevented, true)
|
|
assert.equal(lightbox.activeLightboxImage.value, undefined)
|
|
assert.equal(keyboard.removeCount(), 1)
|
|
assert.equal(keyboard.listeners.size, 0)
|
|
})
|
|
|
|
test('본문 라이트박스 키보드 조작은 좌우 이동과 단일 이미지 예외를 처리한다', () => {
|
|
const lightbox = useContentMarkdownLightbox()
|
|
const images = [
|
|
{ lightboxKey: 'a', url: '/a.jpg' },
|
|
{ lightboxKey: 'b', url: '/b.jpg' }
|
|
]
|
|
|
|
lightbox.openLightbox(images, 0)
|
|
|
|
const rightEvent = createKeyboardEvent('ArrowRight')
|
|
lightbox.handleLightboxKeydown(rightEvent)
|
|
|
|
assert.equal(rightEvent.prevented, true)
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/b.jpg')
|
|
|
|
const leftEvent = createKeyboardEvent('ArrowLeft')
|
|
lightbox.handleLightboxKeydown(leftEvent)
|
|
|
|
assert.equal(leftEvent.prevented, true)
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/a.jpg')
|
|
|
|
lightbox.openLightbox([{ lightboxKey: 'single', url: '/single.jpg' }], 0)
|
|
|
|
const singleLeftEvent = createKeyboardEvent('ArrowLeft')
|
|
lightbox.handleLightboxKeydown(singleLeftEvent)
|
|
|
|
assert.equal(singleLeftEvent.prevented, false)
|
|
assert.equal(lightbox.activeLightboxImage.value.url, '/single.jpg')
|
|
})
|