github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/utils/sort_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2021-Present The Jackal Authors 3 4 // Package utils provides generic utility functions. 5 package utils 6 7 import ( 8 "reflect" 9 "testing" 10 11 "github.com/stretchr/testify/require" 12 ) 13 14 type TestDependency struct { 15 name string 16 dependencies []string 17 } 18 19 func (t TestDependency) Name() string { 20 return t.name 21 } 22 23 func (t TestDependency) Dependencies() []string { 24 return t.dependencies 25 } 26 27 func TestSortDependencies(t *testing.T) { 28 tests := []struct { 29 name string 30 data []TestDependency // input data: a map of nodes to their dependencies 31 expected []string // expected output: a slice of nodes in order of their precedence 32 success bool // whether the test should succeed or fail 33 }{ 34 { 35 name: "simple graph", 36 data: []TestDependency{ 37 { 38 name: "A", 39 dependencies: []string{"B", "C"}, 40 }, 41 { 42 name: "B", 43 dependencies: []string{"C"}, 44 }, 45 { 46 name: "C", 47 }, 48 }, 49 // C has no dependencies, B depends on C, and A depends on both B and C 50 expected: []string{"C", "B", "A"}, 51 success: true, 52 }, 53 { 54 name: "complex graph", 55 data: []TestDependency{ 56 { 57 name: "A", 58 dependencies: []string{"B", "C", "D"}, 59 }, 60 { 61 name: "B", 62 dependencies: []string{"C", "D", "E"}, 63 }, 64 { 65 name: "C", 66 dependencies: []string{"E"}, 67 }, 68 { 69 name: "D", 70 dependencies: []string{"E"}, 71 }, 72 { 73 name: "E", 74 }, 75 }, 76 expected: []string{"E", "D", "C", "B", "A"}, 77 success: true, 78 }, 79 { 80 name: "graph with multiple roots", 81 data: []TestDependency{ 82 { 83 name: "A", 84 }, 85 { 86 name: "B", 87 }, 88 { 89 name: "C", 90 dependencies: []string{"A", "B"}, 91 }, 92 { 93 name: "D", 94 dependencies: []string{"C", "E"}, 95 }, 96 { 97 name: "E", 98 dependencies: []string{"F"}, 99 }, 100 { 101 name: "F", 102 }, 103 }, 104 expected: []string{"F", "B", "A", "E", "C", "D"}, 105 success: true, 106 }, 107 { 108 name: "graph with multiple sinks", 109 data: []TestDependency{ 110 { 111 name: "A", 112 dependencies: []string{"B"}, 113 }, 114 { 115 name: "B", 116 dependencies: []string{"C"}, 117 }, 118 { 119 name: "C", 120 }, 121 { 122 name: "D", 123 dependencies: []string{"E"}, 124 }, 125 { 126 name: "E", 127 dependencies: []string{"F"}, 128 }, 129 { 130 name: "F", 131 }, 132 { 133 name: "G", 134 }, 135 }, 136 expected: []string{"F", "C", "E", "B", "G", "D", "A"}, 137 success: true, 138 }, 139 { 140 name: "graph with circular dependencies", 141 data: []TestDependency{ 142 { 143 name: "A", 144 dependencies: []string{"B"}, 145 }, 146 { 147 name: "B", 148 dependencies: []string{"C"}, 149 }, 150 { 151 name: "C", 152 dependencies: []string{"A"}, 153 }, 154 }, 155 expected: []string{}, 156 success: false, 157 }, 158 } 159 160 for _, tt := range tests { 161 t.Run(tt.name, func(t *testing.T) { 162 deps := make([]Dependency, len(tt.data)) 163 for i := range tt.data { 164 deps[i] = tt.data[i] 165 } 166 result, err := SortDependencies(deps) 167 if tt.success { 168 require.NoError(t, err) 169 } else { 170 require.Error(t, err) 171 } 172 if !reflect.DeepEqual(result, tt.expected) { 173 t.Errorf("expected %v but got %v", tt.expected, result) 174 } 175 }) 176 } 177 }