package executor import ( "testing" "github.com/vladimir/goherence/internal/parser" ) func names(tasks []parser.Task) []string { out := make([]string, len(tasks)) for i, t := range tasks { out[i] = t.Name } return out } func TestOrderTasksNoDepsPreservesOrder(t *testing.T) { tasks := []parser.Task{{Name: "a"}, {Name: "b"}, {Name: "c"}} got, err := orderTasks(tasks) if err != nil { t.Fatal(err) } want := []string{"a", "b", "c"} if got := names(got); !equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestOrderTasksAfterReorders(t *testing.T) { // "b" объявлен раньше "a" в файле, но зависит от него через after — // должен переместиться после "a". tasks := []parser.Task{ {Name: "b", After: []string{"a"}}, {Name: "a"}, {Name: "c"}, } got, err := orderTasks(tasks) if err != nil { t.Fatal(err) } want := []string{"a", "b", "c"} if got := names(got); !equal(got, want) { t.Errorf("got %v, want %v", got, want) } } func TestOrderTasksBefore(t *testing.T) { tasks := []parser.Task{ {Name: "a"}, {Name: "b"}, {Name: "c", Before: []string{"a"}}, } got, err := orderTasks(tasks) if err != nil { t.Fatal(err) } // Единственное жёсткое требование — c должен идти раньше a. // b ничем не связан ни с a, ни с c, так что его позиция относительно // них — вопрос тай-брейка алгоритма (см. комментарий в graph.go), // а не то, что тест должен закреплять как "единственно верное". order := names(got) posA, posC := indexOf(order, "a"), indexOf(order, "c") if posC >= posA { t.Errorf("c должен идти раньше a, получили порядок %v", order) } } func indexOf(s []string, v string) int { for i, x := range s { if x == v { return i } } return -1 } func TestOrderTasksCycleDetected(t *testing.T) { tasks := []parser.Task{ {Name: "a", After: []string{"b"}}, {Name: "b", After: []string{"a"}}, } _, err := orderTasks(tasks) if err == nil { t.Fatal("ожидалась ошибка цикла, получили nil") } } func TestOrderTasksUnknownDependency(t *testing.T) { tasks := []parser.Task{ {Name: "a", After: []string{"nonexistent"}}, } _, err := orderTasks(tasks) if err == nil { t.Fatal("ожидалась ошибка неизвестной зависимости, получили nil") } } func equal(a, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true }