-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
376 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
pull_request: | ||
branches: [main] | ||
|
||
jobs: | ||
test-and-build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
lfs: true | ||
|
||
- name: Setup Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: "20" | ||
cache: "pnpm" | ||
|
||
- name: Install pnpm | ||
uses: pnpm/action-setup@v2 | ||
with: | ||
version: 9 | ||
|
||
- name: Install dependencies | ||
run: pnpm install | ||
|
||
- name: Build | ||
run: pnpm build | ||
|
||
- name: Run tests | ||
run: pnpm test:unit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
dist/ | ||
node_modules/ | ||
|
||
api-response.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { describe, it, expect, vi, beforeEach } from "vitest"; | ||
import { executeCommand, findTestFiles } from "../commands.js"; | ||
import { Config } from "../types.js"; | ||
import { ui } from "../ui.js"; | ||
|
||
const mockSync = vi.hoisted(() => vi.fn()); | ||
|
||
vi.mock("fast-glob", () => ({ | ||
default: { sync: mockSync }, | ||
})); | ||
|
||
describe("Command Utilities", () => { | ||
beforeEach(() => { | ||
vi.restoreAllMocks(); | ||
ui.destroy(); | ||
mockSync.mockReset(); | ||
}); | ||
|
||
describe("executeCommand", () => { | ||
it("should resolve with command output", async () => { | ||
const mockSpawn = vi.fn(() => ({ | ||
stdout: { on: vi.fn() }, | ||
stderr: { on: vi.fn() }, | ||
on: vi.fn((event, cb) => cb(0)), | ||
})); | ||
vi.stubGlobal("child_process", { spawn: mockSpawn }); | ||
const result = await executeCommand("echo", ["test"]); | ||
expect(result).toContain("test"); | ||
}); | ||
|
||
it("should reject on non-zero exit code", async () => { | ||
const mockSpawn = vi.fn(() => ({ | ||
stdout: { on: vi.fn() }, | ||
stderr: { on: vi.fn() }, | ||
on: vi.fn((event, cb) => cb(1)), | ||
})); | ||
vi.stubGlobal("child_process", { spawn: mockSpawn }); | ||
await expect(executeCommand("false", [])).rejects.toThrow(); | ||
}); | ||
|
||
it("should call onData callback with output", async () => { | ||
const onData = vi.fn(); | ||
const mockSpawn = vi.fn(() => ({ | ||
stdout: { on: vi.fn((event, cb) => cb(Buffer.from("test"))) }, | ||
stderr: { on: vi.fn() }, | ||
on: vi.fn((event, cb) => cb(0)), | ||
})); | ||
vi.stubGlobal("child_process", { spawn: mockSpawn }); | ||
await executeCommand("echo", ["test"], { onData } as any); | ||
expect(onData).toHaveBeenCalledWith(expect.stringContaining("test")); | ||
}); | ||
}); | ||
|
||
describe("findTestFiles", () => { | ||
const mockConfig: Config = { testFilePattern: ["**/*.test.ts"] } as Config; | ||
|
||
it("should find test files in output", () => { | ||
const testOutput = ["FAIL src/test.test.ts", "PASS src/other.ts"].join( | ||
"\n" | ||
); | ||
mockSync.mockReturnValue(["src/test.test.ts"]); | ||
const result = findTestFiles(testOutput, mockConfig); | ||
expect(result).toEqual(["src/test.test.ts"]); | ||
expect(mockSync).toHaveBeenCalledWith( | ||
mockConfig.testFilePattern, | ||
expect.any(Object) | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { describe, it, expect, vi, beforeEach } from "vitest"; | ||
import { extractFixedCode, identifyFixableFiles } from "../fix.js"; | ||
import { FILE_PATH_TAG, FIX_END_TAG, FIX_START_TAG } from "../constants.js"; | ||
|
||
describe("Fix Utilities", () => { | ||
describe("extractFixedCode", () => { | ||
it("should return null when tags are missing", () => { | ||
expect(extractFixedCode("no tags here")).toBeNull(); | ||
}); | ||
|
||
it("should extract content between tags", () => { | ||
const content = `prefix\n<updated-code>\nconst a = 1;\n</updated-code>\nsuffix`; | ||
expect(extractFixedCode(content)).toBe("const a = 1;"); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import { logStore } from '../log-store.js'; | ||
|
||
describe('LogStore', () => { | ||
beforeEach(() => { | ||
logStore.clear(); | ||
}); | ||
|
||
it('should notify subscribers when logs are updated', async () => { | ||
const listener = vi.fn(); | ||
const unsubscribe = logStore.subscribe(listener); | ||
logStore.appendOutput('test'); | ||
await new Promise((r) => setTimeout(r, 20)); | ||
expect(listener).toHaveBeenCalledTimes(1); | ||
unsubscribe(); | ||
}); | ||
|
||
it('should debounce multiple notifications', async () => { | ||
const listener = vi.fn(); | ||
logStore.subscribe(listener); | ||
logStore.appendOutput('test1'); | ||
logStore.appendOutput('test2'); | ||
logStore.appendReasoning('reason1'); | ||
await new Promise((r) => setTimeout(r, 5)); | ||
expect(listener).toHaveBeenCalledTimes(0); | ||
await new Promise((r) => setTimeout(r, 20)); | ||
expect(listener).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should maintain separate buffers for output and reasoning', () => { | ||
logStore.appendOutput('output'); | ||
logStore.appendReasoning('reasoning'); | ||
expect(logStore.getOutput()).toBe('output'); | ||
expect(logStore.getReasoning()).toBe('reasoning'); | ||
expect(logStore.getOutputBuffer()).toBe('output'); | ||
expect(logStore.getReasoningBuffer()).toBe('reasoning'); | ||
}); | ||
|
||
it('should clear logs properly', () => { | ||
logStore.appendOutput('test'); | ||
logStore.appendReasoning('test'); | ||
logStore.clear(); | ||
expect(logStore.getOutput()).toBe(''); | ||
expect(logStore.getReasoning()).toBe(''); | ||
}); | ||
|
||
it('should handle multiple subscribers', async () => { | ||
const listener1 = vi.fn(); | ||
const listener2 = vi.fn(); | ||
logStore.subscribe(listener1); | ||
logStore.subscribe(listener2); | ||
logStore.appendOutput('test'); | ||
await new Promise((r) => setTimeout(r, 20)); | ||
expect(listener1).toHaveBeenCalledTimes(1); | ||
expect(listener2).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should unsubscribe properly', async () => { | ||
const listener = vi.fn(); | ||
const unsubscribe = logStore.subscribe(listener); | ||
unsubscribe(); | ||
logStore.appendOutput('test'); | ||
await new Promise((r) => setTimeout(r, 20)); | ||
expect(listener).not.toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { describe, it, expect, vi, beforeEach } from "vitest"; | ||
import { ui } from "../ui.js"; | ||
import { render } from "ink"; | ||
import { logStore } from "../log-store.js"; | ||
|
||
// Mock process.stdin.isTTY to true for tests | ||
Object.defineProperty(process.stdin, "isTTY", { value: true }); | ||
|
||
vi.mock("ink", () => ({ | ||
render: vi.fn(() => ({ | ||
unmount: vi.fn(), | ||
waitUntilExit: vi.fn(), | ||
rerender: vi.fn(), | ||
cleanup: vi.fn(), | ||
clear: vi.fn(), | ||
})), | ||
})); | ||
|
||
describe("UI Manager", () => { | ||
let mockUnmount: ReturnType<typeof vi.fn>; | ||
|
||
beforeEach(() => { | ||
vi.resetAllMocks(); | ||
mockUnmount = vi.fn(); | ||
vi.spyOn(process, "exit").mockImplementation(() => undefined as never); | ||
const mockRender = render as unknown as ReturnType<typeof vi.fn>; | ||
mockRender.mockReturnValue({ unmount: mockUnmount }); | ||
ui.destroy(); | ||
logStore.clear(); | ||
}); | ||
|
||
it("should initialize UI only once", () => { | ||
ui.initialize(); | ||
ui.initialize(); // Second call should be ignored | ||
expect(render).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should handle output logging correctly", () => { | ||
const consoleSpy = vi.spyOn(process.stdout, "write"); | ||
|
||
// Test without UI initialized | ||
ui.appendOutputLog("test output"); | ||
expect(consoleSpy).toHaveBeenCalledWith("test output"); | ||
|
||
// Initialize UI and test again | ||
ui.initialize(); | ||
ui.appendOutputLog("ui output"); | ||
expect(logStore.getOutput()).toBe("ui output"); | ||
}); | ||
|
||
it("should clean up resources on destroy", () => { | ||
ui.initialize(); | ||
ui.destroy(); | ||
expect(mockUnmount).toHaveBeenCalled(); | ||
}); | ||
|
||
it("should handle SIGINT cleanup", () => { | ||
ui.initialize(); | ||
process.emit("SIGINT"); | ||
expect(mockUnmount).toHaveBeenCalled(); | ||
expect(process.exit).toHaveBeenCalledWith(0); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.