/ go / test / cli_test.go
cli_test.go
  1  package test
  2  
  3  import (
  4  	"bytes"
  5  	"context"
  6  	"os"
  7  	"os/exec"
  8  	"strings"
  9  	"testing"
 10  	"time"
 11  )
 12  
 13  func TestCLICommands(t *testing.T) {
 14  	// Build the CLI first
 15  	buildCLI(t)
 16  	
 17  	t.Run("Help", testCLIHelp)
 18  	t.Run("Config", testCLIConfig)
 19  	t.Run("Tasks", testCLITasks)
 20  	t.Run("Ask", testCLIAsk)
 21  }
 22  
 23  func buildCLI(t *testing.T) {
 24  	cmd := exec.Command("go", "build", "-o", "bin/kamaji-test", "./cmd/kamaji")
 25  	cmd.Dir = "/home/tao/kamaji/go"
 26  	
 27  	if err := cmd.Run(); err != nil {
 28  		t.Fatalf("Failed to build CLI: %v", err)
 29  	}
 30  }
 31  
 32  func testCLIHelp(t *testing.T) {
 33  	cmd := exec.Command("./bin/kamaji-test", "--help")
 34  	cmd.Dir = "/home/tao/kamaji/go"
 35  	
 36  	output, err := cmd.Output()
 37  	if err != nil {
 38  		t.Fatalf("Help command failed: %v", err)
 39  	}
 40  	
 41  	outputStr := string(output)
 42  	expectedCommands := []string{"agent", "ask", "chat", "config", "tasks"}
 43  	
 44  	for _, expected := range expectedCommands {
 45  		if !strings.Contains(outputStr, expected) {
 46  			t.Errorf("Help output missing command: %s", expected)
 47  		}
 48  	}
 49  }
 50  
 51  func testCLIConfig(t *testing.T) {
 52  	cmd := exec.Command("./bin/kamaji-test", "config")
 53  	cmd.Dir = "/home/tao/kamaji/go"
 54  	
 55  	output, err := cmd.Output()
 56  	if err != nil {
 57  		t.Fatalf("Config command failed: %v", err)
 58  	}
 59  	
 60  	outputStr := string(output)
 61  	expectedFields := []string{"Provider:", "Model:", "Temperature:"}
 62  	
 63  	for _, expected := range expectedFields {
 64  		if !strings.Contains(outputStr, expected) {
 65  			t.Errorf("Config output missing field: %s", expected)
 66  		}
 67  	}
 68  }
 69  
 70  func testCLITasks(t *testing.T) {
 71  	// Clear any existing tasks
 72  	os.Remove(os.ExpandEnv("$HOME/.kamaji/tasks.json"))
 73  	
 74  	// Test empty tasks
 75  	cmd := exec.Command("./bin/kamaji-test", "tasks")
 76  	cmd.Dir = "/home/tao/kamaji/go"
 77  	
 78  	output, err := cmd.Output()
 79  	if err != nil {
 80  		t.Fatalf("Tasks command failed: %v", err)
 81  	}
 82  	
 83  	if !strings.Contains(string(output), "No tasks") {
 84  		t.Error("Expected 'No tasks' message for empty task list")
 85  	}
 86  	
 87  	// Add a task
 88  	cmd = exec.Command("./bin/kamaji-test", "queue", "Test task")
 89  	cmd.Dir = "/home/tao/kamaji/go"
 90  	
 91  	output, err = cmd.Output()
 92  	if err != nil {
 93  		t.Fatalf("Queue command failed: %v", err)
 94  	}
 95  	
 96  	if !strings.Contains(string(output), "Added task") {
 97  		t.Error("Expected 'Added task' message")
 98  	}
 99  	
100  	// List tasks
101  	cmd = exec.Command("./bin/kamaji-test", "tasks")
102  	cmd.Dir = "/home/tao/kamaji/go"
103  	
104  	output, err = cmd.Output()
105  	if err != nil {
106  		t.Fatalf("Tasks command failed: %v", err)
107  	}
108  	
109  	if !strings.Contains(string(output), "Test task") {
110  		t.Error("Expected to see 'Test task' in task list")
111  	}
112  }
113  
114  func testCLIAsk(t *testing.T) {
115  	// This will fail due to no LLM server, but should show proper error handling
116  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
117  	defer cancel()
118  	
119  	cmd := exec.CommandContext(ctx, "./bin/kamaji-test", "ask", "What is 2+2?")
120  	cmd.Dir = "/home/tao/kamaji/go"
121  	
122  	var stderr bytes.Buffer
123  	cmd.Stderr = &stderr
124  	
125  	// We expect this to fail due to no Ollama server
126  	err := cmd.Run()
127  	if err == nil {
128  		t.Log("Ask command succeeded (unexpected but not an error)")
129  		return
130  	}
131  	
132  	// Check that it fails gracefully with a proper error message
133  	stderrStr := stderr.String()
134  	if !strings.Contains(stderrStr, "failed") && !strings.Contains(stderrStr, "Error") {
135  		t.Errorf("Expected proper error message, got: %s", stderrStr)
136  	}
137  }
138  
139  // Integration test with timeout
140  func TestCLIIntegration(t *testing.T) {
141  	if testing.Short() {
142  		t.Skip("Skipping integration test in short mode")
143  	}
144  	
145  	buildCLI(t)
146  	
147  	// Test command chaining
148  	t.Run("TaskWorkflow", func(t *testing.T) {
149  		// Clear tasks
150  		os.Remove(os.ExpandEnv("$HOME/.kamaji/tasks.json"))
151  		
152  		// Add multiple tasks
153  		tasks := []string{"Task 1", "Task 2", "Task 3"}
154  		for _, task := range tasks {
155  			cmd := exec.Command("./bin/kamaji-test", "queue", task)
156  			cmd.Dir = "/home/tao/kamaji/go"
157  			
158  			if err := cmd.Run(); err != nil {
159  				t.Fatalf("Failed to add task '%s': %v", task, err)
160  			}
161  		}
162  		
163  		// Verify all tasks are listed
164  		cmd := exec.Command("./bin/kamaji-test", "tasks")
165  		cmd.Dir = "/home/tao/kamaji/go"
166  		
167  		output, err := cmd.Output()
168  		if err != nil {
169  			t.Fatalf("Failed to list tasks: %v", err)
170  		}
171  		
172  		outputStr := string(output)
173  		for _, task := range tasks {
174  			if !strings.Contains(outputStr, task) {
175  				t.Errorf("Task '%s' not found in output", task)
176  			}
177  		}
178  	})
179  }
180  
181  // Performance test
182  func TestCLIPerformance(t *testing.T) {
183  	buildCLI(t)
184  	
185  	// Test startup time
186  	start := time.Now()
187  	cmd := exec.Command("./bin/kamaji-test", "--help")
188  	cmd.Dir = "/home/tao/kamaji/go"
189  	
190  	err := cmd.Run()
191  	duration := time.Since(start)
192  	
193  	if err != nil {
194  		t.Fatalf("Help command failed: %v", err)
195  	}
196  	
197  	// Should start up in less than 1 second
198  	if duration > time.Second {
199  		t.Errorf("CLI startup too slow: %v", duration)
200  	}
201  	
202  	t.Logf("CLI startup time: %v", duration)
203  }