v / vlib / bitfield / bitfield_test.v
401 lines · 372 sloc · 8.86 KB · de5eaa63e849a8642b5410dac72babc770376cbe
Raw
1import bitfield
2import rand
3
4fn test_bf_new_size() {
5 instance := bitfield.new(75)
6 assert instance.get_size() == 75
7}
8
9fn test_bf_set_clear_toggle_get() {
10 mut instance := bitfield.new(75)
11 instance.set_bit(47)
12 assert instance.get_bit(47) == 1
13 instance.clear_bit(47)
14 assert instance.get_bit(47) == 0
15 instance.toggle_bit(47)
16 assert instance.get_bit(47) == 1
17 instance.set_if(true, 48)
18 assert instance.get_bit(48) == 1
19 instance.set_if(false, 48)
20 assert instance.get_bit(48) == 0
21}
22
23fn test_bf_multiple_flags() {
24 mut instance := bitfield.new(75)
25
26 // 1,3,5,7,9 set
27 instance.set_bits(1, 3, 5, 7, 9)
28 assert instance.all(1, 3, 5, 7, 9)
29 assert instance.all(1, 3, 20) == false
30 assert instance.has(1, 20, 30, 40)
31 assert instance.has(20, 30, 40) == false
32
33 // 1,3 set
34 instance.clear_bits(5, 7, 9)
35 assert instance.all(1, 3, 5, 7, 9) == false
36 assert instance.all(1, 3)
37 assert instance.has(3, 20, 30, 40)
38
39 // 3,5,7 set
40 instance.toggle_bits(1, 5, 7)
41 assert instance.all(3, 5, 7)
42 assert instance.all(1, 3, 5, 7) == false
43 assert instance.has(5, 20, 30, 40)
44}
45
46fn test_bf_insert_extract() {
47 mut instance := bitfield.new(11)
48 instance.set_all()
49 instance.insert(2, 9, 3)
50 assert instance.extract(2, 1) == 0
51 assert instance.extract(2, 8) == 1
52 assert instance.extract(10, 1) == 1
53 instance.set_all()
54 instance.insert_lowest_bits_first(2, 9, 3)
55 assert instance.extract_lowest_bits_first(2, 1) == 1
56 assert instance.extract_lowest_bits_first(2, 8) == 3
57 assert instance.extract_lowest_bits_first(10, 1) == 0
58}
59
60fn test_bf_and_not_or_xor() {
61 len := 80
62 mut input1 := bitfield.new(len)
63 mut input2 := bitfield.new(len)
64 mut i := 0
65 for i < len {
66 if rand.intn(2) or { 0 } == 1 {
67 input1.set_bit(i)
68 }
69 if rand.intn(2) or { 0 } == 1 {
70 input2.set_bit(i)
71 }
72 i++
73 }
74 output1 := bitfield.bf_xor(input1, input2)
75 bf_and := bitfield.bf_and(input1, input2)
76 bf_or := bitfield.bf_or(input1, input2)
77 bf_not := bitfield.bf_not(bf_and)
78 output2 := bitfield.bf_and(bf_or, bf_not)
79 mut result := 1
80 i = 0
81 for i < len {
82 if output1.get_bit(i) != output2.get_bit(i) {
83 result = 0
84 }
85 i++
86 }
87 assert result == 1
88}
89
90fn test_clone_cmp() {
91 len := 80
92 mut input := bitfield.new(len)
93 for i in 0 .. len {
94 if rand.intn(2) or { 0 } == 1 {
95 input.set_bit(i)
96 }
97 }
98 output := input.clone()
99 assert output.get_size() == len
100 assert input == output
101}
102
103fn test_slice_join() {
104 len := 80
105 mut input := bitfield.new(len)
106 for i in 0 .. len {
107 if rand.intn(2) or { 0 } == 1 {
108 input.set_bit(i)
109 }
110 }
111 mut result := 1
112 for point := 1; point < (len - 1); point++ {
113 // divide a bitfield into two subfields
114 chunk1 := input.slice(0, point)
115 chunk2 := input.slice(point, input.get_size())
116 // concatenate them back into one and compare to the original
117 output := bitfield.join(chunk1, chunk2)
118 if input != output {
119 result = 0
120 }
121 }
122 assert result == 1
123}
124
125fn test_pop_count() {
126 len := 80
127 mut count0 := 0
128 mut input := bitfield.new(len)
129 for i in 0 .. len {
130 if rand.intn(2) or { 0 } == 1 {
131 input.set_bit(i)
132 count0++
133 }
134 }
135 count1 := input.pop_count()
136 assert count0 == count1
137}
138
139fn test_pop_count2() {
140 b :=
141 bitfield.from_str('011000110110110000010001000011010011011111011110101001010011011010001100001001101111111011010011')
142 assert b.pop_count() == 50
143}
144
145fn test_hamming() {
146 len := 80
147 mut count := 0
148 mut input1 := bitfield.new(len)
149 mut input2 := bitfield.new(len)
150 for i in 0 .. len {
151 match rand.intn(4) {
152 0, 1 {
153 input1.set_bit(i)
154 count++
155 }
156 2 {
157 input2.set_bit(i)
158 count++
159 }
160 3 {
161 input1.set_bit(i)
162 input2.set_bit(i)
163 }
164 else {}
165 } or { 0 }
166 }
167 assert count == bitfield.hamming(input1, input2)
168}
169
170fn test_bf_from_bytes() {
171 input := [u8(0x01), 0xF0, 0x0F, 0xF0, 0xFF]
172 output := bitfield.from_bytes(input).str()
173 assert output == '00000001' + '11110000' + '00001111' + '11110000' + '11111111'
174 newoutput := bitfield.from_str(output).str()
175 assert newoutput == output
176}
177
178fn test_bf_from_bytes_lowest_bits_first() {
179 input := [u8(0x01), 0xF0]
180 output := bitfield.from_bytes_lowest_bits_first(input).str()
181 assert output == '10000000' + '00001111'
182 newoutput := bitfield.from_str(output).str()
183 assert newoutput == output
184}
185
186fn test_bf_from_str() {
187 len := 80
188 mut input := ''
189 for _ in 0 .. len {
190 if rand.intn(2) or { 0 } == 1 {
191 input = input + '1'
192 } else {
193 input = input + '0'
194 }
195 }
196 output := bitfield.from_str(input)
197 mut result := 1
198 for i in 0 .. len {
199 if input[i] != output.get_bit(i) + 48 {
200 result = 0
201 }
202 }
203 assert result == 1
204}
205
206fn test_bf_bf2str() {
207 len := 80
208 mut input := bitfield.new(len)
209 for i in 0 .. len {
210 if rand.intn(2) or { 0 } == 1 {
211 input.set_bit(i)
212 }
213 }
214 mut check := ''
215 for i in 0 .. len {
216 if input.get_bit(i) == 1 {
217 check = check + '1'
218 } else {
219 check = check + '0'
220 }
221 }
222 output := input.str()
223 mut result := 1
224 for i in 0 .. len {
225 if check[i] != output[i] {
226 result = 0
227 }
228 }
229 assert result == 1
230}
231
232fn test_bf_set_all() {
233 len := 80
234 mut input := bitfield.new(len)
235 input.set_all()
236 mut result := 1
237 for i in 0 .. len {
238 if input.get_bit(i) != 1 {
239 result = 0
240 }
241 }
242 assert result == 1
243}
244
245fn test_bf_clear_all() {
246 len := 80
247 mut input := bitfield.new(len)
248 for i in 0 .. len {
249 if rand.intn(2) or { 0 } == 1 {
250 input.set_bit(i)
251 }
252 }
253 input.clear_all()
254 mut result := 1
255 for i in 0 .. len {
256 if input.get_bit(i) != 0 {
257 result = 0
258 }
259 }
260 assert result == 1
261}
262
263fn test_bf_reverse() {
264 len := 80
265 mut input := bitfield.new(len)
266 for i in 0 .. len {
267 if rand.intn(2) or { 0 } == 1 {
268 input.set_bit(i)
269 }
270 }
271 check := input.clone()
272 output := input.reverse()
273 mut result := 1
274 for i in 0 .. len {
275 if output.get_bit(i) != check.get_bit(len - i - 1) {
276 result = 0
277 }
278 }
279 assert result == 1
280}
281
282fn test_bf_resize() {
283 len := 80
284 mut input := bitfield.new(rand.intn(len) or { 0 } + 1)
285 for _ in 0 .. 100 {
286 input.resize(rand.intn(len) or { 0 } + 1)
287 input.set_bit(input.get_size() - 1)
288 }
289 assert input.get_bit(input.get_size() - 1) == 1
290}
291
292fn test_bf_pos() {
293 /*
294 *
295 * set haystack size to 80
296 * test different sizes of needle, from 1 to 80
297 * test different positions of needle, from 0 to where it fits
298 * all haystacks here contain exactly one instance of needle,
299 * so search should return non-negative-values
300 *
301 */
302 len := 80
303 mut result := 1
304 for i := 1; i < len; i++ { // needle size
305 for j in 0 .. len - i { // needle position in the haystack
306 // create the needle
307 mut needle := bitfield.new(i)
308 // fill the needle with random values
309 for k in 0 .. i {
310 if rand.intn(2) or { 0 } == 1 {
311 needle.set_bit(k)
312 }
313 }
314 // make sure the needle contains at least one set bit, selected randomly
315 r := rand.intn(i) or { 0 }
316 needle.set_bit(r)
317 // create the haystack, make sure it contains the needle
318 mut haystack := needle.clone()
319 // if there is space between the start of the haystack and the sought needle, fill it with zeroes
320 if j > 0 {
321 start := bitfield.new(j)
322 tmp := bitfield.join(start, haystack)
323 haystack = tmp
324 }
325 // if there is space between the sought needle and the end of haystack, fill it with zeroes
326 if j + i < len {
327 end := bitfield.new(len - j - i)
328 tmp2 := bitfield.join(haystack, end)
329 haystack = tmp2
330 }
331 // now let's test
332 // the result should be equal to j
333 if haystack.pos(needle) != j {
334 result = 0
335 }
336 }
337 }
338 assert result == 1
339}
340
341fn test_bf_rotate() {
342 mut result := 1
343 len := 80
344 for i := 1; i < 80 && result == 1; i++ {
345 mut chunk1 := bitfield.new(i)
346 chunk2 := bitfield.new(len - i)
347 chunk1.set_all()
348 input := bitfield.join(chunk1, chunk2)
349 output := input.rotate(i)
350 if output.get_bit(len - i - 1) != 0 || output.get_bit(len - i) != 1 {
351 result = 0
352 }
353 }
354 assert result == 1
355}
356
357fn test_bf_printing() {
358 len := 80
359 mut input := bitfield.new(len)
360 for i in 0 .. len {
361 if rand.intn(2) or { 0 } == 0 {
362 input.set_bit(i)
363 }
364 }
365 // the following should convert the bitfield input into a string automatically
366 println(input)
367 assert true
368}
369
370fn test_bf_shift() {
371 str := '0001001101111111'
372 bf := bitfield.from_str(str)
373 bf_left := bf.shift_left(4)
374 assert bf_left.str() == '0011011111110000'
375 bf_right := bf.shift_right(4)
376 assert bf_right.str() == '0000000100110111'
377
378 bf_large_left := bf.shift_left(100)
379 bf_large_right := bf.shift_right(100)
380 assert bf_large_left.str() == '0000000000000000'
381 assert bf_large_right.str() == '0000000000000000'
382}
383
384// Regression test: zero-length slice must not panic (reported via slice(i,i) and pos(new(0))).
385fn test_zero_length_slice_and_pos() {
386 // slice(i, i) on a non-empty bitfield must return an empty bitfield
387 bf := bitfield.from_str('101')
388 empty := bf.slice(1, 1)
389 assert empty.get_size() == 0
390 assert empty.str() == ''
391
392 // pos with a zero-length needle on a non-empty bitfield must not panic
393 needle := bitfield.new(0)
394 pos := bf.pos(needle)
395 // empty needle matches at position 0 by convention
396 assert pos == 0
397
398 // pos on a zero-length bitfield with a zero-length needle must not panic
399 empty_bf := bitfield.new(0)
400 assert empty_bf.pos(needle) == 0
401}
402