github.com/tunabay/go-bitarray@v1.3.1/bitarray_slice_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 "math/rand" 9 "testing" 10 "time" 11 12 "github.com/tunabay/go-bitarray" 13 ) 14 15 func TestBitArray_Slice(t *testing.T) { 16 bs := "" 17 set := func(s string) { 18 t.Helper() 19 bs = s 20 // t.Logf("data: %q", bs) 21 } 22 test := func(s, e int, exp string) { 23 t.Helper() 24 ba := bitarray.MustParse(bs) 25 sliced := ba.Slice(s, e) 26 sliced.V() 27 slicedE := sliced.ZExpand() 28 slicedO := sliced.ZOptimize() 29 expected := bitarray.MustParse(exp) 30 switch { 31 case !sliced.Equal(expected): 32 t.Errorf("% b: [%d:%d]: unexpected slice:", ba, s, e) 33 t.Logf(" got: %#b", sliced) 34 t.Logf(" got: %s", sliced.D()) 35 case !slicedE.Equal(expected): 36 t.Errorf("% b: [%d:%d]: unexpected slice (e):", ba, s, e) 37 t.Logf(" got: %#b", slicedE) 38 t.Logf(" got: %s", slicedE.D()) 39 case !slicedO.Equal(expected): 40 t.Errorf("% b: [%d:%d]: unexpected slice (o):", ba, s, e) 41 t.Logf(" got: %#b", slicedO) 42 t.Logf(" got: %s", slicedO.D()) 43 } 44 if t.Failed() { 45 t.Logf("want: %#b", expected) 46 t.FailNow() 47 } 48 // t.Logf("pass: [%d:%d]: % b", s, e, sliced) 49 } 50 testPanic := func(s, e int) { 51 t.Helper() 52 ba := bitarray.MustParse(bs) 53 var rba *bitarray.BitArray 54 defer func() { 55 if recover() == nil { 56 t.Errorf("panic expected:") 57 t.Logf(" got: %#b", rba) 58 t.Logf(" got: %s", rba.D()) 59 } 60 }() 61 rba = ba.Slice(s, e) 62 } 63 64 set("") 65 test(0, 0, "") 66 testPanic(0, 1) 67 68 set("1111-11") 69 test(0, 0, "") 70 test(4, 4, "") 71 test(0, 3, "111") 72 test(0, 6, "1111-11") 73 testPanic(-1, 1) 74 testPanic(1, 0) 75 testPanic(5, 0) 76 testPanic(5, 3) 77 testPanic(99, 3) 78 testPanic(0, -1) 79 80 set("1111-0000 1010-0101 1100-11") 81 test(0, 0, "") 82 test(0, 1, "1") 83 test(1, 3, "11") 84 test(0, 3, "111") 85 test(0, 8, "1111-0000") 86 test(2, 8, "11-0000") 87 test(3, 11, "1-0000 101") 88 test(9, 15, "010-010") 89 test(0, 22, "1111-0000 1010-0101 1100-11") 90 test(18, 22, "0011") 91 test(21, 22, "1") 92 93 set("0000-0000 0000-0000 0000-0000 0000-0000") 94 test(0, 0, "") 95 test(0, 1, "0") 96 test(0, 7, "0000-000") 97 test(0, 8, "0000-0000") 98 test(0, 9, "0000-0000 0") 99 test(0, 15, "0000-0000 0000-000") 100 test(0, 16, "0000-0000 0000-0000") 101 test(0, 17, "0000-0000 0000-0000 0") 102 test(6, 15, "00 0000-000") 103 test(6, 16, "00 0000-0000") 104 test(6, 17, "00 0000-0000 0") 105 test(0, 31, "0000-0000 0000-0000 0000-0000 0000-000") 106 test(0, 32, "0000-0000 0000-0000 0000-0000 0000-0000") 107 test(15, 31, "0 0000-0000 0000-000") 108 test(15, 32, "0 0000-0000 0000-0000") 109 test(16, 31, "0000-0000 0000-000") 110 test(16, 32, "0000-0000 0000-0000") 111 test(19, 31, "0-0000 0000-000") 112 test(19, 32, "0-0000 0000-0000") 113 test(24, 31, "0000-000") 114 test(24, 32, "0000-0000") 115 test(27, 31, "0-000") 116 test(27, 32, "0-0000") 117 118 set("0000-0000 0") 119 test(0, 9, "0000-0000 0") 120 testPanic(0, 10) 121 testPanic(9, 10) 122 123 set("1010-0101 1010-0101 1010-0101 1010-0101") 124 test(0, 0, "") 125 test(0, 1, "1") 126 test(3, 6, "0-01") 127 test(7, 8, "1") 128 test(8, 9, "1") 129 test(0, 7, "1010-010") 130 test(0, 8, "1010-0101") 131 test(0, 9, "1010-0101 1") 132 test(0, 15, "1010-0101 1010-010") 133 test(0, 16, "1010-0101 1010-0101") 134 test(0, 17, "1010-0101 1010-0101 1") 135 test(6, 15, "01 1010-010") 136 test(6, 16, "01 1010-0101") 137 test(6, 17, "01 1010-0101 1") 138 test(10, 14, "10-01") 139 test(0, 31, "1010-0101 1010-0101 1010-0101 1010-010") 140 test(0, 32, "1010-0101 1010-0101 1010-0101 1010-0101") 141 test(15, 31, "1 1010-0101 1010-010") 142 test(15, 32, "1 1010-0101 1010-0101") 143 test(16, 31, "1010-0101 1010-010") 144 test(16, 32, "1010-0101 1010-0101") 145 test(19, 31, "0-0101 1010-010") 146 test(19, 32, "0-0101 1010-0101") 147 test(24, 31, "1010-010") 148 test(24, 32, "1010-0101") 149 test(26, 29, "10-0") 150 test(27, 31, "0-010") 151 test(27, 32, "0-0101") 152 153 set("1110-0011 1000-1110 0011-1000 1110-0011 1000") 154 test(0, 0, "") 155 test(0, 1, "1") 156 test(2, 6, "10-00") 157 test(6, 8, "11") 158 test(8, 10, "10") 159 test(0, 7, "1110-001") 160 test(0, 8, "1110-0011") 161 test(0, 9, "1110-0011 1") 162 test(0, 15, "1110-0011 1000-111") 163 test(0, 16, "1110-0011 1000-1110") 164 test(0, 17, "1110-0011 1000-1110 0") 165 test(5, 15, "011 1000-111") 166 test(5, 16, "011 1000-1110") 167 test(5, 17, "011 1000-1110 0") 168 test(10, 14, "00-11") 169 test(0, 31, "1110-0011 1000-1110 0011-1000 1110-001") 170 test(0, 32, "1110-0011 1000-1110 0011-1000 1110-0011") 171 test(0, 33, "1110-0011 1000-1110 0011-1000 1110-0011 1") 172 test(0, 34, "1110-0011 1000-1110 0011-1000 1110-0011 10") 173 test(0, 35, "1110-0011 1000-1110 0011-1000 1110-0011 100") 174 test(0, 36, "1110-0011 1000-1110 0011-1000 1110-0011 1000") 175 test(14, 31, "10 0011-1000 1110-001") 176 test(14, 32, "10 0011-1000 1110-0011") 177 test(14, 33, "10 0011-1000 1110-0011 1") 178 test(14, 34, "10 0011-1000 1110-0011 10") 179 test(14, 35, "10 0011-1000 1110-0011 100") 180 test(14, 36, "10 0011-1000 1110-0011 1000") 181 test(16, 31, "0011-1000 1110-001") 182 test(16, 32, "0011-1000 1110-0011") 183 test(16, 33, "0011-1000 1110-0011 1") 184 test(16, 36, "0011-1000 1110-0011 1000") 185 test(19, 31, "1-1000 1110-001") 186 test(19, 32, "1-1000 1110-0011") 187 test(19, 33, "1-1000 1110-0011 1") 188 test(19, 36, "1-1000 1110-0011 1000") 189 test(24, 31, "1110-001") 190 test(24, 32, "1110-0011") 191 test(25, 31, "110-001") 192 test(26, 29, "10-0") 193 test(27, 31, "0-001") 194 test(27, 32, "0-0011") 195 } 196 197 func TestBitArray_Slice_rand(t *testing.T) { 198 const testIterations = 50000 199 rand.Seed(time.Now().UnixNano()) 200 201 n := 0 202 for i := 0; i < testIterations/1000; i++ { 203 ba := bitarray.PseudoRand(0x100, nil) // random 256 bits 204 srcStr := ba.String() 205 for j := 0; j < 1000 && n < testIterations; j++ { 206 ss := rand.Intn(0x101) // 0 .. 256 207 sl := rand.Intn(0x101 - ss) // 0 .. 256-ss 208 se := ss + sl // ss .. 256 209 210 expected := bitarray.MustParse(srcStr[ss:se]) 211 sliced := ba.Slice(ss, se) 212 sliced.V() 213 slicedE := sliced.ZExpand() 214 slicedO := sliced.ZOptimize() 215 if !sliced.Equal(expected) || !slicedE.Equal(expected) || !slicedO.Equal(expected) { 216 t.Errorf("unxepected slice of [%d:%d] len=%d:", ss, se, se-ss) 217 t.Logf(" all: % s", ba) 218 t.Logf("want: % s", expected) 219 t.Logf("want: %s", expected.D()) 220 t.Logf(" got: % s", sliced) 221 t.Logf(" got: %s", sliced.D()) 222 t.FailNow() 223 } 224 if i == 0 && j < 32 { 225 // t.Logf("pass: [%d:%d] % s", ss, se, sliced) 226 } 227 n++ 228 } 229 } 230 } 231 232 func TestBitArray_ToWidth(t *testing.T) { 233 tcs := []struct { 234 w int 235 s, l, r string 236 }{ 237 {0, "0000-0000", "", ""}, 238 {0, "1111-1111", "", ""}, 239 {12, "1111-1111 1100", "1111-1111 1100", "1111-1111 1100"}, 240 {1, "1010-1010", "1", "0"}, 241 {5, "0000-000", "00000", "00000"}, 242 {4, "1100-0001", "1100", "0001"}, 243 // TODO: more 244 } 245 chk := func(got, want *bitarray.BitArray) { 246 t.Helper() 247 got.V() 248 if !got.Equal(want) { 249 t.Error("unexpected result:") 250 t.Logf(" got: %#b", got) 251 t.Logf(" got: %s", got.D()) 252 t.Logf("want: %#b", want) 253 t.FailNow() 254 } 255 } 256 for _, tc := range tcs { 257 expL := bitarray.MustParse(tc.l).ZOptimize() 258 expR := bitarray.MustParse(tc.r).ZOptimize() 259 ba := bitarray.MustParse(tc.s) 260 baE := ba.ZExpand() 261 262 chk(ba.ToWidth(tc.w, bitarray.AlignLeft), expL) 263 chk(baE.ToWidth(tc.w, bitarray.AlignLeft), expL) 264 chk(ba.ToWidth(tc.w, bitarray.AlignRight), expR) 265 chk(baE.ToWidth(tc.w, bitarray.AlignRight), expR) 266 } 267 func() { 268 var ba *bitarray.BitArray 269 defer func() { 270 if recover() == nil { 271 t.Errorf("panic expected: got %#b", ba) 272 } 273 }() 274 ba = bitarray.MustParse("10101").ToWidth(-1, bitarray.AlignLeft) 275 }() 276 } 277 278 func TestBitArray_TrimPrefix(t *testing.T) { 279 tdt := []string{ 280 "", "", "", 281 "", "0011", "", 282 "", "1", "", 283 "0", "", "0", 284 "0", "0", "", 285 "0", "1", "0", 286 "1", "", "1", 287 "1", "0", "1", 288 "1", "1", "", 289 "0000-0000 0000-0000", "", "0000-0000 0000-0000", 290 "0000-0000 0000-0000", "0", "0000-0000 0000-000", 291 "0000-0000 0000-0000", "0000", "0000-0000 0000", 292 "0000-0000 0000-0000", "0001", "0000-0000 0000-0000", 293 "1111-1111 0000-0011", "0000", "1111-1111 0000-0011", 294 "1111-1111 0000-0011", "111", "1111-1000 0001-1", 295 "1111-1111 0000-0011", "1111-1111 00", "0000-11", 296 "0101-1111 0101-1111 0101-11", "01", "0111-1101 0111-1101 0111", 297 } 298 chk := func(got, want *bitarray.BitArray) { 299 t.Helper() 300 got.V() 301 if !got.Equal(want) { 302 t.Error("unexpected result:") 303 t.Logf(" got: %#b", got) 304 t.Logf(" got: %s", got.D()) 305 t.Logf("want: %#b", want) 306 t.FailNow() 307 } 308 } 309 for i := 0; i < len(tdt); i += 3 { 310 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 311 ba1 := bitarray.MustParse(tdt[i+1]).ZOptimize() 312 exp := bitarray.MustParse(tdt[i+2]) 313 ba0E := ba0.ZExpand() 314 ba1E := ba1.ZExpand() 315 316 chk(ba0.TrimPrefix(ba1), exp) 317 chk(ba0.TrimPrefix(ba1E), exp) 318 chk(ba0E.TrimPrefix(ba1), exp) 319 chk(ba0E.TrimPrefix(ba1E), exp) 320 } 321 } 322 323 func TestBitArray_TrimSuffix(t *testing.T) { 324 tdt := []string{ 325 "", "", "", 326 "", "0011", "", 327 "", "1", "", 328 "0", "", "0", 329 "0", "0", "", 330 "0", "1", "0", 331 "1", "", "1", 332 "1", "0", "1", 333 "1", "1", "", 334 "0000-0000 0000-0000", "", "0000-0000 0000-0000", 335 "0000-0000 0000-0000", "0", "0000-0000 0000-000", 336 "0000-0000 0000-0000", "0000", "0000-0000 0000", 337 "0000-0000 0000-0000", "0001", "0000-0000 0000-0000", 338 "1111-1111 0000-0011", "0000", "1111-1111 0000-0011", 339 "1111-1111 0000-0011", "011", "1111-1111 0000-0", 340 "1111-1111 0000-0011", "1111 0000-0011", "1111", 341 "0101-1111 0101-1111 0101-11", "0111", "0101-1111 0101-1111 01", 342 } 343 chk := func(got, want *bitarray.BitArray) { 344 t.Helper() 345 got.V() 346 if !got.Equal(want) { 347 t.Error("unexpected result:") 348 t.Logf(" got: %#b", got) 349 t.Logf(" got: %s", got.D()) 350 t.Logf("want: %#b", want) 351 t.FailNow() 352 } 353 } 354 for i := 0; i < len(tdt); i += 3 { 355 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 356 ba1 := bitarray.MustParse(tdt[i+1]).ZOptimize() 357 exp := bitarray.MustParse(tdt[i+2]) 358 ba0E := ba0.ZExpand() 359 ba1E := ba1.ZExpand() 360 chk(ba0.TrimSuffix(ba1), exp) 361 chk(ba0.TrimSuffix(ba1E), exp) 362 chk(ba0E.TrimSuffix(ba1), exp) 363 chk(ba0E.TrimSuffix(ba1E), exp) 364 } 365 } 366 367 func TestBitArray_TrimLeadingZeros(t *testing.T) { 368 tdt := []string{ 369 "", "", 370 "0", "", 371 "1", "1", 372 "1100", "1100", 373 "0011", "11", 374 "0000-0000", "", 375 "0000-1010", "1010", 376 "0000-0000 0000", "", 377 "0000-0000 1010", "1010", 378 "0000-0000 0000-1010", "1010", 379 "0000-0000 0000-0001 010", "1010", 380 "0000-0000 0000-0000 0010-10", "1010", 381 "0000-0000 0000-0000 0000-0101 0", "1010", 382 "0x_0000_0000 0x_0000_0000 0x_0000 0b_0011_11", "1111", 383 } 384 chk := func(got, want *bitarray.BitArray) { 385 t.Helper() 386 got.V() 387 if !got.Equal(want) { 388 t.Error("unexpected result:") 389 t.Logf(" got: %#b", got) 390 t.Logf(" got: %s", got.D()) 391 t.Logf("want: %#b", want) 392 t.FailNow() 393 } 394 } 395 for i := 0; i < len(tdt); i += 2 { 396 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 397 exp := bitarray.MustParse(tdt[i+1]) 398 ba0E := ba0.ZExpand() 399 chk(ba0.TrimLeadingZeros(), exp) 400 chk(ba0E.TrimLeadingZeros(), exp) 401 } 402 } 403 404 func TestBitArray_TrimTrailingZeros(t *testing.T) { 405 tdt := []string{ 406 "", "", 407 "0", "", 408 "1", "1", 409 "1100", "11", 410 "0011", "0011", 411 "0000-0000", "", 412 "0000-1010", "0000-101", 413 "0000-0101", "0000-0101", 414 "1010-0000", "101", 415 "0000-0000 0000", "", 416 "0101-0000 0000", "0101", 417 "0000-0000 0101", "0000-0000 0101", 418 "0101-0000 0000-0000", "0101", 419 "0101-0000 0000-0000 000", "0101", 420 "0101-0000 0000-0000 0000-00", "0101", 421 "0101-0000 0000-0000 0000-0000 0", "0101", 422 "0101-0000 0000-0000 0000-0001 0", "0101-0000 0000-0000 0000-0001", 423 "1111 0x_0000_0000 0x_0000_0000 0x_0000 0", "1111", 424 } 425 chk := func(got, want *bitarray.BitArray) { 426 t.Helper() 427 got.V() 428 if !got.Equal(want) { 429 t.Error("unexpected result:") 430 t.Logf(" got: %#b", got) 431 t.Logf(" got: %s", got.D()) 432 t.Logf("want: %#b", want) 433 t.FailNow() 434 } 435 } 436 for i := 0; i < len(tdt); i += 2 { 437 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 438 exp := bitarray.MustParse(tdt[i+1]) 439 ba0E := ba0.ZExpand() 440 chk(ba0.TrimTrailingZeros(), exp) 441 chk(ba0E.TrimTrailingZeros(), exp) 442 } 443 }