github.com/cayleygraph/cayley@v0.7.7/graph/iterator/or_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/iterator" 25 ) 26 27 func iterated(it graph.Iterator) []int { 28 ctx := context.TODO() 29 var res []int 30 for it.Next(ctx) { 31 res = append(res, int(it.Result().(Int64Node))) 32 } 33 return res 34 } 35 36 func TestOrIteratorBasics(t *testing.T) { 37 ctx := context.TODO() 38 or := NewOr() 39 f1 := NewFixed( 40 Int64Node(1), 41 Int64Node(2), 42 Int64Node(3), 43 ) 44 f2 := NewFixed( 45 Int64Node(3), 46 Int64Node(9), 47 Int64Node(20), 48 Int64Node(21), 49 ) 50 or.AddSubIterator(f1) 51 or.AddSubIterator(f2) 52 53 if v, _ := or.Size(); v != 7 { 54 t.Errorf("Unexpected iterator size, got:%d expected %d", v, 7) 55 } 56 57 expect := []int{1, 2, 3, 3, 9, 20, 21} 58 for i := 0; i < 2; i++ { 59 if got := iterated(or); !reflect.DeepEqual(got, expect) { 60 t.Errorf("Failed to iterate Or correctly on repeat %d, got:%v expect:%v", i, got, expect) 61 } 62 or.Reset() 63 } 64 65 // Check that optimization works. 66 optOr, _ := or.Optimize() 67 if got := iterated(optOr); !reflect.DeepEqual(got, expect) { 68 t.Errorf("Failed to iterate optimized Or correctly, got:%v expect:%v", got, expect) 69 } 70 71 for _, v := range []int{2, 3, 21} { 72 if !or.Contains(ctx, Int64Node(v)) { 73 t.Errorf("Failed to correctly check %d as true", v) 74 } 75 } 76 77 for _, v := range []int{22, 5, 0} { 78 if or.Contains(ctx, Int64Node(v)) { 79 t.Errorf("Failed to correctly check %d as false", v) 80 } 81 } 82 } 83 84 func TestShortCircuitingOrBasics(t *testing.T) { 85 ctx := context.TODO() 86 var or *Or 87 88 f1 := NewFixed( 89 Int64Node(1), 90 Int64Node(2), 91 Int64Node(3), 92 ) 93 f2 := NewFixed( 94 Int64Node(3), 95 Int64Node(9), 96 Int64Node(20), 97 Int64Node(21), 98 ) 99 100 or = NewShortCircuitOr() 101 or.AddSubIterator(f1) 102 or.AddSubIterator(f2) 103 f2.Reset() 104 size, exact := or.Size() 105 if size != 4 { 106 t.Errorf("Unexpected iterator size, got:%d expected %d", size, 4) 107 } 108 if !exact { 109 t.Error("Size not exact.") 110 } 111 112 // It should extract the first iterators' numbers. 113 or = NewShortCircuitOr() 114 or.AddSubIterator(f1) 115 or.AddSubIterator(f2) 116 f2.Reset() 117 expect := []int{1, 2, 3} 118 for i := 0; i < 2; i++ { 119 if got := iterated(or); !reflect.DeepEqual(got, expect) { 120 t.Errorf("Failed to iterate Or correctly on repeat %d, got:%v expect:%v", i, got, expect) 121 } 122 or.Reset() 123 } 124 125 // Check optimization works. 126 optOr, _ := or.Optimize() 127 if got := iterated(optOr); !reflect.DeepEqual(got, expect) { 128 t.Errorf("Failed to iterate optimized Or correctly, got:%v expect:%v", got, expect) 129 } 130 131 // Check that numbers in either iterator exist. 132 or = NewShortCircuitOr() 133 or.AddSubIterator(f1) 134 or.AddSubIterator(f2) 135 f2.Reset() 136 for _, v := range []int{2, 3, 21} { 137 if !or.Contains(ctx, Int64Node(v)) { 138 t.Errorf("Failed to correctly check %d as true", v) 139 } 140 } 141 for _, v := range []int{22, 5, 0} { 142 if or.Contains(ctx, Int64Node(v)) { 143 t.Errorf("Failed to correctly check %d as false", v) 144 } 145 } 146 147 // Check that it pulls the second iterator's numbers if the first is empty. 148 or = NewShortCircuitOr() 149 or.AddSubIterator(NewFixed()) 150 or.AddSubIterator(f2) 151 f2.Reset() 152 expect = []int{3, 9, 20, 21} 153 for i := 0; i < 2; i++ { 154 if got := iterated(or); !reflect.DeepEqual(got, expect) { 155 t.Errorf("Failed to iterate Or correctly on repeat %d, got:%v expect:%v", i, got, expect) 156 } 157 or.Reset() 158 } 159 // Check optimization works. 160 optOr, _ = or.Optimize() 161 if got := iterated(optOr); !reflect.DeepEqual(got, expect) { 162 t.Errorf("Failed to iterate optimized Or correctly, got:%v expect:%v", got, expect) 163 } 164 } 165 166 func TestOrIteratorErr(t *testing.T) { 167 ctx := context.TODO() 168 wantErr := errors.New("unique") 169 orErr := newTestIterator(false, wantErr) 170 171 fix1 := NewFixed(Int64Node(1)) 172 173 or := NewOr( 174 fix1, 175 orErr, 176 newInt64(1, 5, true), 177 ) 178 179 if !or.Next(ctx) { 180 t.Errorf("Failed to iterate Or correctly") 181 } 182 if got := or.Result(); got.(Int64Node) != 1 { 183 t.Errorf("Failed to iterate Or correctly, got:%v expect:1", got) 184 } 185 186 if or.Next(ctx) != false { 187 t.Errorf("Or iterator did not pass through underlying 'false'") 188 } 189 if or.Err() != wantErr { 190 t.Errorf("Or iterator did not pass through underlying Err") 191 } 192 } 193 194 func TestShortCircuitOrIteratorErr(t *testing.T) { 195 ctx := context.TODO() 196 wantErr := errors.New("unique") 197 orErr := newTestIterator(false, wantErr) 198 199 or := NewOr( 200 orErr, 201 newInt64(1, 5, true), 202 ) 203 204 if or.Next(ctx) != false { 205 t.Errorf("Or iterator did not pass through underlying 'false'") 206 } 207 if or.Err() != wantErr { 208 t.Errorf("Or iterator did not pass through underlying Err") 209 } 210 }