- Verify() pokreće build, vet, test sa merenjem trajanja - Ako build padne, ostalo se preskače - parseTestCount parsira go test -v output - FormatResult za čitljiv ispis - 10 checker testova — svi prolaze Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
264 lines
5.4 KiB
Go
264 lines
5.4 KiB
Go
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
|
|
}
|