From 2e2b2187b957e9af78797a67ec5c6874615fae02 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sun, 8 Feb 2026 21:35:45 -1000 Subject: Initial project: task model, executor, API server, CLI, storage, reporter Claudomator automation toolkit for Claude Code with: - Task model with YAML parsing, validation, state machine (49 tests, 0 races) - SQLite storage for tasks and executions - Executor pool with bounded concurrency, timeout, cancellation - REST API + WebSocket for mobile PWA integration - Webhook/multi-notifier system - CLI: init, run, serve, list, status commands - Console, JSON, HTML reporters with cost tracking Co-Authored-By: Claude Opus 4.6 --- internal/executor/claude_test.go | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 internal/executor/claude_test.go (limited to 'internal/executor/claude_test.go') diff --git a/internal/executor/claude_test.go b/internal/executor/claude_test.go new file mode 100644 index 0000000..448ab40 --- /dev/null +++ b/internal/executor/claude_test.go @@ -0,0 +1,84 @@ +package executor + +import ( + "testing" + + "github.com/claudomator/claudomator/internal/task" +) + +func TestClaudeRunner_BuildArgs_BasicTask(t *testing.T) { + r := &ClaudeRunner{} + tk := &task.Task{ + Claude: task.ClaudeConfig{ + Instructions: "fix the bug", + Model: "sonnet", + }, + } + + args := r.buildArgs(tk) + + expected := []string{"-p", "fix the bug", "--output-format", "stream-json", "--model", "sonnet"} + if len(args) != len(expected) { + t.Fatalf("args length: want %d, got %d: %v", len(expected), len(args), args) + } + for i, want := range expected { + if args[i] != want { + t.Errorf("arg[%d]: want %q, got %q", i, want, args[i]) + } + } +} + +func TestClaudeRunner_BuildArgs_FullConfig(t *testing.T) { + r := &ClaudeRunner{} + tk := &task.Task{ + Claude: task.ClaudeConfig{ + Instructions: "implement feature", + Model: "opus", + MaxBudgetUSD: 5.0, + PermissionMode: "bypassPermissions", + SystemPromptAppend: "Follow TDD", + AllowedTools: []string{"Bash", "Edit"}, + DisallowedTools: []string{"Write"}, + ContextFiles: []string{"/src"}, + AdditionalArgs: []string{"--verbose"}, + }, + } + + args := r.buildArgs(tk) + + // Check key args are present. + argMap := make(map[string]bool) + for _, a := range args { + argMap[a] = true + } + + requiredArgs := []string{ + "-p", "implement feature", "--output-format", "stream-json", + "--model", "opus", "--max-budget-usd", "5.00", + "--permission-mode", "bypassPermissions", + "--append-system-prompt", "Follow TDD", + "--allowedTools", "Bash", "Edit", + "--disallowedTools", "Write", + "--add-dir", "/src", + "--verbose", + } + for _, req := range requiredArgs { + if !argMap[req] { + t.Errorf("missing arg %q in %v", req, args) + } + } +} + +func TestClaudeRunner_BinaryPath_Default(t *testing.T) { + r := &ClaudeRunner{} + if r.binaryPath() != "claude" { + t.Errorf("want 'claude', got %q", r.binaryPath()) + } +} + +func TestClaudeRunner_BinaryPath_Custom(t *testing.T) { + r := &ClaudeRunner{BinaryPath: "/usr/local/bin/claude"} + if r.binaryPath() != "/usr/local/bin/claude" { + t.Errorf("want custom path, got %q", r.binaryPath()) + } +} -- cgit v1.2.3