github.com/supragya/TendermintConnector@v0.0.0-20210619045051-113e32b84fb1/_deprecated_chains/cosmos/libs/common/bit_array_test.go (about)

     1  package common
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func randBitArray(bits int) (*BitArray, []byte) {
    14  	src := RandBytes((bits + 7) / 8)
    15  	bA := NewBitArray(bits)
    16  	for i := 0; i < len(src); i++ {
    17  		for j := 0; j < 8; j++ {
    18  			if i*8+j >= bits {
    19  				return bA, src
    20  			}
    21  			setBit := src[i]&(1<<uint(j)) > 0
    22  			bA.SetIndex(i*8+j, setBit)
    23  		}
    24  	}
    25  	return bA, src
    26  }
    27  
    28  func TestAnd(t *testing.T) {
    29  
    30  	bA1, _ := randBitArray(51)
    31  	bA2, _ := randBitArray(31)
    32  	bA3 := bA1.And(bA2)
    33  
    34  	var bNil *BitArray
    35  	require.Equal(t, bNil.And(bA1), (*BitArray)(nil))
    36  	require.Equal(t, bA1.And(nil), (*BitArray)(nil))
    37  	require.Equal(t, bNil.And(nil), (*BitArray)(nil))
    38  
    39  	if bA3.Bits != 31 {
    40  		t.Error("Expected min bits", bA3.Bits)
    41  	}
    42  	if len(bA3.Elems) != len(bA2.Elems) {
    43  		t.Error("Expected min elems length")
    44  	}
    45  	for i := 0; i < bA3.Bits; i++ {
    46  		expected := bA1.GetIndex(i) && bA2.GetIndex(i)
    47  		if bA3.GetIndex(i) != expected {
    48  			t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i))
    49  		}
    50  	}
    51  }
    52  
    53  func TestOr(t *testing.T) {
    54  
    55  	bA1, _ := randBitArray(51)
    56  	bA2, _ := randBitArray(31)
    57  	bA3 := bA1.Or(bA2)
    58  
    59  	bNil := (*BitArray)(nil)
    60  	require.Equal(t, bNil.Or(bA1), bA1)
    61  	require.Equal(t, bA1.Or(nil), bA1)
    62  	require.Equal(t, bNil.Or(nil), (*BitArray)(nil))
    63  
    64  	if bA3.Bits != 51 {
    65  		t.Error("Expected max bits")
    66  	}
    67  	if len(bA3.Elems) != len(bA1.Elems) {
    68  		t.Error("Expected max elems length")
    69  	}
    70  	for i := 0; i < bA3.Bits; i++ {
    71  		expected := bA1.GetIndex(i) || bA2.GetIndex(i)
    72  		if bA3.GetIndex(i) != expected {
    73  			t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i))
    74  		}
    75  	}
    76  }
    77  
    78  func TestSub(t *testing.T) {
    79  	testCases := []struct {
    80  		initBA        string
    81  		subtractingBA string
    82  		expectedBA    string
    83  	}{
    84  		{`null`, `null`, `null`},
    85  		{`"x"`, `null`, `null`},
    86  		{`null`, `"x"`, `null`},
    87  		{`"x"`, `"x"`, `"_"`},
    88  		{`"xxxxxx"`, `"x_x_x_"`, `"_x_x_x"`},
    89  		{`"x_x_x_"`, `"xxxxxx"`, `"______"`},
    90  		{`"xxxxxx"`, `"x_x_x_xxxx"`, `"_x_x_x"`},
    91  		{`"x_x_x_xxxx"`, `"xxxxxx"`, `"______xxxx"`},
    92  		{`"xxxxxxxxxx"`, `"x_x_x_"`, `"_x_x_xxxxx"`},
    93  		{`"x_x_x_"`, `"xxxxxxxxxx"`, `"______"`},
    94  	}
    95  	for _, tc := range testCases {
    96  		var bA *BitArray
    97  		err := json.Unmarshal([]byte(tc.initBA), &bA)
    98  		require.Nil(t, err)
    99  
   100  		var o *BitArray
   101  		err = json.Unmarshal([]byte(tc.subtractingBA), &o)
   102  		require.Nil(t, err)
   103  
   104  		got, _ := json.Marshal(bA.Sub(o))
   105  		require.Equal(t, tc.expectedBA, string(got), "%s minus %s doesn't equal %s", tc.initBA, tc.subtractingBA, tc.expectedBA)
   106  	}
   107  }
   108  
   109  func TestPickRandom(t *testing.T) {
   110  	empty16Bits := "________________"
   111  	empty64Bits := empty16Bits + empty16Bits + empty16Bits + empty16Bits
   112  	testCases := []struct {
   113  		bA string
   114  		ok bool
   115  	}{
   116  		{`null`, false},
   117  		{`"x"`, true},
   118  		{`"` + empty16Bits + `"`, false},
   119  		{`"x` + empty16Bits + `"`, true},
   120  		{`"` + empty16Bits + `x"`, true},
   121  		{`"x` + empty16Bits + `x"`, true},
   122  		{`"` + empty64Bits + `"`, false},
   123  		{`"x` + empty64Bits + `"`, true},
   124  		{`"` + empty64Bits + `x"`, true},
   125  		{`"x` + empty64Bits + `x"`, true},
   126  	}
   127  	for _, tc := range testCases {
   128  		var bitArr *BitArray
   129  		err := json.Unmarshal([]byte(tc.bA), &bitArr)
   130  		require.NoError(t, err)
   131  		_, ok := bitArr.PickRandom()
   132  		require.Equal(t, tc.ok, ok, "PickRandom got an unexpected result on input %s", tc.bA)
   133  	}
   134  }
   135  
   136  func TestBytes(t *testing.T) {
   137  	bA := NewBitArray(4)
   138  	bA.SetIndex(0, true)
   139  	check := func(bA *BitArray, bz []byte) {
   140  		if !bytes.Equal(bA.Bytes(), bz) {
   141  			panic(fmt.Sprintf("Expected %X but got %X", bz, bA.Bytes()))
   142  		}
   143  	}
   144  	check(bA, []byte{0x01})
   145  	bA.SetIndex(3, true)
   146  	check(bA, []byte{0x09})
   147  
   148  	bA = NewBitArray(9)
   149  	check(bA, []byte{0x00, 0x00})
   150  	bA.SetIndex(7, true)
   151  	check(bA, []byte{0x80, 0x00})
   152  	bA.SetIndex(8, true)
   153  	check(bA, []byte{0x80, 0x01})
   154  
   155  	bA = NewBitArray(16)
   156  	check(bA, []byte{0x00, 0x00})
   157  	bA.SetIndex(7, true)
   158  	check(bA, []byte{0x80, 0x00})
   159  	bA.SetIndex(8, true)
   160  	check(bA, []byte{0x80, 0x01})
   161  	bA.SetIndex(9, true)
   162  	check(bA, []byte{0x80, 0x03})
   163  }
   164  
   165  func TestEmptyFull(t *testing.T) {
   166  	ns := []int{47, 123}
   167  	for _, n := range ns {
   168  		bA := NewBitArray(n)
   169  		if !bA.IsEmpty() {
   170  			t.Fatal("Expected bit array to be empty")
   171  		}
   172  		for i := 0; i < n; i++ {
   173  			bA.SetIndex(i, true)
   174  		}
   175  		if !bA.IsFull() {
   176  			t.Fatal("Expected bit array to be full")
   177  		}
   178  	}
   179  }
   180  
   181  func TestUpdateNeverPanics(t *testing.T) {
   182  	newRandBitArray := func(n int) *BitArray {
   183  		ba, _ := randBitArray(n)
   184  		return ba
   185  	}
   186  	pairs := []struct {
   187  		a, b *BitArray
   188  	}{
   189  		{nil, nil},
   190  		{newRandBitArray(10), newRandBitArray(12)},
   191  		{newRandBitArray(23), newRandBitArray(23)},
   192  		{newRandBitArray(37), nil},
   193  		{nil, NewBitArray(10)},
   194  	}
   195  
   196  	for _, pair := range pairs {
   197  		a, b := pair.a, pair.b
   198  		a.Update(b)
   199  		b.Update(a)
   200  	}
   201  }
   202  
   203  func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) {
   204  	bitList := []int{-127, -128, -1 << 31}
   205  	for _, bits := range bitList {
   206  		_ = NewBitArray(bits)
   207  	}
   208  }
   209  
   210  func TestJSONMarshalUnmarshal(t *testing.T) {
   211  
   212  	bA1 := NewBitArray(0)
   213  
   214  	bA2 := NewBitArray(1)
   215  
   216  	bA3 := NewBitArray(1)
   217  	bA3.SetIndex(0, true)
   218  
   219  	bA4 := NewBitArray(5)
   220  	bA4.SetIndex(0, true)
   221  	bA4.SetIndex(1, true)
   222  
   223  	testCases := []struct {
   224  		bA           *BitArray
   225  		marshalledBA string
   226  	}{
   227  		{nil, `null`},
   228  		{bA1, `null`},
   229  		{bA2, `"_"`},
   230  		{bA3, `"x"`},
   231  		{bA4, `"xx___"`},
   232  	}
   233  
   234  	for _, tc := range testCases {
   235  		t.Run(tc.bA.String(), func(t *testing.T) {
   236  			bz, err := json.Marshal(tc.bA)
   237  			require.NoError(t, err)
   238  
   239  			assert.Equal(t, tc.marshalledBA, string(bz))
   240  
   241  			var unmarshalledBA *BitArray
   242  			err = json.Unmarshal(bz, &unmarshalledBA)
   243  			require.NoError(t, err)
   244  
   245  			if tc.bA == nil {
   246  				require.Nil(t, unmarshalledBA)
   247  			} else {
   248  				require.NotNil(t, unmarshalledBA)
   249  				assert.EqualValues(t, tc.bA.Bits, unmarshalledBA.Bits)
   250  				if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
   251  					assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
   252  				}
   253  			}
   254  		})
   255  	}
   256  }