mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
- Add onboarding module for pre-flight checks (Redis, Ollama, model, project) - Implement start command with TUI rendering and dependency injection - Implement init command for .ipuaro.json config file creation - Implement index command for standalone project indexing - Add CLI options: --auto-apply, --model, --help, --version - Register all 18 tools via tools-setup helper - Add 29 unit tests for CLI commands - Update CHANGELOG and ROADMAP for v0.15.0
118 lines
4.1 KiB
TypeScript
118 lines
4.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"
|
|
import * as fs from "node:fs/promises"
|
|
import * as path from "node:path"
|
|
import { executeInit } from "../../../../src/cli/commands/init.js"
|
|
|
|
vi.mock("node:fs/promises")
|
|
|
|
describe("executeInit", () => {
|
|
const testPath = "/test/project"
|
|
const configPath = path.join(testPath, ".ipuaro.json")
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
vi.spyOn(console, "warn").mockImplementation(() => {})
|
|
vi.spyOn(console, "error").mockImplementation(() => {})
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
it("should create .ipuaro.json file successfully", async () => {
|
|
vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"))
|
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
|
|
|
const result = await executeInit(testPath)
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(result.filePath).toBe(configPath)
|
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
|
configPath,
|
|
expect.stringContaining('"redis"'),
|
|
"utf-8",
|
|
)
|
|
})
|
|
|
|
it("should skip existing file without force option", async () => {
|
|
vi.mocked(fs.access).mockResolvedValue(undefined)
|
|
|
|
const result = await executeInit(testPath)
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(result.skipped).toBe(true)
|
|
expect(fs.writeFile).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it("should overwrite existing file with force option", async () => {
|
|
vi.mocked(fs.access).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
|
|
|
const result = await executeInit(testPath, { force: true })
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(result.skipped).toBeUndefined()
|
|
expect(fs.writeFile).toHaveBeenCalled()
|
|
})
|
|
|
|
it("should handle write errors", async () => {
|
|
vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"))
|
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockRejectedValue(new Error("Permission denied"))
|
|
|
|
const result = await executeInit(testPath)
|
|
|
|
expect(result.success).toBe(false)
|
|
expect(result.error).toContain("Permission denied")
|
|
})
|
|
|
|
it("should create parent directories if needed", async () => {
|
|
vi.mocked(fs.access)
|
|
.mockRejectedValueOnce(new Error("ENOENT"))
|
|
.mockRejectedValueOnce(new Error("ENOENT"))
|
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
|
|
|
const result = await executeInit(testPath)
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(fs.mkdir).toHaveBeenCalledWith(expect.any(String), { recursive: true })
|
|
})
|
|
|
|
it("should use current directory as default", async () => {
|
|
vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"))
|
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
|
|
|
const result = await executeInit()
|
|
|
|
expect(result.success).toBe(true)
|
|
expect(result.filePath).toContain(".ipuaro.json")
|
|
})
|
|
|
|
it("should include expected config sections", async () => {
|
|
vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"))
|
|
vi.mocked(fs.mkdir).mockResolvedValue(undefined)
|
|
vi.mocked(fs.writeFile).mockResolvedValue(undefined)
|
|
|
|
await executeInit(testPath)
|
|
|
|
const writeCall = vi.mocked(fs.writeFile).mock.calls[0]
|
|
const content = writeCall[1] as string
|
|
const config = JSON.parse(content) as {
|
|
redis: unknown
|
|
llm: unknown
|
|
edit: unknown
|
|
}
|
|
|
|
expect(config).toHaveProperty("redis")
|
|
expect(config).toHaveProperty("llm")
|
|
expect(config).toHaveProperty("edit")
|
|
expect(config.redis).toHaveProperty("host", "localhost")
|
|
expect(config.redis).toHaveProperty("port", 6379)
|
|
expect(config.llm).toHaveProperty("model", "qwen2.5-coder:7b-instruct")
|
|
expect(config.edit).toHaveProperty("autoApply", false)
|
|
})
|
|
})
|