gonum.org/v1/gonum@v0.14.0/graph/path/internal/testgraphs/grid_test.go (about) 1 // Copyright ©2014 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package testgraphs 6 7 import ( 8 "bytes" 9 "errors" 10 "reflect" 11 "strings" 12 "testing" 13 14 "gonum.org/v1/gonum/graph" 15 "gonum.org/v1/gonum/graph/simple" 16 ) 17 18 var _ graph.Graph = (*Grid)(nil) 19 20 func join(g ...string) string { return strings.Join(g, "\n") } 21 22 type node int64 23 24 func (n node) ID() int64 { return int64(n) } 25 26 func TestGrid(t *testing.T) { 27 t.Parallel() 28 g := NewGrid(4, 4, false) 29 30 got := g.String() 31 want := join( 32 "****", 33 "****", 34 "****", 35 "****", 36 ) 37 if got != want { 38 t.Fatalf("unexpected grid rendering:\ngot: %q\nwant:%q", got, want) 39 } 40 41 var ops = []struct { 42 r, c int 43 state bool 44 want string 45 }{ 46 { 47 r: 0, c: 1, 48 state: true, 49 want: join( 50 "*.**", 51 "****", 52 "****", 53 "****", 54 ), 55 }, 56 { 57 r: 0, c: 1, 58 state: false, 59 want: join( 60 "****", 61 "****", 62 "****", 63 "****", 64 ), 65 }, 66 { 67 r: 0, c: 1, 68 state: true, 69 want: join( 70 "*.**", 71 "****", 72 "****", 73 "****", 74 ), 75 }, 76 { 77 r: 0, c: 2, 78 state: true, 79 want: join( 80 "*..*", 81 "****", 82 "****", 83 "****", 84 ), 85 }, 86 { 87 r: 1, c: 2, 88 state: true, 89 want: join( 90 "*..*", 91 "**.*", 92 "****", 93 "****", 94 ), 95 }, 96 { 97 r: 2, c: 2, 98 state: true, 99 want: join( 100 "*..*", 101 "**.*", 102 "**.*", 103 "****", 104 ), 105 }, 106 { 107 r: 3, c: 2, 108 state: true, 109 want: join( 110 "*..*", 111 "**.*", 112 "**.*", 113 "**.*", 114 ), 115 }, 116 } 117 for _, test := range ops { 118 g.Set(test.r, test.c, test.state) 119 got := g.String() 120 if got != test.want { 121 t.Fatalf("unexpected grid rendering after set (%d, %d) open state to %t:\ngot: %q\nwant:%q", 122 test.r, test.c, test.state, got, test.want) 123 } 124 } 125 126 // Match the last state from the loop against the 127 // explicit description of the grid. 128 got = NewGridFrom( 129 "*..*", 130 "**.*", 131 "**.*", 132 "**.*", 133 ).String() 134 want = g.String() 135 if got != want { 136 t.Fatalf("unexpected grid rendering from NewGridFrom:\ngot: %q\nwant:%q", got, want) 137 } 138 139 var paths = []struct { 140 path []graph.Node 141 diagonal bool 142 want string 143 }{ 144 { 145 path: nil, 146 diagonal: false, 147 want: join( 148 "*..*", 149 "**.*", 150 "**.*", 151 "**.*", 152 ), 153 }, 154 { 155 path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, 156 diagonal: false, 157 want: join( 158 "*So*", 159 "**o*", 160 "**o*", 161 "**G*", 162 ), 163 }, 164 { 165 path: []graph.Node{node(1), node(6), node(10), node(14)}, 166 diagonal: false, 167 want: join( 168 "*S.*", 169 "**!*", 170 "**.*", 171 "**.*", 172 ), 173 }, 174 { 175 path: []graph.Node{node(1), node(6), node(10), node(14)}, 176 diagonal: true, 177 want: join( 178 "*S.*", 179 "**o*", 180 "**o*", 181 "**G*", 182 ), 183 }, 184 { 185 path: []graph.Node{node(1), node(5), node(9)}, 186 diagonal: false, 187 want: join( 188 "*S.*", 189 "*!.*", 190 "**.*", 191 "**.*", 192 ), 193 }, 194 } 195 for _, test := range paths { 196 g.AllowDiagonal = test.diagonal 197 got, err := g.Render(test.path) 198 errored := err != nil 199 if bytes.Contains(got, []byte{'!'}) != errored { 200 t.Fatalf("unexpected error return: got:%v want:%v", err, errors.New("grid: not a path in graph")) 201 } 202 if string(got) != test.want { 203 t.Fatalf("unexpected grid path rendering for %v:\ngot: %q\nwant:%q", test.path, got, want) 204 } 205 } 206 207 var coords = []struct { 208 r, c int 209 id int64 210 }{ 211 {r: 0, c: 0, id: 0}, 212 {r: 0, c: 3, id: 3}, 213 {r: 3, c: 0, id: 12}, 214 {r: 3, c: 3, id: 15}, 215 } 216 for _, test := range coords { 217 if id := g.NodeAt(test.r, test.c).ID(); id != test.id { 218 t.Fatalf("unexpected ID for node at (%d, %d):\ngot: %d\nwant:%d", test.r, test.c, id, test.id) 219 } 220 if r, c := g.RowCol(test.id); r != test.r || c != test.c { 221 t.Fatalf("unexpected row/col for node %d:\ngot: (%d, %d)\nwant:(%d, %d)", test.id, r, c, test.r, test.c) 222 } 223 } 224 225 var reach = []struct { 226 from graph.Node 227 diagonal bool 228 to []graph.Node 229 }{ 230 { 231 from: node(0), 232 diagonal: false, 233 to: nil, 234 }, 235 { 236 from: node(2), 237 diagonal: false, 238 to: []graph.Node{simple.Node(1), simple.Node(6)}, 239 }, 240 { 241 from: node(1), 242 diagonal: false, 243 to: []graph.Node{simple.Node(2)}, 244 }, 245 { 246 from: node(1), 247 diagonal: true, 248 to: []graph.Node{simple.Node(2), simple.Node(6)}, 249 }, 250 } 251 for _, test := range reach { 252 g.AllowDiagonal = test.diagonal 253 got := graph.NodesOf(g.From(test.from.ID())) 254 if !reflect.DeepEqual(got, test.to) { 255 t.Fatalf("unexpected nodes from %d with allow diagonal=%t:\ngot: %v\nwant:%v", 256 test.from, test.diagonal, got, test.to) 257 } 258 } 259 }