import { debounce } from '@/utils/utils';

const sleep = (time) => new Promise(resolve => setTimeout(resolve, time));
const debounceTime = 10;
const sleepTime = 15;

describe('utils: debounce', () => {
  test('it calls a function only once in a given window', async () => {
    const fn = jest.fn();
    const debounced = debounce(fn, debounceTime);

    debounced();
    debounced();
    debounced();
    await sleep(sleepTime);

    expect(fn.mock.calls.length).toBe(1);
  });

  test('it allows multiple calls when outside the given window', async () => {
    const fn = jest.fn();
    const debounced = debounce(fn, debounceTime);

    debounced();
    await sleep(sleepTime);
    debounced();
    debounced();
    await sleep(sleepTime);

    expect(fn.mock.calls.length).toBe(2);
  });

  test('it passes arguments to the debounced function', async () => {
    const fn = jest.fn();
    const debounced = debounce(fn, debounceTime);

    debounced(1, 'two', { three: 4 });
    await sleep(sleepTime);

    expect(fn.mock.calls.length).toBe(1);

    expect(fn.mock.calls[0][0]).toBe(1);
    expect(fn.mock.calls[0][1]).toBe('two');
    expect(fn.mock.calls[0][2]).toEqual({ three: 4 });
  });

  test('it only executes the final call in the time window, even with different arguments', async () => {
    const fn = jest.fn();
    const debounced = debounce(fn, debounceTime);

    debounced('a');
    debounced('b');
    debounced('c');
    await sleep(sleepTime);

    expect(fn.mock.calls.length).toBe(1);
    expect(fn.mock.calls[0][0]).toBe('c');
  });

  test('it keeps the window open on subsequent calls, until it first expires', async () => {
    const fn = jest.fn();
    const debounced = debounce(fn, debounceTime);

    // Call the function multiple times, each a little bit before the previous window
    // would have expired. Even though this sequence will last 3.2 times the debounce
    // window length plus the full sleep time, we expect only the final call to be
    // actually executed.
    debounced(1);
    await sleep(debounceTime * 0.8);
    debounced(2);
    await sleep(debounceTime * 0.8);
    debounced(3);
    await sleep(debounceTime * 0.8);
    debounced(4);
    await sleep(debounceTime * 0.8);
    debounced(5);
    await sleep(sleepTime);

    expect(fn.mock.calls.length).toBe(1);
    expect(fn.mock.calls[0][0]).toBe(5);
  });
});

@@ -40,83 +40,46 @@
 ';%0A%0A
-const sleep = (time) =%3E new Promise(resolve =%3E setTimeout(resolve, time));%0A
+describe('utils: debounce', () =%3E %7B%0A  
 cons
@@ -97,18 +97,22 @@
 ime = 10
-;%0A
+00;%0A  
 const sl
@@ -127,46 +127,117 @@
 = 15
+00
 ;%0A%0A
-describe('utils: debounce', () =%3E %7B
+  beforeAll(() =%3E %7B%0A    jest.useFakeTimers();%0A  %7D);%0A%0A  afterAll(() =%3E %7B%0A    jest.useRealTimers();%0A  %7D);%0A
 %0A  t
@@ -282,38 +282,32 @@
 a given window',
- async
  () =%3E %7B%0A    con
@@ -427,35 +427,48 @@
 nced();%0A    
-await sleep
+jest.advanceTimersByTime
 (sleepTime);
@@ -582,22 +582,16 @@
 window',
- async
  () =%3E %7B
@@ -685,35 +685,48 @@
 nced();%0A    
-await sleep
+jest.advanceTimersByTime
 (sleepTime);
@@ -760,35 +760,48 @@
 nced();%0A    
-await sleep
+jest.advanceTimersByTime
 (sleepTime);
@@ -906,22 +906,16 @@
 nction',
- async
  () =%3E %7B
@@ -1031,35 +1031,48 @@
 : 4 %7D);%0A    
-await sleep
+jest.advanceTimersByTime
 (sleepTime);
@@ -1355,22 +1355,16 @@
 uments',
- async
  () =%3E %7B
@@ -1501,35 +1501,48 @@
 d('c');%0A    
-await sleep
+jest.advanceTimersByTime
 (sleepTime);
@@ -1717,14 +1717,8 @@
 es',
- async
  () 
@@ -2098,35 +2098,48 @@
 ced(1);%0A    
-await sleep
+jest.advanceTimersByTime
 (debounceTim
@@ -2166,35 +2166,48 @@
 ced(2);%0A    
-await sleep
+jest.advanceTimersByTime
 (debounceTim
@@ -2234,35 +2234,48 @@
 ced(3);%0A    
-await sleep
+jest.advanceTimersByTime
 (debounceTim
@@ -2306,27 +2306,40 @@
 4);%0A    
-await sleep
+jest.advanceTimersByTime
 (debounc
@@ -2378,19 +2378,32 @@
     
-await sleep
+jest.advanceTimersByTime
 (sle

Replace real-time sleep delays with mock waits