diff --git a/test/config.test.ts b/test/config.test.ts new file mode 100644 index 0000000..3e4e3fb --- /dev/null +++ b/test/config.test.ts @@ -0,0 +1,40 @@ +import { test, expect, describe } from "bun:test"; +import { loadConfig } from "../src/config"; + +describe("config", () => { + test("loadConfig env variables override config file and defaults", async () => { + const origBase = process.env.GAI_API_BASE; + const origModel = process.env.GAI_MODEL; + + process.env.GAI_API_BASE = "https://custom.api.com/v1"; + process.env.GAI_MODEL = "custom-model"; + + const config = await loadConfig(); + + expect(config.apiBase).toBe("https://custom.api.com/v1"); + expect(config.model).toBe("custom-model"); + + if (origBase) process.env.GAI_API_BASE = origBase; + else delete process.env.GAI_API_BASE; + if (origModel) process.env.GAI_MODEL = origModel; + else delete process.env.GAI_MODEL; + }); + + test("loadConfig reads from environment variables", async () => { + const origBase = process.env.GAI_API_BASE; + const origModel = process.env.GAI_MODEL; + + process.env.GAI_API_BASE = "https://api.deepseek.com/v1"; + process.env.GAI_MODEL = "deepseek-chat"; + + const config = await loadConfig(); + + expect(config.apiBase).toBe("https://api.deepseek.com/v1"); + expect(config.model).toBe("deepseek-chat"); + + if (origBase) process.env.GAI_API_BASE = origBase; + else delete process.env.GAI_API_BASE; + if (origModel) process.env.GAI_MODEL = origModel; + else delete process.env.GAI_MODEL; + }); +}); diff --git a/test/prompt.test.ts b/test/prompt.test.ts new file mode 100644 index 0000000..032fb05 --- /dev/null +++ b/test/prompt.test.ts @@ -0,0 +1,64 @@ +import { test, expect, describe } from "bun:test"; +import { buildPrompt, SYSTEM_PROMPT } from "../src/prompt"; +import type { ProjectContext } from "../src/types"; + +describe("prompt", () => { + test("SYSTEM_PROMPT contains Conventional Commits format", () => { + expect(SYSTEM_PROMPT).toContain("()"); + expect(SYSTEM_PROMPT).toContain("feat"); + expect(SYSTEM_PROMPT).toContain("fix"); + }); + + test("buildPrompt with full context", () => { + const ctx: ProjectContext = { + readme: "A test project", + packageDescription: "Test package", + structure: "src/, tests/", + recentCommits: ["abc123 feat: initial commit"], + diff: "+new line\n-old line", + }; + + const prompt = buildPrompt(ctx); + + expect(prompt).toContain("## Project Context"); + expect(prompt).toContain("Test package"); + expect(prompt).toContain("src/, tests/"); + expect(prompt).toContain("A test project"); + expect(prompt).toContain("## Recent Commits"); + expect(prompt).toContain("abc123 feat: initial commit"); + expect(prompt).toContain("## Staged Changes"); + expect(prompt).toContain("+new line"); + expect(prompt).toContain("Generate a commit message"); + }); + + test("buildPrompt with minimal context (only diff)", () => { + const ctx: ProjectContext = { + readme: null, + packageDescription: null, + structure: null, + recentCommits: [], + diff: "+added code", + }; + + const prompt = buildPrompt(ctx); + + expect(prompt).not.toContain("## Project Context"); + expect(prompt).not.toContain("## Recent Commits"); + expect(prompt).toContain("## Staged Changes"); + expect(prompt).toContain("+added code"); + }); + + test("buildPrompt includes diff as-is (truncation is caller's responsibility)", () => { + const diff = "+short diff content"; + const ctx: ProjectContext = { + readme: null, + packageDescription: null, + structure: null, + recentCommits: [], + diff, + }; + + const prompt = buildPrompt(ctx); + expect(prompt).toContain(diff); + }); +});