diff --git a/src/application/javascript/JavaScriptModuleRelationships.ts b/src/application/javascript/JavaScriptModuleRelationships.ts index 774b0e4aee..52cbec75b7 100644 --- a/src/application/javascript/JavaScriptModuleRelationships.ts +++ b/src/application/javascript/JavaScriptModuleRelationships.ts @@ -107,7 +107,6 @@ export const addJavaScriptSourceModules = ( semantic_role: "source-module", source_sha256: file.sha256, path: file.path, - container_sha256: file.container_sha256, logical_module_key: file.path, module_format: moduleFormat(file.path, semantic.ir), import_relationships: semantic.ir.moduleLinks.filter( diff --git a/tests/boundary/filesystem/javascript-applications/javascriptModuleRelationships.test.ts b/tests/boundary/filesystem/javascript-applications/javascriptModuleRelationships.test.ts index 3bdb8f6427..860424c6df 100644 --- a/tests/boundary/filesystem/javascript-applications/javascriptModuleRelationships.test.ts +++ b/tests/boundary/filesystem/javascript-applications/javascriptModuleRelationships.test.ts @@ -6,6 +6,7 @@ import { describe, expect, it } from "vitest"; import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js"; import { parseJavaScriptApplicationGraph } from "../../../../src/domain/javascript/javascriptApplicationGraph.js"; +import { compareJavaScriptApplicationVersions } from "../../../../src/domain/javascript/javascriptApplicationVersionComparison.js"; import { findExportNode, @@ -15,6 +16,70 @@ import { writeFixtureFiles, } from "../../../support/javascriptApplicationFixture.js"; +describe("cross-version source module identity", () => { + it("keeps a source module unchanged when only a sibling file changes", async () => { + const root = await createTestTempDirectory("rea-source-module-sibling-"); + const versions = await Promise.all( + ["left", "right"].map(async (name) => { + const path = join(root, name); + await writeFixtureFiles(path, { + "main.js": 'require("./util.js");\n', + "util.js": `module.exports = ${JSON.stringify(name)};\n`, + }); + return reconstructJavaScriptFixture(path); + }), + ); + const [left, right] = versions; + if (left === undefined || right === undefined) + throw new Error("Missing JavaScript application version"); + const leftModule = findSourceModule(left.graph, "main.js"); + const rightModule = findSourceModule(right.graph, "main.js"); + if (leftModule === undefined || rightModule === undefined) + throw new Error("Missing main source module"); + const leftObservation = leftModule.observations.find( + ({ properties }) => properties.semantic_role === "source-module", + ); + const rightObservation = rightModule.observations.find( + ({ properties }) => properties.semantic_role === "source-module", + ); + expect(leftObservation?.properties).not.toHaveProperty("container_sha256"); + expect(rightObservation?.properties).not.toHaveProperty("container_sha256"); + expect(leftObservation?.properties).toEqual(rightObservation?.properties); + expect(leftObservation?.properties.source_sha256).toBe( + rightObservation?.properties.source_sha256, + ); + + const comparison = compareJavaScriptApplicationVersions({ + left: { + evidenceId: `ev_${"a".repeat(64)}`, + rootArtifactSha256: left.root_artifact_sha256, + graph: left.graph, + }, + right: { + evidenceId: `ev_${"b".repeat(64)}`, + rootArtifactSha256: right.root_artifact_sha256, + graph: right.graph, + }, + leftNativeEvidence: [], + rightNativeEvidence: [], + }); + + expect( + comparison.items.find( + ({ left_node_id }) => left_node_id === leftModule.node_id, + ), + ).toMatchObject({ + status: "unchanged", + right_node_id: rightModule.node_id, + match: { + status: "matched", + basis: "exact-module-source-digest", + confidence: "exact", + }, + }); + }); +}); + describe("TypeScript source module loader semantics", () => { it("publishes each source module's own content digest", async () => { const root = await createTestTempDirectory("rea-source-module-digest-");