-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support default test timeout in bunfig.toml
- Loading branch information
1 parent
3d68a94
commit c4148ff
Showing
3 changed files
with
131 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { spawnSync } from "bun"; | ||
import { afterEach, describe, expect, test } from "bun:test"; | ||
import { bunEnv, bunExe, tempDirWithFiles } from "harness"; | ||
import { rmSync } from "node:fs"; | ||
|
||
describe("bunfig test options", () => { | ||
describe("timeout", () => { | ||
let cwd: string; | ||
|
||
const getBunfigWithTimeout = (ms: number) => `[test]\ntimeout = ${ms}\n`; | ||
|
||
const getTestWithDuration = (ms: number) => { | ||
return ` | ||
import { test, expect } from "bun:test"; | ||
test("takes ${ms} milliseconds", async () => { | ||
const p = new Promise(r => setTimeout(r, ${ms}, true)); | ||
expect(await p).toBeTrue(); | ||
}); | ||
`; | ||
}; | ||
|
||
const errorPtn = /timed out after (\d+)ms/; | ||
const durationPtn = /\(fail\) .* \[(\d+)(?:\.\d+)?ms\]/; | ||
|
||
afterEach(() => { | ||
if (cwd) rmSync(cwd, { recursive: true }); | ||
}); | ||
|
||
test("bunfig timeout overrides default", async () => { | ||
const bunfigTimeout = 500; | ||
cwd = tempDirWithFiles("test.bunfig.timeout", { | ||
"bunfig.toml": getBunfigWithTimeout(bunfigTimeout), | ||
"bun-test-bunfig-timeout.test.ts": getTestWithDuration(2000), | ||
}); | ||
|
||
const result = spawnSync({ | ||
cmd: [bunExe(), "-c=bunfig.toml", "test"], | ||
env: bunEnv, | ||
stderr: "pipe", | ||
cwd, | ||
}); | ||
const stderr = result.stderr.toString().trim(); | ||
|
||
const errorMatch = stderr.match(errorPtn); | ||
expect(errorMatch, "test didn't report timeout error to stderr").not.toBeNull(); | ||
const errorTimeout = parseInt(errorMatch!.at(1)!); | ||
expect(errorTimeout, "test timeout error doesn't reflect bunfig value").toEqual(bunfigTimeout); | ||
|
||
const durationMatch = stderr.match(durationPtn); | ||
expect(durationMatch, "test didn't output failing result with actual duration to stderr").not.toBeNull(); | ||
const duration = parseInt(durationMatch!.at(1)!); | ||
expect(duration, "test timed out before bunfig timeout value").toBeGreaterThanOrEqual(bunfigTimeout); | ||
expect(duration, "test didn't honor bunfig timeout value").toBeLessThanOrEqual(5000); | ||
}); | ||
|
||
test("cli timeout overrides bunfig", async () => { | ||
const cliTimeout = 500; | ||
const bunfigTimeout = 1000; | ||
cwd = tempDirWithFiles("test.cli.timeout.wins", { | ||
"bunfig.toml": getBunfigWithTimeout(bunfigTimeout), | ||
"bun-test-cli-timeout-wins.test.ts": getTestWithDuration(2000), | ||
}); | ||
|
||
const result = spawnSync({ | ||
cmd: [bunExe(), "-c=bunfig.toml", "test", "--timeout", `${cliTimeout}`], | ||
env: bunEnv, | ||
stderr: "pipe", | ||
cwd, | ||
}); | ||
const stderr = result.stderr.toString().trim(); | ||
|
||
const errorMatch = stderr.match(errorPtn); | ||
expect(errorMatch, "test didn't report timeout error to stderr").not.toBeNull(); | ||
const errorTimeout = parseInt(errorMatch!.at(1)!); | ||
expect(errorTimeout, "test timeout error doesn't reflect cli value").toEqual(cliTimeout); | ||
|
||
const durationMatch = stderr.match(durationPtn); | ||
expect(durationMatch, "test didn't output failing result with actual duration to stderr").not.toBeNull(); | ||
const duration = parseInt(durationMatch!.at(1)!); | ||
expect(duration, "test timed out before cli value").toBeGreaterThanOrEqual(cliTimeout); | ||
expect(duration, "test honored bunfig timeout instead of cli").toBeLessThan(bunfigTimeout); | ||
}); | ||
|
||
test("default timeout specified via cli overrides bunfig", async () => { | ||
// This addresses a corner case identified by a weak initial implementation. | ||
// By necessity it requires the default test timeout to prove (5s) so it should | ||
// be removed after passing in the PR. | ||
const cliTimeout = 5000; | ||
const bunfigTimeout = 500; | ||
cwd = tempDirWithFiles("test.cli.timeout.wins.default", { | ||
"bunfig.toml": getBunfigWithTimeout(bunfigTimeout), | ||
"bun-test-cli-timeout-wins-default.test.ts": getTestWithDuration(7000), | ||
}); | ||
|
||
const result = spawnSync({ | ||
cmd: [bunExe(), "-c=bunfig.toml", "test", "--timeout", `${cliTimeout}`], | ||
env: bunEnv, | ||
stderr: "pipe", | ||
cwd, | ||
}); | ||
const stderr = result.stderr.toString().trim(); | ||
|
||
const errorMatch = stderr.match(errorPtn); | ||
expect(errorMatch, "test didn't report timeout error to stderr").not.toBeNull(); | ||
const errorTimeout = parseInt(errorMatch!.at(1)!); | ||
expect(errorTimeout, "test timeout error doesn't reflect cli value").toEqual(cliTimeout); | ||
|
||
const durationMatch = stderr.match(durationPtn); | ||
expect(durationMatch, "test didn't output failing result with actual duration to stderr").not.toBeNull(); | ||
const duration = parseInt(durationMatch!.at(1)!); | ||
expect(duration, "test timed out before cli value").toBeGreaterThanOrEqual(cliTimeout); | ||
}); | ||
}); | ||
}); |