doatlas-2 / artifacts /api-server /src /lib /capability /external-knowledge /__tests__ /adapter-coverage.test.ts
| /** | |
| * 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<string, unknown>)["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<string, unknown>)["filters"] as Record<string, unknown>)[ | |
| "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<string, unknown>; | |
| 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<string, unknown>; | |
| 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<string, unknown>; | |
| 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<string, unknown>; | |
| // 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<string, unknown>; | |
| 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<string, unknown>; | |
| 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<string, unknown>)["filters"] as Record<string, unknown>)[ | |
| "drug_id" | |
| ], | |
| "DRUG:nonexistent_xyzzy", | |
| ); | |
| }, | |
| ); | |