github.com/tunabay/go-bitarray@v1.3.1/bitarray_concat_test.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray_test 6 7 import ( 8 "errors" 9 "fmt" 10 "math/rand" 11 "testing" 12 "time" 13 14 "github.com/tunabay/go-bitarray" 15 ) 16 17 // this also tests JoinBitArrayer. 18 func TestJoin(t *testing.T) { 19 chk := func(got, want *bitarray.BitArray, src []*bitarray.BitArray) { 20 t.Helper() 21 got.V() 22 if !got.Equal(want) { 23 t.Error("unexpected result:") 24 t.Logf(" got: %#b", got) 25 t.Logf(" got: %s", got.D()) 26 t.Logf("want: %#b", want) 27 for i, s := range src { 28 t.Logf("data: #%2d: %#b", i, s) 29 } 30 t.FailNow() 31 } 32 } 33 test := func(s, sep string, elems ...string) { 34 t.Helper() 35 want := bitarray.MustParse(s) 36 sepB := bitarray.MustParse(sep) 37 bas := make([]*bitarray.BitArray, len(elems)) 38 basEA := make([]*bitarray.BitArray, len(elems)) 39 basE0 := make([]*bitarray.BitArray, len(elems)) 40 basE1 := make([]*bitarray.BitArray, len(elems)) 41 basI := make([]bitarray.BitArrayer, len(elems)) 42 basIEA := make([]bitarray.BitArrayer, len(elems)) 43 basIE0 := make([]bitarray.BitArrayer, len(elems)) 44 basIE1 := make([]bitarray.BitArrayer, len(elems)) 45 for i, elem := range elems { 46 bas[i] = bitarray.MustParse(elem).ZOptimize() 47 basI[i] = bas[i] 48 basEA[i] = bas[i].ZExpand() 49 basIEA[i] = basEA[i] 50 basE0[i] = bas[i] 51 basIE0[i] = basE0[i] 52 if i&1 == 0 { 53 basE0[i] = basEA[i] 54 basIE0[i] = basE0[i] 55 } 56 basE1[i] = bas[i] 57 basIE1[i] = basE1[i] 58 if i&1 == 1 { 59 basE1[i] = basEA[i] 60 basIE1[i] = basE1[i] 61 } 62 } 63 chk(bitarray.Join(bas, sepB), want, bas) 64 chk(bitarray.Join(basEA, sepB), want, basEA) 65 chk(bitarray.Join(basE0, sepB), want, basE0) 66 chk(bitarray.Join(basE1, sepB), want, basE1) 67 chk(bitarray.JoinBitArrayer(basI, sepB), want, bas) 68 chk(bitarray.JoinBitArrayer(basIEA, sepB), want, basEA) 69 chk(bitarray.JoinBitArrayer(basIE0, sepB), want, basE0) 70 chk(bitarray.JoinBitArrayer(basIE1, sepB), want, basE1) 71 } 72 test("", "") 73 test("", "111") 74 test("", "", "") 75 test("", "111", "") 76 test("", "", "", "", "", "") 77 test("101101101", "101", "", "", "", "") 78 test("111", "00", "111") 79 test("1111-1111", "00", "1111-1111") 80 test("1111-0000 1010", "0000", "1111", "1010") 81 test( 82 "1010-1010 11 0000-0000 1111-1111 1111-1111 1111-1111 11"+ 83 " 0000-0000 0000-0000 0000-0000 1111-1111 1111-1111"+ 84 " 0000-0000 0000-0000 0000-0000 00", 85 "", 86 "1010-1010 11", 87 "0000-0000", 88 "1111-1111", 89 "1111-1111 1111-1111 11", 90 "0000-0000 0000-0000 0000-0000", 91 "1111-1111 1111-1111", 92 "0000-0000 0000-0000 0000-0000 00", 93 ) 94 } 95 96 func TestJoinBitArrayer_edge(t *testing.T) { 97 sep := bitarray.MustParse("1111") 98 z := bitarray.New() 99 if got := bitarray.JoinBitArrayer(nil, nil); !got.IsZero() { 100 t.Errorf("unexpected result: got %#b, want zero", got) 101 } 102 if got := bitarray.JoinBitArrayer(nil, z); !got.IsZero() { 103 t.Errorf("unexpected result: got %#b, want zero", got) 104 } 105 if got := bitarray.JoinBitArrayer(nil, sep); !got.IsZero() { 106 t.Errorf("unexpected result: got %#b, want zero", got) 107 } 108 109 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{}, nil); !got.IsZero() { 110 t.Errorf("unexpected result: got %#b, want zero", got) 111 } 112 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{}, z); !got.IsZero() { 113 t.Errorf("unexpected result: got %#b, want zero", got) 114 } 115 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{}, sep); !got.IsZero() { 116 t.Errorf("unexpected result: got %#b, want zero", got) 117 } 118 119 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil}, nil); !got.IsZero() { 120 t.Errorf("unexpected result: got %#b, want zero", got) 121 } 122 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil}, z); !got.IsZero() { 123 t.Errorf("unexpected result: got %#b, want zero", got) 124 } 125 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil}, sep); !got.IsZero() { 126 t.Errorf("unexpected result: got %#b, want zero", got) 127 } 128 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z}, nil); !got.IsZero() { 129 t.Errorf("unexpected result: got %#b, want zero", got) 130 } 131 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z}, z); !got.IsZero() { 132 t.Errorf("unexpected result: got %#b, want zero", got) 133 } 134 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z}, sep); !got.IsZero() { 135 t.Errorf("unexpected result: got %#b, want zero", got) 136 } 137 138 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil, nil}, nil); !got.IsZero() { 139 t.Errorf("unexpected result: got %#b, want zero", got) 140 } 141 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil, nil}, z); !got.IsZero() { 142 t.Errorf("unexpected result: got %#b, want zero", got) 143 } 144 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{nil, nil}, sep); !got.Equal(sep) { 145 t.Errorf("unexpected result: got %#b, want %#b", got, sep) 146 } 147 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z, z}, nil); !got.IsZero() { 148 t.Errorf("unexpected result: got %#b, want zero", got) 149 } 150 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z, z}, z); !got.IsZero() { 151 t.Errorf("unexpected result: got %#b, want zero", got) 152 } 153 if got := bitarray.JoinBitArrayer([]bitarray.BitArrayer{z, z}, sep); !got.Equal(sep) { 154 t.Errorf("unexpected result: got %#b, want %#b", got, sep) 155 } 156 } 157 158 func TestBitArray_Append_edge(t *testing.T) { 159 var ba0 *bitarray.BitArray 160 ba1 := bitarray.MustParse("1010") 161 if got := ba0.Append(); !got.IsZero() { 162 t.Errorf("unexpected result: got %#b, want zero", got) 163 } 164 if got := ba1.Append(); !got.Equal(ba1) { 165 t.Errorf("unexpected result: got %#b, want %#b", got, ba1) 166 } 167 168 baL := bitarray.MustParse("1111-1100 0000-0000 0000-0000 00") 169 baS := baL.Slice(0, 7) 170 baA := bitarray.NewZeroFilled(8) 171 baZ := bitarray.New() 172 want := bitarray.MustParse("1111-1100 0000-000") 173 if got := baS.Append(baA); !got.Equal(want) { 174 t.Errorf("unexpected result: got %#b, want %#b", got, want) 175 } 176 177 if got := baS.Append(nil); !got.Equal(baS) { 178 t.Errorf("unexpected result: got %#b, want %#b", got, baS) 179 } 180 if got := baS.Append(baZ); !got.Equal(baS) { 181 t.Errorf("unexpected result: got %#b, want %#b", got, baS) 182 } 183 if got := baZ.Append(baZ); !got.IsZero() { 184 t.Errorf("unexpected result: got %#b, want zero", got) 185 } 186 if got := ba0.Append(baS); !got.Equal(baS) { 187 t.Errorf("unexpected result: got %#b, want %#b", got, baS) 188 } 189 } 190 191 func TestBitArray_Append_rand(t *testing.T) { 192 const testIterations = 10000 193 rand.Seed(time.Now().UnixNano()) 194 195 for i := 0; i < testIterations; i++ { 196 var ba *bitarray.BitArray 197 switch rand.Intn(20) { 198 case 0, 1, 2, 3: 199 nBits := rand.Intn(64) 200 ba = bitarray.PseudoRand(nBits, nil) 201 case 4, 5, 6, 7: 202 nBits := 8*(1+rand.Intn(64)) - 1 + rand.Intn(3) 203 ba = bitarray.PseudoRand(nBits, nil) 204 case 8: 205 nBits := rand.Intn(1024) 206 ba = bitarray.NewZeroFilled(nBits) 207 case 9: 208 nBits := rand.Intn(1024) 209 ba = bitarray.NewOneFilled(nBits) 210 default: 211 nBits := rand.Intn(1024) 212 ba = bitarray.PseudoRand(nBits, nil) 213 } 214 lim := ba.Len() 215 if rand.Intn(100) == 0 { 216 lim = ba.Len() - rand.Intn(ba.Len()>>1+1) 217 } 218 var myErr error 219 if rand.Intn(50) == 0 { 220 myErr = fmt.Errorf("custom error %d", i) 221 } 222 223 baS := ba.String() 224 225 fn := func(i, b int) error { 226 t.Helper() 227 if baS[i] != '0'+byte(b) { 228 return fmt.Errorf("%d: got %d, want %c", i, b, baS[i]) 229 } 230 if lim < i { 231 if myErr == nil { 232 return bitarray.BreakIteration 233 } 234 return fmt.Errorf("test error: %d: %w", i, myErr) 235 } 236 return nil 237 } 238 if err := ba.Iterate(fn); err != nil { 239 if myErr == nil || !errors.Is(err, myErr) { 240 t.Errorf("unexpected error: %s", err) 241 t.FailNow() 242 } 243 } 244 if err := ba.ZExpand().Iterate(fn); err != nil { 245 if myErr == nil || !errors.Is(err, myErr) { 246 t.Errorf("unexpected bit (e): %s", err) 247 t.FailNow() 248 } 249 } 250 // if i < 32 { 251 // t.Logf("pass: %#b", ba) 252 // } 253 } 254 } 255 256 func TestBitArray_Repeat_edge(t *testing.T) { 257 ba1 := bitarray.NewZeroFilled(123) 258 ba2 := ba1.Repeat(100) 259 if !ba2.Equal(bitarray.NewZeroFilled(12300)) { 260 t.Errorf("unexpected result: %#b", ba2) 261 t.Logf("data: %s", ba2.D()) 262 } 263 ba3 := ba1.Repeat(0) 264 if !ba3.IsZero() { 265 t.Errorf("unexpected result: %#b", ba3) 266 t.Logf("data: %s", ba3.D()) 267 } 268 ba4 := bitarray.New().Repeat(999) 269 if !ba4.IsZero() { 270 t.Errorf("unexpected result: %#b", ba4) 271 t.Logf("data: %s", ba4.D()) 272 } 273 func() { 274 var ba *bitarray.BitArray 275 defer func() { 276 if recover() == nil { 277 t.Errorf("panic expected: got %#b", ba) 278 } 279 }() 280 ba = bitarray.MustParse("1010-10").Repeat(-1) 281 }() 282 }