diff --git a/src/domain/referenceSourceClassification.test.ts b/src/domain/referenceSourceClassification.test.ts new file mode 100644 index 000000000..35398983b --- /dev/null +++ b/src/domain/referenceSourceClassification.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from "vitest"; + +import { classifyReferenceSourcePath } from "./referenceSourceClassification.js"; + +describe("reference source manifest filenames", () => { + it.each(["CMakeLists.txt", "cmakelists.txt", "CMAKELISTS.TXT"])( + "recognizes %s with the existing case-insensitive policy", + (path) => { + expect(classifyReferenceSourcePath(path)).toEqual([ + "documentation", + "manifest", + ]); + }, + ); + + it("preserves secondary classifications for a nested CMake manifest", () => { + expect(classifyReferenceSourcePath("src/CMakeLists.txt")).toEqual([ + "documentation", + "manifest", + "source", + ]); + }); + + it.each(["CMakeLists.txt.backup", "CMakeList.txt", "notes.txt"])( + "does not classify the near-match %s as a manifest", + (path) => { + expect(classifyReferenceSourcePath(path)).not.toContain("manifest"); + }, + ); + + it.each(["package.json", "PACKAGE.JSON", "Cargo.toml"])( + "preserves case-insensitive recognition of %s", + (path) => { + expect(classifyReferenceSourcePath(path)).toContain("manifest"); + }, + ); +}); diff --git a/src/domain/referenceSourceClassification.ts b/src/domain/referenceSourceClassification.ts index 8246e6ccf..c567cf06a 100644 --- a/src/domain/referenceSourceClassification.ts +++ b/src/domain/referenceSourceClassification.ts @@ -108,7 +108,7 @@ const MANIFEST_FILENAMES = new Set([ "pipfile.lock", "setup.cfg", "manifest.in", - "CMakeLists.txt", + "cmakelists.txt", "meson.build", "configure", "configure.ac", diff --git a/tests/boundary/filesystem/referenceSourceImport.test.ts b/tests/boundary/filesystem/referenceSourceImport.test.ts index 2c6d5d13f..0b6864d26 100644 --- a/tests/boundary/filesystem/referenceSourceImport.test.ts +++ b/tests/boundary/filesystem/referenceSourceImport.test.ts @@ -136,6 +136,41 @@ describe("reference source symlink import", () => { }); }); +describe("reference source manifest inventory", () => { + it("retains CMake build manifests in the imported inventory", async () => { + const root = await createTestTempDirectory("rea-reference-cmake-"); + await mkdir(join(root, "src")); + await Promise.all([ + writeFile(join(root, "CMakeLists.txt"), "project(example)\n"), + writeFile( + join(root, "src", "CMakeLists.txt"), + "add_library(example main.cpp)\n", + ), + writeFile(join(root, "notes.txt"), "Build notes.\n"), + ]); + + const result = await importTree(root); + expect(result.ok).toBe(true); + if (!result.ok) return; + expect(result.value.manifests).toEqual([ + "CMakeLists.txt", + "src/CMakeLists.txt", + ]); + expect(result.value.entries).toContainEqual( + expect.objectContaining({ + path: "CMakeLists.txt", + classifications: ["documentation", "manifest"], + }), + ); + expect(result.value.entries).toContainEqual( + expect.objectContaining({ + path: "src/CMakeLists.txt", + classifications: ["documentation", "manifest", "source"], + }), + ); + }); +}); + 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,