Skip to content

Commit ea23fbb

Browse files
committed
test: add comprehensive test coverage for CLI, fs, loop modules
- Add CLI argument parsing tests - Add file system utilities tests - Add loop phase tests - Update ideas and evaluator tests Signed-off-by: leocavalcante <[email protected]>
1 parent 80bfa62 commit ea23fbb

File tree

5 files changed

+902
-6
lines changed

5 files changed

+902
-6
lines changed

tests/cli.test.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/**
2+
* Tests for cli module
3+
*/
4+
5+
import { describe, expect, test } from "bun:test"
6+
import { parseCli } from "../src/cli.ts"
7+
8+
describe("parseCli", () => {
9+
// Helper to create argv array (simulates process.argv)
10+
const argv = (...args: string[]) => ["node", "opencoder", ...args]
11+
12+
describe("model options", () => {
13+
test("parses --model option", () => {
14+
const result = parseCli(argv("--model", "anthropic/claude-sonnet-4"))
15+
16+
expect(result.options.model).toBe("anthropic/claude-sonnet-4")
17+
})
18+
19+
test("parses -m shorthand", () => {
20+
const result = parseCli(argv("-m", "openai/gpt-4"))
21+
22+
expect(result.options.model).toBe("openai/gpt-4")
23+
})
24+
25+
test("parses --plan-model option", () => {
26+
const result = parseCli(argv("--plan-model", "anthropic/claude-opus-4"))
27+
28+
expect(result.options.planModel).toBe("anthropic/claude-opus-4")
29+
})
30+
31+
test("parses -P shorthand for plan model", () => {
32+
const result = parseCli(argv("-P", "anthropic/claude-opus-4"))
33+
34+
expect(result.options.planModel).toBe("anthropic/claude-opus-4")
35+
})
36+
37+
test("parses --build-model option", () => {
38+
const result = parseCli(argv("--build-model", "anthropic/claude-sonnet-4"))
39+
40+
expect(result.options.buildModel).toBe("anthropic/claude-sonnet-4")
41+
})
42+
43+
test("parses -B shorthand for build model", () => {
44+
const result = parseCli(argv("-B", "anthropic/claude-sonnet-4"))
45+
46+
expect(result.options.buildModel).toBe("anthropic/claude-sonnet-4")
47+
})
48+
49+
test("parses separate plan and build models", () => {
50+
const result = parseCli(
51+
argv("-P", "anthropic/claude-opus-4", "-B", "anthropic/claude-sonnet-4"),
52+
)
53+
54+
expect(result.options.planModel).toBe("anthropic/claude-opus-4")
55+
expect(result.options.buildModel).toBe("anthropic/claude-sonnet-4")
56+
})
57+
})
58+
59+
describe("project option", () => {
60+
test("parses --project option", () => {
61+
const result = parseCli(argv("--project", "/path/to/project"))
62+
63+
expect(result.options.project).toBe("/path/to/project")
64+
})
65+
66+
test("parses -p shorthand", () => {
67+
const result = parseCli(argv("-p", "./myproject"))
68+
69+
expect(result.options.project).toBe("./myproject")
70+
})
71+
72+
test("project is undefined when not provided", () => {
73+
const result = parseCli(argv("-m", "anthropic/claude-sonnet-4"))
74+
75+
expect(result.options.project).toBeUndefined()
76+
})
77+
})
78+
79+
describe("verbose option", () => {
80+
test("parses --verbose flag", () => {
81+
const result = parseCli(argv("--verbose"))
82+
83+
expect(result.options.verbose).toBe(true)
84+
})
85+
86+
test("parses -v shorthand", () => {
87+
const result = parseCli(argv("-v"))
88+
89+
expect(result.options.verbose).toBe(true)
90+
})
91+
92+
test("verbose is undefined when not provided", () => {
93+
const result = parseCli(argv("-m", "anthropic/claude-sonnet-4"))
94+
95+
expect(result.options.verbose).toBeUndefined()
96+
})
97+
})
98+
99+
describe("hint argument", () => {
100+
test("parses hint argument", () => {
101+
const result = parseCli(argv("build a REST API"))
102+
103+
expect(result.hint).toBe("build a REST API")
104+
})
105+
106+
test("parses hint with options", () => {
107+
const result = parseCli(argv("-m", "anthropic/claude-sonnet-4", "focus on tests"))
108+
109+
expect(result.hint).toBe("focus on tests")
110+
expect(result.options.model).toBe("anthropic/claude-sonnet-4")
111+
})
112+
113+
test("hint is undefined when not provided", () => {
114+
const result = parseCli(argv("-m", "anthropic/claude-sonnet-4"))
115+
116+
expect(result.hint).toBeUndefined()
117+
})
118+
119+
test("parses quoted hint with spaces", () => {
120+
const result = parseCli(argv("implement user authentication flow"))
121+
122+
expect(result.hint).toBe("implement user authentication flow")
123+
})
124+
})
125+
126+
describe("combined options", () => {
127+
test("parses all options together", () => {
128+
const result = parseCli(
129+
argv(
130+
"-p",
131+
"./myproject",
132+
"-P",
133+
"anthropic/claude-opus-4",
134+
"-B",
135+
"anthropic/claude-sonnet-4",
136+
"-v",
137+
"build the feature",
138+
),
139+
)
140+
141+
expect(result.options.project).toBe("./myproject")
142+
expect(result.options.planModel).toBe("anthropic/claude-opus-4")
143+
expect(result.options.buildModel).toBe("anthropic/claude-sonnet-4")
144+
expect(result.options.verbose).toBe(true)
145+
expect(result.hint).toBe("build the feature")
146+
})
147+
148+
test("parses model with project and verbose", () => {
149+
const result = parseCli(argv("-m", "openai/gpt-4o", "-p", "/project", "-v"))
150+
151+
expect(result.options.model).toBe("openai/gpt-4o")
152+
expect(result.options.project).toBe("/project")
153+
expect(result.options.verbose).toBe(true)
154+
})
155+
156+
test("options can appear in any order", () => {
157+
const result = parseCli(
158+
argv("-v", "my hint", "-m", "anthropic/claude-sonnet-4", "-p", "./proj"),
159+
)
160+
161+
expect(result.options.verbose).toBe(true)
162+
expect(result.options.model).toBe("anthropic/claude-sonnet-4")
163+
expect(result.options.project).toBe("./proj")
164+
expect(result.hint).toBe("my hint")
165+
})
166+
})
167+
168+
describe("default values", () => {
169+
test("returns undefined for all options when none provided", () => {
170+
const result = parseCli(argv())
171+
172+
expect(result.options.project).toBeUndefined()
173+
expect(result.options.model).toBeUndefined()
174+
expect(result.options.planModel).toBeUndefined()
175+
expect(result.options.buildModel).toBeUndefined()
176+
expect(result.options.verbose).toBeUndefined()
177+
expect(result.hint).toBeUndefined()
178+
})
179+
})
180+
})

tests/evaluator.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
import { describe, expect, test } from "bun:test"
6-
import { parseEvaluation, isComplete, extractEvaluationReason } from "../src/evaluator.ts"
6+
import { extractEvaluationReason, isComplete, parseEvaluation } from "../src/evaluator.ts"
77

88
describe("evaluator", () => {
99
describe("parseEvaluation", () => {

0 commit comments

Comments
 (0)