github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/dag/graph_test.go (about) 1 package dag 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 ) 8 9 func TestGraph_empty(t *testing.T) { 10 var g Graph 11 g.Add(1) 12 g.Add(2) 13 g.Add(3) 14 15 actual := strings.TrimSpace(g.String()) 16 expected := strings.TrimSpace(testGraphEmptyStr) 17 if actual != expected { 18 t.Fatalf("bad: %s", actual) 19 } 20 } 21 22 func TestGraph_basic(t *testing.T) { 23 var g Graph 24 g.Add(1) 25 g.Add(2) 26 g.Add(3) 27 g.Connect(BasicEdge(1, 3)) 28 29 actual := strings.TrimSpace(g.String()) 30 expected := strings.TrimSpace(testGraphBasicStr) 31 if actual != expected { 32 t.Fatalf("bad: %s", actual) 33 } 34 } 35 36 func TestGraph_remove(t *testing.T) { 37 var g Graph 38 g.Add(1) 39 g.Add(2) 40 g.Add(3) 41 g.Connect(BasicEdge(1, 3)) 42 g.Remove(3) 43 44 actual := strings.TrimSpace(g.String()) 45 expected := strings.TrimSpace(testGraphRemoveStr) 46 if actual != expected { 47 t.Fatalf("bad: %s", actual) 48 } 49 } 50 51 func TestGraph_replace(t *testing.T) { 52 var g Graph 53 g.Add(1) 54 g.Add(2) 55 g.Add(3) 56 g.Connect(BasicEdge(1, 2)) 57 g.Connect(BasicEdge(2, 3)) 58 g.Replace(2, 42) 59 60 actual := strings.TrimSpace(g.String()) 61 expected := strings.TrimSpace(testGraphReplaceStr) 62 if actual != expected { 63 t.Fatalf("bad: %s", actual) 64 } 65 } 66 67 func TestGraph_replaceSelf(t *testing.T) { 68 var g Graph 69 g.Add(1) 70 g.Add(2) 71 g.Add(3) 72 g.Connect(BasicEdge(1, 2)) 73 g.Connect(BasicEdge(2, 3)) 74 g.Replace(2, 2) 75 76 actual := strings.TrimSpace(g.String()) 77 expected := strings.TrimSpace(testGraphReplaceSelfStr) 78 if actual != expected { 79 t.Fatalf("bad: %s", actual) 80 } 81 } 82 83 // This tests that connecting edges works based on custom Hashcode 84 // implementations for uniqueness. 85 func TestGraph_hashcode(t *testing.T) { 86 var g Graph 87 g.Add(&hashVertex{code: 1}) 88 g.Add(&hashVertex{code: 2}) 89 g.Add(&hashVertex{code: 3}) 90 g.Connect(BasicEdge( 91 &hashVertex{code: 1}, 92 &hashVertex{code: 3})) 93 94 actual := strings.TrimSpace(g.String()) 95 expected := strings.TrimSpace(testGraphBasicStr) 96 if actual != expected { 97 t.Fatalf("bad: %s", actual) 98 } 99 } 100 101 func TestGraphHasVertex(t *testing.T) { 102 var g Graph 103 g.Add(1) 104 105 if !g.HasVertex(1) { 106 t.Fatal("should have 1") 107 } 108 if g.HasVertex(2) { 109 t.Fatal("should not have 2") 110 } 111 } 112 113 func TestGraphHasEdge(t *testing.T) { 114 var g Graph 115 g.Add(1) 116 g.Add(2) 117 g.Connect(BasicEdge(1, 2)) 118 119 if !g.HasEdge(BasicEdge(1, 2)) { 120 t.Fatal("should have 1,2") 121 } 122 if g.HasVertex(BasicEdge(2, 3)) { 123 t.Fatal("should not have 2,3") 124 } 125 } 126 127 func TestGraphEdgesFrom(t *testing.T) { 128 var g Graph 129 g.Add(1) 130 g.Add(2) 131 g.Add(3) 132 g.Connect(BasicEdge(1, 3)) 133 g.Connect(BasicEdge(2, 3)) 134 135 edges := g.EdgesFrom(1) 136 137 expected := make(Set) 138 expected.Add(BasicEdge(1, 3)) 139 140 s := make(Set) 141 for _, e := range edges { 142 s.Add(e) 143 } 144 145 if s.Intersection(expected).Len() != expected.Len() { 146 t.Fatalf("bad: %#v", edges) 147 } 148 } 149 150 func TestGraphEdgesTo(t *testing.T) { 151 var g Graph 152 g.Add(1) 153 g.Add(2) 154 g.Add(3) 155 g.Connect(BasicEdge(1, 3)) 156 g.Connect(BasicEdge(1, 2)) 157 158 edges := g.EdgesTo(3) 159 160 expected := make(Set) 161 expected.Add(BasicEdge(1, 3)) 162 163 s := make(Set) 164 for _, e := range edges { 165 s.Add(e) 166 } 167 168 if s.Intersection(expected).Len() != expected.Len() { 169 t.Fatalf("bad: %#v", edges) 170 } 171 } 172 173 func TestGraphUpdownEdges(t *testing.T) { 174 // Verify that we can't inadvertently modify the internal graph sets 175 var g Graph 176 g.Add(1) 177 g.Add(2) 178 g.Add(3) 179 g.Connect(BasicEdge(1, 2)) 180 g.Connect(BasicEdge(2, 3)) 181 182 up := g.UpEdges(2) 183 if up.Len() != 1 || !up.Include(1) { 184 t.Fatalf("expected only an up edge of '1', got %#v", up) 185 } 186 // modify the up set 187 up.Add(9) 188 189 orig := g.UpEdges(2) 190 diff := up.Difference(orig) 191 if diff.Len() != 1 || !diff.Include(9) { 192 t.Fatalf("expected a diff of only '9', got %#v", diff) 193 } 194 195 down := g.DownEdges(2) 196 if down.Len() != 1 || !down.Include(3) { 197 t.Fatalf("expected only a down edge of '3', got %#v", down) 198 } 199 // modify the down set 200 down.Add(8) 201 202 orig = g.DownEdges(2) 203 diff = down.Difference(orig) 204 if diff.Len() != 1 || !diff.Include(8) { 205 t.Fatalf("expected a diff of only '8', got %#v", diff) 206 } 207 } 208 209 type hashVertex struct { 210 code interface{} 211 } 212 213 func (v *hashVertex) Hashcode() interface{} { 214 return v.code 215 } 216 217 func (v *hashVertex) Name() string { 218 return fmt.Sprintf("%#v", v.code) 219 } 220 221 const testGraphBasicStr = ` 222 1 223 3 224 2 225 3 226 ` 227 228 const testGraphEmptyStr = ` 229 1 230 2 231 3 232 ` 233 234 const testGraphRemoveStr = ` 235 1 236 2 237 ` 238 239 const testGraphReplaceStr = ` 240 1 241 42 242 3 243 42 244 3 245 ` 246 247 const testGraphReplaceSelfStr = ` 248 1 249 2 250 2 251 3 252 3 253 `