bitstring 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/CONTRIBUTORS.txt +5 -0
  2. data/Changelog.txt +20 -0
  3. data/LICENCE.txt +202 -0
  4. data/NOTICE.txt +5 -0
  5. data/README.txt +63 -0
  6. data/doc/classes/BitString.html +2479 -0
  7. data/doc/classes/BitString.src/M000001.html +99 -0
  8. data/doc/classes/BitString.src/M000002.html +18 -0
  9. data/doc/classes/BitString.src/M000003.html +20 -0
  10. data/doc/classes/BitString.src/M000004.html +19 -0
  11. data/doc/classes/BitString.src/M000005.html +24 -0
  12. data/doc/classes/BitString.src/M000006.html +44 -0
  13. data/doc/classes/BitString.src/M000007.html +21 -0
  14. data/doc/classes/BitString.src/M000008.html +18 -0
  15. data/doc/classes/BitString.src/M000009.html +18 -0
  16. data/doc/classes/BitString.src/M000010.html +22 -0
  17. data/doc/classes/BitString.src/M000011.html +29 -0
  18. data/doc/classes/BitString.src/M000012.html +22 -0
  19. data/doc/classes/BitString.src/M000013.html +43 -0
  20. data/doc/classes/BitString.src/M000014.html +19 -0
  21. data/doc/classes/BitString.src/M000015.html +40 -0
  22. data/doc/classes/BitString.src/M000016.html +21 -0
  23. data/doc/classes/BitString.src/M000017.html +18 -0
  24. data/doc/classes/BitString.src/M000018.html +18 -0
  25. data/doc/classes/BitString.src/M000019.html +18 -0
  26. data/doc/classes/BitString.src/M000020.html +20 -0
  27. data/doc/classes/BitString.src/M000021.html +24 -0
  28. data/doc/classes/BitString.src/M000022.html +23 -0
  29. data/doc/classes/BitString.src/M000023.html +42 -0
  30. data/doc/classes/BitString.src/M000024.html +61 -0
  31. data/doc/classes/BitString.src/M000025.html +18 -0
  32. data/doc/classes/BitString.src/M000026.html +18 -0
  33. data/doc/classes/BitString.src/M000027.html +20 -0
  34. data/doc/classes/BitString.src/M000028.html +18 -0
  35. data/doc/classes/BitString.src/M000029.html +18 -0
  36. data/doc/classes/BitString.src/M000030.html +18 -0
  37. data/doc/classes/BitString.src/M000031.html +18 -0
  38. data/doc/classes/BitString.src/M000032.html +18 -0
  39. data/doc/created.rid +1 -0
  40. data/doc/files/lib/bitstring/operators_rb.html +122 -0
  41. data/doc/files/lib/bitstring_rb.html +153 -0
  42. data/doc/fr_class_index.html +27 -0
  43. data/doc/fr_file_index.html +28 -0
  44. data/doc/fr_method_index.html +60 -0
  45. data/doc/index.html +24 -0
  46. data/doc/rdoc-style.css +208 -0
  47. data/lib/bitstring.rb +1318 -0
  48. data/lib/bitstring/operators.rb +481 -0
  49. data/test/Rakefile +21 -0
  50. data/test/test_basic.rb +848 -0
  51. data/test/test_data.rb +24 -0
  52. data/test/test_enum.rb +671 -0
  53. data/test/test_helper.rb +3 -0
  54. data/test/test_operators.rb +454 -0
  55. metadata +121 -0
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require File.dirname(__FILE__) + '/test_helper.rb'
3
+
4
+ module Tests
5
+
6
+ class Test_BitStrings < Test::Unit::TestCase
7
+
8
+ TestVals = [
9
+ '00000000000001111111111111',
10
+ '00101001010100101010111001101101',
11
+ '1100111000111100001111100000',
12
+ '101100111000111100001111100000',
13
+ '101010101010101010101010101010',
14
+ '010101010101010101010101010101',
15
+ '0000000000000000000000000000',
16
+ '1111111111111111111111111111'
17
+ ]
18
+
19
+ IfNoneCalled = 'IfNone invoked'
20
+ IfNone = lambda { return IfNoneCalled }
21
+
22
+ end # class Test_BitStrings
23
+
24
+ end # module Tests
@@ -0,0 +1,671 @@
1
+ require 'rubygems'
2
+ require File.dirname(__FILE__) + '/test_helper.rb'
3
+ require File.dirname(__FILE__) + '/test_data.rb'
4
+
5
+ #
6
+ # Test the methods inherited from the Enumerable mixin.
7
+ #
8
+
9
+ module Tests
10
+
11
+ class Test_BitStrings < Test::Unit::TestCase
12
+
13
+ #
14
+ # The all? method returns true IFF every iteration of the block returns
15
+ # a true value.
16
+ #
17
+ def test_010_all?()
18
+ return unless (BitString.new.respond_to?(:all?))
19
+ TestVals.each do |sVal|
20
+ #
21
+ # Start with unbounded bitstrings.
22
+ #
23
+ bs = BitString.new(sVal)
24
+ assert(bs.all? { |v| true },
25
+ "Test unbounded '#{sVal}'.all? true == true")
26
+ assert(! bs.all? { |v| false },
27
+ "Test unbounded '#{sVal}'.all? false == false")
28
+ tick = 0
29
+ assert(! bs.all? { |v| ((tick += 1) % 2).zero? },
30
+ "Test unbounded '#{sVal}'.all? sometimes == false")
31
+ #
32
+ # Repeat for bounded strings.
33
+ #
34
+ bs = BitString.new(sVal, sVal.length)
35
+ assert(bs.all? { |v| true },
36
+ "Test bounded '#{sVal}'.all? true == true")
37
+ assert(! bs.all? { |v| false },
38
+ "Test bounded '#{sVal}'.all? false == false")
39
+ tick = 0
40
+ assert(! bs.all? { |v| ((tick += 1) % 2).zero? },
41
+ "Test bounded '#{sVal}'.all? sometimes == false")
42
+ end
43
+ end
44
+
45
+ #
46
+ # Test that the any? method works. (Returns true if any iteration of
47
+ # the block does.)
48
+ #
49
+ def test_020_any?()
50
+ return unless (BitString.new.respond_to?(:any?))
51
+ TestVals.each do |sVal|
52
+ #
53
+ # Start with unbounded bitstrings.
54
+ #
55
+ bs = BitString.new(sVal)
56
+ assert(bs.any? { |v| true },
57
+ "Test unbounded '#{sVal}'.any? true == true")
58
+ assert(! bs.any? { |v| false },
59
+ "Test unbounded '#{sVal}'.any? false == false")
60
+ tick = 0
61
+ assert(bs.any? { |v| v == sVal[-1,1].to_i(2) },
62
+ "Test unbounded '#{sVal}'.any? sometimes == true")
63
+ #
64
+ # Repeat for bounded strings.
65
+ #
66
+ bs = BitString.new(sVal, sVal.length)
67
+ assert(bs.any? { |v| true },
68
+ "Test bounded '#{sVal}'.any? true == true")
69
+ assert(! bs.any? { |v| false },
70
+ "Test bounded '#{sVal}'.any? false == false")
71
+ tick = 0
72
+ assert(bs.any? { |v| v == sVal[-1,1].to_i(2) },
73
+ "Test bounded '#{sVal}'.any? sometimes == true")
74
+ end
75
+ end
76
+
77
+ def test_030_collect()
78
+ return unless (BitString.new.respond_to?(:collect))
79
+ TestVals.each do |sVal|
80
+ #
81
+ # Unbounded first.
82
+ #
83
+ bs = BitString.new(sVal)
84
+ tVal = sVal.sub(/^0+(.)/, '\1').reverse
85
+ assert_equal(tVal.split(//),
86
+ bs.collect { |v| v.to_s(2) },
87
+ "Test that unbounded '#{sVal}'.collect works")
88
+ #
89
+ # Now bounded..
90
+ #
91
+ bs = BitString.new(sVal, sVal.length)
92
+ tVal = sVal.reverse
93
+ assert_equal(tVal.split(//),
94
+ bs.collect { |v| v.to_s(2) },
95
+ "Test that bounded '#{sVal}'.collect works")
96
+ end
97
+ end
98
+
99
+ #
100
+ # Returns the first value for which the block doesn't return false.
101
+ # If all iterations return false, .detect() calls the proc specified
102
+ # by the ifnone argument and returns its result; otherwise it returns
103
+ # nil.
104
+ #
105
+ def test_040_detect()
106
+ return unless (BitString.new.respond_to?(:detect))
107
+ TestVals.each do |sVal|
108
+ #
109
+ # Start with unbounded bitstrings.
110
+ #
111
+ bs = BitString.new(sVal)
112
+ assert_equal(sVal[-1,1].to_i(2),
113
+ bs.detect { |v| true },
114
+ "Test unbounded '#{sVal}'.detect {true} == '#{sVal[-1,1]}'")
115
+ assert_nil(bs.detect { |v| false },
116
+ "Test unbounded '#{sVal}'.detect {false} == nil")
117
+ assert_equal(IfNoneCalled,
118
+ bs.detect(IfNone) { |v| false },
119
+ "Test unbounded '#{sVal}'.detect(ifnone) {false} == " +
120
+ "'#{IfNoneCalled}'")
121
+ #
122
+ # Now bounded ones.
123
+ #
124
+ bs = BitString.new(sVal, sVal.length)
125
+ assert_equal(sVal[-1,1].to_i(2),
126
+ bs.detect { |v| true },
127
+ "Test bounded '#{sVal}'.detect {true} == '#{sVal[-1,1]}'")
128
+ assert_nil(bs.detect { |v| false },
129
+ "Test bounded '#{sVal}'.detect {false} == nil")
130
+ assert_equal(IfNoneCalled,
131
+ bs.detect(IfNone) { |v| false },
132
+ "Test bounded '#{sVal}'.detect(ifnone) {false} == " +
133
+ "'#{IfNoneCalled}'")
134
+ end
135
+ end
136
+
137
+ #
138
+ # Like .each, only passes two arguments.
139
+ #
140
+ def test_050_each_with_index()
141
+ return unless (BitString.new.respond_to?(:each_with_index))
142
+ TestVals.each do |sVal|
143
+ #
144
+ # Unbounded first..
145
+ #
146
+ bs = BitString.new(sVal)
147
+ bs.each_with_index do |val,pos|
148
+ assert_equal(sVal[-1-pos,1],
149
+ val.to_s,
150
+ "Test unbounded '#{sVal}'.each_with_index" +
151
+ "(#{val},#{pos}) == #{sVal[-1-pos,1]}")
152
+ end
153
+ #
154
+ # Now bounded strings.
155
+ #
156
+ bs = BitString.new(sVal, sVal.length)
157
+ bs.each_with_index do |val,pos|
158
+ assert_equal(sVal[-1-pos,1],
159
+ val.to_s,
160
+ "Test bounded '#{sVal}'.each_with_index" +
161
+ "(#{val},#{pos}) == #{sVal[-1-pos,1]}")
162
+ end
163
+ end
164
+ end
165
+
166
+ #
167
+ # Convert to an array. (Equivalent to .to_a ?)
168
+ #
169
+ def test_060_entries()
170
+ return unless (BitString.new.respond_to?(:entries))
171
+ TestVals.each do |sVal|
172
+ #
173
+ # Unbounded.
174
+ #
175
+ bs = BitString.new(sVal)
176
+ sVal_a = sVal.sub(/^0+(.)/, '\1').reverse.split(//).collect { |v| v.to_i(2) }
177
+ assert_equal(sVal_a,
178
+ bs.entries,
179
+ "Test unbounded '#{sVal}'.entries")
180
+ #
181
+ # Bounded.
182
+ #
183
+ bs = BitString.new(sVal, sVal.length)
184
+ sVal_a = sVal.reverse.split(//).collect { |v| v.to_i(2) }
185
+ assert_equal(sVal_a,
186
+ bs.entries,
187
+ "Test bounded '#{sVal}'.entries")
188
+ end
189
+ end
190
+
191
+ def test_070_find()
192
+ #
193
+ # Same as .detect(), don't bother to test.
194
+ #
195
+ end
196
+
197
+ #
198
+ # Like .find/.detect except it returns all matching values, not just
199
+ # the first.
200
+ #
201
+ def test_080_find_all()
202
+ return unless (BitString.new.respond_to?(:find_all))
203
+ TestVals.each do |sVal|
204
+ #
205
+ # Unbounded.
206
+ #
207
+ bs = BitString.new(sVal)
208
+ assert(bs.find_all { |v| false }.empty?,
209
+ "Test unbounded '#{sVal}'.find_all{false} == []")
210
+ #
211
+ # .population should have been tested in test_basic
212
+ #
213
+ assert_equal(bs.population(0),
214
+ bs.find_all { |v| v.zero? }.length,
215
+ "Test unbounded '#{sVal}.find_all{0}.length " +
216
+ "== population(0)")
217
+ assert_equal(bs.population(1),
218
+ bs.find_all { |v| v == 1 }.length,
219
+ "Test unbounded '#{sVal}.find_all{1}.length " +
220
+ "== population(1)")
221
+ sVal_t = sVal.sub(/^0+(.)/, '\1').reverse.split(//)
222
+ tick = 0
223
+ sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2).zero? }
224
+ sVal_t.collect! { |v| v.to_i(2) }
225
+ tick = 0
226
+ assert_equal(sVal_t,
227
+ bs.find_all { |v| ((tick += 1) % 2).zero? },
228
+ "Test unbounded '#{sVal}'.find_all(alt) works")
229
+ #
230
+ # Bounded.
231
+ #
232
+ bs = BitString.new(sVal, sVal.length)
233
+ assert(bs.find_all { |v| false }.empty?,
234
+ "Test bounded '#{sVal}'.find_all{false} == []")
235
+ assert_equal(bs.population(0),
236
+ bs.find_all { |v| v.zero? }.length,
237
+ "Test bounded '#{sVal}.find_all{0}.length " +
238
+ "== population(0)")
239
+ assert_equal(bs.population(1),
240
+ bs.find_all { |v| v == 1 }.length,
241
+ "Test bounded '#{sVal}.find_all{1}.length " +
242
+ "== population(1)")
243
+ sVal_t = sVal.reverse.split(//)
244
+ tick = 0
245
+ sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2).zero? }
246
+ sVal_t.collect! { |v| v.to_i(2) }
247
+ tick = 0
248
+ assert_equal(sVal_t,
249
+ bs.find_all { |v| ((tick += 1) % 2).zero? },
250
+ "Test bounded '#{sVal}'.find_all(alt) works")
251
+ end
252
+ end
253
+
254
+ #
255
+ # No grep here..
256
+ #
257
+ def test_090_grep()
258
+ return unless (BitString.new.respond_to?(:grep))
259
+ assert(false, '###FAIL! .grep not supported but .respond_to? is true!')
260
+ end
261
+
262
+ #
263
+ # Only 0 and 1 will ever succeed..
264
+ #
265
+ def test_100_include?()
266
+ return unless (BitString.new.respond_to?(:include?))
267
+ TestVals.each do |sVal|
268
+ #
269
+ # Unbounded.
270
+ #
271
+ bs = BitString.new(sVal)
272
+ assert(! bs.include?(2),
273
+ "Test unbounded '#{sVal}'.include?(2) fails")
274
+ [0, 1].each do |val|
275
+ if (bs.population(val) != 0)
276
+ assert(bs.include?(val),
277
+ "Test unbounded '#{sVal}'.include?(#{val}) succeeds")
278
+ else
279
+ assert(! bs.include?(val),
280
+ "Test unbounded '#{sVal}'.include?(#{val}) fails")
281
+ end
282
+ end
283
+ #
284
+ # Bounded.
285
+ #
286
+ bs = BitString.new(sVal, sVal.length)
287
+ assert(! bs.include?(2),
288
+ "Test bounded '#{sVal}'.include?(2) fails")
289
+ [0, 1].each do |val|
290
+ if (bs.population(val) != 0)
291
+ assert(bs.include?(val),
292
+ "Test bounded '#{sVal}'.include?(#{val}) succeeds")
293
+ else
294
+ assert(! bs.include?(val),
295
+ "Test bounded '#{sVal}'.include?(#{val}) fails")
296
+ end
297
+ end
298
+ end
299
+ end
300
+
301
+ #
302
+ # Test .inject
303
+ #
304
+ def test_110_inject()
305
+ return unless (BitString.new.respond_to?(:inject))
306
+ TestVals.each do |sVal|
307
+ #
308
+ # Unbounded..
309
+ #
310
+ bs = BitString.new(sVal)
311
+ result = bs.inject { |memo,val| memo + val }
312
+ assert_equal(bs.population(1),
313
+ result,
314
+ "Test unbounded '#{sVal}'.inject { memo + 1s}")
315
+ result = bs.inject(-20) { |memo,val| memo + val }
316
+ assert_equal(bs.population(1) - 20,
317
+ result,
318
+ "Test unbounded '#{sVal}'.inject(-20) { memo + 1s}")
319
+ #
320
+ # This one is failing because of the issue with the leading
321
+ # zeroes being stripped and the initial memo value being set
322
+ # from the LSB. I think.
323
+ #
324
+ result = bs.inject { |memo,val| memo + (val.zero? ? 1 : 0) }
325
+ expected = bs.population(0)
326
+ if (bs.population(1) == bs.length)
327
+ #
328
+ # All 1s means no 0s -- but memo picked up
329
+ # the value of bs[0]. Adjust the expectation.
330
+ #
331
+ expected = bs[0]
332
+ elsif (bs[0].zero?)
333
+ #
334
+ # memo will start out as zero, taken from the first bit, which
335
+ # won't be counted. .population did, though, so take it off.
336
+ #
337
+ expected -= 1
338
+ elsif (bs[0] == 1)
339
+ #
340
+ # memo will start out as 1 from the lsb, but that's not a zero --
341
+ # so alter the population result to allow for its addition.
342
+ #
343
+ expected += 1
344
+ end
345
+ assert_equal(expected,
346
+ result,
347
+ "Test unbounded '#{sVal}'.inject { memo + 0s}")
348
+ result = bs.inject(-20) { |memo,val| memo + (val.zero? ? 1 : 0) }
349
+ assert_equal(bs.population(0) - 20,
350
+ result,
351
+ "Test unbounded '#{sVal}'.inject(-20) { memo + 0s}")
352
+ #
353
+ # Bounded..
354
+ #
355
+ bs = BitString.new(sVal, sVal.length)
356
+ result = bs.inject { |memo,val| memo + val }
357
+ expected = bs.population(1)
358
+ assert_equal(expected,
359
+ result,
360
+ "Test bounded '#{sVal}'.inject { memo + 1s}")
361
+ result = bs.inject(-20) { |memo,val| memo + val }
362
+ expected = bs.population(1) - 20
363
+ assert_equal(expected,
364
+ result,
365
+ "Test bounded '#{sVal}'.inject(-20) { memo + 1s}")
366
+ result = bs.inject { |memo,val| memo + (val.zero? ? 1 : 0) }
367
+ expected = bs.population(0)
368
+ if (bs.population(1) == bs.length)
369
+ #
370
+ # All 1s means no 0s -- but memo picked up
371
+ # the value of bs[0]. Adjust the expectation.
372
+ #
373
+ expected = bs[0]
374
+ elsif (bs[0].zero?)
375
+ #
376
+ # memo will start out as zero, taken from the first bit, which
377
+ # won't be counted. .population did, though, so take it off.
378
+ #
379
+ expected -= 1
380
+ elsif (bs[0] == 1)
381
+ #
382
+ # memo will start out as 1 from the lsb, but that's not a zero --
383
+ # so alter the population result to allow for its addition.
384
+ #
385
+ expected += 1
386
+ end
387
+ assert_equal(expected,
388
+ result,
389
+ "Test bounded '#{sVal}'.inject { memo + 0s}")
390
+ result = bs.inject(-20) { |memo,val| memo + (val.zero? ? 1 : 0) }
391
+ assert_equal(bs.population(0) - 20,
392
+ result,
393
+ "Test bounded '#{sVal}'.inject(-20) { memo + 0s}")
394
+ end
395
+ end
396
+
397
+ def test_120_map()
398
+ #
399
+ # Same as .collect so don't bother to test.
400
+ #
401
+ end
402
+
403
+ def test_130_max()
404
+ return unless (BitString.new.respond_to?(:max))
405
+ TestVals.each do |sVal|
406
+ #
407
+ # Unbounded.
408
+ #
409
+ bs = BitString.new(sVal)
410
+ expected = bs.to_i.zero? ? 0 : 1
411
+ assert_equal(expected,
412
+ bs.max,
413
+ "Test unbounded '#{sVal}'.max == #{expected}")
414
+ #
415
+ # Bounded.
416
+ #
417
+ bs = BitString.new(sVal, sVal.length)
418
+ expected = bs.to_i.zero? ? 0 : 1
419
+ assert_equal(expected,
420
+ bs.max,
421
+ "Test bounded '#{sVal}'.max == #{expected}")
422
+ end
423
+ end
424
+
425
+ def test_140_member?()
426
+ #
427
+ # Same as .include? so don't bother to test.
428
+ #
429
+ end
430
+
431
+ def test_150_min()
432
+ return unless (BitString.new.respond_to?(:min))
433
+ TestVals.each do |sVal|
434
+ #
435
+ # Unbounded.
436
+ #
437
+ bs = BitString.new(sVal)
438
+ expected = (bs.population(1) == bs.length) ? 1 : 0
439
+ assert_equal(expected,
440
+ bs.min,
441
+ "Test unbounded '#{sVal}'.min == #{expected}")
442
+ #
443
+ # Bounded.
444
+ #
445
+ bs = BitString.new(sVal, sVal.length)
446
+ expected = (bs.population(1) == bs.length) ? 1 : 0
447
+ assert_equal(expected,
448
+ bs.min,
449
+ "Test bounded '#{sVal}'.min == #{expected}")
450
+ end
451
+ end
452
+
453
+ def test_160_partition()
454
+ return unless (BitString.new.respond_to?(:partition))
455
+ TestVals.each do |sVal|
456
+ #
457
+ # Unbounded.
458
+ #
459
+ bs = BitString.new(sVal)
460
+ n0 = bs.population(0)
461
+ n1 = bs.population(1)
462
+ expected = [ Array.new(n0, 0), Array.new(n1, 1) ]
463
+ result = bs.partition { |val| val.zero? }
464
+ assert_equal(expected,
465
+ result,
466
+ "Test unbounded '#{sVal}'.partition{0,1}")
467
+ expected.reverse!
468
+ result = bs.partition { |val| ! val.zero? }
469
+ assert_equal(expected,
470
+ result,
471
+ "Test unbounded '#{sVal}'.partition{1,0}")
472
+ #
473
+ # Bounded.
474
+ #
475
+ bs = BitString.new(sVal, sVal.length)
476
+ n0 = bs.population(0)
477
+ n1 = bs.population(1)
478
+ expected = [ Array.new(n0, 0), Array.new(n1, 1) ]
479
+ result = bs.partition { |val| val.zero? }
480
+ assert_equal(expected,
481
+ result,
482
+ "Test bounded '#{sVal}'.partition{0,1}")
483
+ expected.reverse!
484
+ result = bs.partition { |val| ! val.zero? }
485
+ assert_equal(expected,
486
+ result,
487
+ "Test bounded '#{sVal}'.partition{1,0}")
488
+ end
489
+ end
490
+
491
+ def test_170_reject()
492
+ return unless (BitString.new.respond_to?(:reject))
493
+ TestVals.each do |sVal|
494
+ #
495
+ # Unbounded.
496
+ #
497
+ bs = BitString.new(sVal)
498
+ n0 = bs.population(0)
499
+ n1 = bs.population(1)
500
+ expected = Array.new(n0, 0)
501
+ result = bs.reject { |val| ! val.zero? }
502
+ assert_equal(expected,
503
+ result,
504
+ "Test unbounded '#{sVal}'.reject {! 0}")
505
+ expected = Array.new(n1, 1)
506
+ result = bs.reject { |val| val.zero? }
507
+ assert_equal(expected,
508
+ result,
509
+ "Test unbounded '#{sVal}'.reject {0}")
510
+ expected = []
511
+ bs.to_a.each_with_index do |val,pos|
512
+ expected.push(val) unless (pos.%(2).zero?)
513
+ end
514
+ tick = -1
515
+ result = bs.reject { |val| tick += 1; tick.%(2).zero? }
516
+ assert_equal(expected,
517
+ result,
518
+ "Test unbounded '#{sVal}'.reject(%2)")
519
+ expected = []
520
+ bs.to_a.each_with_index do |val,pos|
521
+ expected.push(val) unless (pos.%(3).zero?)
522
+ end
523
+ tick = -1
524
+ result = bs.reject { |val| tick += 1; tick.%(3).zero? }
525
+ assert_equal(expected,
526
+ result,
527
+ "Test unbounded '#{sVal}'.reject(%3)")
528
+ #
529
+ # Bounded.
530
+ #
531
+ bs = BitString.new(sVal, sVal.length)
532
+ n0 = bs.population(0)
533
+ n1 = bs.population(1)
534
+ expected = Array.new(n0, 0)
535
+ result = bs.reject { |val| ! val.zero? }
536
+ assert_equal(expected,
537
+ result,
538
+ "Test bounded '#{sVal}'.reject {! 0}")
539
+ expected = Array.new(n1, 1)
540
+ result = bs.reject { |val| val.zero? }
541
+ assert_equal(expected,
542
+ result,
543
+ "Test bounded '#{sVal}'.reject {0}")
544
+ expected = []
545
+ bs.to_a.each_with_index do |val,pos|
546
+ expected.push(val) unless (pos.%(2).zero?)
547
+ end
548
+ tick = -1
549
+ result = bs.reject { |val| tick += 1; tick.%(2).zero? }
550
+ assert_equal(expected,
551
+ result,
552
+ "Test bounded '#{sVal}'.reject(%2)")
553
+ expected = []
554
+ bs.to_a.each_with_index do |val,pos|
555
+ expected.push(val) unless (pos.%(3).zero?)
556
+ end
557
+ tick = -1
558
+ result = bs.reject { |val| tick += 1; tick.%(3).zero? }
559
+ assert_equal(expected,
560
+ result,
561
+ "Test bounded '#{sVal}'.reject(%3)")
562
+ end
563
+ end
564
+
565
+ #
566
+ # Test the select() method.
567
+ #
568
+ def test_180_select()
569
+ TestVals.each do |sVal|
570
+ bs = BitString.new(sVal)
571
+ aVal = bs.select { |bit| true }
572
+ aVal = aVal.collect { |num| num.to_s }.join('').reverse
573
+ sVal_e = sVal.gsub(/^0+(.)/, '\1')
574
+ assert_equal(sVal_e,
575
+ aVal,
576
+ "Test unbounded select block('#{sVal}')")
577
+ #
578
+ # And again for a bounded value.
579
+ #
580
+ bs = BitString.new(sVal, sVal.length)
581
+ aVal = bs.select { |bit| true }
582
+ aVal = aVal.collect { |num| num.to_s }.join('').reverse
583
+ assert_equal(sVal,
584
+ aVal,
585
+ "Test bounded select block('#{sVal}')")
586
+ end
587
+ end
588
+
589
+ #
590
+ # slice()
591
+ #
592
+ def test_190_slice()
593
+ return unless (BitString.new.respond_to?(:slice))
594
+ TestVals.each do |sVal|
595
+ bs = BitString.new(sVal)
596
+ sVal_r = sVal.reverse
597
+ sVal_l = sVal.length
598
+ (sVal_l - 1).times do |pos|
599
+ (sVal_l - pos).times do |width|
600
+ width += 1
601
+ nbs = bs.slice(pos, width)
602
+ bsPiece = nbs.to_s
603
+ #
604
+ # nbs is now bounded (that's what slice() does), so it should no
605
+ # longer match the original under any conditions.
606
+ #
607
+ assert_not_equal(bs,
608
+ nbs,
609
+ "Verify that slice() doesn't change the original")
610
+ sPiece = sVal_r[pos,width].reverse
611
+ assert_equal(sPiece,
612
+ bsPiece,
613
+ "Test '#{sVal}'.slice(#{pos},#{width}) == '#{sPiece}'")
614
+ end
615
+ end
616
+ end
617
+ end
618
+
619
+ #
620
+ # slice!()
621
+ #
622
+ def test_200_slice!()
623
+ return unless (BitString.new.respond_to?(:slice!))
624
+ TestVals.each do |sVal|
625
+ sVal_r = sVal.reverse
626
+ sVal_l = sVal.length
627
+ (sVal_l - 1).times do |pos|
628
+ (sVal_l - pos).times do |width|
629
+ width += 1
630
+ bs = BitString.new(sVal)
631
+ bs.slice!(pos, width)
632
+ bsPiece = bs.to_s
633
+ #
634
+ # Slicing results in a bounded bitstring, so don't strip the
635
+ # leading zeroes.
636
+ #
637
+ sPiece = sVal_r[pos,width].reverse
638
+ assert_equal(sPiece,
639
+ bsPiece,
640
+ "Test '#{sVal}'.slice!(#{pos},#{width}) == '#{sPiece}'")
641
+ end
642
+ end
643
+ end
644
+ end
645
+
646
+ def test_210_sort()
647
+ return unless (BitString.new.respond_to?(:sort))
648
+ assert(false, '###FAIL! .sort not supported but .respond_to? is true!')
649
+ end
650
+
651
+ #
652
+ # .sort_by *might* make sense for bitstrings, but leave the
653
+ # determination for another time.
654
+ #
655
+ def test_220_sort_by()
656
+ return unless (BitString.new.respond_to?(:sort_by))
657
+ assert(false, '###FAIL! .sort_by not supported but .respond_to? is true!')
658
+ end
659
+
660
+ #
661
+ # .zip makes sense for bitstrings, but writing the tests is likely
662
+ # to be a bit complicated. Punt for now.
663
+ #
664
+ def test_230_zip()
665
+ return unless (BitString.new.respond_to?(:zip))
666
+ assert(false, '###FAIL! .zip not supported but .respond_to? is true!')
667
+ end
668
+
669
+ end # class Test_BitStrings
670
+
671
+ end # module Tests