github.com/cayleygraph/cayley@v0.7.7/graph/iterator/query_shape_test.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package iterator_test 16 17 import ( 18 "reflect" 19 "testing" 20 21 "github.com/cayleygraph/cayley/graph" 22 "github.com/cayleygraph/cayley/graph/graphmock" 23 . "github.com/cayleygraph/cayley/graph/iterator" 24 "github.com/cayleygraph/quad" 25 ) 26 27 func hasaWithTag(namer graph.Namer, quads graph.QuadIndexer, tag string, target string) *HasA { 28 and := NewAnd() 29 30 obj := NewFixed(namer.ValueOf(quad.Raw(target))) 31 and.AddSubIterator(NewLinksTo(quads, Tag(obj, tag), quad.Object)) 32 33 pred := NewFixed(namer.ValueOf(quad.Raw("status"))) 34 and.AddSubIterator(NewLinksTo(quads, pred, quad.Predicate)) 35 36 return NewHasA(quads, and, quad.Subject) 37 } 38 39 func TestQueryShape(t *testing.T) { 40 qs := &graphmock.Oldstore{Data: []string{ 41 1: "cool", 42 2: "status", 43 3: "fun", 44 4: "name", 45 }} 46 47 // Given a single linkage iterator's shape. 48 var hasa graph.Iterator = hasaWithTag(qs, qs, "tag", "cool") 49 hasa = Tag(hasa, "top") 50 51 shape := make(map[string]interface{}) 52 OutputQueryShapeForIterator(hasa, qs, shape) 53 54 nodes := shape["nodes"].([]Node) 55 if len(nodes) != 3 { 56 t.Fatalf("Failed to get correct number of nodes, got:%d expect:3", len(nodes)) 57 } 58 links := shape["links"].([]Link) 59 if len(nodes) != 3 { 60 t.Fatalf("Failed to get correct number of links, got:%d expect:1", len(links)) 61 } 62 63 // Nodes should be correctly tagged. 64 nodes = shape["nodes"].([]Node) 65 for i, expect := range [][]string{{"tag"}, nil, {"top"}} { 66 if !reflect.DeepEqual(nodes[i].Tags, expect) { 67 t.Errorf("Failed to get correct tag for node[%d], got:%s expect:%s", i, nodes[i].Tags, expect) 68 } 69 } 70 if !nodes[1].IsLinkNode { 71 t.Error("Failed to get node[1] as link node") 72 } 73 74 // Link should be correctly typed. 75 nodes = shape["nodes"].([]Node) 76 link := shape["links"].([]Link)[0] 77 if link.Source != nodes[2].ID { 78 t.Errorf("Failed to get correct link source, got:%v expect:%v", link.Source, nodes[2].ID) 79 } 80 if link.Target != nodes[0].ID { 81 t.Errorf("Failed to get correct link target, got:%v expect:%v", link.Target, nodes[0].ID) 82 } 83 if link.LinkNode != nodes[1].ID { 84 t.Errorf("Failed to get correct link node, got:%v expect:%v", link.LinkNode, nodes[1].ID) 85 } 86 if link.Pred != 0 { 87 t.Errorf("Failed to get correct number of predecessors:%v expect:0", link.Pred) 88 } 89 90 // Given a name-of-an-and-iterator's shape. 91 andInternal := NewAnd() 92 93 var hasa1 graph.Iterator = hasaWithTag(qs, qs, "tag1", "cool") 94 hasa1 = Tag(hasa1, "hasa1") 95 andInternal.AddSubIterator(hasa1) 96 97 var hasa2 graph.Iterator = hasaWithTag(qs, qs, "tag2", "fun") 98 hasa2 = Tag(hasa2, "hasa2") 99 andInternal.AddSubIterator(hasa2) 100 101 pred := NewFixed(qs.ValueOf(quad.Raw("name"))) 102 103 and := NewAnd() 104 and.AddSubIterator(NewLinksTo(qs, andInternal, quad.Subject)) 105 and.AddSubIterator(NewLinksTo(qs, pred, quad.Predicate)) 106 107 shape = make(map[string]interface{}) 108 OutputQueryShapeForIterator(NewHasA(qs, and, quad.Object), qs, shape) 109 110 links = shape["links"].([]Link) 111 if len(links) != 3 { 112 t.Errorf("Failed to find the correct number of links, got:%d expect:3", len(links)) 113 } 114 nodes = shape["nodes"].([]Node) 115 if len(nodes) != 7 { 116 t.Errorf("Failed to find the correct number of nodes, got:%d expect:7", len(nodes)) 117 } 118 var n int 119 for _, node := range nodes { 120 if node.IsLinkNode { 121 n++ 122 } 123 } 124 if n != 3 { 125 t.Errorf("Failed to find the correct number of link nodes, got:%d expect:3", n) 126 } 127 }