Files
rea/tests/boundary/filesystem/javascript-applications/javascriptRuntimeContentPriority.test.ts

232 lines
7.7 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect, it } from "vitest";
import {
parseRuntimeReconciliationInput,
reconcileJavaScriptRuntime,
} from "../../../../src/domain/javascript/javascriptRuntimeReconciliation.js";
import { reconcileRuntimeEntities } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationMatching.js";
import { classifyStaticLoadStates } from "../../../../src/domain/javascript/javascriptRuntimeLoadState.js";
import { projectRuntimeCaptures } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationRuntime.js";
import { reconcileJavaScriptRuntimeInputSchema } from "../../../../src/domain/javascript/javascriptRuntimeReconciliationSchemas.js";
import { collectStaticRuntimeCandidates } from "../../../../src/domain/javascript/javascriptRuntimeStaticCandidates.js";
import {
SOURCE,
analyzeFixture,
applicationFixture,
electronRuntimeEvidence,
} from "../../../fixtures/javascriptRuntimeReconciliation.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
const CAPTURED = "export const observed = 'different';\n";
const collisionInput = async (
alternatives: number,
explicitMapping: boolean,
) => {
const root = await applicationFixture();
if (alternatives > 0) await writeFile(join(root, "other.js"), CAPTURED);
const live = explicitMapping
? await createTestTempDirectory("rea-runtime-content-live-")
: root;
const extra = await createTestTempDirectory("rea-runtime-content-extra-");
await writeFile(join(extra, "app.js"), CAPTURED);
return parseRuntimeReconciliationInput(
reconcileJavaScriptRuntimeInputSchema.parse({
static_layers: [
{
role: "application",
analysis: await analyzeFixture(root),
runtime_mappings: explicitMapping
? [{ kind: "file-root", root: live, artifact_prefix: "" }]
: [],
},
...(alternatives > 1
? [{ role: "assets", analysis: await analyzeFixture(extra) }]
: []),
],
runtime_observations: [
electronRuntimeEvidence(live, CAPTURED, { includeWorker: false }),
],
}),
);
};
it.each([
[0, false],
[1, false],
[2, false],
[0, true],
[1, true],
[2, true],
] as const)(
"preserves mapped disagreement with %i other content matches (explicit mapping: %s)",
async (alternatives, explicitMapping) => {
const parsed = await collisionInput(alternatives, explicitMapping);
const result = reconcileJavaScriptRuntime(parsed);
const script = result.reconciliations.find(
({ entity_kind }) => entity_kind === "script",
);
expect(script).toMatchObject({
status: "unmatched",
basis: explicitMapping ? "operator-file-mapping" : "artifact-path",
confidence: "high",
reason: "captured-content-disagrees-with-static-location",
static_layer_id: null,
static_node_id: null,
candidate_static_count: 1,
});
const candidate = script?.candidate_static_nodes[0];
const selected = result.graph.nodes.find(
({ node_id }) => node_id === candidate?.static_node_id,
);
expect(selected?.observations).toEqual(
expect.arrayContaining([
expect.objectContaining({
properties: expect.objectContaining({ path: "app.js" }),
}),
]),
);
expect(
result.graph.edges.some(
(edge) =>
edge.relation === "observed_as" &&
edge.target_node_id === script?.runtime_node_id,
),
).toBe(false);
},
);
it("restricts content-and-location ambiguity to mapped candidates", async () => {
const application = await applicationFixture();
const cache = await applicationFixture();
const other = await applicationFixture();
const live = await createTestTempDirectory("rea-runtime-content-mapped-");
const analysis = await analyzeFixture(application);
const mapping = [{ kind: "file-root", root: live, artifact_prefix: "" }];
const parsed = parseRuntimeReconciliationInput(
reconcileJavaScriptRuntimeInputSchema.parse({
static_layers: [
{ role: "application", analysis, runtime_mappings: mapping },
{
role: "cache",
analysis: await analyzeFixture(cache),
runtime_mappings: mapping,
},
{ role: "assets", analysis: await analyzeFixture(other) },
],
runtime_observations: [
electronRuntimeEvidence(live, SOURCE, { includeWorker: false }),
],
}),
);
const result = reconcileJavaScriptRuntime(parsed);
const script = result.reconciliations.find(
({ entity_kind }) => entity_kind === "script",
);
expect(script).toMatchObject({
status: "ambiguous",
reason: "ambiguous-static-candidates",
candidate_static_count: 2,
});
const unmapped = result.static_layers.find(({ role }) => role === "assets");
expect(
script?.candidate_static_nodes.map(
({ static_layer_id }) => static_layer_id,
),
).not.toContain(unmapped?.layer_id);
});
it.each([false, true])(
"retains digest-only matching without a mapped candidate (mapping: %s)",
async (mapped) => {
const root = await applicationFixture();
await writeFile(join(root, "other.js"), CAPTURED);
const live = await createTestTempDirectory(
"rea-runtime-content-unlocated-",
);
const result = reconcileJavaScriptRuntime(
parseRuntimeReconciliationInput(
reconcileJavaScriptRuntimeInputSchema.parse({
static_layers: [
{
role: "application",
analysis: await analyzeFixture(root),
runtime_mappings: mapped
? [{ kind: "file-root", root: live, artifact_prefix: "" }]
: [],
},
],
runtime_observations: [
electronRuntimeEvidence(live, CAPTURED, {
scriptFile: "absent.js",
includeWorker: false,
}),
],
}),
),
);
expect(
result.reconciliations.find(
({ entity_kind }) => entity_kind === "script",
),
).toMatchObject({
status: "matched",
basis: "content-sha256",
confidence: "high",
reason: "unique-content-match",
candidate_static_count: 1,
});
},
);
it("keeps unavailable mapped digests unknown instead of borrowing unrelated matches", async () => {
const parsed = await collisionInput(1, true);
const candidates = collectStaticRuntimeCandidates(parsed.layers).map(
(candidate) =>
candidate.paths.includes("app.js") && candidate.category === "javascript"
? { ...candidate, digests: [] }
: candidate,
);
// Model the matcher's supported missing-digest boundary; do not falsify Evidence.
const runtime = projectRuntimeCaptures(parsed.captures);
const result = reconcileRuntimeEntities({
entities: runtime.entities,
candidates,
layers: parsed.layers,
});
expect(
result.items.find(({ entity_kind }) => entity_kind === "script"),
).toMatchObject({
status: "unknown",
basis: "operator-file-mapping",
confidence: "unknown",
reason: "static-or-runtime-coverage-incomplete",
candidate_static_count: 1,
});
const script = result.items.find(
({ entity_kind }) => entity_kind === "script",
);
const candidate = script?.candidate_static_nodes[0];
const states = classifyStaticLoadStates(
parsed.layers,
runtime.entities,
result.items,
{
reconciliationComplete: true,
},
);
expect(
states.states.find(
(state) =>
state.static_layer_id === candidate?.static_layer_id &&
state.static_node_id === candidate?.static_node_id,
),
).toMatchObject({
status: "unknown",
reason: "static-or-runtime-coverage-incomplete",
});
});