@@ -12,16 +12,36 @@ import { page } from 'vitest/browser';
1212import GeneralObserver from './general-observer.svelte' ;
1313
1414// Mock IntersectionObserver
15- const mockIntersectionObserver = vi . fn ( ) ;
1615const mockObserve = vi . fn ( ) ;
1716const mockDisconnect = vi . fn ( ) ;
17+ let lastObserverInstance : MockIntersectionObserver | null = null ;
18+ let lastObserverCallback : IntersectionObserverCallback | null = null ;
19+ let lastObserverOptions : IntersectionObserverInit | undefined =
20+ undefined ;
21+
22+ class MockIntersectionObserver {
23+ constructor (
24+ public callback : IntersectionObserverCallback ,
25+ public options ?: IntersectionObserverInit ,
26+ ) {
27+ lastObserverInstance = this ;
28+ lastObserverCallback = callback ;
29+ lastObserverOptions = options ;
30+ }
31+ observe = mockObserve ;
32+ disconnect = mockDisconnect ;
33+ unobserve = vi . fn ( ) ;
34+ takeRecords = vi . fn ( ( ) => [ ] ) ;
35+ root = null ;
36+ rootMargin = '0px' ;
37+ thresholds = [ 0 ] ;
38+ }
1839
1940beforeEach ( ( ) => {
20- mockIntersectionObserver . mockReturnValue ( {
21- observe : mockObserve ,
22- disconnect : mockDisconnect ,
23- } ) ;
24- vi . stubGlobal ( 'IntersectionObserver' , mockIntersectionObserver ) ;
41+ lastObserverInstance = null ;
42+ lastObserverCallback = null ;
43+ lastObserverOptions = undefined ;
44+ vi . stubGlobal ( 'IntersectionObserver' , MockIntersectionObserver ) ;
2545} ) ;
2646
2747afterEach ( ( ) => {
@@ -69,13 +89,11 @@ describe('General Observer', () => {
6989 children : ( ( ) => 'Test content' ) as any ,
7090 } ) ;
7191
72- expect ( mockIntersectionObserver ) . toHaveBeenCalledWith (
73- expect . any ( Function ) ,
74- {
75- rootMargin : '0px' ,
76- threshold : 0.5 ,
77- } ,
78- ) ;
92+ expect ( lastObserverCallback ) . toBeTypeOf ( 'function' ) ;
93+ expect ( lastObserverOptions ) . toEqual ( {
94+ rootMargin : '0px' ,
95+ threshold : 0.5 ,
96+ } ) ;
7997 } ) ;
8098
8199 it ( 'should observe root element when observer is created' , async ( ) => {
@@ -97,13 +115,10 @@ describe('General Observer', () => {
97115 children : ( ( ) => 'Test content' ) as any ,
98116 } ) ;
99117
100- expect ( mockIntersectionObserver ) . toHaveBeenCalledWith (
101- expect . any ( Function ) ,
102- {
103- rootMargin : '0px' ,
104- threshold : customThreshold ,
105- } ,
106- ) ;
118+ expect ( lastObserverOptions ) . toEqual ( {
119+ rootMargin : '0px' ,
120+ threshold : customThreshold ,
121+ } ) ;
107122 } ) ;
108123
109124 it ( 'should handle threshold edge cases (0, 1)' , async ( ) => {
@@ -116,33 +131,16 @@ describe('General Observer', () => {
116131 children : ( ( ) => 'Test content' ) as any ,
117132 } ) ;
118133
119- expect ( mockIntersectionObserver ) . toHaveBeenCalledWith (
120- expect . any ( Function ) ,
121- {
122- rootMargin : '0px' ,
123- threshold,
124- } ,
125- ) ;
134+ expect ( lastObserverOptions ) . toEqual ( {
135+ rootMargin : '0px' ,
136+ threshold,
137+ } ) ;
126138 }
127139 } ) ;
128140 } ) ;
129141
130142 describe ( 'IntersectionObserver Behavior' , ( ) => {
131143 it . skip ( 'should render children when intersection threshold is met' , async ( ) => {
132- let intersectionCallback :
133- | ( ( entries : any [ ] ) => void )
134- | undefined ;
135-
136- mockIntersectionObserver . mockImplementation (
137- ( callback , options ) => {
138- intersectionCallback = callback ;
139- return {
140- observe : mockObserve ,
141- disconnect : mockDisconnect ,
142- } ;
143- } ,
144- ) ;
145-
146144 const testContent = 'Content to show after intersection' ;
147145 const { container } = render ( GeneralObserver , {
148146 disable_observer : false ,
@@ -153,12 +151,11 @@ describe('General Observer', () => {
153151 // Initially, content should not be visible
154152 expect ( container . textContent ) . not . toContain ( testContent ) ;
155153
156- // Simulate intersection
157- intersectionCallback ?.( [
158- {
159- intersectionRatio : 0.6 , // Above threshold
160- } ,
161- ] ) ;
154+ // Simulate intersection using captured callback
155+ lastObserverCallback ?.(
156+ [ { intersectionRatio : 0.6 } ] as IntersectionObserverEntry [ ] ,
157+ lastObserverInstance as unknown as IntersectionObserver ,
158+ ) ;
162159
163160 // Wait for reactivity
164161 await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
@@ -168,31 +165,16 @@ describe('General Observer', () => {
168165 } ) ;
169166
170167 it ( 'should disconnect observer after successful intersection' , async ( ) => {
171- let intersectionCallback :
172- | ( ( entries : any [ ] ) => void )
173- | undefined ;
174-
175- mockIntersectionObserver . mockImplementation (
176- ( callback , options ) => {
177- intersectionCallback = callback ;
178- return {
179- observe : mockObserve ,
180- disconnect : mockDisconnect ,
181- } ;
182- } ,
183- ) ;
184-
185168 render ( GeneralObserver , {
186169 disable_observer : false ,
187170 children : ( ( ) => 'Test content' ) as any ,
188171 } ) ;
189172
190- // Simulate intersection
191- intersectionCallback ?.( [
192- {
193- intersectionRatio : 0.6 ,
194- } ,
195- ] ) ;
173+ // Simulate intersection using the captured callback
174+ lastObserverCallback ?.(
175+ [ { intersectionRatio : 0.6 } ] as IntersectionObserverEntry [ ] ,
176+ lastObserverInstance as unknown as IntersectionObserver ,
177+ ) ;
196178
197179 expect ( mockDisconnect ) . toHaveBeenCalled ( ) ;
198180 } ) ;
@@ -289,13 +271,10 @@ describe('General Observer', () => {
289271 children : ( ( ) => 'Test content' ) as any ,
290272 } ) ;
291273
292- expect ( mockIntersectionObserver ) . toHaveBeenCalledWith (
293- expect . any ( Function ) ,
294- {
295- rootMargin : '0px' ,
296- threshold : 0.5 ,
297- } ,
298- ) ;
274+ expect ( lastObserverOptions ) . toEqual ( {
275+ rootMargin : '0px' ,
276+ threshold : 0.5 ,
277+ } ) ;
299278 } ) ;
300279 } ) ;
301280} ) ;
0 commit comments