191 lines
6.3 KiB
TypeScript
191 lines
6.3 KiB
TypeScript
import { mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { describe, expect } from "vitest";
|
|
|
|
import {
|
|
createHistoricalSourceManifest,
|
|
parseHistoricalSourceGraph,
|
|
} from "../../../src/domain/referenceSourceGraph.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
describe.skipIf(process.platform === "win32")(
|
|
"compiled historical-source summaries",
|
|
() => {
|
|
cliTest(
|
|
"selects a committed summary without changing complete output",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory("rea-reference-summary-");
|
|
await mkdir(join(root, "src", "nested"), { recursive: true });
|
|
await Promise.all([
|
|
writeFile(join(root, "package.json"), '{"name":"fixture"}\n'),
|
|
writeFile(
|
|
join(root, "src", "main.js"),
|
|
'import "./nested/value.js";\n',
|
|
),
|
|
writeFile(
|
|
join(root, "src", "nested", "value.js"),
|
|
"export const value = 1;\n",
|
|
),
|
|
writeFile(join(root, "\uE000.js"), "export const first = 1;\n"),
|
|
writeFile(join(root, "\u{10000}.js"), "export const last = 2;\n"),
|
|
]);
|
|
const run = (...options: string[]) =>
|
|
cli.run({
|
|
arguments: ["import-reference-source", root, "--json", ...options],
|
|
cwd: root,
|
|
});
|
|
const complete = await run();
|
|
expect(complete.exitCode).toBe(0);
|
|
const graph = parseHistoricalSourceGraph(complete.json);
|
|
expect((await run("--detail", "full")).stdout).toBe(complete.stdout);
|
|
for (const depth of [undefined, 0, 1, 10]) {
|
|
const result = await run(
|
|
"--detail",
|
|
"summary",
|
|
...(depth === undefined ? [] : ["--outline-depth", String(depth)]),
|
|
);
|
|
expect(result.exitCode).toBe(0);
|
|
const selected = graph.entries.filter(
|
|
(entry) => entry.path.split("/").length <= (depth ?? 2),
|
|
);
|
|
expect(result.json).toMatchObject({
|
|
schema: "HistoricalSourceSummary",
|
|
authority: graph.authority,
|
|
root_alias: graph.root_alias,
|
|
manifest: createHistoricalSourceManifest(graph),
|
|
inventory_state: graph.inventory_state,
|
|
provenance: graph.provenance,
|
|
vcs: graph.vcs,
|
|
languages: graph.languages,
|
|
manifests: graph.manifests,
|
|
counts: {
|
|
entries: 7,
|
|
files: 5,
|
|
directories: 2,
|
|
symlinks: 0,
|
|
relationships: 1,
|
|
parse_failures: 0,
|
|
exclusions: 0,
|
|
},
|
|
outline: {
|
|
depth: depth ?? 2,
|
|
entries: selected.map(({ path, kind }) =>
|
|
expect.objectContaining({ path, kind }),
|
|
),
|
|
omitted_entry_count: graph.entries.length - selected.length,
|
|
},
|
|
});
|
|
expect(result.json).not.toHaveProperty("relationships");
|
|
}
|
|
},
|
|
);
|
|
|
|
cliTest(
|
|
"retains exclusions and parse coverage independently of a hidden outline",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory(
|
|
"rea-reference-partial-summary-",
|
|
);
|
|
await Promise.all([
|
|
writeFile(join(root, ".gitignore"), "ignored.txt\n"),
|
|
writeFile(join(root, "ignored.txt"), "ignored\n"),
|
|
writeFile(join(root, "broken.js"), "export const = ;\n"),
|
|
]);
|
|
const result = await cli.run({
|
|
arguments: [
|
|
"import-reference-source",
|
|
root,
|
|
"--detail",
|
|
"summary",
|
|
"--outline-depth",
|
|
"0",
|
|
"--json",
|
|
],
|
|
cwd: root,
|
|
});
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.json).toMatchObject({
|
|
inventory_state: "partial",
|
|
counts: { parse_failures: 1, exclusions: 1 },
|
|
exclusions: [
|
|
{
|
|
path: "ignored.txt",
|
|
reason: "project-ignored",
|
|
pattern: "ignored.txt",
|
|
},
|
|
],
|
|
outline: { depth: 0, entries: [], omitted_entry_count: 2 },
|
|
});
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
describe("compiled historical-source summary input boundaries", () => {
|
|
cliTest(
|
|
"documents detail and depth in public command help",
|
|
async ({ cli }) => {
|
|
const result = await cli.run({
|
|
arguments: ["import-reference-source", "--help"],
|
|
});
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stdout).toContain("--detail");
|
|
expect(result.stdout).toContain("--outline-depth");
|
|
expect(result.stdout).toContain("requires --detail summary");
|
|
},
|
|
);
|
|
|
|
for (const options of [
|
|
["--detail", "summry"],
|
|
["--detail", "summary", "--outline-depth", "-1"],
|
|
["--detail", "summary", "--outline-depth", "1.5"],
|
|
["--detail", "summary", "--outline-depth", "NaN"],
|
|
["--detail", "summary", "--outline-depth", "9007199254740992"],
|
|
["--outline-depth", "1"],
|
|
["--detail", "full", "--outline-depth", "1"],
|
|
]) {
|
|
cliTest(`rejects ${options.join(" ")}`, async ({ cli }) => {
|
|
const root = await createTestTempDirectory(
|
|
"rea-reference-summary-input-",
|
|
);
|
|
const result = await cli.run({
|
|
arguments: ["import-reference-source", root, ...options, "--json"],
|
|
cwd: root,
|
|
});
|
|
expect(result.exitCode).toBe(1);
|
|
expect(result.stdout).not.toContain("HistoricalSourceGraph");
|
|
expect(result.stdout).not.toContain("HistoricalSourceSummary");
|
|
expect(result.stdout).toMatch(/detail|outline/u);
|
|
});
|
|
}
|
|
|
|
cliTest(
|
|
"preserves the missing-root failure in summary mode",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory(
|
|
"rea-reference-summary-missing-",
|
|
);
|
|
const result = await cli.run({
|
|
arguments: [
|
|
"import-reference-source",
|
|
join(root, "missing"),
|
|
"--detail",
|
|
"summary",
|
|
"--json",
|
|
],
|
|
cwd: root,
|
|
});
|
|
expect(result.exitCode).toBe(1);
|
|
expect(result.json).toMatchObject({
|
|
error: "Import failed",
|
|
category: "invalid_input",
|
|
message: expect.stringContaining(
|
|
"Reference source root could not be resolved",
|
|
),
|
|
});
|
|
},
|
|
);
|
|
});
|