1
1
import {
2
- fireEvent as dtlFireEvent ,
2
+ fireEvent as baseFireEvent ,
3
3
getQueriesForElement ,
4
4
prettyDOM ,
5
5
} from '@testing-library/dom'
@@ -10,6 +10,52 @@ import { mount, unmount, updateProps, validateOptions } from './core/index.js'
10
10
const targetCache = new Set ( )
11
11
const componentCache = new Set ( )
12
12
13
+ /**
14
+ * Customize how Svelte renders the component.
15
+ *
16
+ * @template {import('svelte').SvelteComponent} C
17
+ * @typedef {import('svelte').ComponentProps<C> | Partial<import('svelte').ComponentConstructorOptions<import('svelte').ComponentProps<C>>> } SvelteComponentOptions
18
+ */
19
+
20
+ /**
21
+ * Customize how Testing Library sets up the document and binds queries.
22
+ *
23
+ * @template {import('@testing-library/dom').Queries } [Q=typeof import('@testing-library/dom').queries]
24
+ * @typedef {{
25
+ * baseElement?: HTMLElement
26
+ * queries?: Q
27
+ * }} RenderOptions
28
+ */
29
+
30
+ /**
31
+ * The rendered component and bound testing functions.
32
+ *
33
+ * @template {import('svelte').SvelteComponent} C
34
+ * @template {import('@testing-library/dom').Queries } [Q=typeof import('@testing-library/dom').queries]
35
+ *
36
+ * @typedef {{
37
+ * container: HTMLElement
38
+ * baseElement: HTMLElement
39
+ * component: C
40
+ * debug: (el?: HTMLElement | DocumentFragment) => void
41
+ * rerender: (props: Partial<import('svelte').ComponentProps<C>>) => Promise<void>
42
+ * unmount: () => void
43
+ * } & {
44
+ * [P in keyof Q]: import('@testing -library/dom').BoundFunction<Q[P]>
45
+ * }} RenderResult
46
+ */
47
+
48
+ /**
49
+ * Render a component into the document.
50
+ *
51
+ * @template {import('svelte').SvelteComponent} C
52
+ * @template {import('@testing-library/dom').Queries } [Q=typeof import('@testing-library/dom').queries]
53
+ *
54
+ * @param {import('svelte').ComponentType<C> } Component - The component to render.
55
+ * @param {SvelteComponentOptions<C> } options - Customize how Svelte renders the component.
56
+ * @param {RenderOptions<Q> } renderOptions - Customize how Testing Library sets up the document and binds queries.
57
+ * @returns {RenderResult<C, Q> } The rendered component and bound testing functions.
58
+ */
13
59
const render = ( Component , options = { } , renderOptions = { } ) => {
14
60
options = validateOptions ( options )
15
61
@@ -33,7 +79,9 @@ const render = (Component, options = {}, renderOptions = {}) => {
33
79
baseElement,
34
80
component,
35
81
container : target ,
36
- debug : ( el = baseElement ) => console . log ( prettyDOM ( el ) ) ,
82
+ debug : ( el = baseElement ) => {
83
+ console . log ( prettyDOM ( el ) )
84
+ } ,
37
85
rerender : async ( props ) => {
38
86
if ( props . props ) {
39
87
console . warn (
@@ -52,6 +100,7 @@ const render = (Component, options = {}, renderOptions = {}) => {
52
100
}
53
101
}
54
102
103
+ /** Remove a component from the component cache. */
55
104
const cleanupComponent = ( component ) => {
56
105
const inCache = componentCache . delete ( component )
57
106
@@ -60,6 +109,7 @@ const cleanupComponent = (component) => {
60
109
}
61
110
}
62
111
112
+ /** Remove a target element from the target cache. */
63
113
const cleanupTarget = ( target ) => {
64
114
const inCache = targetCache . delete ( target )
65
115
@@ -68,27 +118,52 @@ const cleanupTarget = (target) => {
68
118
}
69
119
}
70
120
121
+ /** Unmount all components and remove elements added to `<body>`. */
71
122
const cleanup = ( ) => {
72
123
componentCache . forEach ( cleanupComponent )
73
124
targetCache . forEach ( cleanupTarget )
74
125
}
75
126
127
+ /**
128
+ * Call a function and wait for Svelte to flush pending changes.
129
+ *
130
+ * @param {() => unknown } [fn] - A function, which may be `async`, to call before flushing updates.
131
+ * @returns {Promise<void> }
132
+ */
76
133
const act = async ( fn ) => {
77
134
if ( fn ) {
78
135
await fn ( )
79
136
}
80
137
return tick ( )
81
138
}
82
139
140
+ /**
141
+ * @typedef {(...args: Parameters<import('@testing-library/dom').FireFunction>) => Promise<ReturnType<import('@testing-library/dom').FireFunction>> } FireFunction
142
+ */
143
+
144
+ /**
145
+ * @typedef {{
146
+ * [K in import('@testing -library/dom').EventType]: (...args: Parameters<import('@testing-library/dom').FireObject[K]>) => Promise<ReturnType<import('@testing-library/dom').FireObject[K]>>
147
+ * }} FireObject
148
+ */
149
+
150
+ /**
151
+ * Fire an event on an element.
152
+ *
153
+ * Consider using `@testing-library/user-event` instead, if possible.
154
+ * @see https://testing-library.com/docs/user-event/intro/
155
+ *
156
+ * @type {FireFunction & FireObject }
157
+ */
83
158
const fireEvent = async ( ...args ) => {
84
- const event = dtlFireEvent ( ...args )
159
+ const event = baseFireEvent ( ...args )
85
160
await tick ( )
86
161
return event
87
162
}
88
163
89
- Object . keys ( dtlFireEvent ) . forEach ( ( key ) => {
164
+ Object . keys ( baseFireEvent ) . forEach ( ( key ) => {
90
165
fireEvent [ key ] = async ( ...args ) => {
91
- const event = dtlFireEvent [ key ] ( ...args )
166
+ const event = baseFireEvent [ key ] ( ...args )
92
167
await tick ( )
93
168
return event
94
169
}
0 commit comments