github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/pkg/model/target_test.go (about) 1 package model 2 3 import ( 4 "fmt" 5 "path" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 10 "github.com/tilt-dev/tilt/internal/container" 11 ) 12 13 type topSortCase struct { 14 inputs []TargetSpec 15 outputs []string 16 err string 17 } 18 19 func TestTopSort(t *testing.T) { 20 cases := []topSortCase{ 21 topSortCase{ 22 inputs: []TargetSpec{newDepTarget("a", "b")}, 23 err: "Missing target dependency: b", 24 }, 25 topSortCase{ 26 inputs: []TargetSpec{ 27 newDepTarget("a", "b"), 28 newDepTarget("b", "a"), 29 }, 30 err: "Found a cycle at target: a", 31 }, 32 topSortCase{ 33 inputs: []TargetSpec{ 34 newDepTarget("a", "b"), 35 newDepTarget("b", "c"), 36 newDepTarget("c", "a"), 37 }, 38 err: "Found a cycle at target: a", 39 }, 40 topSortCase{ 41 inputs: []TargetSpec{ 42 newDepTarget("a", "b"), 43 newDepTarget("b", "c"), 44 newDepTarget("c"), 45 }, 46 outputs: []string{"c", "b", "a"}, 47 }, 48 topSortCase{ 49 inputs: []TargetSpec{ 50 newDepTarget("a", "b", "d"), 51 newDepTarget("b", "d"), 52 newDepTarget("c", "d"), 53 newDepTarget("d"), 54 }, 55 outputs: []string{"d", "b", "a", "c"}, 56 }, 57 topSortCase{ 58 inputs: []TargetSpec{ 59 newDepTarget("a", "b", "d"), 60 newDepTarget("c", "d"), 61 newDepTarget("b", "d"), 62 newDepTarget("d"), 63 }, 64 outputs: []string{"d", "b", "a", "c"}, 65 }, 66 topSortCase{ 67 inputs: []TargetSpec{ 68 newDepTarget("c", "d"), 69 newDepTarget("b", "d"), 70 newDepTarget("a", "b", "d"), 71 newDepTarget("d"), 72 }, 73 outputs: []string{"d", "c", "b", "a"}, 74 }, 75 } 76 77 for i, c := range cases { 78 t.Run(fmt.Sprintf("TopSort%d", i), func(t *testing.T) { 79 sorted, err := TopologicalSort(c.inputs) 80 if err != nil { 81 if c.err == "" { 82 t.Fatalf("Unexpected error: %v", err) 83 return 84 } 85 86 assert.Contains(t, err.Error(), c.err) 87 return 88 } 89 90 if c.err != "" { 91 t.Fatalf("Expected error: %s. Actual nil", c.err) 92 } 93 94 sortedIDs := make([]string, len(sorted)) 95 for i, t := range sorted { 96 sortedIDs[i] = path.Base(t.ID().Name.String()) 97 } 98 assert.Equal(t, c.outputs, sortedIDs) 99 }) 100 } 101 } 102 103 func newDepTarget(name string, deps ...string) ImageTarget { 104 ref := container.MustParseSelector(name) 105 depIDs := make([]string, len(deps)) 106 for i, dep := range deps { 107 depIDs[i] = string(ImageID(container.MustParseSelector(dep)).Name) 108 } 109 return MustNewImageTarget(ref). 110 WithBuildDetails(DockerBuild{}). 111 WithImageMapDeps(depIDs) 112 } 113 114 func newK8sTarget(name string, deps ...string) K8sTarget { 115 depIDs := make([]string, len(deps)) 116 for i, dep := range deps { 117 depIDs[i] = string(ImageID(container.MustParseSelector(dep)).Name) 118 } 119 return K8sTarget{Name: TargetName(name)}.WithImageDependencies(depIDs) 120 }