github.com/liucxer/courier@v1.7.1/h3/vertex_graph_test.go (about) 1 package h3 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 ) 8 9 // Fixtures 10 var center GeoCoord 11 12 var vertex1 GeoCoord 13 14 var vertex2 GeoCoord 15 16 var vertex3 GeoCoord 17 18 var vertex4 GeoCoord 19 20 var vertex5 GeoCoord 21 22 var vertex6 GeoCoord 23 24 func init() { 25 setGeoDegs(¢er, 37.77362016769341, -122.41673772517154) 26 setGeoDegs(&vertex1, 87.372002166, 166.160981117) 27 setGeoDegs(&vertex2, 87.370101364, 166.160184306) 28 setGeoDegs(&vertex3, 87.369088356, 166.196239997) 29 setGeoDegs(&vertex4, 87.369975080, 166.233115768) 30 setGeoDegs(&vertex5, 0, 0) 31 setGeoDegs(&vertex6, -10, -10) 32 } 33 34 func Test_makeVertexGraph(t *testing.T) { 35 var graph VertexGraph 36 initVertexGraph(&graph, 10, 9) 37 38 require.True(t, graph.numBuckets == 10, "numBuckets set") 39 require.True(t, graph.size == 0, "size set") 40 41 destroyVertexGraph(&graph) 42 } 43 44 // TODO fixme 45 func _Test_vertexHash(t *testing.T) { 46 //var centerIndex H3Index 47 var outline GeoBoundary 48 var hash1 uint32 49 var hash2 uint32 50 numBuckets := 1000 51 for res := 0; res < 11; res++ { 52 //centerIndex = geoToH3(¢er, res) 53 //h3ToGeoBoundary(centerIndex, &outline) 54 for i := 0; i < outline.numVerts; i++ { 55 hash1 = _hashVertex(&outline.Verts[i], res, numBuckets) 56 hash2 = _hashVertex(&outline.Verts[(i+1)%outline.numVerts], res, numBuckets) 57 require.True(t, hash1 != hash2, "Hashes must not be equal") 58 } 59 } 60 } 61 62 func Test_vertexHashNegative(t *testing.T) { 63 numBuckets := 10 64 require.True(t, _hashVertex(&vertex5, 5, numBuckets) < uint32(numBuckets), "zero vertex hashes correctly") 65 require.True(t, _hashVertex(&vertex6, 5, numBuckets) < uint32(numBuckets), "negative coordinates vertex hashes correctly") 66 } 67 68 func Test_addVertexNode(t *testing.T) { 69 var graph VertexGraph 70 initVertexGraph(&graph, 10, 9) 71 72 var node *VertexNode 73 var addedNode *VertexNode 74 75 t.Run("basic add", func(t *testing.T) { 76 addedNode = addVertexNode(&graph, &vertex1, &vertex2) 77 node = findNodeForEdge(&graph, &vertex1, &vertex2) 78 79 require.True(t, node != nil, "Node found") 80 require.True(t, node == addedNode, "Right node found") 81 require.True(t, graph.size == 1, "Graph size incremented") 82 83 t.Run("collision add", func(t *testing.T) { 84 addedNode = addVertexNode(&graph, &vertex1, &vertex3) 85 node = findNodeForEdge(&graph, &vertex1, &vertex3) 86 87 require.True(t, node != nil, "Node found after hash collision") 88 require.True(t, node == addedNode, "Right node found") 89 require.True(t, graph.size == 2, "Graph size incremented") 90 91 t.Run("collision add #2", func(t *testing.T) { 92 addedNode = addVertexNode(&graph, &vertex1, &vertex4) 93 node = findNodeForEdge(&graph, &vertex1, &vertex4) 94 require.True(t, node != nil, "Node found after 2nd hash collision") 95 require.True(t, node == addedNode, "Right node found") 96 require.True(t, graph.size == 3, "Graph size incremented") 97 98 t.Run("Exact match no-op", func(t *testing.T) { 99 node = findNodeForEdge(&graph, &vertex1, &vertex2) 100 addedNode = addVertexNode(&graph, &vertex1, &vertex2) 101 require.True(t, node == findNodeForEdge(&graph, &vertex1, &vertex2), "Exact match did not change existing node") 102 require.True(t, node == addedNode, "Old node returned") 103 require.True(t, graph.size == 3, "Graph size was not changed") 104 }) 105 }) 106 }) 107 }) 108 109 destroyVertexGraph(&graph) 110 } 111 112 func Test_addVertexNodeDupe(t *testing.T) { 113 var graph VertexGraph 114 initVertexGraph(&graph, 10, 9) 115 var node *VertexNode 116 var addedNode *VertexNode 117 118 t.Run("basic add", func(t *testing.T) { 119 addedNode = addVertexNode(&graph, &vertex1, &vertex2) 120 node = findNodeForEdge(&graph, &vertex1, &vertex2) 121 122 require.True(t, node != nil, "Node found") 123 require.True(t, node == addedNode, "Right node found") 124 require.True(t, graph.size == 1, "Graph size incremented") 125 126 t.Run("dupe add", func(t *testing.T) { 127 addedNode = addVertexNode(&graph, &vertex1, &vertex2) 128 129 require.True(t, node == addedNode, "addVertexNode returned the original node") 130 require.True(t, graph.size == 1, "Graph size not incremented") 131 }) 132 }) 133 134 destroyVertexGraph(&graph) 135 } 136 137 func Test_findNodeForEdge(t *testing.T) { 138 // Basic lookup tested in testAddVertexNode, only test failures here 139 var graph VertexGraph 140 initVertexGraph(&graph, 10, 9) 141 var node *VertexNode 142 143 t.Run("empty graph", func(t *testing.T) { 144 node = findNodeForEdge(&graph, &vertex1, &vertex2) 145 require.True(t, node == nil, "Node lookup failed correctly for empty graph") 146 addVertexNode(&graph, &vertex1, &vertex2) 147 148 t.Run("different hash", func(t *testing.T) { 149 node = findNodeForEdge(&graph, &vertex3, &vertex2) 150 require.True(t, node == nil, "Node lookup failed correctly for different hash") 151 152 t.Run("hash collision", func(t *testing.T) { 153 node = findNodeForEdge(&graph, &vertex1, &vertex3) 154 require.True(t, node == nil, "Node lookup failed correctly for hash collision") 155 addVertexNode(&graph, &vertex1, &vertex4) 156 157 t.Run("list iteration", func(t *testing.T) { 158 node = findNodeForEdge(&graph, &vertex1, &vertex3) 159 require.True(t, node == nil, "Node lookup failed correctly for collision w/iteration") 160 }) 161 }) 162 163 }) 164 }) 165 166 destroyVertexGraph(&graph) 167 } 168 169 func Test_findNodeForVertex(t *testing.T) { 170 var graph VertexGraph 171 initVertexGraph(&graph, 10, 9) 172 var node *VertexNode 173 174 // Empty graph 175 node = findNodeForVertex(&graph, &vertex1) 176 require.True(t, node == nil, "Node lookup failed correctly for empty graph") 177 addVertexNode(&graph, &vertex1, &vertex2) 178 node = findNodeForVertex(&graph, &vertex1) 179 require.True(t, node != nil, "Node lookup succeeded for correct node") 180 node = findNodeForVertex(&graph, &vertex3) 181 require.True(t, node == nil, 182 "Node lookup failed correctly for different node") 183 destroyVertexGraph(&graph) 184 } 185 186 func Test_removeVertexNode(t *testing.T) { 187 var graph VertexGraph 188 initVertexGraph(&graph, 10, 9) 189 var node *VertexNode 190 var success bool 191 192 // Straight removal 193 node = addVertexNode(&graph, &vertex1, &vertex2) 194 success = removeVertexNode(&graph, node) == 0 195 require.True(t, success, "Removal successful") 196 require.True(t, findNodeForVertex(&graph, &vertex1) == nil, 197 "Node lookup cannot find node") 198 require.True(t, graph.size == 0, "Graph size decremented") 199 200 // Remove end of list 201 addVertexNode(&graph, &vertex1, &vertex2) 202 node = addVertexNode(&graph, &vertex1, &vertex3) 203 success = removeVertexNode(&graph, node) == 0 204 require.True(t, success, "Removal successful") 205 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex3) == nil, 206 "Node lookup cannot find node") 207 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex2).next == nil, 208 "Base bucket node not pointing to node") 209 require.True(t, graph.size == 1, "Graph size decremented") 210 211 // This removal is just cleanup 212 node = findNodeForVertex(&graph, &vertex1) 213 require.True(t, removeVertexNode(&graph, node) == 0) 214 215 // Remove beginning of list 216 node = addVertexNode(&graph, &vertex1, &vertex2) 217 addVertexNode(&graph, &vertex1, &vertex3) 218 success = removeVertexNode(&graph, node) == 0 219 require.True(t, success, "Removal successful") 220 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex2) == nil, 221 "Node lookup cannot find node") 222 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex3) != nil, 223 "Node lookup can find previous end of list") 224 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex3).next == nil, 225 "Base bucket node not pointing to node") 226 require.True(t, graph.size == 1, "Graph size decremented") 227 228 // This removal is just cleanup 229 node = findNodeForVertex(&graph, &vertex1) 230 require.True(t, removeVertexNode(&graph, node) == 0) 231 232 // Remove middle of list 233 addVertexNode(&graph, &vertex1, &vertex2) 234 node = addVertexNode(&graph, &vertex1, &vertex3) 235 addVertexNode(&graph, &vertex1, &vertex4) 236 success = removeVertexNode(&graph, node) == 0 237 require.True(t, success, "Removal successful") 238 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex3) == nil, 239 "Node lookup cannot find node") 240 require.True(t, findNodeForEdge(&graph, &vertex1, &vertex4) != nil, 241 "Node lookup can find previous end of list") 242 require.True(t, graph.size == 2, "Graph size decremented") 243 244 // Remove non-existent node 245 node = &VertexNode{} 246 success = removeVertexNode(&graph, node) == 0 247 require.True(t, !success, "Removal of non-existent node fails") 248 require.True(t, graph.size == 2, "Graph size unchanged") 249 destroyVertexGraph(&graph) 250 } 251 252 func Test_firstVertexNode(t *testing.T) { 253 var graph VertexGraph 254 initVertexGraph(&graph, 10, 9) 255 var node *VertexNode 256 var addedNode *VertexNode 257 node = firstVertexNode(&graph) 258 require.True(t, node == nil, "No node found for empty graph") 259 addedNode = addVertexNode(&graph, &vertex1, &vertex2) 260 node = firstVertexNode(&graph) 261 require.True(t, node == addedNode, "Node found") 262 destroyVertexGraph(&graph) 263 } 264 265 func Test_destroyEmptyVertexGraph(t *testing.T) { 266 var graph VertexGraph 267 initVertexGraph(&graph, 10, 9) 268 destroyVertexGraph(&graph) 269 } 270 271 func Test_singleBucketVertexGraph(t *testing.T) { 272 var graph VertexGraph 273 initVertexGraph(&graph, 1, 9) 274 var node *VertexNode 275 require.True(t, graph.numBuckets == 1, "1 bucket created") 276 277 node = firstVertexNode(&graph) 278 require.True(t, node == nil, "No node found for empty graph") 279 280 node = addVertexNode(&graph, &vertex1, &vertex2) 281 require.True(t, node != nil, "Node added") 282 require.True(t, firstVertexNode(&graph) == node, "First node is node") 283 284 addVertexNode(&graph, &vertex2, &vertex3) 285 addVertexNode(&graph, &vertex3, &vertex4) 286 require.True(t, firstVertexNode(&graph) == node, "First node is still node") 287 require.True(t, graph.size == 3, "Graph size updated") 288 289 destroyVertexGraph(&graph) 290 }