@@ -12,7 +12,7 @@ import type {
1212 TokensResult ,
1313} from '../src/lib/types' ;
1414import type { ShikiTransformer } from 'shiki' ;
15- import { throttleHighlighting , useStableOptions } from '../src/lib/utils' ;
15+ import { useThrottledDebounce , useStableOptions } from '../src/lib/utils' ;
1616
1717interface TestComponentProps {
1818 code : string ;
@@ -565,57 +565,50 @@ describe('useShikiHighlighter Hook', () => {
565565 } ) ;
566566
567567 describe ( 'Throttling' , ( ) => {
568- beforeEach ( ( ) => {
569- vi . useFakeTimers ( ) ;
570- } ) ;
571-
572- afterEach ( ( ) => {
573- vi . useRealTimers ( ) ;
568+ test ( 'useThrottledDebounce returns initial value' , ( ) => {
569+ const { result } = renderHook ( ( ) =>
570+ useThrottledDebounce ( 'initial' , 500 )
571+ ) ;
572+ expect ( result . current ) . toBe ( 'initial' ) ;
574573 } ) ;
575574
576- test ( 'throttles highlighting function calls based on timing' , ( ) => {
577- // Mock date to have a consistent starting point
578- const originalDateNow = Date . now ;
579- const mockTime = 1000 ;
580- Date . now = vi . fn ( ( ) => mockTime ) ;
581-
582- // Mock the perform highlight function
583- const performHighlight = vi . fn ( ) . mockResolvedValue ( undefined ) ;
575+ test ( 'useThrottledDebounce with no throttle returns value immediately' , async ( ) => {
576+ const { result, rerender } = renderHook (
577+ ( { value } ) => useThrottledDebounce ( value , undefined ) ,
578+ { initialProps : { value : 'initial' } }
579+ ) ;
584580
585- // Setup timeout control like in the hook
586- const timeoutControl = {
587- current : {
588- timeoutId : undefined ,
589- nextAllowedTime : 0 ,
590- } ,
591- } ;
581+ expect ( result . current ) . toBe ( 'initial' ) ;
592582
593- // First call should schedule immediately since nextAllowedTime is in the past
594- throttleHighlighting ( performHighlight , timeoutControl , 500 ) ;
595- expect ( timeoutControl . current . timeoutId ) . toBeDefined ( ) ;
583+ rerender ( { value : 'updated' } ) ;
596584
597- // Run the timeout
598- vi . runAllTimers ( ) ;
599- expect ( performHighlight ) . toHaveBeenCalledTimes ( 1 ) ;
600- expect ( timeoutControl . current . nextAllowedTime ) . toBe ( 1500 ) ; // 1000 + 500
585+ await waitFor ( ( ) => {
586+ expect ( result . current ) . toBe ( 'updated' ) ;
587+ } ) ;
588+ } ) ;
601589
602- // Reset the mock
603- performHighlight . mockClear ( ) ;
590+ test ( 'delay option throttles code updates' , async ( ) => {
591+ const code1 = 'const a = 1;' ;
592+ const code2 = 'const b = 2;' ;
604593
605- // Call again - should be delayed by the throttle duration
606- throttleHighlighting ( performHighlight , timeoutControl , 500 ) ;
607- expect ( performHighlight ) . not . toHaveBeenCalled ( ) ; // Not called yet
594+ const { getByTestId , rerender } = render (
595+ < TestComponent code = { code1 } language = "javascript" theme = "github-dark" delay = { 100 } />
596+ ) ;
608597
609- // Advance halfway through the delay - should still not be called
610- vi . advanceTimersByTime ( 250 ) ;
611- expect ( performHighlight ) . not . toHaveBeenCalled ( ) ;
598+ // Wait for initial render
599+ await waitFor ( ( ) => {
600+ expect ( getByTestId ( 'highlighted' ) ) . toBeInTheDocument ( ) ;
601+ } ) ;
612602
613- // Advance the full delay
614- vi . advanceTimersByTime ( 250 ) ;
615- expect ( performHighlight ) . toHaveBeenCalledTimes ( 1 ) ;
603+ // Change code - should be throttled
604+ rerender (
605+ < TestComponent code = { code2 } language = "javascript" theme = "github-dark" delay = { 100 } />
606+ ) ;
616607
617- // Restore original Date.now
618- Date . now = originalDateNow ;
608+ // Eventually should show new code
609+ await waitFor ( ( ) => {
610+ expect ( getByTestId ( 'highlighted' ) . textContent ) . toContain ( 'b' ) ;
611+ } ) ;
619612 } ) ;
620613 } ) ;
621614
0 commit comments