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.

265 lines
5.8 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 TestSub(t *testing.T) {
  67. testCases := []struct {
  68. initBA string
  69. subtractingBA string
  70. expectedBA string
  71. }{
  72. {`null`, `null`, `null`},
  73. {`"x"`, `null`, `null`},
  74. {`null`, `"x"`, `null`},
  75. {`"x"`, `"x"`, `"_"`},
  76. {`"xxxxxx"`, `"x_x_x_"`, `"_x_x_x"`},
  77. {`"x_x_x_"`, `"xxxxxx"`, `"______"`},
  78. {`"xxxxxx"`, `"x_x_x_xxxx"`, `"_x_x_x"`},
  79. {`"x_x_x_xxxx"`, `"xxxxxx"`, `"______xxxx"`},
  80. {`"xxxxxxxxxx"`, `"x_x_x_"`, `"_x_x_xxxxx"`},
  81. {`"x_x_x_"`, `"xxxxxxxxxx"`, `"______"`},
  82. }
  83. for _, tc := range testCases {
  84. var bA *BitArray
  85. err := json.Unmarshal([]byte(tc.initBA), &bA)
  86. require.Nil(t, err)
  87. var o *BitArray
  88. err = json.Unmarshal([]byte(tc.subtractingBA), &o)
  89. require.Nil(t, err)
  90. got, _ := json.Marshal(bA.Sub(o))
  91. require.Equal(
  92. t,
  93. tc.expectedBA,
  94. string(got),
  95. "%s minus %s doesn't equal %s",
  96. tc.initBA,
  97. tc.subtractingBA,
  98. tc.expectedBA,
  99. )
  100. }
  101. }
  102. func TestPickRandom(t *testing.T) {
  103. empty16Bits := "________________"
  104. empty64Bits := empty16Bits + empty16Bits + empty16Bits + empty16Bits
  105. testCases := []struct {
  106. bA string
  107. ok bool
  108. }{
  109. {`null`, false},
  110. {`"x"`, true},
  111. {`"` + empty16Bits + `"`, false},
  112. {`"x` + empty16Bits + `"`, true},
  113. {`"` + empty16Bits + `x"`, true},
  114. {`"x` + empty16Bits + `x"`, true},
  115. {`"` + empty64Bits + `"`, false},
  116. {`"x` + empty64Bits + `"`, true},
  117. {`"` + empty64Bits + `x"`, true},
  118. {`"x` + empty64Bits + `x"`, true},
  119. }
  120. for _, tc := range testCases {
  121. var bitArr *BitArray
  122. err := json.Unmarshal([]byte(tc.bA), &bitArr)
  123. require.NoError(t, err)
  124. _, ok := bitArr.PickRandom()
  125. require.Equal(t, tc.ok, ok, "PickRandom got an unexpected result on input %s", tc.bA)
  126. }
  127. }
  128. func TestBytes(t *testing.T) {
  129. bA := NewBitArray(4)
  130. bA.SetIndex(0, true)
  131. check := func(bA *BitArray, bz []byte) {
  132. if !bytes.Equal(bA.Bytes(), bz) {
  133. panic(fmt.Sprintf("Expected %X but got %X", bz, bA.Bytes()))
  134. }
  135. }
  136. check(bA, []byte{0x01})
  137. bA.SetIndex(3, true)
  138. check(bA, []byte{0x09})
  139. bA = NewBitArray(9)
  140. check(bA, []byte{0x00, 0x00})
  141. bA.SetIndex(7, true)
  142. check(bA, []byte{0x80, 0x00})
  143. bA.SetIndex(8, true)
  144. check(bA, []byte{0x80, 0x01})
  145. bA = NewBitArray(16)
  146. check(bA, []byte{0x00, 0x00})
  147. bA.SetIndex(7, true)
  148. check(bA, []byte{0x80, 0x00})
  149. bA.SetIndex(8, true)
  150. check(bA, []byte{0x80, 0x01})
  151. bA.SetIndex(9, true)
  152. check(bA, []byte{0x80, 0x03})
  153. }
  154. func TestEmptyFull(t *testing.T) {
  155. ns := []int{47, 123}
  156. for _, n := range ns {
  157. bA := NewBitArray(n)
  158. if !bA.IsEmpty() {
  159. t.Fatal("Expected bit array to be empty")
  160. }
  161. for i := 0; i < n; i++ {
  162. bA.SetIndex(i, true)
  163. }
  164. if !bA.IsFull() {
  165. t.Fatal("Expected bit array to be full")
  166. }
  167. }
  168. }
  169. func TestUpdateNeverPanics(t *testing.T) {
  170. newRandBitArray := func(n int) *BitArray {
  171. ba, _ := randBitArray(n)
  172. return ba
  173. }
  174. pairs := []struct {
  175. a, b *BitArray
  176. }{
  177. {nil, nil},
  178. {newRandBitArray(10), newRandBitArray(12)},
  179. {newRandBitArray(23), newRandBitArray(23)},
  180. {newRandBitArray(37), nil},
  181. {nil, NewBitArray(10)},
  182. }
  183. for _, pair := range pairs {
  184. a, b := pair.a, pair.b
  185. a.Update(b)
  186. b.Update(a)
  187. }
  188. }
  189. func TestNewBitArrayNeverCrashesOnNegatives(t *testing.T) {
  190. bitList := []int{-127, -128, -1 << 31}
  191. for _, bits := range bitList {
  192. _ = NewBitArray(bits)
  193. }
  194. }
  195. func TestJSONMarshalUnmarshal(t *testing.T) {
  196. bA1 := NewBitArray(0)
  197. bA2 := NewBitArray(1)
  198. bA3 := NewBitArray(1)
  199. bA3.SetIndex(0, true)
  200. bA4 := NewBitArray(5)
  201. bA4.SetIndex(0, true)
  202. bA4.SetIndex(1, true)
  203. testCases := []struct {
  204. bA *BitArray
  205. marshalledBA string
  206. }{
  207. {nil, `null`},
  208. {bA1, `null`},
  209. {bA2, `"_"`},
  210. {bA3, `"x"`},
  211. {bA4, `"xx___"`},
  212. }
  213. for _, tc := range testCases {
  214. tc := tc
  215. t.Run(tc.bA.String(), func(t *testing.T) {
  216. bz, err := json.Marshal(tc.bA)
  217. require.NoError(t, err)
  218. assert.Equal(t, tc.marshalledBA, string(bz))
  219. var unmarshalledBA *BitArray
  220. err = json.Unmarshal(bz, &unmarshalledBA)
  221. require.NoError(t, err)
  222. if tc.bA == nil {
  223. require.Nil(t, unmarshalledBA)
  224. } else {
  225. require.NotNil(t, unmarshalledBA)
  226. assert.EqualValues(t, tc.bA.Bits, unmarshalledBA.Bits)
  227. if assert.EqualValues(t, tc.bA.String(), unmarshalledBA.String()) {
  228. assert.EqualValues(t, tc.bA.Elems, unmarshalledBA.Elems)
  229. }
  230. }
  231. })
  232. }
  233. }