From cd8f16c4b1d97a8236601d865409e729ec470078 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 28 Mar 2026 06:28:10 +0000 Subject: [PATCH] =?UTF-8?q?test:=20fingerprint=20+=20context=20=E2=80=94?= =?UTF-8?q?=20fill=20coverage=20gaps=20in=20core=20utilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests for Fingerprint.refresh() cache invalidation and dbt-packages tag detection (both untested code paths), plus first-ever unit tests for the Context utility (AsyncLocalStorage wrapper) used by every module. Co-Authored-By: Claude Opus 4.6 (1M context) https://claude.ai/code/session_01N8kgPYhXX7SrYnZKJLiTfC --- .../test/altimate/fingerprint-detect.test.ts | 33 ++++++++++++++ packages/opencode/test/util/context.test.ts | 45 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 packages/opencode/test/util/context.test.ts diff --git a/packages/opencode/test/altimate/fingerprint-detect.test.ts b/packages/opencode/test/altimate/fingerprint-detect.test.ts index 70677147b..e61134018 100644 --- a/packages/opencode/test/altimate/fingerprint-detect.test.ts +++ b/packages/opencode/test/altimate/fingerprint-detect.test.ts @@ -107,4 +107,37 @@ describe("Fingerprint.detect: file-based project detection", () => { expect(result.tags).toContain("dbt") expect(result.tags).toContain("sql") }) + + test("detects dbt-packages from dbt_packages.yml", async () => { + await using tmp = await tmpdir() + await fs.writeFile(path.join(tmp.path, "dbt_packages.yml"), "packages:\n - package: dbt-labs/dbt_utils\n") + const result = await Fingerprint.detect(tmp.path) + expect(result.tags).toContain("dbt-packages") + }) + + test("combined project detects multiple technologies", async () => { + await using tmp = await tmpdir() + await fs.writeFile(path.join(tmp.path, "dbt_project.yml"), "name: test\n") + await fs.writeFile(path.join(tmp.path, "airflow.cfg"), "[core]\n") + await fs.writeFile(path.join(tmp.path, "databricks.yml"), "bundle:\n name: test\n") + const result = await Fingerprint.detect(tmp.path) + expect(result.tags).toContain("dbt") + expect(result.tags).toContain("airflow") + expect(result.tags).toContain("databricks") + expect(result.tags).toContain("data-engineering") + }) +}) + +describe("Fingerprint.refresh", () => { + test("invalidates cache and re-detects new files", async () => { + await using tmp = await tmpdir() + // Initial detect — no tags + const r1 = await Fingerprint.detect(tmp.path) + expect(r1.tags).toEqual([]) + // Add dbt_project.yml after initial detect + await fs.writeFile(path.join(tmp.path, "dbt_project.yml"), "name: test\n") + // refresh() should invalidate cache and pick up the new file + const r3 = await Fingerprint.refresh() + expect(r3.tags).toContain("dbt") + }) }) diff --git a/packages/opencode/test/util/context.test.ts b/packages/opencode/test/util/context.test.ts new file mode 100644 index 000000000..0d94dad85 --- /dev/null +++ b/packages/opencode/test/util/context.test.ts @@ -0,0 +1,45 @@ +import { describe, test, expect } from "bun:test" +import { Context } from "../../src/util/context" + +describe("Context: provide and use", () => { + test("use() returns provided value", () => { + const ctx = Context.create<{ id: number }>("test") + const result = ctx.provide({ id: 42 }, () => ctx.use()) + expect(result).toEqual({ id: 42 }) + }) + + test("use() throws NotFound outside provider", () => { + const ctx = Context.create<{ id: number }>("myctx") + expect(() => ctx.use()).toThrow(Context.NotFound) + expect(() => ctx.use()).toThrow("No context found for myctx") + }) + + test("nested provide uses innermost value", () => { + const ctx = Context.create<{ val: string }>("nest") + const result = ctx.provide({ val: "outer" }, () => + ctx.provide({ val: "inner" }, () => ctx.use().val), + ) + expect(result).toBe("inner") + }) + + test("provide passes through callback return value", () => { + const ctx = Context.create<{ val: string }>("passthrough") + const result = ctx.provide({ val: "x" }, () => 42) + expect(result).toBe(42) + }) + + test("concurrent contexts are isolated", async () => { + const ctx = Context.create<{ id: number }>("concurrent") + const results = await Promise.all([ + ctx.provide({ id: 1 }, async () => { + await new Promise((r) => setTimeout(r, 10)) + return ctx.use().id + }), + ctx.provide({ id: 2 }, async () => { + await new Promise((r) => setTimeout(r, 5)) + return ctx.use().id + }), + ]) + expect(results).toEqual([1, 2]) + }) +})