11import {
2- fireEvent as dtlFireEvent ,
2+ fireEvent as baseFireEvent ,
33 getQueriesForElement ,
44 prettyDOM ,
55} from '@testing-library/dom'
@@ -10,6 +10,52 @@ import { mount, unmount, updateProps, validateOptions } from './core/index.js'
1010const targetCache = new Set ( )
1111const componentCache = new Set ( )
1212
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+ */
1359const render = ( Component , options = { } , renderOptions = { } ) => {
1460 options = validateOptions ( options )
1561
@@ -33,7 +79,9 @@ const render = (Component, options = {}, renderOptions = {}) => {
3379 baseElement,
3480 component,
3581 container : target ,
36- debug : ( el = baseElement ) => console . log ( prettyDOM ( el ) ) ,
82+ debug : ( el = baseElement ) => {
83+ console . log ( prettyDOM ( el ) )
84+ } ,
3785 rerender : async ( props ) => {
3886 if ( props . props ) {
3987 console . warn (
@@ -52,6 +100,7 @@ const render = (Component, options = {}, renderOptions = {}) => {
52100 }
53101}
54102
103+ /** Remove a component from the component cache. */
55104const cleanupComponent = ( component ) => {
56105 const inCache = componentCache . delete ( component )
57106
@@ -60,6 +109,7 @@ const cleanupComponent = (component) => {
60109 }
61110}
62111
112+ /** Remove a target element from the target cache. */
63113const cleanupTarget = ( target ) => {
64114 const inCache = targetCache . delete ( target )
65115
@@ -68,27 +118,52 @@ const cleanupTarget = (target) => {
68118 }
69119}
70120
121+ /** Unmount all components and remove elements added to `<body>`. */
71122const cleanup = ( ) => {
72123 componentCache . forEach ( cleanupComponent )
73124 targetCache . forEach ( cleanupTarget )
74125}
75126
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+ */
76133const act = async ( fn ) => {
77134 if ( fn ) {
78135 await fn ( )
79136 }
80137 return tick ( )
81138}
82139
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+ */
83158const fireEvent = async ( ...args ) => {
84- const event = dtlFireEvent ( ...args )
159+ const event = baseFireEvent ( ...args )
85160 await tick ( )
86161 return event
87162}
88163
89- Object . keys ( dtlFireEvent ) . forEach ( ( key ) => {
164+ Object . keys ( baseFireEvent ) . forEach ( ( key ) => {
90165 fireEvent [ key ] = async ( ...args ) => {
91- const event = dtlFireEvent [ key ] ( ...args )
166+ const event = baseFireEvent [ key ] ( ...args )
92167 await tick ( )
93168 return event
94169 }
0 commit comments