Verified coding tasks
Tasks that prove their own tests
Each task is what a coding agent would receive: a problem statement and starting code, plus hidden tests and a reference solution. Our sandbox ran every one: the tests fail on the starting code, pass twice on the reference, and have no network access.
- 12 tasks
- Python 3.12, TypeScript, JavaScript
- 33 fail→pass tests
- Bug fixes, features, two security fixes
Add leading calls and cancel to debounce
code-08 · what the agent sees is the problem statement and the starting code
debounce.ts powers search-as-you-type. Product wants two changes, and neither works today: 1. With { leading: true } the first call in a burst runs immediately; later calls in the same burst still produce one trailing call with the latest arguments (unless { trailing: false }). 2. The returned function has cancel(), which drops any pending call. A burst ends when wait milliseconds pass without a call. Keep the default behavior: trailing only.
export function debounce<A extends unknown[]>(
fn: (...args: A) => void,
wait: number,
_options: { leading?: boolean; trailing?: boolean } = {},
) {
let timer: ReturnType<typeof setTimeout> | undefined;
return (...args: A) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), wait);
};
}export function debounce<A extends unknown[]>(
fn: (...args: A) => void,
wait: number,
{ leading = false, trailing = true }: { leading?: boolean; trailing?: boolean } = {},
) {
let timer: ReturnType<typeof setTimeout> | undefined;
let pending: A | undefined;
const debounced = (...args: A) => {
if (timer === undefined && leading) {
fn(...args);
pending = undefined;
} else {
pending = args;
}
clearTimeout(timer);
timer = setTimeout(() => {
timer = undefined;
if (trailing && pending) fn(...pending);
pending = undefined;
}, wait);
};
debounced.cancel = () => {
clearTimeout(timer);
timer = undefined;
pending = undefined;
};
return debounced;
}import assert from "node:assert/strict";
import { afterEach, beforeEach, mock, test } from "node:test";
import { debounce } from "./debounce.ts";
beforeEach(() => mock.timers.enable({ apis: ["setTimeout"] }));
afterEach(() => mock.timers.reset());
test("calls once with the latest arguments after the wait", () => {
const calls: number[] = [];
const d = debounce((n: number) => calls.push(n), 100);
d(1);
d(2);
d(3);
mock.timers.tick(99);
assert.deepEqual(calls, []);
mock.timers.tick(1);
assert.deepEqual(calls, [3]);
});
test("leading runs the first call now and the latest call at the end", () => {
const calls: number[] = [];
const d = debounce((n: number) => calls.push(n), 100, { leading: true });
d(1);
assert.deepEqual(calls, [1]);
d(2);
d(3);
mock.timers.tick(100);
assert.deepEqual(calls, [1, 3]);
});
test("leading without trailing runs once per burst", () => {
const calls: number[] = [];
const d = debounce((n: number) => calls.push(n), 100, { leading: true, trailing: false });
d(1);
d(2);
mock.timers.tick(100);
d(3);
assert.deepEqual(calls, [1, 3]);
});
test("cancel drops the pending call", () => {
const calls: number[] = [];
const d = debounce((n: number) => calls.push(n), 100);
d(1);
d.cancel();
mock.timers.tick(200);
assert.deepEqual(calls, []);
});node:test mock timers make the tests instant and deterministic.
Sandbox run
Recorded by pnpm samples:verify. Our tests fail the build if this stops matching the task.
| Test | Starting code | Reference | Second run | |
|---|---|---|---|---|
debounce.test.ts::calls once with the latest arguments after the wait | pass | pass | pass | pass → pass |
debounce.test.ts::leading runs the first call now and the latest call at the end Expected values to be strictly deep-equal:
+ actual - expected
+ []
- [
- 1
- ]
| fail | pass | pass | fail → pass |
debounce.test.ts::leading without trailing runs once per burst Expected values to be strictly deep-equal:
+ actual - expected
[
+ 2
- 1,
- 3
]
| fail | pass | pass | fail → pass |
debounce.test.ts::cancel drops the pending call d.cancel is not a function | fail | pass | pass | fail → pass |
TypeScript · Node.js 24 · node:test · canonset-sandbox-node:1 · 0.9 s · checked 2026-09-29 23:30 UTC
Output: Starting code (exit 1, 0.2 s)
✔ calls once with the latest arguments after the wait (2.345199ms)
✖ leading runs the first call now and the latest call at the end (1.516396ms)
✖ leading without trailing runs once per burst (0.623787ms)
✖ cancel drops the pending call (0.543414ms)
ℹ tests 4
ℹ suites 0
ℹ pass 1
ℹ fail 3
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 125.533351
✖ failing tests:
test at debounce.test.ts:20:1
✖ leading runs the first call now and the latest call at the end (1.516396ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ []
- [
- 1
- ]
at TestContext.<anonymous> (file:///work/0-starter/debounce.test.ts:24:10)
at Test.runInAsyncScope (node:async_hooks:227:14)
at Test.run (node:internal/test_runner/test:1402:25)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [],
expected: [ 1 ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at debounce.test.ts:31:1
✖ leading without trailing runs once per burst (0.623787ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
[
+ 2
- 1,
- 3
]
at TestContext.<anonymous> (file:///work/0-starter/debounce.test.ts:38:10)
at Test.runInAsyncScope (node:async_hooks:227:14)
at Test.run (node:internal/test_runner/test:1402:25)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: [ 2 ],
expected: [ 1, 3 ],
operator: 'deepStrictEqual',
diff: 'simple'
}
test at debounce.test.ts:41:1
✖ cancel drops the pending call (0.543414ms)
TypeError: d.cancel is not a function
at TestContext.<anonymous> (file:///work/0-starter/debounce.test.ts:45:5)
at Test.runInAsyncScope (node:async_hooks:227:14)
at Test.run (node:internal/test_runner/test:1402:25)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
Output: Reference solution (exit 0, 0.2 s)
✔ calls once with the latest arguments after the wait (2.401213ms) ✔ leading runs the first call now and the latest call at the end (0.505366ms) ✔ leading without trailing runs once per burst (0.55992ms) ✔ cancel drops the pending call (0.662648ms) ℹ tests 4 ℹ suites 0 ℹ pass 4 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 162.379412
Output: Reference, second run (exit 0, 0.2 s)
✔ calls once with the latest arguments after the wait (2.36765ms) ✔ leading runs the first call now and the latest call at the end (0.569899ms) ✔ leading without trailing runs once per burst (0.660209ms) ✔ cancel drops the pending call (1.746941ms) ℹ tests 4 ℹ suites 0 ℹ pass 4 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 159.101999