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  }