Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tests/scripts/annotator_boundary.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import path from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = fileURLToPath(new URL("../../", import.meta.url));
const PACKAGE = fileURLToPath(new URL("../../frontend/annotator/", import.meta.url));
const TSC = path.join(PACKAGE, "node_modules", ".bin", "tsc");
Expand Down Expand Up @@ -192,9 +194,7 @@ test("the scan finds the line v1 shipped, and nothing that merely names the type
});

test("no module builds a synthetic DOM event to talk to another module", () => {
const listed = spawnSync("git", ["ls-files", "-z", "frontend"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout.split("\0").filter((name) => SOURCE.test(name));
const tracked = trackedFiles(["frontend"]).filter((name) => SOURCE.test(name));
assert.ok(tracked.length > 0, "the scan found no frontend sources, so it proves nothing");

const offenders = tracked.flatMap((file) =>
Expand Down
6 changes: 3 additions & 3 deletions tests/scripts/cdn_vendor_boundary.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
// to npm and must work against any self-hosted mirror. Mirrors ui_core_boundary.test.mjs's
// CDN_VENDOR_LITERALS rule, scoped to the two packages that rule does not cover.
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = fileURLToPath(new URL("../../", import.meta.url));

function shippedSourceUnder(dir) {
return execFileSync("git", ["ls-files", dir], { cwd: REPO, encoding: "utf8" })
.split("\n")
return trackedFiles([dir])
.filter((file) => /\.[cm]?[jt]sx?$/.test(file))
.filter((file) => !/\.test\.[jt]sx?$/.test(file))
.map((file) => ({ path: file, text: readFileSync(path.join(REPO, file), "utf8") }));
Expand Down
5 changes: 2 additions & 3 deletions tests/scripts/checks_wiring.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
// corpus, so this file demonstrates a violation without containing one. It reads
// `git ls-files` (the index) so a merely staged file is gated before any commit lands.
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import path from "node:path";
import { test } from "node:test";

import { operationCheckName, repoRoot, responsesOf } from "../../scripts/generate_client.mjs";
import { trackedFiles } from "./tracked.mjs";

/** The definition site: its prose quotes `unwrap(` verbatim, and it never calls it. */
const DEFINITION = "frontend/ui-core/src/data/errors.ts";
Expand Down Expand Up @@ -89,8 +89,7 @@ export function wrongChecks(files, expected) {
}

const corpus = () =>
execFileSync("git", ["ls-files", "frontend"], { cwd: repoRoot(), encoding: "utf8" })
.split("\n")
trackedFiles(["frontend"], repoRoot())
.filter((line) => /\.[jt]sx?$/.test(line))
.map((file) => ({ path: file, text: readFileSync(path.join(repoRoot(), file), "utf8") }));

Expand Down
7 changes: 3 additions & 4 deletions tests/scripts/cooldown.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import path from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const read = (rel) => readFileSync(path.join(root, rel), "utf8");

Expand Down Expand Up @@ -192,10 +194,7 @@ test("pnpm is the only Node package manager invoked anywhere", () => {
// file's `//` prose about `npx`. What survives is deliberately shape-based
// rather than word-based: a manager named as the first argument of a call, or
// opening a command string with arguments after it.
const listed = (...globs) =>
execFileSync("git", ["ls-files", ...globs], { cwd: root, encoding: "utf8" })
.split("\n")
.filter(Boolean);
const listed = (...globs) => trackedFiles(globs, root);

const offenders = [];
const flag = (file, i, line) => offenders.push(`${file}:${i + 1}: ${line.trim()}`);
Expand Down
7 changes: 3 additions & 4 deletions tests/scripts/design_system.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,20 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { competingStatusPaletteIn, statusPaletteIn } from "@robomous/ui-core/gates";

import { trackedFiles } from "./tracked.mjs";

const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
const SOURCE = /\.(?:ts|tsx|css)$/;
const GENERATED = /^frontend\/ui-core\/src\/generated\//;

/** Every tracked `frontend` source, minus the generated client. */
function frontendSources() {
const listed = spawnSync("git", ["ls-files", "-z", "frontend"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
return listed.stdout.split("\0").filter((name) => SOURCE.test(name) && !GENERATED.test(name));
return trackedFiles(["frontend"]).filter((name) => SOURCE.test(name) && !GENERATED.test(name));
}

const scan = (fn) =>
Expand Down
22 changes: 9 additions & 13 deletions tests/scripts/design_tokens.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ import { test } from "node:test";

import { brandUsagesIn, colouredClassesIn } from "@robomous/ui-core/gates";

import { trackedFiles } from "./tracked.mjs";

const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");

const SOURCE = /\.(?:ts|tsx|css)$/;
// The generated client is 6,000 machine-written lines and contains no class name.
const GENERATED = /^frontend\/ui-core\/src\/generated\//;

test("no frontend source puts a colour inside a class name", () => {
const listed = spawnSync("git", ["ls-files", "-z", "frontend"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout
.split("\0")
.filter((name) => SOURCE.test(name) && !GENERATED.test(name));
const tracked = trackedFiles(["frontend"]).filter(
(name) => SOURCE.test(name) && !GENERATED.test(name),
);
assert.ok(tracked.length > 0, "the scan found no frontend sources, so it proves nothing");

const offenders = tracked.flatMap((file) =>
Expand Down Expand Up @@ -63,11 +63,9 @@ const BRAND_SITES = [
];

test("the brand colour paints identity only — the wordmark and its styleguide swatch", () => {
const listed = spawnSync("git", ["ls-files", "-z", "frontend"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout
.split("\0")
.filter((name) => SOURCE.test(name) && !GENERATED.test(name));
const tracked = trackedFiles(["frontend"]).filter(
(name) => SOURCE.test(name) && !GENERATED.test(name),
);
assert.ok(tracked.length > 0, "the scan found no frontend sources, so it proves nothing");

const usages = tracked.flatMap((file) =>
Expand Down Expand Up @@ -106,9 +104,7 @@ test("the brand colour paints identity only — the wordmark and its styleguide
const RETIRED_ICON_PACKAGE = ["@tabler", "icons-react"].join("/");

test("no package declares a second icon set, and no source imports one", () => {
const listed = spawnSync("git", ["ls-files", "-z"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout.split("\0").filter(Boolean);
const tracked = trackedFiles();

const manifests = tracked.filter((name) => /(?:^|\/)package\.json$/.test(name));
assert.ok(manifests.length > 0, "no manifests were read, so this proves nothing");
Expand Down
13 changes: 4 additions & 9 deletions tests/scripts/docs_links.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@
import assert from "node:assert/strict";
import { existsSync, readFileSync, statSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");

/** The extensions this gate treats as Markdown. See the header for why `.mdx` is here. */
Expand All @@ -80,11 +81,7 @@ export const MARKDOWN = [".md", ".mdx"];
* the headings other documents point at.
*/
function markdownFiles() {
const listed = spawnSync("git", ["-C", REPO, "ls-files", ...MARKDOWN.map((e) => `*${e}`)], {
encoding: "utf8",
});
assert.equal(listed.status, 0, "git ls-files must succeed");
return listed.stdout.split("\n").filter(Boolean);
return trackedFiles(MARKDOWN.map((e) => `*${e}`), REPO);
}

/** Is this a document whose headings this gate can read? */
Expand Down Expand Up @@ -195,9 +192,7 @@ export function linksIn(source) {
}

test("every internal Markdown link resolves to a tracked file", () => {
const tracked = new Set(
spawnSync("git", ["-C", REPO, "ls-files"], { encoding: "utf8" }).stdout.split("\n"),
);
const tracked = new Set(trackedFiles([], REPO));
const broken = [];

for (const file of markdownFiles()) {
Expand Down
7 changes: 3 additions & 4 deletions tests/scripts/e2e_discipline.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
// Both browser-driven suites. `bench/` is under the rule rather than being
// exempted from it: a benchmark is the file most tempted to sleep — "give it a
Expand Down Expand Up @@ -83,9 +84,7 @@ test("the scan finds v1's sync points, and nothing that merely mentions them", (
test("no end-to-end scenario waits on a clock", () => {
const offenders = [];
for (const suite of SUITES) {
const listed = spawnSync("git", ["ls-files", "-z", suite], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout.split("\0").filter((name) => SOURCE.test(name));
const tracked = trackedFiles([suite]).filter((name) => SOURCE.test(name));
// Asserted per suite, not over the union: a renamed or emptied directory would
// otherwise be covered by its neighbour and the scan would quietly prove less
// than it says.
Expand Down
7 changes: 3 additions & 4 deletions tests/scripts/form_buttons.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");

const TSX = /\.tsx$/;
Expand Down Expand Up @@ -319,9 +320,7 @@ const RENDERED_INSIDE_FORMS = {

/** Every tracked `frontend/**\/*.tsx`, read from the index. */
function trackedTsx() {
const listed = spawnSync("git", ["ls-files", "-z", "frontend"], { cwd: REPO, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
const tracked = listed.stdout.split("\0").filter((name) => TSX.test(name));
const tracked = trackedFiles(["frontend"]).filter((name) => TSX.test(name));
assert.ok(tracked.length > 0, "the scan found no frontend components, so it proves nothing");
return tracked;
}
Expand Down
6 changes: 3 additions & 3 deletions tests/scripts/media_core_boundary.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
// the way `ui_core_boundary.test.mjs` backs ui-core. Type-level mentions of `Blob` and
// `File` (`BlobLike`, `FileLike`) are legitimate and pass: only value uses are caught.
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = fileURLToPath(new URL("../../", import.meta.url));

function coreSource() {
return execFileSync("git", ["ls-files", "frontend/media/src"], { cwd: REPO, encoding: "utf8" })
.split("\n")
return trackedFiles(["frontend/media/src"])
.filter((file) => /\.[cm]?[jt]sx?$/.test(file))
.filter((file) => !/\.test\.[jt]sx?$/.test(file))
.filter((file) => !file.startsWith("frontend/media/src/mediabunny/"))
Expand Down
17 changes: 17 additions & 0 deletions tests/scripts/tracked.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { existsSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const REPO = fileURLToPath(new URL("../../", import.meta.url));

export function trackedFiles(pathspecs = [], root = REPO) {
const listed = spawnSync("git", ["ls-files", "-z", "--", ...pathspecs], { cwd: root, encoding: "utf8" });
assert.equal(listed.status, 0, `git ls-files failed: ${listed.stderr}`);
return listed.stdout
.split("\0")
.filter(Boolean)
// The index can name a path that is not on disk, e.g. during an unstaged rename or delete.
.filter((name) => existsSync(path.join(root, name)));
}
45 changes: 45 additions & 0 deletions tests/scripts/tracked.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

function scratchRepo(files) {
const root = mkdtempSync(path.join(tmpdir(), "visionset-tracked-"));
const git = (...args) => execFileSync("git", args, { cwd: root, encoding: "utf8" });
git("init", "-q");
git("config", "user.name", "Scratch");
git("config", "user.email", "scratch@example.invalid");
git("config", "commit.gpgsign", "false");
for (const file of files) {
mkdirSync(path.dirname(path.join(root, file)), { recursive: true });
writeFileSync(path.join(root, file), `${file}\n`);
}
git("add", ".");
git("commit", "-q", "-m", "scratch");
return root;
}

test("a path the index names but the disk lacks is not listed", () => {
const root = scratchRepo(["a.txt", "b.txt"]);
try {
rmSync(path.join(root, "b.txt"));
assert.deepEqual(trackedFiles([], root), ["a.txt"]);
} finally {
rmSync(root, { recursive: true, force: true });
}
});

test("pathspecs narrow the listing and the missing-path filter still applies", () => {
const root = scratchRepo(["src/a.ts", "src/b.ts", "docs/c.md"]);
try {
rmSync(path.join(root, "src/b.ts"));
assert.deepEqual(trackedFiles(["src"], root), ["src/a.ts"]);
assert.deepEqual(trackedFiles(["*.md"], root), ["docs/c.md"]);
} finally {
rmSync(root, { recursive: true, force: true });
}
});
6 changes: 3 additions & 3 deletions tests/scripts/ui_core_boundary.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@
// proven only by its positive case has not been proven against the case it exists
// to distinguish from.
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "node:test";

import { trackedFiles } from "./tracked.mjs";

const REPO = fileURLToPath(new URL("../../", import.meta.url));

/** Shipped `ui-core` source: no tests, no harness. `.mts`/`.cts`/`.mjs`/`.cjs` count as
* source too — `tsc` compiles them, and a filter that only knew `.ts`/`.tsx`/`.js`/`.jsx`
* would silently stop covering a file the moment one appeared. */
function shippedSource() {
return execFileSync("git", ["ls-files", "frontend/ui-core/src"], { cwd: REPO, encoding: "utf8" })
.split("\n")
return trackedFiles(["frontend/ui-core/src"])
.filter((file) => /\.[cm]?[jt]sx?$/.test(file))
.filter((file) => !/\.test\.[jt]sx?$/.test(file))
.filter((file) => !file.startsWith("frontend/ui-core/src/testing/"))
Expand Down
Loading