108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
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
|
||
}
|