AVA stores snapshots in a binary format (`.snap`), which produces no
meaningful diffs and bloats Git history. This replaces AVA with the
built-in `node:test` module, whose snapshot support generates
human-readable text files that are easy to diff and review in pull
requests.
The migration also replaces `@sinonjs/fake-timers` and `execa` with
Node.js built-ins (`node:test` mock timers and `node:child_process`),
removing three dev dependencies total.
- **`tests/index.js`**: Rewritten to use `node:test` with a custom
snapshot serializer that renders strings with actual newlines. Uses
subtests for labeled `stderr`/`stdout` snapshots, and only snapshots
non-empty output.
- **`tests/main-repo-skew.test.js`**: Replace `@sinonjs/fake-timers`
with `mock.timers.enable()` from `node:test`.
- **`tests/README.md`**: Updated documentation to reflect `node --test`
and the new snapshot file.
- **`package.json`**: Remove `ava`, `@sinonjs/fake-timers`, and `execa`
from devDependencies. Update test script to `c8 --100 node --test
tests/index.js`.
- **`tests/index.js.snapshot`**: New text-based snapshot file replacing
binary `tests/snapshots/index.js.snap`.
- **`tests/snapshots/`**: Deleted.
All 22 test scenarios (66 subtests) pass with 100% code coverage.
Closes #344
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit f863ba5554)
57 lines
1.7 KiB
JavaScript
57 lines
1.7 KiB
JavaScript
import { readdirSync } from "node:fs";
|
||
import { execFile } from "node:child_process";
|
||
import { promisify } from "node:util";
|
||
|
||
import { snapshot, test } from "node:test";
|
||
|
||
const execFileAsync = promisify(execFile);
|
||
|
||
// Serialize strings as-is so multiline output is human-readable in snapshots
|
||
snapshot.setDefaultSnapshotSerializers([
|
||
(value) => (typeof value === "string" ? value : undefined),
|
||
]);
|
||
|
||
// Get all files in tests directory
|
||
const files = readdirSync("tests");
|
||
|
||
// Files to ignore
|
||
const ignore = ["index.js", "index.js.snapshot", "main.js", "README.md"];
|
||
|
||
const testFiles = files.filter((file) => !ignore.includes(file)).sort();
|
||
|
||
// Throw an error if there is a file that does not end with test.js in the tests directory
|
||
for (const file of testFiles) {
|
||
if (!file.endsWith(".test.js")) {
|
||
throw new Error(`File ${file} does not end with .test.js`);
|
||
}
|
||
test(file, async (t) => {
|
||
// Override Actions environment variables that change `core`’s behavior
|
||
const {
|
||
GITHUB_OUTPUT,
|
||
GITHUB_STATE,
|
||
HTTP_PROXY,
|
||
HTTPS_PROXY,
|
||
http_proxy,
|
||
https_proxy,
|
||
NO_PROXY,
|
||
no_proxy,
|
||
NODE_OPTIONS,
|
||
NODE_USE_ENV_PROXY,
|
||
...env
|
||
} = process.env;
|
||
const { stderr, stdout } = await execFileAsync("node", [`tests/${file}`], {
|
||
env,
|
||
});
|
||
const trimmedStderr = stderr.replace(/\r?\n$/, "");
|
||
const trimmedStdout = stdout.replace(/\r?\n$/, "");
|
||
await t.test("stderr", (t) => {
|
||
if (trimmedStderr) t.assert.snapshot(trimmedStderr);
|
||
else t.assert.strictEqual(trimmedStderr, "");
|
||
});
|
||
await t.test("stdout", (t) => {
|
||
if (trimmedStdout) t.assert.snapshot(trimmedStdout);
|
||
else t.assert.strictEqual(trimmedStdout, "");
|
||
});
|
||
});
|
||
}
|