Files
gitea/web_src/js/utils/func.test.ts
silverwind 66794e0549 refactor: replace debounce/throttle deps with first-party code (#38610)
Adds `web_src/js/utils/func.ts` with `debounce` and `throttle`, dropping
`throttle-debounce` and `perfect-debounce` dependencies. Both were
needed before: the former has no promise-returning debounce, which
`TextExpander` requires, and the latter no `throttle`.

Signature follows lodash and es-toolkit: `(func, wait, {leading,
trailing})` plus `cancel`, so argument order flips at the migrated call
sites.
2026-07-24 16:39:15 +00:00

75 lines
1.9 KiB
TypeScript

import {debounce, throttle} from './func.ts';
test('debounce', {concurrent: false}, () => {
vi.useFakeTimers();
const spy = vi.fn();
const fn = debounce(spy, 10);
fn();
fn();
fn();
expect(spy).toHaveBeenCalledTimes(0);
vi.advanceTimersByTime(30);
expect(spy).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});
test('debounce leading', {concurrent: false}, () => {
vi.useFakeTimers();
const spy = vi.fn();
const fn = debounce(spy, 10, {leading: true, trailing: false});
fn();
expect(spy).toHaveBeenCalledTimes(1);
fn();
vi.advanceTimersByTime(30);
expect(spy).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});
test('debounce result', {concurrent: false}, async () => {
vi.useFakeTimers();
const fn = debounce((value: number) => value * 2, 10);
const first = fn(1);
const second = fn(2);
vi.advanceTimersByTime(10);
expect(await first).toEqual(4); // both calls collapse into the last one
expect(await second).toEqual(4);
vi.useRealTimers();
});
test('debounce cancel', {concurrent: false}, () => {
vi.useFakeTimers();
const spy = vi.fn();
const fn = debounce(spy, 10);
fn();
fn.cancel();
vi.advanceTimersByTime(30);
expect(spy).toHaveBeenCalledTimes(0);
vi.useRealTimers();
});
test('throttle', {concurrent: false}, () => {
vi.useFakeTimers();
const spy = vi.fn();
const fn = throttle(spy, 10);
fn();
fn();
fn();
expect(spy).toHaveBeenCalledTimes(1); // leading
vi.advanceTimersByTime(30);
expect(spy).toHaveBeenCalledTimes(2); // plus one trailing for the collapsed rest
vi.useRealTimers();
});
test('throttle trailing only', {concurrent: false}, () => {
vi.useFakeTimers();
const spy = vi.fn();
const fn = throttle(spy, 10, {leading: false});
fn();
fn();
fn();
expect(spy).toHaveBeenCalledTimes(0);
vi.advanceTimersByTime(30);
expect(spy).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});