@@ -7,85 +7,61 @@ import { VERSION as SVELTE_VERSION } from 'svelte/compiler'
77import * as Svelte from 'svelte'
88
99const IS_SVELTE_5 = / ^ 5 \. / . test ( SVELTE_VERSION )
10- export const targetCache = new Set ( )
11- export const componentCache = new Set ( )
12-
13- const svelteComponentOptions = [
14- 'accessors' ,
15- 'anchor' ,
16- 'props' ,
17- 'hydrate' ,
18- 'intro' ,
19- 'context' ,
20- ]
21-
22- export const buildCheckProps = ( svelteComponentOptions ) => ( options ) => {
23- const isProps = ! Object . keys ( options ) . some ( ( option ) =>
24- svelteComponentOptions . includes ( option )
25- )
26-
27- // Check if any props and Svelte options were accidentally mixed.
28- if ( ! isProps ) {
29- const unrecognizedOptions = Object . keys ( options ) . filter (
30- ( option ) => ! svelteComponentOptions . includes ( option )
10+
11+ export class SvelteTestingLibrary {
12+ svelteComponentOptions = [
13+ 'accessors' ,
14+ 'anchor' ,
15+ 'props' ,
16+ 'hydrate' ,
17+ 'intro' ,
18+ 'context' ,
19+ ]
20+
21+ targetCache = new Set ( )
22+ componentCache = new Set ( )
23+
24+ checkProps ( options ) {
25+ const isProps = ! Object . keys ( options ) . some ( ( option ) =>
26+ this . svelteComponentOptions . includes ( option )
3127 )
3228
33- if ( unrecognizedOptions . length > 0 ) {
34- throw Error ( `
29+ // Check if any props and Svelte options were accidentally mixed.
30+ if ( ! isProps ) {
31+ const unrecognizedOptions = Object . keys ( options ) . filter (
32+ ( option ) => ! this . svelteComponentOptions . includes ( option )
33+ )
34+
35+ if ( unrecognizedOptions . length > 0 ) {
36+ throw Error ( `
3537 Unknown options were found [${ unrecognizedOptions } ]. This might happen if you've mixed
3638 passing in props with Svelte options into the render function. Valid Svelte options
37- are [${ svelteComponentOptions } ]. You can either change the prop names, or pass in your
39+ are [${ this . svelteComponentOptions } ]. You can either change the prop names, or pass in your
3840 props for that component via the \`props\` option.\n\n
3941 Eg: const { /** Results **/ } = render(MyComponent, { props: { /** props here **/ } })\n\n
4042 ` )
41- }
42-
43- return options
44- }
45-
46- return { props : options }
47- }
48-
49- const checkProps = buildCheckProps ( svelteComponentOptions )
50-
51- const buildRenderComponent =
52- ( { target, ComponentConstructor } ) =>
53- ( options ) => {
54- options = { target, ...checkProps ( options ) }
55-
56- if ( IS_SVELTE_5 )
57- throw new Error ( 'for Svelte 5, use `@testing-library/svelte/svelte5`' )
43+ }
5844
59- const component = new ComponentConstructor ( options )
60-
61- componentCache . add ( component )
62-
63- // TODO(mcous, 2024-02-11): remove this behavior in the next major version
64- // It is unnecessary has no path to implementation in Svelte v5
65- if ( ! IS_SVELTE_5 ) {
66- component . $$ . on_destroy . push ( ( ) => {
67- componentCache . delete ( component )
68- } )
45+ return options
6946 }
7047
71- return component
48+ return { props : options }
7249 }
7350
74- export const buildRender =
75- ( buildRenderComponent ) =>
76- ( Component , { target, ...options } = { } , { container, queries } = { } ) => {
51+ render ( Component , { target, ...options } = { } , { container, queries } = { } ) {
7752 container = container || document . body
7853 target = target || container . appendChild ( document . createElement ( 'div' ) )
79- targetCache . add ( target )
54+ this . targetCache . add ( target )
8055
8156 const ComponentConstructor = Component . default || Component
8257
83- const renderComponent = buildRenderComponent ( {
84- target,
85- ComponentConstructor,
86- } )
87-
88- let component = renderComponent ( options )
58+ const component = this . renderComponent (
59+ {
60+ target,
61+ ComponentConstructor,
62+ } ,
63+ options
64+ )
8965
9066 return {
9167 container,
@@ -102,35 +78,61 @@ export const buildRender =
10278 await Svelte . tick ( )
10379 } ,
10480 unmount : ( ) => {
105- cleanupComponent ( component )
81+ this . cleanupComponent ( component )
10682 } ,
10783 ...getQueriesForElement ( container , queries ) ,
10884 }
10985 }
11086
111- export const render = buildRender ( buildRenderComponent )
87+ renderComponent ( { target, ComponentConstructor } , options ) {
88+ options = { target, ...this . checkProps ( options ) }
11289
113- export const cleanupComponent = ( component ) => {
114- const inCache = componentCache . delete ( component )
90+ if ( IS_SVELTE_5 )
91+ throw new Error ( 'for Svelte 5, use `@testing-library/svelte/svelte5`' )
92+
93+ const component = new ComponentConstructor ( options )
94+
95+ this . componentCache . add ( component )
96+
97+ // TODO(mcous, 2024-02-11): remove this behavior in the next major version
98+ // It is unnecessary has no path to implementation in Svelte v5
99+ if ( ! IS_SVELTE_5 ) {
100+ component . $$ . on_destroy . push ( ( ) => {
101+ this . componentCache . delete ( component )
102+ } )
103+ }
115104
116- if ( inCache ) {
117- component . $destroy ( )
105+ return component
118106 }
119- }
120107
121- const cleanupTarget = ( target ) => {
122- const inCache = targetCache . delete ( target )
108+ cleanupComponent ( component ) {
109+ const inCache = this . componentCache . delete ( component )
123110
124- if ( inCache && target . parentNode === document . body ) {
125- document . body . removeChild ( target )
111+ if ( inCache ) {
112+ component . $destroy ( )
113+ }
114+ }
115+
116+ cleanupTarget ( target ) {
117+ const inCache = this . targetCache . delete ( target )
118+
119+ if ( inCache && target . parentNode === document . body ) {
120+ document . body . removeChild ( target )
121+ }
126122 }
127- }
128123
129- export const cleanup = ( ) => {
130- componentCache . forEach ( cleanupComponent )
131- targetCache . forEach ( cleanupTarget )
124+ cleanup ( ) {
125+ this . componentCache . forEach ( this . cleanupComponent . bind ( this ) )
126+ this . targetCache . forEach ( this . cleanupTarget . bind ( this ) )
127+ }
132128}
133129
130+ const instance = new SvelteTestingLibrary ( )
131+
132+ export const render = instance . render . bind ( instance )
133+
134+ export const cleanup = instance . cleanup . bind ( instance )
135+
134136export const act = async ( fn ) => {
135137 if ( fn ) {
136138 await fn ( )
0 commit comments