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  }