bitstring 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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