test: give oversized registration groups semantic owners

This commit is contained in:
morluto committed 2026-10-24 04:23:56 +08:00
1 parent a03096cb85
commit a3eae6e236
8 files changed
+345 -311

No files matched your search

@@ -18,7 +18,7 @@ import { err, ok } from "../domain/result.js";
const provider = { id: "fixture", name: "Fixture", version: "1" };
describe("analysis context queries: navigation", () => {
const registerNavigationSelectionValidationTests = (): void => {
it.each([
[null, "0x401000", "current_document"],
["fixture", null, "current_address"],
@@ -47,6 +47,10 @@ describe("analysis context queries: navigation", () => {
);
},
);
};
describe("analysis context queries: navigation", () => {
registerNavigationSelectionValidationTests();
it("aggregates volatile navigation and treats a missing procedure as null", async () => {
const calls: {
+71 -67
View File
@@ -419,6 +419,76 @@ describe("root input presentation", () => {
});
});
const registerBooleanLiteralCompatibilityTests = (): void => {
it("keeps canonical boolean-literal inputs accepted after advertisement", () => {
const canonical = {
type: "object",
properties: {
enabled: { type: "boolean", const: false },
},
required: ["enabled"],
additionalProperties: false,
};
const advertised = presentInputJsonSchema(canonical, () => undefined);
const canonicalValidate = new Ajv2020({ strict: false }).compile(canonical);
const advertisedValidate = new Ajv2020({ strict: false }).compile(
advertised,
);
expect(canonicalValidate({ enabled: false })).toBe(true);
expect(canonicalValidate({ enabled: true })).toBe(false);
expect(advertisedValidate({ enabled: false })).toBe(true);
expect(advertisedValidate({ enabled: true })).toBe(true);
expect(advertised.properties).toEqual({ enabled: { type: "boolean" } });
});
it("drops affected negation and conditional groups without rejecting canonical inputs", () => {
const negated = {
type: "object",
properties: {
flag: { type: "boolean", not: { const: false } },
},
};
const negatedAdvertisement = presentInputJsonSchema(
negated,
() => undefined,
);
const canonicalNegated = new Ajv2020({ strict: false }).compile(negated);
const advertisedNegated = new Ajv2020({ strict: false }).compile(
negatedAdvertisement,
);
expect(canonicalNegated({ flag: true })).toBe(true);
expect(canonicalNegated({ flag: false })).toBe(false);
expect(advertisedNegated({ flag: true })).toBe(true);
const conditional = {
type: "object",
properties: {
choice: {
if: { const: false },
then: { type: "string" },
else: { type: "boolean" },
},
},
};
const conditionalAdvertisement = presentInputJsonSchema(
conditional,
() => undefined,
);
const canonicalConditional = new Ajv2020({ strict: false }).compile(
conditional,
);
const advertisedConditional = new Ajv2020({ strict: false }).compile(
conditionalAdvertisement,
);
expect(canonicalConditional({ choice: true })).toBe(true);
expect(advertisedConditional({ choice: true })).toBe(true);
expect(conditionalAdvertisement.properties).toEqual({
choice: {},
});
});
};
describe("advertised client-compatible literals", () => {
it.each([{ const: "" }, { enum: ["", "named"] }])(
"widens unsupported empty-string literals without changing canonical validation: %j",
@@ -510,73 +580,7 @@ describe("advertised client-compatible literals", () => {
expect(schema.safeParse(input).success).toBe(true);
expect(input).not.toHaveProperty("only_left");
});
it("keeps canonical boolean-literal inputs accepted after advertisement", () => {
const canonical = {
type: "object",
properties: {
enabled: { type: "boolean", const: false },
},
required: ["enabled"],
additionalProperties: false,
};
const advertised = presentInputJsonSchema(canonical, () => undefined);
const canonicalValidate = new Ajv2020({ strict: false }).compile(canonical);
const advertisedValidate = new Ajv2020({ strict: false }).compile(
advertised,
);
expect(canonicalValidate({ enabled: false })).toBe(true);
expect(canonicalValidate({ enabled: true })).toBe(false);
expect(advertisedValidate({ enabled: false })).toBe(true);
expect(advertisedValidate({ enabled: true })).toBe(true);
expect(advertised.properties).toEqual({ enabled: { type: "boolean" } });
});
it("drops affected negation and conditional groups without rejecting canonical inputs", () => {
const negated = {
type: "object",
properties: {
flag: { type: "boolean", not: { const: false } },
},
};
const negatedAdvertisement = presentInputJsonSchema(
negated,
() => undefined,
);
const canonicalNegated = new Ajv2020({ strict: false }).compile(negated);
const advertisedNegated = new Ajv2020({ strict: false }).compile(
negatedAdvertisement,
);
expect(canonicalNegated({ flag: true })).toBe(true);
expect(canonicalNegated({ flag: false })).toBe(false);
expect(advertisedNegated({ flag: true })).toBe(true);
const conditional = {
type: "object",
properties: {
choice: {
if: { const: false },
then: { type: "string" },
else: { type: "boolean" },
},
},
};
const conditionalAdvertisement = presentInputJsonSchema(
conditional,
() => undefined,
);
const canonicalConditional = new Ajv2020({ strict: false }).compile(
conditional,
);
const advertisedConditional = new Ajv2020({ strict: false }).compile(
conditionalAdvertisement,
);
expect(canonicalConditional({ choice: true })).toBe(true);
expect(advertisedConditional({ choice: true })).toBe(true);
expect(conditionalAdvertisement.properties).toEqual({
choice: {},
});
});
registerBooleanLiteralCompatibilityTests();
});
describe("advertised Boolean schema composition", () => {
+56 -48
View File
@@ -103,53 +103,7 @@ const graphInput = (): HistoricalSourceGraphInput => ({
limitations: [],
});
describe("historical source graph", () => {
it("validates supplementary paths and derived indexes by code point", () => {
const paths = ["a", "aa", "\uE000", "\u{10000}"];
const input: HistoricalSourceGraphInput = {
...graphInput(),
entries: paths.map((path) =>
fileEntry({
path,
language: path,
classifications: ["manifest"],
}),
),
relationships: [],
languages: paths,
manifests: paths,
};
const graph = createHistoricalSourceGraph(input);
expect(parseHistoricalSourceGraph(graph)).toEqual(graph);
expect(() =>
createHistoricalSourceGraph({
...input,
entries: [...input.entries].sort((left, right) =>
left.path < right.path ? -1 : left.path > right.path ? 1 : 0,
),
}),
).toThrow(/Unicode code point/u);
});
it("omits absent local diagnostics and rejects explicitly undefined non-JSON metadata", () => {
const input = graphInput();
const graph = createHistoricalSourceGraph(input);
expect(
graph.entries.every(
(entry) => !Object.hasOwn(entry, "local_diagnostics"),
),
).toBe(true);
expect(() =>
createHistoricalSourceGraph({
...input,
entries: input.entries.map((entry) => ({
...entry,
local_diagnostics: undefined,
})),
}),
).toThrow();
});
const registerSourceCommitmentTests = (): void => {
it("builds and verifies internal root and manifest commitments", () => {
const graph = createHistoricalSourceGraph(graphInput());
const first = createHistoricalSourceManifest(graph);
@@ -224,6 +178,56 @@ describe("historical source graph", () => {
graphWith("*.env").root_sha256,
);
});
};
describe("historical source graph", () => {
it("validates supplementary paths and derived indexes by code point", () => {
const paths = ["a", "aa", "\uE000", "\u{10000}"];
const input: HistoricalSourceGraphInput = {
...graphInput(),
entries: paths.map((path) =>
fileEntry({
path,
language: path,
classifications: ["manifest"],
}),
),
relationships: [],
languages: paths,
manifests: paths,
};
const graph = createHistoricalSourceGraph(input);
expect(parseHistoricalSourceGraph(graph)).toEqual(graph);
expect(() =>
createHistoricalSourceGraph({
...input,
entries: [...input.entries].sort((left, right) =>
left.path < right.path ? -1 : left.path > right.path ? 1 : 0,
),
}),
).toThrow(/Unicode code point/u);
});
it("omits absent local diagnostics and rejects explicitly undefined non-JSON metadata", () => {
const input = graphInput();
const graph = createHistoricalSourceGraph(input);
expect(
graph.entries.every(
(entry) => !Object.hasOwn(entry, "local_diagnostics"),
),
).toBe(true);
expect(() =>
createHistoricalSourceGraph({
...input,
entries: input.entries.map((entry) => ({
...entry,
local_diagnostics: undefined,
})),
}),
).toThrow();
});
registerSourceCommitmentTests();
it("retains actual external targets and rejects placeholder targets", () => {
const input = { ...graphInput(), inventory_state: "partial" as const };
@@ -277,7 +281,7 @@ describe("historical source graph", () => {
});
});
describe("partial historical source graphs", () => {
const registerLocalDiagnosticCommitmentTests = (): void => {
it("keeps unknown-entry diagnostics outside the root commitment", () => {
const base = graphInput();
base.inventory_state = "partial";
@@ -332,6 +336,10 @@ describe("partial historical source graphs", () => {
computeHistoricalSourceGraphSha256(createHistoricalSourceGraph(moved)),
).not.toBe(computeHistoricalSourceGraphSha256(graph));
});
};
describe("partial historical source graphs", () => {
registerLocalDiagnosticCommitmentTests();
it("keeps an unreadable symlink target unknown and out of root identity", () => {
const base = graphInput();
@@ -75,7 +75,7 @@ const omissionRejected = (schema: z.ZodObject | undefined): string[] =>
const acceptsOmittedKey = (key: string, field: z.ZodType): boolean =>
z.object({ [key]: field }).safeParse({}).success;
describe("CLI advertised input schemas", () => {
const registerParserAdvertisementInventoryTests = (): void => {
it("require exactly the inputs whose omission the parser rejects", async () => {
const cli = createCli({});
const mismatches: string[] = [];
@@ -111,6 +111,10 @@ describe("CLI advertised input schemas", () => {
}
expect(mismatches).toEqual([]);
});
};
describe("CLI advertised input schemas", () => {
registerParserAdvertisementInventoryTests();
it("preserves client choices, selected path bounds and required decoded steps", async () => {
const cli = createCli({});
@@ -10,50 +10,52 @@ import { historicalSourceGraphSchema } from "../../../src/domain/referenceSource
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const historicalModuleFixture = async () => {
const root = await createTestTempDirectory("rea-reference-module-semantics-");
const files: Record<string, string> = {
"package.json": '{"type":"module"}\n',
"main.js": 'require("./dep.cjs"); export {};\n',
"dep.cjs": 'throw new Error("must never load");\n',
"directory.cjs": 'require("./nested/");\n',
"nested/index.js": 'module.exports = "fallback";\n',
"optional.cjs":
'require.resolve?.("./dep.cjs"); require?.resolve("./dep.cjs");\n',
"overwritten.cjs":
'require.resolve = other; require.resolve?.("./dep.cjs");\n',
"shadowed.cjs": 'function f(require) { require?.resolve("./dep.cjs"); }\n',
"types.d.ts":
'declare module "consumer" { import type { Marker } from "dependency"; export type A = import("./dep").Marker; export type B = typeof import("./dep"); }\n',
"dep.ts": "export interface Marker { id: string }\n",
"nested/package.json": '{"type":"commonjs","main":"main.js"}\n',
"nested/main.js": 'require("../dep.cjs");\n',
"untyped/package.json": "{}\n",
"untyped/main.js": 'require("../dep.cjs");\n',
"unknown/package.json": "{invalid",
"unknown/main.js": 'require("../dep.cjs");\n',
"url.mjs":
'import "./dep%20name.mjs?v=1#first"; import "./dep%20name.mjs?v=2#second"; import "./dep%2520name.mjs"; import "./bad%2Fname.mjs"; import "./bad%.mjs";\n',
"dep name.mjs": "export const actual = 1;\n",
"dep%20name.mjs": "export const literalPercent = 2;\n",
"literal.cjs":
'require.resolve("./dep%20name.mjs"); require.resolve("./dep?literal.cjs");\n',
"dep?literal.cjs": 'throw new Error("must never load");\n',
"oracle.mjs":
'import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; const require = createRequire(import.meta.url); console.log(JSON.stringify([fileURLToPath(import.meta.resolve("./dep%20name.mjs?v=1#first")), fileURLToPath(import.meta.resolve("./dep%2520name.mjs")), require.resolve("./dep%20name.mjs"), require.resolve("./dep?literal.cjs")]));\n',
};
for (const directory of ["nested", "unknown", "untyped"])
await mkdir(join(root, directory));
await Promise.all(
Object.entries(files).map(([path, source]) =>
writeFile(join(root, path), source),
),
);
return { root, files };
};
cliTest(
"preserves historical module syntax, loader scope and URL request identity",
async ({ cli }) => {
const root = await createTestTempDirectory(
"rea-reference-module-semantics-",
);
const files: Record<string, string> = {
"package.json": '{"type":"module"}\n',
"main.js": 'require("./dep.cjs"); export {};\n',
"dep.cjs": 'throw new Error("must never load");\n',
"directory.cjs": 'require("./nested/");\n',
"nested/index.js": 'module.exports = "fallback";\n',
"optional.cjs":
'require.resolve?.("./dep.cjs"); require?.resolve("./dep.cjs");\n',
"overwritten.cjs":
'require.resolve = other; require.resolve?.("./dep.cjs");\n',
"shadowed.cjs":
'function f(require) { require?.resolve("./dep.cjs"); }\n',
"types.d.ts":
'declare module "consumer" { import type { Marker } from "dependency"; export type A = import("./dep").Marker; export type B = typeof import("./dep"); }\n',
"dep.ts": "export interface Marker { id: string }\n",
"nested/package.json": '{"type":"commonjs","main":"main.js"}\n',
"nested/main.js": 'require("../dep.cjs");\n',
"untyped/package.json": "{}\n",
"untyped/main.js": 'require("../dep.cjs");\n',
"unknown/package.json": "{invalid",
"unknown/main.js": 'require("../dep.cjs");\n',
"url.mjs":
'import "./dep%20name.mjs?v=1#first"; import "./dep%20name.mjs?v=2#second"; import "./dep%2520name.mjs"; import "./bad%2Fname.mjs"; import "./bad%.mjs";\n',
"dep name.mjs": "export const actual = 1;\n",
"dep%20name.mjs": "export const literalPercent = 2;\n",
"literal.cjs":
'require.resolve("./dep%20name.mjs"); require.resolve("./dep?literal.cjs");\n',
"dep?literal.cjs": 'throw new Error("must never load");\n',
"oracle.mjs":
'import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; const require = createRequire(import.meta.url); console.log(JSON.stringify([fileURLToPath(import.meta.resolve("./dep%20name.mjs?v=1#first")), fileURLToPath(import.meta.resolve("./dep%2520name.mjs")), require.resolve("./dep%20name.mjs"), require.resolve("./dep?literal.cjs")]));\n',
};
for (const directory of ["nested", "unknown", "untyped"])
await mkdir(join(root, directory));
await Promise.all(
Object.entries(files).map(([path, source]) =>
writeFile(join(root, path), source),
),
);
const { root, files } = await historicalModuleFixture();
// This self-authored resolver control never loads a dependency.
const oracle = await promisify(execFile)(
process.execPath,
@@ -22,7 +22,7 @@ const application = async () => {
return { root, directory };
};
describe("JavaScript application input selection", () => {
const registerSelectedPathResolutionTests = (): void => {
it("preserves the selected path and host reason for an overlong name", async () => {
const { root } = await application();
const longPath = join(root, "x".repeat(300));
@@ -90,6 +90,10 @@ describe("JavaScript application input selection", () => {
expect(loopError).not.toEqual(chainError);
},
);
};
describe("JavaScript application input selection", () => {
registerSelectedPathResolutionTests();
it("reports a missing input path as invalid input, not an artifact read failure", async () => {
const { root } = await application();
@@ -18,6 +18,76 @@ import {
createJavaScriptApplicationNode,
} from "../../../src/domain/javascript/javascriptApplicationGraph.js";
const registerImplicitInvocationComparisonTests = (): void => {
it("preserves accessor-effect uncertainty through analyzed Evidence and export comparison", async () => {
const [left, right] = await analyzeSources({
left: `export default function observe() {
const box = { value: 1, get trigger() { this.value = 2; return 0; } };
box.trigger;
return { type: "event", value: box.value, stable: "kept" };
}`,
right: `export default function observe() {
return { type: "event", value: 2, stable: "kept" };
}`,
});
const execution = compareJavaScriptExportShapesEvidence({
left: left.evidence,
right: right.evidence,
left_module_path: "parser.mjs",
left_export_name: "default",
right_module_path: "parser.mjs",
right_export_name: "default",
});
if (!execution.ok) throw execution.error;
expect(execution.value.result.changes).toEqual([
expect.objectContaining({
status: "unknown",
path: "/value",
left: expect.objectContaining({ availability: "unknown" }),
right: { availability: "literal", value: 2 },
}),
]);
expect(execution.value.sources).toContain(left.evidence);
expect(execution.value.result.coverage.status).toBe("partial");
expect(inventoryProperties(execution.value.result, "left", 0)).toEqual(
expect.arrayContaining(["/stable", "/value", "/type"]),
);
});
it("preserves independent implicit invocation unknowns through retained export Evidence", async () => {
const [left, right] = await analyzeSources({
left: `export default function observe() {
const getter = { value: 1, get trigger() { this.value = 2; return 0; } };
const copy = { ...getter };
const coercion = { [Symbol.toPrimitive]() { this.value = 2; return "key"; }, value: 1 };
const keyed = { [coercion]: 0 };
const disposal = { [Symbol.dispose]() { this.value = 2; }, value: 1 };
{ using owned = disposal; }
return { type: "event", getter: getter.value, coercion: coercion.value, disposal: disposal.value, stable: "kept" };
}`,
right: `export default function observe() {
return { type: "event", getter: 2, coercion: 2, disposal: 2, stable: "kept" };
}`,
});
const result = compare(left, right);
expect(result.changes).toHaveLength(3);
expect(result.changes).toEqual(
expect.arrayContaining(
["/getter", "/coercion", "/disposal"].map((path) =>
expect.objectContaining({
path,
status: "unknown",
left: expect.objectContaining({ availability: "unknown" }),
right: { availability: "literal", value: 2 },
}),
),
),
);
expect(result.coverage.status).toBe("partial");
expect(inventoryProperties(result, "left", 0)).toContain("/stable");
});
};
describe("JavaScript export return-shape comparison", () => {
it("propagates proven ancestor absence to nested additions and removals", async () => {
const [left, right] = await analyzeSources({
@@ -130,73 +200,7 @@ describe("JavaScript export return-shape comparison", () => {
);
});
it("preserves accessor-effect uncertainty through analyzed Evidence and export comparison", async () => {
const [left, right] = await analyzeSources({
left: `export default function observe() {
const box = { value: 1, get trigger() { this.value = 2; return 0; } };
box.trigger;
return { type: "event", value: box.value, stable: "kept" };
}`,
right: `export default function observe() {
return { type: "event", value: 2, stable: "kept" };
}`,
});
const execution = compareJavaScriptExportShapesEvidence({
left: left.evidence,
right: right.evidence,
left_module_path: "parser.mjs",
left_export_name: "default",
right_module_path: "parser.mjs",
right_export_name: "default",
});
if (!execution.ok) throw execution.error;
expect(execution.value.result.changes).toEqual([
expect.objectContaining({
status: "unknown",
path: "/value",
left: expect.objectContaining({ availability: "unknown" }),
right: { availability: "literal", value: 2 },
}),
]);
expect(execution.value.sources).toContain(left.evidence);
expect(execution.value.result.coverage.status).toBe("partial");
expect(inventoryProperties(execution.value.result, "left", 0)).toEqual(
expect.arrayContaining(["/stable", "/value", "/type"]),
);
});
it("preserves independent implicit invocation unknowns through retained export Evidence", async () => {
const [left, right] = await analyzeSources({
left: `export default function observe() {
const getter = { value: 1, get trigger() { this.value = 2; return 0; } };
const copy = { ...getter };
const coercion = { [Symbol.toPrimitive]() { this.value = 2; return "key"; }, value: 1 };
const keyed = { [coercion]: 0 };
const disposal = { [Symbol.dispose]() { this.value = 2; }, value: 1 };
{ using owned = disposal; }
return { type: "event", getter: getter.value, coercion: coercion.value, disposal: disposal.value, stable: "kept" };
}`,
right: `export default function observe() {
return { type: "event", getter: 2, coercion: 2, disposal: 2, stable: "kept" };
}`,
});
const result = compare(left, right);
expect(result.changes).toHaveLength(3);
expect(result.changes).toEqual(
expect.arrayContaining(
["/getter", "/coercion", "/disposal"].map((path) =>
expect.objectContaining({
path,
status: "unknown",
left: expect.objectContaining({ availability: "unknown" }),
right: { availability: "literal", value: 2 },
}),
),
),
);
expect(result.coverage.status).toBe("partial");
expect(inventoryProperties(result, "left", 0)).toContain("/stable");
});
registerImplicitInvocationComparisonTests();
it("keeps additions unknown when spread coverage is incomplete", async () => {
const [left, right] = await analyzeSources({
@@ -602,6 +602,94 @@ describe("reference source manifest inventory", () => {
});
});
const registerReferenceRelocationTests = (): void => {
it("is relocation-stable, resolves imports, and excludes secrets before capture", async () => {
const parent = await createTestTempDirectory("rea-reference-import-");
try {
const leftRoot = await fixture(parent, "left");
const rightRoot = await fixture(parent, "right");
const [left, right] = await Promise.all([
importTree(leftRoot),
importTree(rightRoot),
]);
if (!left.ok || !right.ok) throw new Error("expected imports to pass");
expect(createHistoricalSourceManifest(left.value)).toEqual(
createHistoricalSourceManifest(right.value),
);
expect(left.value.relationships).toContainEqual(
expect.objectContaining({
from_path: "src/main.ts",
to: "src/dep.ts",
resolution: "internal",
}),
);
expect(left.value.parse_failures).toHaveLength(1);
expect(left.value.exclusions).toContainEqual({
path: ".env",
entry_kind: "file",
reason: "configured-secret",
pattern: ".env",
});
expect(JSON.stringify(left.value)).not.toContain("SECRET_SENTINEL");
expect(JSON.stringify(left.value)).not.toContain(leftRoot);
} finally {
await rm(parent, { recursive: true, force: true });
}
});
it
.skipIf(process.platform === "win32" || process.getuid?.() === 0)
.each(["file", "directory"] as const)(
"commits equivalent unreadable %s inventories independently of relocation and retains exact local diagnostics",
async (kind) => {
const parent = await createTestTempDirectory(
"rea-reference-failure-relocation-",
);
const roots = [join(parent, "left"), join(parent, "right")];
const denied: string[] = [];
try {
for (const root of roots) {
await mkdir(root);
const path = join(root, kind === "file" ? "blocked.ts" : "blocked");
if (kind === "file")
await writeFile(path, "export const answer = 42;\n");
else await mkdir(path);
denied.push(path);
await chmod(path, 0);
}
const [left, right] = await Promise.all(
roots.map((root) => importTree(root)),
);
if (left === undefined || right === undefined || !left.ok || !right.ok)
throw new Error("Expected partial imports");
expect(left.value.inventory_state).toBe("partial");
expect(createHistoricalSourceManifest(left.value)).toEqual(
createHistoricalSourceManifest(right.value),
);
for (const [index, graph] of [left.value, right.value].entries()) {
const entry = graph.entries[0];
const root = roots[index];
if (entry === undefined || root === undefined)
throw new Error("Expected failed entry");
expect(entry.limitations.join(" ")).toContain("EACCES");
expect(entry.limitations.join(" ")).toMatch(/Check.*permissions/u);
expect(entry.limitations.join(" ")).not.toContain(root);
expect(entry.local_diagnostics).toEqual([
expect.stringContaining(await realpath(root)),
]);
expect(
createHistoricalSourceSummary(graph, 2).outline.entries[0],
).toMatchObject({ local_diagnostics: entry.local_diagnostics });
}
} finally {
for (const path of denied)
await chmod(path, kind === "file" ? 0o600 : 0o700);
await rm(parent, { recursive: true, force: true });
}
},
);
};
describe("reference source import behavior", () => {
// The importer declares no byte ceiling and no entry-count ceiling. Scale
// independence cannot be asserted as a relationship over a bounded fixture,
@@ -697,91 +785,7 @@ describe("reference source import behavior", () => {
}
});
it("is relocation-stable, resolves imports, and excludes secrets before capture", async () => {
const parent = await createTestTempDirectory("rea-reference-import-");
try {
const leftRoot = await fixture(parent, "left");
const rightRoot = await fixture(parent, "right");
const [left, right] = await Promise.all([
importTree(leftRoot),
importTree(rightRoot),
]);
if (!left.ok || !right.ok) throw new Error("expected imports to pass");
expect(createHistoricalSourceManifest(left.value)).toEqual(
createHistoricalSourceManifest(right.value),
);
expect(left.value.relationships).toContainEqual(
expect.objectContaining({
from_path: "src/main.ts",
to: "src/dep.ts",
resolution: "internal",
}),
);
expect(left.value.parse_failures).toHaveLength(1);
expect(left.value.exclusions).toContainEqual({
path: ".env",
entry_kind: "file",
reason: "configured-secret",
pattern: ".env",
});
expect(JSON.stringify(left.value)).not.toContain("SECRET_SENTINEL");
expect(JSON.stringify(left.value)).not.toContain(leftRoot);
} finally {
await rm(parent, { recursive: true, force: true });
}
});
it
.skipIf(process.platform === "win32" || process.getuid?.() === 0)
.each(["file", "directory"] as const)(
"commits equivalent unreadable %s inventories independently of relocation and retains exact local diagnostics",
async (kind) => {
const parent = await createTestTempDirectory(
"rea-reference-failure-relocation-",
);
const roots = [join(parent, "left"), join(parent, "right")];
const denied: string[] = [];
try {
for (const root of roots) {
await mkdir(root);
const path = join(root, kind === "file" ? "blocked.ts" : "blocked");
if (kind === "file")
await writeFile(path, "export const answer = 42;\n");
else await mkdir(path);
denied.push(path);
await chmod(path, 0);
}
const [left, right] = await Promise.all(
roots.map((root) => importTree(root)),
);
if (left === undefined || right === undefined || !left.ok || !right.ok)
throw new Error("Expected partial imports");
expect(left.value.inventory_state).toBe("partial");
expect(createHistoricalSourceManifest(left.value)).toEqual(
createHistoricalSourceManifest(right.value),
);
for (const [index, graph] of [left.value, right.value].entries()) {
const entry = graph.entries[0];
const root = roots[index];
if (entry === undefined || root === undefined)
throw new Error("Expected failed entry");
expect(entry.limitations.join(" ")).toContain("EACCES");
expect(entry.limitations.join(" ")).toMatch(/Check.*permissions/u);
expect(entry.limitations.join(" ")).not.toContain(root);
expect(entry.local_diagnostics).toEqual([
expect.stringContaining(await realpath(root)),
]);
expect(
createHistoricalSourceSummary(graph, 2).outline.entries[0],
).toMatchObject({ local_diagnostics: entry.local_diagnostics });
}
} finally {
for (const path of denied)
await chmod(path, kind === "file" ? 0o600 : 0o700);
await rm(parent, { recursive: true, force: true });
}
},
);
registerReferenceRelocationTests();
it("imports the caller-selected directory and honors cancellation", async () => {
const outside = await createTestTempDirectory("rea-reference-outside-");