@@ -21,20 +21,22 @@ func (s stringWrapper) String() string {
2121 return s .Value
2222}
2323
24+ type testCase struct {
25+ name string
26+ nodes []string
27+ seen []string
28+ seenSorted []string
29+ edges []edge
30+ returnValues map [string ]bool // node -> false to indicate failure
31+ cycle string
32+ failedFrom map [string ]string // node -> expected failedFrom
33+ failedFromOneOf map [string ][]string // node -> any of these failedFrom values acceptable
34+ }
35+
2436func TestRun_VariousGraphsAndPools (t * testing.T ) {
2537 poolsToRun := []int {1 , 2 , 3 , 4 }
2638
27- tests := []struct {
28- name string
29- nodes []string
30- seen []string
31- seenSorted []string
32- edges []edge
33- returnValues map [string ]bool // node -> false to indicate failure
34- cycle string
35- failedFrom map [string ]string // node -> expected failedFrom
36- failedFromOneOf map [string ][]string // node -> any of these failedFrom values acceptable
37- }{
39+ tests := []testCase {
3840 // disconnected graphs
3941 {
4042 name : "empty graph" ,
@@ -152,63 +154,70 @@ func TestRun_VariousGraphsAndPools(t *testing.T) {
152154 g .AddDirectedEdge (stringWrapper {e .from }, stringWrapper {e .to }, e .name )
153155 }
154156
155- err := g .DetectCycle ()
156- if tc .cycle != "" {
157- require .Error (t , err , "expected cycle, got none" )
158- require .Equal (t , tc .cycle , err .Error ())
159- innerCalled := 0
160- require .Panics (t , func () {
161- g .Run (p , func (n stringWrapper , failed * stringWrapper ) bool {
162- innerCalled += 1
163- return true
164- })
165- })
166- require .Zero (t , innerCalled )
167- return
168- }
169- require .NoError (t , err )
157+ runTestCase (t , tc , g , p )
170158
171- var mu sync.Mutex
172- var seen []string
173- failedFrom := map [string ]* string {}
174- g .Run (p , func (n stringWrapper , failed * stringWrapper ) bool {
175- mu .Lock ()
176- seen = append (seen , n .Value )
177- if failed != nil {
178- v := failed .Value
179- failedFrom [n .Value ] = & v
180- } else {
181- failedFrom [n .Value ] = nil
182- }
183- mu .Unlock ()
184- if stop , exists := tc .returnValues [n .Value ]; exists {
185- return stop
186- }
187- return true // success by default
188- })
189-
190- if tc .seen != nil {
191- assert .Equal (t , tc .seen , seen )
192- } else if tc .seenSorted != nil {
193- sort .Strings (seen )
194- assert .Equal (t , tc .seenSorted , seen )
195- } else {
196- assert .Empty (t , seen )
197- }
159+ // graph should be usable for multiple runs:
160+ runTestCase (t , tc , g , p )
161+ })
162+ }
163+ }
164+ }
198165
199- for node , want := range tc .failedFrom {
200- gotPtr := failedFrom [node ]
201- if assert .NotNil (t , gotPtr , "expected failedFrom for %s" , node ) {
202- assert .Equal (t , want , * gotPtr )
203- }
204- }
205- for node , oneOf := range tc .failedFromOneOf {
206- gotPtr := failedFrom [node ]
207- if assert .NotNil (t , gotPtr , "expected failedFrom for %s" , node ) {
208- assert .True (t , slices .Contains (oneOf , * gotPtr ), "failedFrom for %s not in %v, got %v" , node , oneOf , * gotPtr )
209- }
210- }
166+ func runTestCase (t * testing.T , tc testCase , g * Graph [stringWrapper ], p int ) {
167+ err := g .DetectCycle ()
168+ if tc .cycle != "" {
169+ require .Error (t , err , "expected cycle, got none" )
170+ require .Equal (t , tc .cycle , err .Error ())
171+ innerCalled := 0
172+ require .Panics (t , func () {
173+ g .Run (p , func (n stringWrapper , failed * stringWrapper ) bool {
174+ innerCalled += 1
175+ return true
211176 })
177+ })
178+ require .Zero (t , innerCalled )
179+ return
180+ }
181+ require .NoError (t , err )
182+
183+ var mu sync.Mutex
184+ var seen []string
185+ failedFrom := map [string ]* string {}
186+ g .Run (p , func (n stringWrapper , failed * stringWrapper ) bool {
187+ mu .Lock ()
188+ seen = append (seen , n .Value )
189+ if failed != nil {
190+ v := failed .Value
191+ failedFrom [n .Value ] = & v
192+ } else {
193+ failedFrom [n .Value ] = nil
194+ }
195+ mu .Unlock ()
196+ if stop , exists := tc .returnValues [n .Value ]; exists {
197+ return stop
198+ }
199+ return true // success by default
200+ })
201+
202+ if tc .seen != nil {
203+ assert .Equal (t , tc .seen , seen )
204+ } else if tc .seenSorted != nil {
205+ sort .Strings (seen )
206+ assert .Equal (t , tc .seenSorted , seen )
207+ } else {
208+ assert .Empty (t , seen )
209+ }
210+
211+ for node , want := range tc .failedFrom {
212+ gotPtr := failedFrom [node ]
213+ if assert .NotNil (t , gotPtr , "expected failedFrom for %s" , node ) {
214+ assert .Equal (t , want , * gotPtr )
215+ }
216+ }
217+ for node , oneOf := range tc .failedFromOneOf {
218+ gotPtr := failedFrom [node ]
219+ if assert .NotNil (t , gotPtr , "expected failedFrom for %s" , node ) {
220+ assert .True (t , slices .Contains (oneOf , * gotPtr ), "failedFrom for %s not in %v, got %v" , node , oneOf , * gotPtr )
212221 }
213222 }
214223}
0 commit comments