mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
@@ -538,6 +538,11 @@ const relationsByPath = (
|
||||
? null
|
||||
: (occurrences.get(occurrence.parent_occurrence_id)?.logical_path ??
|
||||
null),
|
||||
// Containment roots are path-normalized to avoid graph-wide deltas, but
|
||||
// a source map's target is a semantic content identity, not its parent
|
||||
// directory. Preserve that identity in the relation comparison.
|
||||
mapped_artifact_id:
|
||||
edge.relation === "maps-source" ? edge.parent_artifact_id : null,
|
||||
child_artifact_id: occurrence.artifact_id,
|
||||
relation: edge.relation,
|
||||
logical_path: occurrence.logical_path,
|
||||
@@ -556,6 +561,8 @@ const relationsByPath = (
|
||||
interface RelationProjection {
|
||||
/** Logical parent is stable across graph-root ID changes. */
|
||||
readonly parent_logical_path: string | null;
|
||||
/** Content identity is material for a maps-source edge. */
|
||||
readonly mapped_artifact_id: string | null;
|
||||
readonly child_artifact_id: string;
|
||||
readonly relation: ArtifactInventoryResult["edges"][number]["relation"];
|
||||
readonly logical_path: string | null;
|
||||
|
||||
@@ -571,6 +571,49 @@ describe("artifact comparison completeness", () => {
|
||||
});
|
||||
|
||||
describe("artifact source-map relationship coverage", () => {
|
||||
it("reports when an unchanged map points to changed source content", async () => {
|
||||
const root = await createTestTempDirectory("rea-map-target-change-");
|
||||
const leftPath = join(root, "left");
|
||||
const rightPath = join(root, "right");
|
||||
await Promise.all([mkdir(leftPath), mkdir(rightPath)]);
|
||||
await Promise.all([
|
||||
writeFile(join(leftPath, "main.js"), "/* first source */\n"),
|
||||
writeFile(join(rightPath, "main.js"), "/* second source */\n"),
|
||||
writeFile(
|
||||
join(leftPath, "main.js.map"),
|
||||
'{"version":3,"sources":[],"names":[],"mappings":""}',
|
||||
),
|
||||
writeFile(
|
||||
join(rightPath, "main.js.map"),
|
||||
'{"version":3,"sources":[],"names":[],"mappings":""}',
|
||||
),
|
||||
]);
|
||||
const [left, right] = await Promise.all([
|
||||
observe(leftPath),
|
||||
observe(rightPath),
|
||||
]);
|
||||
|
||||
const comparison = compareArtifacts(left, right);
|
||||
const leftInventory = parseArtifactInventoryEvidence(left).inventory;
|
||||
const rightInventory = parseArtifactInventoryEvidence(right).inventory;
|
||||
const leftMap = leftInventory.occurrences.find(
|
||||
({ logical_path }) => logical_path === "main.js.map",
|
||||
);
|
||||
const rightMap = rightInventory.occurrences.find(
|
||||
({ logical_path }) => logical_path === "main.js.map",
|
||||
);
|
||||
expect(leftMap?.artifact_id).toBe(rightMap?.artifact_id);
|
||||
expect(comparison.changes).toContainEqual(
|
||||
expect.objectContaining({
|
||||
logical_path: "main.js.map",
|
||||
classification: "changed",
|
||||
dimensions: ["relations"],
|
||||
left_artifact_id: leftMap?.artifact_id,
|
||||
right_artifact_id: rightMap?.artifact_id,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves unknown source-map relationships for duplicate ZIP paths", async () => {
|
||||
const root = await createTestTempDirectory("rea-duplicate-source-map-");
|
||||
const path = join(root, "duplicate-source-map.zip");
|
||||
|
||||
Reference in New Issue
Block a user