element-plus/packages/directives/__tests__/click-outside.test.ts
2022-04-20 17:02:44 +08:00

160 lines
3.6 KiB
TypeScript

import { h, withDirectives } from 'vue'
import { mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, test, vi } from 'vitest'
import ClickOutside from '../click-outside'
const AXIOM = 'Rem is the best girl'
const TRIGGER = 'trigger'
const OTHER_CLASS = 'other-class'
// init some local variables
let mousedownObject
let mouseupObject
// mock handler with implementations which makes assignment to the local variable that we registered above.
const handler = vi.fn((eMouseup, eMousedown) => {
mouseupObject = eMouseup
mousedownObject = eMousedown
})
const Component = {
template: `
<div>
<div class="${OTHER_CLASS}">Hello</div>
<div class="${TRIGGER}" v-click-outside="handler">${AXIOM}</div>
</div>
`,
setup() {
return {
handler,
}
},
}
const _mount = () =>
mount(Component, {
global: {
directives: {
ClickOutside,
},
},
})
const triggerDocumentClickEvent = () => {
const mousedown = document.createEvent('MouseEvents')
mousedown.initMouseEvent(
'mousedown',
true,
true,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
)
document.dispatchEvent(mousedown)
const mouseup = document.createEvent('MouseEvents')
mouseup.initMouseEvent(
'mouseup',
true,
true,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
)
document.dispatchEvent(mouseup)
}
describe('Directives.vue', () => {
beforeEach(() => {
// clear the previously assigned event object
mousedownObject = null
mouseupObject = null
})
test('render test', () => {
const wrapper = _mount()
expect(wrapper.text()).toContain(AXIOM)
expect(handler).toHaveBeenCalledTimes(0)
wrapper.unmount()
})
test('should trigger handler', async () => {
const wrapper = _mount()
await wrapper.find(`.${TRIGGER}`).trigger('mousedown')
await wrapper.find(`.${TRIGGER}`).trigger('mouseup')
expect(handler).toHaveBeenCalledTimes(0)
triggerDocumentClickEvent()
// here is the different part
// we test the existence of the local variable.
expect(mousedownObject).toBeDefined()
expect(mouseupObject).toBeDefined()
})
})
describe('Multiple click-outside directives', () => {
const firstHandler = vi.fn()
const InnerComponent = {
template: `<div class="${TRIGGER}" v-click-outside="handler">${AXIOM}</div>`,
setup() {
return { handler: firstHandler }
},
}
const secondHandler = vi.fn()
const OuterComponent = {
setup() {
return () => {
const triggerNode = withDirectives(h(InnerComponent), [
[ClickOutside, secondHandler],
])
return h('div', { class: OTHER_CLASS }, triggerNode)
}
},
}
it('should support for multiple directives', async () => {
const wrapper = mount(OuterComponent, {
global: {
directives: {
ClickOutside,
},
},
})
// click inside trigger element
await wrapper.find(`.${TRIGGER}`).trigger('mousedown')
await wrapper.find(`.${TRIGGER}`).trigger('mouseup')
expect(firstHandler).toHaveBeenCalledTimes(0)
expect(secondHandler).toHaveBeenCalledTimes(0)
// click outside trigger element
triggerDocumentClickEvent()
expect(firstHandler).toHaveBeenCalledTimes(1)
expect(secondHandler).toHaveBeenCalledTimes(1)
// update the component instance
wrapper.vm.$forceUpdate()
triggerDocumentClickEvent()
expect(firstHandler).toHaveBeenCalledTimes(2)
expect(secondHandler).toHaveBeenCalledTimes(2)
})
})