/** * adapter-coverage — 4 真适配器各自的 task-required 行为测试。 * * 单元(无 DB): * - causal extractCI / extractScore — pooled_estimate JSON 多种约定 * * 集成(真 DB,自动 skip 当 DATABASE_URL 未设): * - causal bucket_key 不匹配返空 + reason='bucket_key_no_match' * - drug target_id-only 走 target → drugs 路径(可附带 2-hop outcomes) * - internal-experience 默认排除 caller(sourceMetadata.excludedSelf=true) * - internal-experience include_self=true 时不排除 */ import test from "node:test"; import assert from "node:assert/strict"; import { extractCI, extractScore, causalAdapter } from "../causal.adapter.ts"; import { drugAdapter } from "../drug.adapter.ts"; import { internalExperienceAdapter } from "../internal-experience.adapter.ts"; import { _resetBudgetCounters } from "../index.ts"; const HAS_DB = Boolean(process.env["DATABASE_URL"]); test.beforeEach(() => { _resetBudgetCounters(); }); // ---------- causal pure-function unit tests ---------- test("causal.extractCI — { ci: [lo, hi] } 数组形式", () => { assert.deepEqual(extractCI({ ci: [0.2, 0.8] }), [0.2, 0.8]); }); test("causal.extractCI — { ci_low, ci_high } 形式", () => { assert.deepEqual(extractCI({ ci_low: -1.5, ci_high: 2.5 }), [-1.5, 2.5]); }); test("causal.extractCI — { lo, hi } 简写形式", () => { assert.deepEqual(extractCI({ lo: 0, hi: 1 }), [0, 1]); }); test("causal.extractCI — { lower, upper } 学术形式", () => { assert.deepEqual(extractCI({ lower: 0.1, upper: 0.9 }), [0.1, 0.9]); }); test("causal.extractCI — 缺失 / 非对象 → null,不假装", () => { assert.equal(extractCI(null), null); assert.equal(extractCI(undefined), null); assert.equal(extractCI({}), null); assert.equal(extractCI({ ci: [1] }), null); // 长度不对 assert.equal(extractCI({ ci: ["a", "b"] }), null); // 类型不对 assert.equal(extractCI("not_an_object"), null); }); test("causal.extractScore — value > estimate > mean > score 优先级", () => { assert.equal(extractScore({ value: 0.42, estimate: 0.99 }), 0.42); assert.equal(extractScore({ estimate: 0.7 }), 0.7); assert.equal(extractScore({ mean: -0.1 }), -0.1); assert.equal(extractScore({ score: 3.14 }), 3.14); assert.equal(extractScore({}), null); assert.equal(extractScore({ value: "not-a-number" }), null); assert.equal(extractScore({ value: NaN }), null); }); // ---------- DB-backed integration tests (skip when no DATABASE_URL) ---------- test("causal — bucket_key 不匹配返空 + reason='bucket_key_no_match'", { skip: !HAS_DB }, async () => { // 用一个肯定不存在的 jsonb 做 key const r = await causalAdapter.query({ kind: "causal_network", capabilityId: "cap_test_causal_bk", params: { bucket_key: { __test_marker__: "this_key_does_not_exist_xyzzy_42" } }, }); assert.equal(r.items.length, 0); assert.equal( (r.sourceMetadata as Record)["reason"], "bucket_key_no_match", ); }); test("causal — score_min/max 入 SQL 不报错(空结果也 OK)", { skip: !HAS_DB }, async () => { const r = await causalAdapter.query({ kind: "causal_network", capabilityId: "cap_test_causal_score", params: { score_min: -1e9, score_max: 1e9 }, limit: 5, }); // 不 throw 即通过(items 数随真 DB 状态) assert.ok(Array.isArray(r.items)); assert.equal(r.kind, "causal_network"); }); test("drug — target_id-only 路径不 throw(走 target → drugs/outcomes)", { skip: !HAS_DB }, async () => { // 任意不存在的 target_id 也应该走完路径返空,不应该 throw const r = await drugAdapter.query({ kind: "drug_network", capabilityId: "cap_test_drug_target", params: { target_id: "TARGET:nonexistent_xyzzy" }, limit: 5, }); assert.ok(Array.isArray(r.items)); assert.equal(r.kind, "drug_network"); assert.equal( ((r.sourceMetadata as Record)["filters"] as Record)[ "target_id" ], "TARGET:nonexistent_xyzzy", ); }); test("internal-experience — 默认 sourceMetadata.excludedSelf=true", { skip: !HAS_DB }, async () => { const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_self_test", params: {}, // no include_self limit: 5, }); const meta = r.sourceMetadata as Record; assert.equal(meta["excludedSelf"], true); assert.equal(meta["callerCapability"], "cap_caller_self_test"); }); test("internal-experience — include_self=true 时 excludedSelf=false", { skip: !HAS_DB }, async () => { const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_self_test_2", params: { include_self: true }, limit: 5, }); const meta = r.sourceMetadata as Record; assert.equal(meta["excludedSelf"], false); }); test( "internal-experience — 不存在的 capability_id 参数返空 items 但 sourceMetadata 完整(空表语义)", { skip: !HAS_DB }, async () => { // capability_data_foundation 在 B2 阶段 B7 才写入,所以本任务中绝大多数 // capability_id 都查不到行。验证 adapter 在"空表"语义下不假装有数据, // sourceMetadata 仍如实返回 caller / kindFilter / excludedSelf。 const bogus = `cap_does_not_exist_${Date.now()}_${Math.random().toString(36).slice(2)}`; const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_empty_table", params: { capability_id: bogus }, limit: 5, }); assert.deepEqual(r.items, []); assert.equal(r.cursor, null); const meta = r.sourceMetadata as Record; assert.equal(meta["callerCapability"], "cap_caller_empty_table"); assert.equal(meta["filteredCapability"], bogus); // excludedSelf 默认 true,因为 caller != filteredCapability 时也保留语义 assert.equal(meta["excludedSelf"], true); }, ); test( "internal-experience — kind 过滤进 SQL where 子句(不存在的 kind 返空)", { skip: !HAS_DB }, async () => { const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_kind_filter", params: { kind: `__nonexistent_kind_xyzzy_${Date.now()}__` }, limit: 5, }); assert.deepEqual(r.items, []); const meta = r.sourceMetadata as Record; // adapter 把 kindFilter 透传到 sourceMetadata,证明 where 子句真的进了 SQL assert.ok( typeof meta["kindFilter"] === "string" && (meta["kindFilter"] as string).startsWith("__nonexistent_kind_"), `expected kindFilter passthrough in sourceMetadata, got ${JSON.stringify(meta)}`, ); }, ); test( "internal-experience — invalid since 字符串:sinceFilterApplied=false(反 metadata 撒谎)", { skip: !HAS_DB }, async () => { // architect caveat #6 fix:caller 传了 since 但解析失败时,sourceMetadata // 必须老实告诉 caller "我没用",绝不能 echo 个 sinceFilter 假装应用了。 const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_invalid_since", params: { since: "this-is-not-a-date" }, limit: 5, }); const meta = r.sourceMetadata as Record; assert.equal(meta["sinceProvided"], "this-is-not-a-date"); assert.equal( meta["sinceFilterApplied"], false, "invalid since 必须 sinceFilterApplied=false,否则 metadata 撒谎", ); }, ); test( "internal-experience — 合法 since 字符串:sinceFilterApplied=true", { skip: !HAS_DB }, async () => { const r = await internalExperienceAdapter.query({ kind: "internal_experience", capabilityId: "cap_caller_valid_since", params: { since: "2020-01-01T00:00:00Z" }, limit: 5, }); const meta = r.sourceMetadata as Record; assert.equal(meta["sinceProvided"], "2020-01-01T00:00:00Z"); assert.equal(meta["sinceFilterApplied"], true); }, ); test( "drug — drug_id-only 路径不 throw(走 drug → targets/outcomes/trials)", { skip: !HAS_DB }, async () => { // 任意不存在的 drug_id 也应该走完路径返空,不应该 throw const r = await drugAdapter.query({ kind: "drug_network", capabilityId: "cap_test_drug_only", params: { drug_id: "DRUG:nonexistent_xyzzy" }, limit: 5, }); assert.ok(Array.isArray(r.items)); assert.equal(r.kind, "drug_network"); assert.equal( ((r.sourceMetadata as Record)["filters"] as Record)[ "drug_id" ], "DRUG:nonexistent_xyzzy", ); }, );