github.com/haraldrudell/parl@v0.4.176/iters/function_test.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package iters 7 8 import ( 9 "testing" 10 11 "github.com/haraldrudell/parl/internal/cyclebreaker" 12 "github.com/haraldrudell/parl/perrors" 13 ) 14 15 func TestFunction(t *testing.T) { 16 var value1, value2 = 1, 2 17 var values = []int{value1, value2} 18 19 var err error 20 var value, zeroValue, iterationVariable int 21 var hasValue, condition bool 22 var actIterator Iterator[int] 23 24 var iterator Iterator[int] 25 var reset = func() { 26 iterator = NewFunctionIterator(newHasFunc(values).IteratorFunction) 27 } 28 // Init() Cond() Next() Same() Cancel() 29 var _ Slice[int] 30 31 // Init should return zero value and iterator 32 reset() 33 iterationVariable, actIterator = iterator.Init() 34 if iterationVariable != zeroValue { 35 t.Errorf("Init iterationVariable %d exp %d", iterationVariable, zeroValue) 36 } 37 if actIterator != iterator { 38 t.Error("Init iterator bad") 39 } 40 41 // Cond should return true and update value 42 reset() 43 value = zeroValue 44 condition = iterator.Cond(&value) 45 if !condition { 46 t.Error("Cond condition false") 47 } 48 if value != value1 { 49 t.Errorf("Cond value %d exp %d", value, value1) 50 } 51 52 // Next should return first value 53 reset() 54 value, hasValue = iterator.Next() 55 if !hasValue { 56 t.Error("Next hasValue false") 57 } 58 if value != value1 { 59 t.Errorf("Next value %d exp %d", value, value1) 60 } 61 62 // Cancel should return no error 63 reset() 64 err = iterator.Cancel() 65 if err != nil { 66 t.Errorf("Cancel err: %s", perrors.Short(err)) 67 } 68 69 // CondCond should return second value 70 reset() 71 condition = iterator.Cond(&value) 72 _ = condition 73 value = zeroValue 74 condition = iterator.Cond(&value) 75 if !condition { 76 t.Error("CondCond condition false") 77 } 78 if value != value2 { 79 t.Errorf("Cond value %d exp %d", value, value2) 80 } 81 82 // CondCondCond should return no value 83 // request IsSame value twice should: 84 // - retrieve the first value and return it 85 // - then return the same value again 86 // 87 // Cond should return true and update value 88 reset() 89 condition = iterator.Cond(&value) 90 _ = condition 91 condition = iterator.Cond(&value) 92 _ = condition 93 value = zeroValue 94 condition = iterator.Cond(&value) 95 if condition { 96 t.Error("CondCondCond condition true") 97 } 98 if value != zeroValue { 99 t.Errorf("CondCondCond value %d exp %d", value, zeroValue) 100 } 101 102 // NextNext should return second value 103 reset() 104 value, hasValue = iterator.Next() 105 _ = value 106 _ = hasValue 107 value, hasValue = iterator.Next() 108 if !hasValue { 109 t.Error("NextNext hasValue false") 110 } 111 if value != value2 { 112 t.Errorf("NextNext value %d exp %d", value, value2) 113 } 114 115 // NextNextNext should return no value 116 reset() 117 value, hasValue = iterator.Next() 118 _ = value 119 _ = hasValue 120 value, hasValue = iterator.Next() 121 _ = value 122 _ = hasValue 123 value, hasValue = iterator.Next() 124 if hasValue { 125 t.Error("NextNextNext hasValue true") 126 } 127 if value != zeroValue { 128 t.Errorf("NextNextNext value %d exp %d", value, zeroValue) 129 } 130 131 // CancelCond should return false 132 reset() 133 err = iterator.Cancel() 134 _ = err 135 condition = iterator.Cond(&value) 136 if condition { 137 t.Error("CancelCond condition true") 138 } 139 140 // CancelNext should return no value 141 reset() 142 err = iterator.Cancel() 143 _ = err 144 value, hasValue = iterator.Next() 145 if hasValue { 146 t.Error("CancelNext hasValue true") 147 } 148 if value != zeroValue { 149 t.Errorf("CancelNext value %d exp %d", value, zeroValue) 150 } 151 } 152 153 type hasFunc[T any] struct { 154 slice []T 155 index int 156 } 157 158 func newHasFunc[T any](slice []T) (s *hasFunc[T]) { return &hasFunc[T]{slice: slice} } 159 func (s *hasFunc[T]) IteratorFunction(isCancel bool) (value T, err error) { 160 if isCancel { 161 return 162 } else if s.index >= len(s.slice) { 163 err = cyclebreaker.ErrEndCallbacks 164 return 165 } 166 value = s.slice[s.index] 167 s.index++ 168 169 return 170 }