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 }