Skip to content

Commit

Permalink
fix: remove interop and deep DTL imports
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Dec 27, 2023
1 parent d7483f0 commit 6a3c896
Show file tree
Hide file tree
Showing 16 changed files with 167 additions and 90 deletions.
26 changes: 0 additions & 26 deletions src/_interop/dom-events.d.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/_interop/dom-helpers.d.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/_interop/dtl.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/_interop/dtlEventMap.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/_interop/dtlHelpers.ts

This file was deleted.

30 changes: 24 additions & 6 deletions src/event/createEvent.ts
@@ -1,13 +1,30 @@
import {getWindow} from '../utils'
import {eventMap, eventMapKeys} from './eventMap'
import {eventMap} from './eventMap'
import {
type EventType,
type EventTypeInit,
type FixedDocumentEventMap,
} from './types'

const eventInitializer = {
interface InterfaceMap {
ClipboardEvent: {type: ClipboardEvent; init: ClipboardEventInit}
InputEvent: {type: InputEvent; init: InputEventInit}
MouseEvent: {type: MouseEvent; init: MouseEventInit}
PointerEvent: {type: PointerEvent; init: PointerEventInit}
KeyboardEvent: {type: KeyboardEvent; init: KeyboardEventInit}
}
type InterfaceNames = typeof eventMap[keyof typeof eventMap]['EventType']
type Interface<k extends InterfaceNames> = k extends keyof InterfaceMap
? InterfaceMap[k]
: never

const eventInitializer: {
[k in InterfaceNames]: Array<
(e: Interface<k>['type'], i: Interface<k>['init']) => void
>
} = {
ClipboardEvent: [initClipboardEvent],
Event: [],
InputEvent: [initUIEvent, initInputEvent],
MouseEvent: [initUIEvent, initUIEventModififiers, initMouseEvent],
PointerEvent: [
Expand All @@ -17,18 +34,19 @@ const eventInitializer = {
initPointerEvent,
],
KeyboardEvent: [initUIEvent, initUIEventModififiers, initKeyboardEvent],
} as Record<EventInterface, undefined | Array<(e: Event, i: EventInit) => void>>
}

export function createEvent<K extends EventType>(
type: K,
target: Element,
init?: EventTypeInit<K>,
) {
const window = getWindow(target)
const {EventType, defaultInit} =
eventMap[eventMapKeys[type] as keyof typeof eventMap]
const {EventType, defaultInit} = eventMap[type]
const event = new (getEventConstructors(window)[EventType])(type, defaultInit)
eventInitializer[EventType]?.forEach(f => f(event, init ?? {}))
eventInitializer[EventType].forEach(f =>
f(event as never, (init ?? {}) as never),
)

return event as FixedDocumentEventMap[K]
}
Expand Down
118 changes: 105 additions & 13 deletions src/event/eventMap.ts
@@ -1,39 +1,131 @@
import dtlEvents from '../_interop/dtlEventMap'
import {EventType} from './types'

export const eventMap = {
...dtlEvents.eventMap,

click: {
auxclick: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
auxclick: {
beforeinput: {
EventType: 'InputEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
click: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
contextmenu: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
beforeInput: {
copy: {
EventType: 'ClipboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
change: {
EventType: 'Event',
defaultInit: {bubbles: true, cancelable: false},
},
cut: {
EventType: 'ClipboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
dblclick: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
keydown: {
EventType: 'KeyboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
keypress: {
EventType: 'KeyboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
keyup: {
EventType: 'KeyboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
paste: {
EventType: 'ClipboardEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
input: {
EventType: 'InputEvent',
defaultInit: {bubbles: true, cancelable: false, composed: true},
},
mousedown: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
mouseenter: {
EventType: 'MouseEvent',
defaultInit: {bubbles: false, cancelable: false, composed: true},
},
mouseleave: {
EventType: 'MouseEvent',
defaultInit: {bubbles: false, cancelable: false, composed: true},
},
mousemove: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
mouseout: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
mouseover: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
mouseup: {
EventType: 'MouseEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointerover: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointerenter: {
EventType: 'PointerEvent',
defaultInit: {bubbles: false, cancelable: false},
},
pointerdown: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointermove: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointerup: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointercancel: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: false, composed: true},
},
pointerout: {
EventType: 'PointerEvent',
defaultInit: {bubbles: true, cancelable: true, composed: true},
},
pointerleave: {
EventType: 'PointerEvent',
defaultInit: {bubbles: false, cancelable: false},
},
submit: {
EventType: 'Event',
defaultInit: {bubbles: true, cancelable: true},
},
} as const

export const eventMapKeys: {
[k in keyof DocumentEventMap]?: keyof typeof eventMap
} = Object.fromEntries(Object.keys(eventMap).map(k => [k.toLowerCase(), k]))

function getEventClass(type: EventType) {
const k = eventMapKeys[type]
return k && eventMap[k].EventType
return eventMap[type].EventType
}

const mouseEvents = ['MouseEvent', 'PointerEvent']
export function isMouseEvent(type: EventType) {
return mouseEvents.includes(getEventClass(type) as string)
return mouseEvents.includes(getEventClass(type))
}

export function isKeyboardEvent(type: EventType) {
Expand Down
4 changes: 3 additions & 1 deletion src/event/types.ts
@@ -1,4 +1,6 @@
export type EventType = keyof DocumentEventMap
import {eventMap} from './eventMap'

export type EventType = keyof typeof eventMap

export type EventTypeInit<K extends EventType> = SpecificEventInit<
FixedDocumentEventMap[K]
Expand Down
4 changes: 1 addition & 3 deletions src/event/wrapEvent.ts
@@ -1,6 +1,4 @@
import dtl from '../_interop/dtl'

const {getConfig} = dtl
import {getConfig} from '@testing-library/dom'

export function wrapEvent<R>(cb: () => R, _element: Element) {
return getConfig().eventWrapper(cb) as unknown as R
Expand Down
4 changes: 1 addition & 3 deletions src/setup/wrapAsync.ts
@@ -1,6 +1,4 @@
import dtl from '../_interop/dtl'

const {getConfig} = dtl
import {getConfig} from '@testing-library/dom'

/**
* Wrap an internal Promise
Expand Down
4 changes: 1 addition & 3 deletions src/utility/selectOptions.ts
@@ -1,10 +1,8 @@
import dtl from '../_interop/dtl'
import {getConfig} from '@testing-library/dom'
import {hasPointerEvents, isDisabled, isElementType, wait} from '../utils'
import {type Instance} from '../setup'
import {focusElement} from '../event'

const {getConfig} = dtl

export async function selectOptions(
this: Instance,
select: Element,
Expand Down
23 changes: 19 additions & 4 deletions src/utils/misc/getWindow.ts
@@ -1,7 +1,22 @@
import dtlHelpers from '../../_interop/dtlHelpers'
export function getWindow(node: Node) {
if (isDocument(node) && node.defaultView) {
return node.defaultView
} else if (node.ownerDocument?.defaultView) {
return node.ownerDocument.defaultView
}
throw new Error(
`Could not determine window of node. Node was ${describe(node)}`,
)
}

const {getWindowFromNode} = dtlHelpers
function isDocument(node: Node): node is Document {
return node.nodeType === 9
}

export function getWindow(node: Node) {
return getWindowFromNode(node) as Window & typeof globalThis
function describe(val: unknown) {
return typeof val === 'function'
? `function ${val.name}`
: val === null
? 'null'
: String(val)
}
9 changes: 0 additions & 9 deletions tests/_helpers/dom-events.d.ts

This file was deleted.

15 changes: 11 additions & 4 deletions tests/_helpers/listeners.ts
@@ -1,4 +1,4 @@
import {eventMapKeys} from '#src/event/eventMap'
import {eventMap} from '#src/event/eventMap'
import {isElementType} from '#src/utils'
import {MouseButton, MouseButtonFlip} from '#src/system/pointer/buttons'

Expand Down Expand Up @@ -31,6 +31,15 @@ export function addEventListener(

export type EventHandlers = {[k in keyof DocumentEventMap]?: EventListener}

const loggedEvents = [
...(Object.keys(eventMap) as Array<keyof typeof eventMap>),
'focus',
'focusin',
'focusout',
'blur',
'select',
] as const

/**
* Add listeners for logging events.
*/
Expand All @@ -50,9 +59,7 @@ export function addListeners(

const generalListener = mocks.fn(eventHandler).mockName('eventListener')

for (const eventType of Object.keys(eventMapKeys) as Array<
keyof typeof eventMapKeys
>) {
for (const eventType of loggedEvents) {
addEventListener(element, eventType, (...args) => {
generalListener(...args)
eventHandlers[eventType]?.(...args)
Expand Down
4 changes: 1 addition & 3 deletions tests/setup/index.ts
@@ -1,11 +1,9 @@
import {getSpy} from './_mockApis'
import DOMTestingLibrary from '#src/_interop/dtl'
import {getConfig} from '@testing-library/dom'
import userEvent from '#src'
import {type Instance, type UserEventApi} from '#src/setup/setup'
import {render} from '#testHelpers'

const {getConfig} = DOMTestingLibrary

type ApiDeclarations = {
[api in keyof UserEventApi]: {
args?: unknown[]
Expand Down
4 changes: 1 addition & 3 deletions tests/utils/misc/isVisible.ts
@@ -1,9 +1,7 @@
import DOMTestingLibrary from '#src/_interop/dtl'
import {screen} from '@testing-library/dom'
import {isVisible} from '#src/utils'
import {setup} from '#testHelpers'

const {screen} = DOMTestingLibrary

test('check if element is visible', async () => {
setup(`
<input data-testid="visibleInput"/>
Expand Down

0 comments on commit 6a3c896

Please sign in to comment.