返回 CodeWhale
facts-drift.test.ts
根目录 / web / lib / facts-drift.test.ts
1 import { afterEach, describe, expect, it, vi } from "vitest";
2 import { deriveFactsFromRemote } from "./facts-drift";
3
4 const REVISION = "b".repeat(40);
5
6 function response(body: string, status = 200): Response {
7 return new Response(body, { status });
8 }
9
10 function installGitHubFixture(toolCountSource: string | null): void {
11 vi.stubGlobal(
12 "fetch",
13 vi.fn(async (input: string | URL | Request) => {
14 const url = String(input);
15 if (url.endsWith("/commits/main")) {
16 return response(
17 JSON.stringify({
18 sha: REVISION,
19 commit: { committer: { date: "2026-07-21T23:00:00Z" } },
20 }),
21 );
22 }
23 if (url.endsWith("/releases/latest")) {
24 return response(
25 JSON.stringify({
26 tag_name: "v0.9.0",
27 published_at: "2026-07-16T20:05:39Z",
28 html_url: "https://github.com/Hmbown/CodeWhale/releases/tag/v0.9.0",
29 }),
30 );
31 }
32 const rawPath = url.split(`/${REVISION}/`)[1];
33 const sources: Record<string, string> = {
34 "Cargo.toml": 'version = "0.9.2"\nmembers = ["crates/tui"]',
35 "crates/tui/src/config.rs":
36 'pub enum ApiProvider {\n Deepseek,\n}\nconst DEFAULT_TEXT_MODEL: &str = "remote-model";',
37 "crates/tui/src/config/models.rs": "",
38 "crates/tui/src/sandbox/mod.rs": `
39 pub const PUBLIC_SANDBOX_BACKENDS: &[&str] = &[
40 "seatbelt (macOS, when available)",
41 "bubblewrap (Linux, opt-in when installed)",
42 ];
43 `,
44 "npm/codewhale/package.json": JSON.stringify({ engines: { node: ">=18" } }),
45 LICENSE: "MIT License\n",
46 };
47 if (rawPath === "web/lib/facts.generated.ts") {
48 return toolCountSource === null ? response("not found", 404) : response(toolCountSource);
49 }
50 return rawPath && rawPath in sources
51 ? response(sources[rawPath])
52 : response("not found", 404);
53 }),
54 );
55 }
56
57 afterEach(() => {
58 vi.unstubAllGlobals();
59 });
60
61 describe("deriveFactsFromRemote", () => {
62 it("derives tool count from the same exact remote revision", async () => {
63 installGitHubFixture(
64 'export const FACTS: RepoFacts = {"toolCount":73};',
65 );
66
67 const facts = await deriveFactsFromRemote();
68
69 expect(facts?.sourceRevision).toBe(REVISION);
70 expect(facts?.version).toBe("0.9.2");
71 expect(facts?.toolCount).toBe(73);
72 expect(facts?.sandboxBackends).toEqual([
73 "seatbelt (macOS, when available)",
74 "bubblewrap (Linux, opt-in when installed)",
75 ]);
76 const fetchMock = vi.mocked(fetch);
77 expect(
78 fetchMock.mock.calls.some(([input]) => String(input).includes("/contents/")),
79 ).toBe(false);
80 });
81
82 it("fails derivation when the exact revision has no valid tool count", async () => {
83 installGitHubFixture(null);
84
85 await expect(deriveFactsFromRemote()).resolves.toBeNull();
86 });
87 });
88
88 lines TYPESCRIPT