package supervisor import ( "os" "path/filepath" "testing" ) // setupTempGoProject creates a minimal Go project in a temp directory. func setupTempGoProject(t *testing.T, mainContent, testContent string) string { t.Helper() dir := t.TempDir() // go.mod goMod := "module tempproject\n\ngo 1.22\n" if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(goMod), 0644); err != nil { t.Fatalf("write go.mod: %v", err) } // main.go if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(mainContent), 0644); err != nil { t.Fatalf("write main.go: %v", err) } // test file (optional) if testContent != "" { if err := os.WriteFile(filepath.Join(dir, "main_test.go"), []byte(testContent), 0644); err != nil { t.Fatalf("write main_test.go: %v", err) } } return dir } func TestVerify_PassingProject(t *testing.T) { mainGo := `package main import "fmt" func main() { fmt.Println("hello") } func Add(a, b int) int { return a + b } ` testGo := `package main import "testing" func TestAdd(t *testing.T) { if Add(1, 2) != 3 { t.Fatal("expected 3") } } func TestAddZero(t *testing.T) { if Add(0, 0) != 0 { t.Fatal("expected 0") } } ` dir := setupTempGoProject(t, mainGo, testGo) result := Verify(dir) if !result.AllPassed { t.Errorf("expected AllPassed=true\nBuild: %s %s\nVet: %s %s\nTest: %s %s", result.Build.Status, result.Build.Output, result.Vet.Status, result.Vet.Output, result.Test.Status, result.Test.Output) } if result.Build.Status != "pass" { t.Errorf("expected build pass, got %s", result.Build.Status) } if result.Vet.Status != "pass" { t.Errorf("expected vet pass, got %s", result.Vet.Status) } if result.Test.Status != "pass" { t.Errorf("expected test pass, got %s", result.Test.Status) } if result.Test.TestCount != 2 { t.Errorf("expected 2 tests, got %d", result.Test.TestCount) } } func TestVerify_BuildFail(t *testing.T) { badGo := `package main func main() { this is not valid go code } ` dir := setupTempGoProject(t, badGo, "") result := Verify(dir) if result.AllPassed { t.Error("expected AllPassed=false") } if result.Build.Status != "fail" { t.Errorf("expected build fail, got %s", result.Build.Status) } // Vet and test should be skipped if result.Vet.Status != "fail" { t.Errorf("expected vet fail (skipped), got %s", result.Vet.Status) } if result.Test.Status != "fail" { t.Errorf("expected test fail (skipped), got %s", result.Test.Status) } } func TestVerify_TestFail(t *testing.T) { mainGo := `package main func main() {} func Broken() int { return 42 } ` testGo := `package main import "testing" func TestBroken(t *testing.T) { if Broken() != 99 { t.Fatal("expected 99") } } ` dir := setupTempGoProject(t, mainGo, testGo) result := Verify(dir) if result.AllPassed { t.Error("expected AllPassed=false") } if result.Build.Status != "pass" { t.Errorf("expected build pass, got %s", result.Build.Status) } if result.Test.Status != "fail" { t.Errorf("expected test fail, got %s", result.Test.Status) } } func TestVerify_Duration(t *testing.T) { mainGo := `package main func main() {} ` dir := setupTempGoProject(t, mainGo, "") result := Verify(dir) if result.Build.Duration <= 0 { t.Error("expected build duration > 0") } if result.Vet.Duration <= 0 { t.Error("expected vet duration > 0") } if result.Test.Duration <= 0 { t.Error("expected test duration > 0") } } func TestVerify_OutputPopulated(t *testing.T) { mainGo := `package main func main() {} ` testGo := `package main import "testing" func TestNothing(t *testing.T) {} ` dir := setupTempGoProject(t, mainGo, testGo) result := Verify(dir) // Test output should contain test results if result.Test.Output == "" { t.Error("expected non-empty test output") } } func TestParseTestCount_PassingTests(t *testing.T) { output := `=== RUN TestAdd --- PASS: TestAdd (0.00s) === RUN TestSub --- PASS: TestSub (0.00s) PASS ok github.com/dal/kaos 0.003s ` count := parseTestCount(output) if count != 2 { t.Errorf("expected 2, got %d", count) } } func TestParseTestCount_MixedResults(t *testing.T) { output := `=== RUN TestGood --- PASS: TestGood (0.00s) === RUN TestBad --- FAIL: TestBad (0.00s) FAIL ` count := parseTestCount(output) if count != 2 { t.Errorf("expected 2, got %d", count) } } func TestParseTestCount_NoTests(t *testing.T) { output := "FAIL\n" count := parseTestCount(output) if count != 0 { t.Errorf("expected 0, got %d", count) } } func TestParseTestCount_Empty(t *testing.T) { count := parseTestCount("") if count != 0 { t.Errorf("expected 0, got %d", count) } } func TestFormatResult(t *testing.T) { result := VerifyResult{ Build: CheckResult{Name: "build", Status: "pass"}, Vet: CheckResult{Name: "vet", Status: "pass"}, Test: CheckResult{Name: "test", Status: "pass", TestCount: 5}, AllPassed: true, } out := FormatResult(result) if out == "" { t.Error("expected non-empty format output") } if !contains(out, "All checks passed") { t.Errorf("expected 'All checks passed' in output, got: %s", out) } if !contains(out, "5 tests") { t.Errorf("expected '5 tests' in output, got: %s", out) } } func contains(s, substr string) bool { return len(s) >= len(substr) && searchString(s, substr) } func searchString(s, substr string) bool { for i := 0; i <= len(s)-len(substr); i++ { if s[i:i+len(substr)] == substr { return true } } return false }