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  }