github.com/cayleygraph/cayley@v0.7.7/graph/iterator/value_comparison_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  	"context"
    19  	"errors"
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/cayleygraph/cayley/graph"
    24  	"github.com/cayleygraph/cayley/graph/graphmock"
    25  	. "github.com/cayleygraph/cayley/graph/iterator"
    26  	"github.com/cayleygraph/quad"
    27  )
    28  
    29  var (
    30  	simpleStore = &graphmock.Oldstore{Data: []string{"0", "1", "2", "3", "4", "5"}, Parse: true}
    31  	stringStore = &graphmock.Oldstore{Data: []string{"foo", "bar", "baz", "echo"}, Parse: true}
    32  	mixedStore  = &graphmock.Oldstore{Data: []string{"0", "1", "2", "3", "4", "5", "foo", "bar", "baz", "echo"}, Parse: true}
    33  )
    34  
    35  func simpleFixedIterator() *Fixed {
    36  	f := NewFixed()
    37  	for i := 0; i < 5; i++ {
    38  		f.Add(Int64Node(i))
    39  	}
    40  	return f
    41  }
    42  
    43  func stringFixedIterator() *Fixed {
    44  	f := NewFixed()
    45  	for _, value := range stringStore.Data {
    46  		f.Add(graphmock.StringNode(value))
    47  	}
    48  	return f
    49  }
    50  
    51  func mixedFixedIterator() *Fixed {
    52  	f := NewFixed()
    53  	for i := 0; i < len(mixedStore.Data); i++ {
    54  		f.Add(Int64Node(i))
    55  	}
    56  	return f
    57  }
    58  
    59  var comparisonTests = []struct {
    60  	message  string
    61  	operand  quad.Value
    62  	operator Operator
    63  	expect   []quad.Value
    64  	qs       graph.Namer
    65  	iterator func() *Fixed
    66  }{
    67  	{
    68  		message:  "successful int64 less than comparison",
    69  		operand:  quad.Int(3),
    70  		operator: CompareLT,
    71  		expect:   []quad.Value{quad.Int(0), quad.Int(1), quad.Int(2)},
    72  		qs:       simpleStore,
    73  		iterator: simpleFixedIterator,
    74  	},
    75  	{
    76  		message:  "empty int64 less than comparison",
    77  		operand:  quad.Int(0),
    78  		operator: CompareLT,
    79  		expect:   nil,
    80  		qs:       simpleStore,
    81  		iterator: simpleFixedIterator,
    82  	},
    83  	{
    84  		message:  "successful int64 greater than comparison",
    85  		operand:  quad.Int(2),
    86  		operator: CompareGT,
    87  		expect:   []quad.Value{quad.Int(3), quad.Int(4)},
    88  		qs:       simpleStore,
    89  		iterator: simpleFixedIterator,
    90  	},
    91  	{
    92  		message:  "successful int64 greater than or equal comparison",
    93  		operand:  quad.Int(2),
    94  		operator: CompareGTE,
    95  		expect:   []quad.Value{quad.Int(2), quad.Int(3), quad.Int(4)},
    96  		qs:       simpleStore,
    97  		iterator: simpleFixedIterator,
    98  	},
    99  	{
   100  		message:  "successful int64 greater than or equal comparison (mixed)",
   101  		operand:  quad.Int(2),
   102  		operator: CompareGTE,
   103  		expect:   []quad.Value{quad.Int(2), quad.Int(3), quad.Int(4), quad.Int(5)},
   104  		qs:       mixedStore,
   105  		iterator: mixedFixedIterator,
   106  	},
   107  	{
   108  		message:  "successful string less than comparison",
   109  		operand:  quad.String("echo"),
   110  		operator: CompareLT,
   111  		expect:   []quad.Value{quad.String("bar"), quad.String("baz")},
   112  		qs:       stringStore,
   113  		iterator: stringFixedIterator,
   114  	},
   115  	{
   116  		message:  "empty string less than comparison",
   117  		operand:  quad.String(""),
   118  		operator: CompareLT,
   119  		expect:   nil,
   120  		qs:       stringStore,
   121  		iterator: stringFixedIterator,
   122  	},
   123  	{
   124  		message:  "successful string greater than comparison",
   125  		operand:  quad.String("echo"),
   126  		operator: CompareGT,
   127  		expect:   []quad.Value{quad.String("foo")},
   128  		qs:       stringStore,
   129  		iterator: stringFixedIterator,
   130  	},
   131  	{
   132  		message:  "successful string greater than or equal comparison",
   133  		operand:  quad.String("echo"),
   134  		operator: CompareGTE,
   135  		expect:   []quad.Value{quad.String("foo"), quad.String("echo")},
   136  		qs:       stringStore,
   137  		iterator: stringFixedIterator,
   138  	},
   139  }
   140  
   141  func TestValueComparison(t *testing.T) {
   142  	ctx := context.TODO()
   143  	for _, test := range comparisonTests {
   144  		qs := test.qs
   145  		vc := NewComparison(test.iterator(), test.operator, test.operand, qs)
   146  
   147  		var got []quad.Value
   148  		for vc.Next(ctx) {
   149  			got = append(got, qs.NameOf(vc.Result()))
   150  		}
   151  		if !reflect.DeepEqual(got, test.expect) {
   152  			t.Errorf("Failed to show %s, got:%q expect:%q", test.message, got, test.expect)
   153  		}
   154  	}
   155  }
   156  
   157  var vciContainsTests = []struct {
   158  	message  string
   159  	operator Operator
   160  	check    graph.Ref
   161  	expect   bool
   162  	qs       graph.Namer
   163  	val      quad.Value
   164  	iterator func() *Fixed
   165  }{
   166  	{
   167  		message:  "1 is less than 2",
   168  		operator: CompareGTE,
   169  		check:    Int64Node(1),
   170  		expect:   false,
   171  		qs:       simpleStore,
   172  		val:      quad.Int(2),
   173  		iterator: simpleFixedIterator,
   174  	},
   175  	{
   176  		message:  "2 is greater than or equal to 2",
   177  		operator: CompareGTE,
   178  		check:    Int64Node(2),
   179  		expect:   true,
   180  		qs:       simpleStore,
   181  		val:      quad.Int(2),
   182  		iterator: simpleFixedIterator,
   183  	},
   184  	{
   185  		message:  "3 is greater than or equal to 2",
   186  		operator: CompareGTE,
   187  		check:    Int64Node(3),
   188  		expect:   true,
   189  		qs:       simpleStore,
   190  		val:      quad.Int(2),
   191  		iterator: simpleFixedIterator,
   192  	},
   193  	{
   194  		message:  "5 is absent from iterator",
   195  		operator: CompareGTE,
   196  		check:    Int64Node(5),
   197  		expect:   false,
   198  		qs:       simpleStore,
   199  		val:      quad.Int(2),
   200  		iterator: simpleFixedIterator,
   201  	},
   202  	{
   203  		message:  "foo is greater than or equal to echo",
   204  		operator: CompareGTE,
   205  		check:    graphmock.StringNode("foo"),
   206  		expect:   true,
   207  		qs:       stringStore,
   208  		val:      quad.String("echo"),
   209  		iterator: stringFixedIterator,
   210  	},
   211  	{
   212  		message:  "echo is greater than or equal to echo",
   213  		operator: CompareGTE,
   214  		check:    graphmock.StringNode("echo"),
   215  		expect:   true,
   216  		qs:       stringStore,
   217  		val:      quad.String("echo"),
   218  		iterator: stringFixedIterator,
   219  	},
   220  	{
   221  		message:  "foo is missing from the iterator",
   222  		operator: CompareLTE,
   223  		check:    graphmock.StringNode("foo"),
   224  		expect:   false,
   225  		qs:       stringStore,
   226  		val:      quad.String("echo"),
   227  		iterator: stringFixedIterator,
   228  	},
   229  }
   230  
   231  func TestVCIContains(t *testing.T) {
   232  	ctx := context.TODO()
   233  	for _, test := range vciContainsTests {
   234  		vc := NewComparison(test.iterator(), test.operator, test.val, test.qs)
   235  		if vc.Contains(ctx, test.check) != test.expect {
   236  			t.Errorf("Failed to show %s", test.message)
   237  		}
   238  	}
   239  }
   240  
   241  var comparisonIteratorTests = []struct {
   242  	message string
   243  	qs      graph.Namer
   244  	val     quad.Value
   245  }{
   246  	{
   247  		message: "2 is absent from iterator",
   248  		qs:      simpleStore,
   249  		val:     quad.Int(2),
   250  	},
   251  	{
   252  		message: "'missing' is absent from iterator",
   253  		qs:      stringStore,
   254  		val:     quad.String("missing"),
   255  	},
   256  }
   257  
   258  func TestComparisonIteratorErr(t *testing.T) {
   259  	ctx := context.TODO()
   260  	wantErr := errors.New("unique")
   261  	errIt := newTestIterator(false, wantErr)
   262  
   263  	for _, test := range comparisonIteratorTests {
   264  		vc := NewComparison(errIt, CompareLT, test.val, test.qs)
   265  
   266  		if vc.Next(ctx) != false {
   267  			t.Errorf("Comparison iterator did not pass through initial 'false': %s", test.message)
   268  		}
   269  		if vc.Err() != wantErr {
   270  			t.Errorf("Comparison iterator did not pass through underlying Err: %s", test.message)
   271  		}
   272  	}
   273  }