package supervisor import ( "os" "path/filepath" "strings" "testing" "time" ) func makeTestData(allPassed bool) (Task, RunResult, VerifyResult) { task := Task{ ID: "T07", Title: "Test feature", Agent: "coder", Model: "Sonnet", Description: "Implement test feature.", } run := RunResult{ TaskID: "T07", StartedAt: time.Date(2026, 2, 20, 10, 15, 0, 0, time.UTC), FinishedAt: time.Date(2026, 2, 20, 10, 23, 45, 0, time.UTC), Duration: 8*time.Minute + 45*time.Second, ExitCode: 0, Output: "Task completed successfully.\nAll tests passed.", } verify := VerifyResult{ Build: CheckResult{ Name: "build", Status: "pass", Duration: 300 * time.Millisecond, }, Vet: CheckResult{ Name: "vet", Status: "pass", Duration: 200 * time.Millisecond, }, Test: CheckResult{ Name: "test", Status: "pass", Duration: 2100 * time.Millisecond, TestCount: 12, }, AllPassed: allPassed, } if !allPassed { verify.Test.Status = "fail" run.ExitCode = 1 } return task, run, verify } func TestWriteReport_CreatesFile(t *testing.T) { dir := t.TempDir() reportsDir := filepath.Join(dir, "reports") task, run, verify := makeTestData(true) path, err := WriteReport(task, run, verify, reportsDir) if err != nil { t.Fatalf("unexpected error: %v", err) } if _, err := os.Stat(path); err != nil { t.Fatalf("report file not found: %v", err) } expectedFilename := "T07-report.md" if filepath.Base(path) != expectedFilename { t.Errorf("expected filename %s, got %s", expectedFilename, filepath.Base(path)) } } func TestWriteReport_Content(t *testing.T) { dir := t.TempDir() task, run, verify := makeTestData(true) path, err := WriteReport(task, run, verify, dir) if err != nil { t.Fatalf("unexpected error: %v", err) } data, err := os.ReadFile(path) if err != nil { t.Fatalf("read report: %v", err) } content := string(data) checks := []struct { name string substr string }{ {"header", "# T07: Test feature"}, {"date format", "2026-02-20 10:15"}, {"duration", "8m 45s"}, {"status passed", "✅ Završen"}, {"build check", "✅ build"}, {"vet check", "✅ vet"}, {"test count", "12 testova"}, {"agent output section", "## Agent output"}, {"output content", "Task completed successfully"}, } for _, c := range checks { if !strings.Contains(content, c.substr) { t.Errorf("%s: expected %q in report, got:\n%s", c.name, c.substr, content) } } } func TestWriteReport_FailedStatus(t *testing.T) { dir := t.TempDir() task, run, verify := makeTestData(false) path, err := WriteReport(task, run, verify, dir) if err != nil { t.Fatalf("unexpected error: %v", err) } data, _ := os.ReadFile(path) content := string(data) if !strings.Contains(content, "❌ Neuspešan") { t.Errorf("expected '❌ Neuspešan' in report, got:\n%s", content) } if !strings.Contains(content, "❌ test") { t.Errorf("expected '❌ test' in report, got:\n%s", content) } } func TestWriteReport_CreatesDirectory(t *testing.T) { dir := t.TempDir() reportsDir := filepath.Join(dir, "deep", "nested", "reports") task, run, verify := makeTestData(true) path, err := WriteReport(task, run, verify, reportsDir) if err != nil { t.Fatalf("unexpected error: %v", err) } if _, err := os.Stat(path); err != nil { t.Fatalf("report file not found: %v", err) } } func TestTruncateOutput_Short(t *testing.T) { output := "line1\nline2\nline3\n" result := truncateOutput(output, 50) if strings.Contains(result, "skraćeno") { t.Error("should not truncate short output") } if !strings.Contains(result, "line1") { t.Error("expected all lines present") } } func TestTruncateOutput_Long(t *testing.T) { var lines []string for i := 1; i <= 80; i++ { lines = append(lines, "line "+string(rune('0'+i/10))+string(rune('0'+i%10))) } output := strings.Join(lines, "\n") result := truncateOutput(output, 50) if !strings.Contains(result, "skraćeno") { t.Error("expected truncation marker") } if !strings.Contains(result, "poslednjih 50 od 80") { t.Errorf("expected 'poslednjih 50 od 80' in: %s", result) } // First lines should be gone if strings.Contains(result, "line 01") { t.Error("expected first lines to be removed") } } func TestTruncateOutput_Empty(t *testing.T) { result := truncateOutput("", 50) if !strings.Contains(result, "nema outputa") { t.Errorf("expected 'nema outputa', got: %s", result) } } func TestFormatDuration_Minutes(t *testing.T) { d := 8*time.Minute + 45*time.Second result := formatDuration(d) if result != "8m 45s" { t.Errorf("expected '8m 45s', got %q", result) } } func TestFormatDuration_SecondsOnly(t *testing.T) { d := 45 * time.Second result := formatDuration(d) if result != "45s" { t.Errorf("expected '45s', got %q", result) } } func TestFormatDuration_Zero(t *testing.T) { result := formatDuration(0) if result != "0s" { t.Errorf("expected '0s', got %q", result) } }