You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
5.7 KiB

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