github.com/apache/arrow/go/v16@v16.1.0/arrow/array/boolean_test.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one 2 // or more contributor license agreements. See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership. The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package array_test 18 19 import ( 20 "fmt" 21 "reflect" 22 "strings" 23 "testing" 24 25 "github.com/apache/arrow/go/v16/arrow/array" 26 "github.com/apache/arrow/go/v16/arrow/memory" 27 "github.com/stretchr/testify/assert" 28 ) 29 30 func TestBooleanSliceData(t *testing.T) { 31 pool := memory.NewCheckedAllocator(memory.NewGoAllocator()) 32 defer pool.AssertSize(t, 0) 33 34 values := []bool{true, false, true, true, true, true, true, false, true, false} 35 36 b := array.NewBooleanBuilder(pool) 37 defer b.Release() 38 39 for _, v := range values { 40 b.Append(v) 41 } 42 43 arr := b.NewArray().(*array.Boolean) 44 defer arr.Release() 45 46 if got, want := arr.Len(), len(values); got != want { 47 t.Fatalf("got=%d, want=%d", got, want) 48 } 49 50 vs := make([]bool, arr.Len()) 51 52 for i := range vs { 53 vs[i] = arr.Value(i) 54 } 55 56 if got, want := vs, values; !reflect.DeepEqual(got, want) { 57 t.Fatalf("got=%v, want=%v", got, want) 58 } 59 60 tests := []struct { 61 interval [2]int64 62 want []bool 63 }{ 64 { 65 interval: [2]int64{0, 0}, 66 want: []bool{}, 67 }, 68 { 69 interval: [2]int64{10, 10}, 70 want: []bool{}, 71 }, 72 { 73 interval: [2]int64{0, 5}, 74 want: []bool{true, false, true, true, true}, 75 }, 76 { 77 interval: [2]int64{5, 10}, 78 want: []bool{true, true, false, true, false}, 79 }, 80 { 81 interval: [2]int64{2, 7}, 82 want: []bool{true, true, true, true, true}, 83 }, 84 } 85 86 for _, tc := range tests { 87 t.Run("", func(t *testing.T) { 88 89 slice := array.NewSlice(arr, tc.interval[0], tc.interval[1]).(*array.Boolean) 90 defer slice.Release() 91 92 if got, want := slice.Len(), len(tc.want); got != want { 93 t.Fatalf("got=%d, want=%d", got, want) 94 } 95 96 vs := make([]bool, slice.Len()) 97 98 for i := range vs { 99 vs[i] = slice.Value(i) 100 } 101 102 if got, want := vs, tc.want; !reflect.DeepEqual(got, want) { 103 t.Fatalf("got=%v, want=%v", got, want) 104 } 105 }) 106 } 107 } 108 109 func TestBooleanSliceDataWithNull(t *testing.T) { 110 pool := memory.NewCheckedAllocator(memory.NewGoAllocator()) 111 defer pool.AssertSize(t, 0) 112 113 values := []bool{true, false, true, false, false, false, true, false, true, false} 114 valids := []bool{true, false, true, true, true, true, true, false, true, true} 115 116 b := array.NewBooleanBuilder(pool) 117 defer b.Release() 118 119 b.AppendValues(values, valids) 120 121 arr := b.NewArray().(*array.Boolean) 122 defer arr.Release() 123 124 if got, want := arr.Len(), len(valids); got != want { 125 t.Fatalf("got=%d, want=%d", got, want) 126 } 127 128 if got, want := arr.NullN(), 2; got != want { 129 t.Fatalf("got=%d, want=%d", got, want) 130 } 131 132 vs := make([]bool, arr.Len()) 133 134 for i := range vs { 135 vs[i] = arr.Value(i) 136 } 137 138 if got, want := vs, values; !reflect.DeepEqual(got, want) { 139 t.Fatalf("got=%v, want=%v", got, want) 140 } 141 142 tests := []struct { 143 interval [2]int64 144 nulls int 145 want []bool 146 }{ 147 { 148 interval: [2]int64{2, 9}, 149 nulls: 1, 150 want: []bool{true, false, false, false, true, false, true}, 151 }, 152 { 153 interval: [2]int64{0, 7}, 154 nulls: 1, 155 want: []bool{true, false, true, false, false, false, true}, 156 }, 157 { 158 interval: [2]int64{1, 8}, 159 nulls: 2, 160 want: []bool{false, true, false, false, false, true, false}, 161 }, 162 { 163 interval: [2]int64{2, 7}, 164 nulls: 0, 165 want: []bool{true, false, false, false, true}, 166 }, 167 } 168 169 for _, tc := range tests { 170 t.Run("", func(t *testing.T) { 171 172 slice := array.NewSlice(arr, tc.interval[0], tc.interval[1]).(*array.Boolean) 173 defer slice.Release() 174 175 if got, want := slice.NullN(), tc.nulls; got != want { 176 t.Errorf("got=%d, want=%d", got, want) 177 } 178 179 if got, want := slice.Len(), len(tc.want); got != want { 180 t.Fatalf("got=%d, want=%d", got, want) 181 } 182 183 vs := make([]bool, slice.Len()) 184 185 for i := range vs { 186 vs[i] = slice.Value(i) 187 } 188 189 if got, want := vs, tc.want; !reflect.DeepEqual(got, want) { 190 t.Fatalf("got=%v, want=%v", got, want) 191 } 192 }) 193 } 194 } 195 196 func TestBooleanSliceOutOfBounds(t *testing.T) { 197 pool := memory.NewCheckedAllocator(memory.NewGoAllocator()) 198 defer pool.AssertSize(t, 0) 199 200 values := []bool{true, false, true, false, true, false, true, false, true, false} 201 202 b := array.NewBooleanBuilder(pool) 203 defer b.Release() 204 205 for _, v := range values { 206 b.Append(v) 207 } 208 209 arr := b.NewArray().(*array.Boolean) 210 defer arr.Release() 211 212 slice := array.NewSlice(arr, 3, 8).(*array.Boolean) 213 defer slice.Release() 214 215 tests := []struct { 216 index int 217 panic bool 218 }{ 219 { 220 index: -1, 221 panic: true, 222 }, 223 { 224 index: 5, 225 panic: true, 226 }, 227 { 228 index: 0, 229 panic: false, 230 }, 231 { 232 index: 4, 233 panic: false, 234 }, 235 } 236 237 for _, tc := range tests { 238 t.Run("", func(t *testing.T) { 239 240 var val bool 241 242 if tc.panic { 243 defer func() { 244 e := recover() 245 if e == nil { 246 t.Fatalf("this should have panicked, but did not; slice value %v", val) 247 } 248 if got, want := e.(string), "arrow/array: index out of range"; got != want { 249 t.Fatalf("invalid error. got=%q, want=%q", got, want) 250 } 251 }() 252 } else { 253 defer func() { 254 if e := recover(); e != nil { 255 t.Fatalf("unexpected panic: %v", e) 256 } 257 }() 258 } 259 260 val = slice.Value(tc.index) 261 }) 262 } 263 } 264 265 func TestBooleanStringer(t *testing.T) { 266 pool := memory.NewCheckedAllocator(memory.NewGoAllocator()) 267 defer pool.AssertSize(t, 0) 268 269 var ( 270 values = []bool{true, false, true, false, true, false, true, false, true, false} 271 valids = []bool{true, true, false, true, true, true, false, true, true, true} 272 ) 273 274 b := array.NewBooleanBuilder(pool) 275 defer b.Release() 276 277 b.AppendValues(values, valids) 278 279 arr := b.NewArray().(*array.Boolean) 280 defer arr.Release() 281 282 out := new(strings.Builder) 283 fmt.Fprintf(out, "%v", arr) 284 285 const want = "[true false (null) false true false (null) false true false]" 286 if got := out.String(); got != want { 287 t.Fatalf("invalid stringer:\ngot= %q\nwant=%q", got, want) 288 } 289 assert.Equal(t, "true", arr.ValueStr(0)) 290 assert.Equal(t, "false", arr.ValueStr(1)) 291 assert.Equal(t, array.NullValueStr, arr.ValueStr(2)) 292 } 293 294 func TestBooleanStringRoundTrip(t *testing.T) { 295 // 1. create array 296 mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) 297 defer mem.AssertSize(t, 0) 298 299 values := []bool{true, false, true, true, true, true, true, false, true, false} 300 valid := []bool{true, false, false, true, false, true, true, false, true, false} 301 302 b := array.NewBooleanBuilder(mem) 303 defer b.Release() 304 305 b.AppendValues(values, valid) 306 307 arr := b.NewArray().(*array.Boolean) 308 defer arr.Release() 309 310 // 2. create array via AppendValueFromString 311 b1 := array.NewBooleanBuilder(mem) 312 defer b1.Release() 313 314 for i := 0; i < arr.Len(); i++ { 315 assert.NoError(t, b1.AppendValueFromString(arr.ValueStr(i))) 316 } 317 318 arr1 := b1.NewArray().(*array.Boolean) 319 defer arr1.Release() 320 321 assert.True(t, array.Equal(arr, arr1)) 322 }