feat(engine): add topological sort and descendants for module DAG
This commit is contained in:
79
internal/engine/dag_test.go
Normal file
79
internal/engine/dag_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/MDietermann/ArduinoArchSetup/internal/module"
|
||||
)
|
||||
|
||||
func TestTopoSort(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
metas []module.Meta
|
||||
want []string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "linear chain",
|
||||
metas: []module.Meta{{ID: "a"}, {ID: "b", Deps: []string{"a"}}, {ID: "c", Deps: []string{"b"}}},
|
||||
want: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
name: "independent modules sorted alphabetically",
|
||||
metas: []module.Meta{{ID: "c"}, {ID: "a"}, {ID: "b"}},
|
||||
want: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
name: "diamond",
|
||||
metas: []module.Meta{{ID: "a"}, {ID: "b", Deps: []string{"a"}}, {ID: "c", Deps: []string{"a"}}, {ID: "d", Deps: []string{"b", "c"}}},
|
||||
want: []string{"a", "b", "c", "d"},
|
||||
},
|
||||
{
|
||||
name: "unknown dep",
|
||||
metas: []module.Meta{{ID: "a", Deps: []string{"missing"}}},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "cycle",
|
||||
metas: []module.Meta{{ID: "a", Deps: []string{"b"}}, {ID: "b", Deps: []string{"a"}}},
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, err := TopoSort(tc.metas)
|
||||
if tc.err {
|
||||
if err == nil {
|
||||
t.Fatalf("want error, got nil (order=%v)", got)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Fatalf("order = %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescendants(t *testing.T) {
|
||||
metas := []module.Meta{
|
||||
{ID: "a"},
|
||||
{ID: "b", Deps: []string{"a"}},
|
||||
{ID: "c", Deps: []string{"a"}},
|
||||
{ID: "d", Deps: []string{"b"}},
|
||||
{ID: "e"}, // independent
|
||||
}
|
||||
got := Descendants(metas, "a")
|
||||
want := map[string]bool{"b": true, "c": true, "d": true}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("descendants(a) = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
if len(Descendants(metas, "e")) != 0 {
|
||||
t.Fatalf("descendants(e) should be empty")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user