From nobody at rubyforge.org Mon Feb 1 01:06:16 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Mon, 1 Feb 2010 01:06:16 -0500 (EST) Subject: [Bitstring-commits] [6] trunk: Up to 24672 unit tests, all passing. Message-ID: <20100201060617.03FF81858319@rubyforge.org> Revision: 6 Author: coar Date: 2010-02-01 01:06:16 -0500 (Mon, 01 Feb 2010) Log Message: ----------- Up to 24672 unit tests, all passing. Thousands more to go, though.. Modified Paths: -------------- trunk/doc/created.rid trunk/test/test_basic.rb trunk/test/test_data.rb trunk/test/test_enum.rb trunk/test/test_operators.rb Modified: trunk/doc/created.rid =================================================================== --- trunk/doc/created.rid 2010-01-31 07:33:36 UTC (rev 5) +++ trunk/doc/created.rid 2010-02-01 06:06:16 UTC (rev 6) @@ -1 +1 @@ -Sun, 31 Jan 2010 02:31:31 -0500 +Mon, 01 Feb 2010 01:05:29 -0500 Modified: trunk/test/test_basic.rb =================================================================== --- trunk/test/test_basic.rb 2010-01-31 07:33:36 UTC (rev 5) +++ trunk/test/test_basic.rb 2010-02-01 06:06:16 UTC (rev 6) @@ -753,18 +753,6 @@ end # - # @TODO - # - # slice() and slice!() - # - def test_016_slice() - TestVals.each do |sVal| - iVal = sVal.to_i(2) - bs = BitString.new(sVal) - end - end - - # # Test the masking. # def test_017_mask() @@ -814,7 +802,7 @@ end # - # Test the each() method. + # Test the bit-counting method. # def test_020_population() TestVals.each do |sVal| Modified: trunk/test/test_data.rb =================================================================== --- trunk/test/test_data.rb 2010-01-31 07:33:36 UTC (rev 5) +++ trunk/test/test_data.rb 2010-02-01 06:06:16 UTC (rev 6) @@ -14,6 +14,9 @@ '010101010101010101010101010101' ] + IfNoneCalled = 'IfNone invoked' + IfNone = lambda { return IfNoneCalled } + end # class Test_BitStrings end # module Tests Modified: trunk/test/test_enum.rb =================================================================== --- trunk/test/test_enum.rb 2010-01-31 07:33:36 UTC (rev 5) +++ trunk/test/test_enum.rb 2010-02-01 06:06:16 UTC (rev 6) @@ -8,7 +8,7 @@ module Tests -#all> +#all? #any? #collect #detect @@ -30,44 +30,245 @@ class Test_BitStrings < Test::Unit::TestCase + # + # The all? method returns true IFF every iteration of the block returns + # a true value. + # def test_xxx_all?() return unless (BitString.new.respond_to?(:all?)) - assert(true) + TestVals.each do |sVal| + # + # Start with unbounded bitstrings. + # + bs = BitString.new(sVal) + assert(bs.all? { |v| true }, + "Test unbounded '#{sVal}'.all? true == true") + assert(! bs.all? { |v| false }, + "Test unbounded '#{sVal}'.all? false == false") + tick = 0 + assert(! bs.all? { |v| ((tick += 1) % 2) == 0 }, + "Test unbounded '#{sVal}'.all? sometimes == false") + # + # Repeat for bounded strings. + # + bs = BitString.new(sVal, sVal.length) + assert(bs.all? { |v| true }, + "Test bounded '#{sVal}'.all? true == true") + assert(! bs.all? { |v| false }, + "Test bounded '#{sVal}'.all? false == false") + tick = 0 + assert(! bs.all? { |v| v == sVal[-1,1].to_i(2) }, + "Test bounded '#{sVal}'.all? sometimes == false") + end end + # + # Test that the any? method works. (Returns true if any iteration of + # the block does.) + # def test_xxx_any?() return unless (BitString.new.respond_to?(:any?)) - assert(true) + TestVals.each do |sVal| + # + # Start with unbounded bitstrings. + # + bs = BitString.new(sVal) + assert(bs.any? { |v| true }, + "Test unbounded '#{sVal}'.any? true == true") + assert(! bs.any? { |v| false }, + "Test unbounded '#{sVal}'.any? false == false") + tick = 0 + assert(bs.any? { |v| v == sVal[-1,1].to_i(2) }, + "Test unbounded '#{sVal}'.any? sometimes == true") + # + # Repeat for bounded strings. + # + bs = BitString.new(sVal, sVal.length) + assert(bs.any? { |v| true }, + "Test bounded '#{sVal}'.any? true == true") + assert(! bs.any? { |v| false }, + "Test bounded '#{sVal}'.any? false == false") + tick = 0 + assert(bs.any? { |v| v == sVal[-1,1].to_i(2) }, + "Test bounded '#{sVal}'.any? sometimes == true") + end end def test_xxx_collect() - return unless (BitString.new.respond_to?(:collect?)) - assert(true) + return unless (BitString.new.respond_to?(:collect)) + TestVals.each do |sVal| + # + # Unbounded first. + # + bs = BitString.new(sVal) + tVal = sVal.sub(/^0+(.)/, '\1').reverse + assert_equal(tVal.split(//), + bs.collect { |v| v.to_s(2) }, + "Test that unbounded '#{sVal}'.collect works") + # + # Now bounded.. + # + bs = BitString.new(sVal, sVal.length) + tVal = sVal.reverse + assert_equal(tVal.split(//), + bs.collect { |v| v.to_s(2) }, + "Test that bounded '#{sVal}'.collect works") + end end + # + # Returns the first value for which the block doesn't return false. + # If all iterations return false, .detect() calls the proc specified + # by the ifnone argument and returns its result; otherwise it returns + # nil. + # def test_xxx_detect() return unless (BitString.new.respond_to?(:detect)) - assert(true) + TestVals.each do |sVal| + # + # Start with unbounded bitstrings. + # + bs = BitString.new(sVal) + assert_equal(sVal[-1,1].to_i(2), + bs.detect { |v| true }, + "Test unbounded '#{sVal}'.detect {true} == '#{sVal[-1,1]}'") + assert_nil(bs.detect { |v| false }, + "Test unbounded '#{sVal}'.detect {false} == nil") + assert_equal(IfNoneCalled, + bs.detect(IfNone) { |v| false }, + "Test unbounded '#{sVal}'.detect(ifnone) {false} == " + + "'#{IfNoneCalled}'") + # + # Now bounded ones. + # + bs = BitString.new(sVal, sVal.length) + assert_equal(sVal[-1,1].to_i(2), + bs.detect { |v| true }, + "Test bounded '#{sVal}'.detect {true} == '#{sVal[-1,1]}'") + assert_nil(bs.detect { |v| false }, + "Test bounded '#{sVal}'.detect {false} == nil") + assert_equal(IfNoneCalled, + bs.detect(IfNone) { |v| false }, + "Test bounded '#{sVal}'.detect(ifnone) {false} == " + + "'#{IfNoneCalled}'") + end end + # + # Like .each, only passes two arguments. + # def test_xxx_each_with_index() return unless (BitString.new.respond_to?(:each_with_index)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded first.. + # + bs = BitString.new(sVal) + bs.each_with_index do |val,pos| + assert_equal(sVal[-1-pos,1], + val.to_s, + "Test unbounded '#{sVal}'.each_with_index" + + "(#{val},#{pos}) == #{sVal[-1-pos,1]}") + end + # + # Now bounded strings. + # + bs = BitString.new(sVal, sVal.length) + bs.each_with_index do |val,pos| + assert_equal(sVal[-1-pos,1], + val.to_s, + "Test bounded '#{sVal}'.each_with_index" + + "(#{val},#{pos}) == #{sVal[-1-pos,1]}") + end + end end + # + # Convert to an array. (Equivalent to .to_a ?) + # def test_xxx_entries() return unless (BitString.new.respond_to?(:entries)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + sVal_a = sVal.sub(/^0+(.)/, '\1').reverse.split(//).collect { |v| v.to_i(2) } + assert_equal(sVal_a, + bs.entries, + "Test unbounded '#{sVal}'.entries") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + sVal_a = sVal.reverse.split(//).collect { |v| v.to_i(2) } + assert_equal(sVal_a, + bs.entries, + "Test bounded '#{sVal}'.entries") + end end def test_xxx_find() - return unless (BitString.new.respond_to?(:find)) - assert(true) + # + # Same as .detect(), don't bother to test. + # end + # + # Like .find/.detect except it returns all matching values, not just + # the first. + # def test_xxx_find_all() return unless (BitString.new.respond_to?(:find_all)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + assert(bs.find_all { |v| false }.empty?, + "Test unbounded '#{sVal}'.find_all{false} == []") + # + # .population should have been tested in test_basic + # + assert_equal(bs.population(0), + bs.find_all { |v| v == 0 }.length, + "Test unbounded '#{sVal}.find_all{0}.length " + + "== population(0)") + assert_equal(bs.population(1), + bs.find_all { |v| v == 1 }.length, + "Test unbounded '#{sVal}.find_all{1}.length " + + "== population(1)") + sVal_t = sVal.sub(/^0+(.)/, '\1').reverse.split(//) + tick = 0 + sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2) == 0 } + sVal_t.collect! { |v| v.to_i(2) } + tick = 0 + assert_equal(sVal_t, + bs.find_all { |v| ((tick += 1) % 2) == 0 }, + "Test unbounded '#{sVal}'.find_all(alt) works") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + assert(bs.find_all { |v| false }.empty?, + "Test bounded '#{sVal}'.find_all{false} == []") + assert_equal(bs.population(0), + bs.find_all { |v| v == 0 }.length, + "Test bounded '#{sVal}.find_all{0}.length " + + "== population(0)") + assert_equal(bs.population(1), + bs.find_all { |v| v == 1 }.length, + "Test bounded '#{sVal}.find_all{1}.length " + + "== population(1)") + sVal_t = sVal.reverse.split(//) + tick = 0 + sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2) == 0 } + sVal_t.collect! { |v| v.to_i(2) } + tick = 0 + assert_equal(sVal_t, + bs.find_all { |v| ((tick += 1) % 2) == 0 }, + "Test bounded '#{sVal}'.find_all(alt) works") + end end def test_xxx_grep() @@ -115,11 +316,87 @@ assert(true) end + # + # Test the select() method. + # def test_xxx_select() - return unless (BitString.new.respond_to?(:select)) - assert(true) + TestVals.each do |sVal| + bs = BitString.new(sVal) + aVal = bs.select { |bit| true } + aVal = aVal.collect { |num| num.to_s }.join('').reverse + sVal_e = sVal.gsub(/^0+(.)/, '\1') + assert_equal(sVal_e, + aVal, + "Test unbounded select block('#{sVal}')") + # + # And again for a bounded value. + # + bs = BitString.new(sVal, sVal.length) + aVal = bs.select { |bit| true } + aVal = aVal.collect { |num| num.to_s }.join('').reverse + assert_equal(sVal, + aVal, + "Test bounded select block('#{sVal}')") + end end + # + # slice() + # + def test_xxx_slice() + return unless (BitString.new.respond_to?(:slice)) + TestVals.each do |sVal| + bs = BitString.new(sVal) + sVal_r = sVal.reverse + sVal_l = sVal.length + (sVal_l - 1).times do |pos| + (sVal_l - pos).times do |width| + width += 1 + nbs = bs.slice(pos, width) + bsPiece = nbs.to_s + # + # nbs is now bounded (that's what slice() does), so it should no + # longer match the original under any conditions. + # + assert_not_equal(bs, + nbs, + "Verify that slice() doesn't change the original") + sPiece = sVal_r[pos,width].reverse + assert_equal(sPiece, + bsPiece, + "Test '#{sVal}'.slice(#{pos},#{width}) == '#{sPiece}'") + end + end + end + end + + # + # slice!() + # + def test_xxx_slice!() + return unless (BitString.new.respond_to?(:slice!)) + TestVals.each do |sVal| + sVal_r = sVal.reverse + sVal_l = sVal.length + (sVal_l - 1).times do |pos| + (sVal_l - pos).times do |width| + width += 1 + bs = BitString.new(sVal) + bs.slice!(pos, width) + bsPiece = bs.to_s + # + # Slicing results in a bounded bitstring, so don't strip the + # leading zeroes. + # + sPiece = sVal_r[pos,width].reverse + assert_equal(sPiece, + bsPiece, + "Test '#{sVal}'.slice!(#{pos},#{width}) == '#{sPiece}'") + end + end + end + end + def test_xxx_sort() return unless (BitString.new.respond_to?(:sort)) assert(true) Modified: trunk/test/test_operators.rb =================================================================== --- trunk/test/test_operators.rb 2010-01-31 07:33:36 UTC (rev 5) +++ trunk/test/test_operators.rb 2010-02-01 06:06:16 UTC (rev 6) @@ -83,18 +83,22 @@ end # def test_001_AND() def test_002_LT() + # Not supported for BitString end # def test_002_LT() def test_003_ShiftLeft() end # def test_003_ShiftLeft() def test_004_LEQ() + # Not supported for BitString end # def test_004_LEQ() def test_005_GT() + # Not supported for BitString end # def test_005_GT() def test_006_GEQ() + # Not supported for BitString end # def test_006_GEQ() def test_007_ShiftRight() From nobody at rubyforge.org Mon Feb 1 23:45:17 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Mon, 1 Feb 2010 23:45:17 -0500 (EST) Subject: [Bitstring-commits] [7] trunk/test: 52 tests, 32241 assertions - and 1 failure. Message-ID: <20100202044517.AB7CA1588069@rubyforge.org> Revision: 7 Author: coar Date: 2010-02-01 23:45:14 -0500 (Mon, 01 Feb 2010) Log Message: ----------- 52 tests, 32241 assertions - and 1 failure. Fix it tomorrow. Modified Paths: -------------- trunk/test/test_basic.rb trunk/test/test_data.rb trunk/test/test_enum.rb Modified: trunk/test/test_basic.rb =================================================================== --- trunk/test/test_basic.rb 2010-02-01 06:06:16 UTC (rev 6) +++ trunk/test/test_basic.rb 2010-02-02 04:45:14 UTC (rev 7) @@ -41,80 +41,85 @@ # # Test making an unbounded string from the integer. # - assert_nothing_raised do + assert_nothing_raised("Test unbounded no exception new(#{iVal})") do bs = BitString.new(iVal) end # # From the string. # - assert_nothing_raised do + assert_nothing_raised("Test unbounded no exception new('#{sVal}')") do bs = BitString.new(sVal) end # # From the array of integers. # - assert_nothing_raised do + assert_nothing_raised("Test unbounded no exception new('#{iVal_a.inspect}')") do bs = BitString.new(iVal_a) end # # Try bounded now. # - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new(#{iVal})") do bs = BitString.new(iVal, lVal) end - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new('#{sVal}')") do bs = BitString.new(sVal, lVal) end - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new(#{iVal_a.inspect})") do bs = BitString.new(iVal_a, lVal) end # # Again, with lengths shorter than the values. # - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new(#{iVal} short)") do bs = BitString.new(iVal, lVal / 2) end - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new('#{sVal}' short)") do bs = BitString.new(sVal, lVal / 2) end - assert_nothing_raised do + assert_nothing_raised("Test bounded no exception new(#{iVal_a.inspect} short)") do bs = BitString.new(iVal_a, lVal / 2) end # # Now the block (bounded) form. # - assert_nothing_raised do + assert_nothing_raised("Test bounded new() {'#{sVal}'}") do bs = BitString.new(lVal) { |bit| sVal_a_r[bit] } end - assert_nothing_raised do + assert_nothing_raised("Test bounded new() {#{iVal_a.inspect}}") do bs = BitString.new(lVal) { |bit| iVal_a_r[bit] } end # # Check that the constructor arguments are vetted. # - assert_raise(ArgumentError) do - bs = BitString.new('a') + input = 'a' + assert_raise(ArgumentError, "Test unbounded new(#{input.inspect})") do + bs = BitString.new(input) end - assert_raise(ArgumentError) do - bs = BitString.new(iVal_a.collect { |v| v * 2 }) + input = iVal_a.collect { |v| v + 2 } + assert_raise(ArgumentError, "Test unbounded new(#{input.inspect})") do + bs = BitString.new(input) end - tVal = iVal.to_s - assert_raise(ArgumentError) do - bs = BitString.new(tVal) + input = iVal.to_s + unless (iVal < 2) + assert_raise(ArgumentError, "Test unbounded new(#{input.inspect})") do + bs = BitString.new(input) + end + assert_raise(ArgumentError, "Test bounded new(#{input.inspect})") do + bs = BitString.new(input, input.length) + end end - assert_raise(ArgumentError) do - bs = BitString.new(tVal, tVal.length) + input = 'a' + assert_raise(ArgumentError, "Test bounded new(#{input.inspect})") do + bs = BitString.new(input, 1) end - assert_raise(ArgumentError) do - bs = BitString.new('a', 1) - end - assert_raise(ArgumentError) do + assert_raise(ArgumentError, "Test bounded new(0, 'a')") do bs = BitString.new(0, 'a') end end @@ -155,7 +160,7 @@ def test_003_to_s() TestVals.each do |sVal| iVal = sVal.to_i(2) - sVal_e = sVal.sub(/^0+/, '') + sVal_e = sVal.sub(/^0+(.)/, '\1') bs = BitString.new(sVal) assert_equal(sVal_e, bs.to_s, @@ -177,7 +182,7 @@ # bitstring, or the number of digits from the most significant # 1. # - uLength = sVal.sub(/^0+/, '').length + uLength = sVal.sub(/^0+(.)/, '\1').length bLength = sVal.length bs = BitString.new(sVal) assert_equal(uLength, @@ -654,6 +659,10 @@ # Try resizing bitstrings. # def test_014_resize() + assert_raise(IndexError, "Test resize(0) raises IndexError") do + bs = BitString.new(-1, 12) + bs.resize(0) + end TestVals.each do |sVal| # # First off, test resizing unbounded bitstrings. The length() @@ -663,11 +672,12 @@ # bs = BitString.new(sVal) oLength = bs.length - uLength = sVal.sub(/^0+/, '').length + uLength = sVal.sub(/^0+(.)/, '\1').length # - # Resize down. + # Resize down. Make sure we have at least 1 bit, since resizing + # to zero length raises an exception. # - nBits = [9, uLength / 2].min + nBits = [9, [uLength / 2, 1].max].min tbs = bs.resize(nBits) assert_equal(oLength, bs.length, @@ -808,7 +818,7 @@ TestVals.each do |sVal| bs = BitString.new(sVal) ones = sVal.gsub(/0/, '').length - zeroes = sVal.gsub(/^0+/, '').gsub(/1/, '').length + zeroes = sVal.gsub(/^0+(.)/, '\1').gsub(/1/, '').length assert_raise(ArgumentError, 'Test exception for population("a")') do bs.population('a') end Modified: trunk/test/test_data.rb =================================================================== --- trunk/test/test_data.rb 2010-02-01 06:06:16 UTC (rev 6) +++ trunk/test/test_data.rb 2010-02-02 04:45:14 UTC (rev 7) @@ -11,7 +11,9 @@ '1100111000111100001111100000', '101100111000111100001111100000', '101010101010101010101010101010', - '010101010101010101010101010101' + '010101010101010101010101010101', + '0000000000000000000000000000', + '1111111111111111111111111111' ] IfNoneCalled = 'IfNone invoked' Modified: trunk/test/test_enum.rb =================================================================== --- trunk/test/test_enum.rb 2010-02-01 06:06:16 UTC (rev 6) +++ trunk/test/test_enum.rb 2010-02-02 04:45:14 UTC (rev 7) @@ -8,23 +8,9 @@ module Tests -#all? -#any? -#collect -#detect -#each_with_index -#entries -#find -#find_all -#include? #inject -#length -#map #member? #reject -#select -#slice -#slice! #to_set #zip @@ -57,7 +43,7 @@ assert(! bs.all? { |v| false }, "Test bounded '#{sVal}'.all? false == false") tick = 0 - assert(! bs.all? { |v| v == sVal[-1,1].to_i(2) }, + assert(! bs.all? { |v| ((tick += 1) % 2) == 0 }, "Test bounded '#{sVal}'.all? sometimes == false") end end @@ -271,24 +257,88 @@ end end + # + # No grep here.. + # def test_xxx_grep() return unless (BitString.new.respond_to?(:grep)) - assert(true) + assert(false, '###FAIL! .grep not supported but .respond_to? is true!') end + # + # Only 0 and 1 will ever succeed.. + # def test_xxx_include?() return unless (BitString.new.respond_to?(:include?)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + assert(! bs.include?(2), + "Test unbounded '#{sVal}'.include?(2) fails") + [0, 1].each do |val| + if (bs.population(val) != 0) + assert(bs.include?(val), + "Test unbounded '#{sVal}'.include?(#{val}) succeeds") + else + assert(! bs.include?(val), + "Test unbounded '#{sVal}'.include?(#{val}) fails") + end + end + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + assert(! bs.include?(2), + "Test bounded '#{sVal}'.include?(2) fails") + [0, 1].each do |val| + if (bs.population(val) != 0) + assert(bs.include?(val), + "Test bounded '#{sVal}'.include?(#{val}) succeeds") + else + assert(! bs.include?(val), + "Test bounded '#{sVal}'.include?(#{val}) fails") + end + end + end end + # + # Test .inject + # def test_xxx_inject() return unless (BitString.new.respond_to?(:inject)) - assert(true) + TestVals.each do |sVal| + bs = BitString.new(sVal) + result = bs.inject { |memo,val| memo += val } + assert_equal(bs.population(1), + result, + "Test unbounded '#{sVal}'.inject { memo + 1s}") + result = bs.inject(-20) { |memo,val| memo += val } + assert_equal(bs.population(1) - 20, + result, + "Test unbounded '#{sVal}'.inject(-20) { memo + 1s}") + # + # This one is failing because of the issue with the leading + # zeroes being stripped and the initial memo value being set + # from the LSB. I think. + # + result = bs.inject { |memo,val| memo += (val == 0 ? 1 : 0) } + assert_equal(bs.population(0), + result, + "Test unbounded '#{sVal}'.inject { memo + 0s}") + result = bs.inject(-20) { |memo,val| memo += (val == 0 ? 1 : 0) } + assert_equal(bs.population(0) - 20, + result, + "Test unbounded '#{sVal}'.inject(-20) { memo + 0s}") + end end def test_xxx_map() - return unless (BitString.new.respond_to?(:map)) - assert(true) + # + # Same as .collect so don't bother to test. + # end def test_xxx_max() From nobody at rubyforge.org Tue Feb 2 23:25:03 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Tue, 2 Feb 2010 23:25:03 -0500 (EST) Subject: [Bitstring-commits] [8] trunk: Add .min and .max back (though basically useless) and the fixed .inject test Message-ID: <20100203042503.E74CF18582E9@rubyforge.org> Revision: 8 Author: coar Date: 2010-02-02 23:25:03 -0500 (Tue, 02 Feb 2010) Log Message: ----------- Add .min and .max back (though basically useless) and the fixed .inject test Modified Paths: -------------- trunk/lib/bitstring.rb trunk/test/test_enum.rb Modified: trunk/lib/bitstring.rb =================================================================== --- trunk/lib/bitstring.rb 2010-02-02 04:45:14 UTC (rev 7) +++ trunk/lib/bitstring.rb 2010-02-03 04:25:03 UTC (rev 8) @@ -237,7 +237,7 @@ # # ..but not all of them. Some just don't make sense for bitstrings. # - undef :grep, :max, :min, :partition, :sort, :sort_by + undef :grep, :partition, :sort, :sort_by # # Boolean. Whether or not the bitstring is bounded and limited Modified: trunk/test/test_enum.rb =================================================================== --- trunk/test/test_enum.rb 2010-02-02 04:45:14 UTC (rev 7) +++ trunk/test/test_enum.rb 2010-02-03 04:25:03 UTC (rev 8) @@ -310,12 +310,15 @@ def test_xxx_inject() return unless (BitString.new.respond_to?(:inject)) TestVals.each do |sVal| + # + # Unbounded.. + # bs = BitString.new(sVal) - result = bs.inject { |memo,val| memo += val } + result = bs.inject { |memo,val| memo + val } assert_equal(bs.population(1), result, "Test unbounded '#{sVal}'.inject { memo + 1s}") - result = bs.inject(-20) { |memo,val| memo += val } + result = bs.inject(-20) { |memo,val| memo + val } assert_equal(bs.population(1) - 20, result, "Test unbounded '#{sVal}'.inject(-20) { memo + 1s}") @@ -324,14 +327,76 @@ # zeroes being stripped and the initial memo value being set # from the LSB. I think. # - result = bs.inject { |memo,val| memo += (val == 0 ? 1 : 0) } - assert_equal(bs.population(0), + result = bs.inject { |memo,val| memo + (val == 0 ? 1 : 0) } + expected = bs.population(0) + if (bs.population(1) == bs.length) + # + # All 1s means no 0s -- but memo picked up + # the value of bs[0]. Adjust the expectation. + # + expected = bs[0] + elsif (bs[0] == 0) + # + # memo will start out as zero, taken from the first bit, which + # won't be counted. .population did, though, so take it off. + # + expected -= 1 + elsif (bs[0] == 1) + # + # memo will start out as 1 from the lsb, but that's not a zero -- + # so alter the population result to allow for its addition. + # + expected += 1 + end + assert_equal(expected, result, "Test unbounded '#{sVal}'.inject { memo + 0s}") - result = bs.inject(-20) { |memo,val| memo += (val == 0 ? 1 : 0) } + result = bs.inject(-20) { |memo,val| memo + (val == 0 ? 1 : 0) } assert_equal(bs.population(0) - 20, result, "Test unbounded '#{sVal}'.inject(-20) { memo + 0s}") + # + # Bounded.. + # + bs = BitString.new(sVal, sVal.length) + result = bs.inject { |memo,val| memo + val } + expected = bs.population(1) + assert_equal(expected, + result, + "Test bounded '#{sVal}'.inject { memo + 1s}") + result = bs.inject(-20) { |memo,val| memo + val } + expected = bs.population(1) - 20 + assert_equal(expected, + result, + "Test bounded '#{sVal}'.inject(-20) { memo + 1s}") + result = bs.inject { |memo,val| memo + (val == 0 ? 1 : 0) } + expected = bs.population(0) + if (bs.population(1) == bs.length) + # + # All 1s means no 0s -- but memo picked up + # the value of bs[0]. Adjust the expectation. + # + expected = bs[0] + elsif (bs[0] == 0) + # + # memo will start out as zero, taken from the first bit, which + # won't be counted. .population did, though, so take it off. + # + expected -= 1 + elsif (bs[0] == 1) + # + # memo will start out as 1 from the lsb, but that's not a zero -- + # so alter the population result to allow for its addition. + # + expected += 1 + end + assert_equal(expected, + result, + "Test bounded '#{sVal}'.inject { memo + 0s}") + result = bs.inject(-20) { |memo,val| memo + (val == 0 ? 1 : 0) } + assert_equal(bs.population(0) - 20, + result, + "Test bounded '#{sVal}'.inject(-20) { memo + 0s}") end end @@ -343,7 +408,24 @@ def test_xxx_max() return unless (BitString.new.respond_to?(:max)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + expected = bs.to_i == 0 ? 0 : 1 + assert_equal(expected, + bs.max, + "Test unbounded '#{sVal}'.max == #{expected}") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + expected = bs.to_i == 0 ? 0 : 1 + assert_equal(expected, + bs.max, + "Test bounded '#{sVal}'.max == #{expected}") + end end def test_xxx_member?() @@ -353,7 +435,24 @@ def test_xxx_min() return unless (BitString.new.respond_to?(:min)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + expected = (bs.population(1) == bs.length) ? 1 : 0 + assert_equal(expected, + bs.min, + "Test unbounded '#{sVal}'.min == #{expected}") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + expected = (bs.population(1) == bs.length) ? 1 : 0 + assert_equal(expected, + bs.min, + "Test bounded '#{sVal}'.min == #{expected}") + end end def test_xxx_partition() From nobody at rubyforge.org Wed Feb 3 02:16:13 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Wed, 3 Feb 2010 02:16:13 -0500 (EST) Subject: [Bitstring-commits] [9] trunk: 33359 unit tests, all passing. Message-ID: <20100203071613.251EE18582E9@rubyforge.org> Revision: 9 Author: coar Date: 2010-02-03 02:16:12 -0500 (Wed, 03 Feb 2010) Log Message: ----------- 33359 unit tests, all passing. Only 4 more sets to write, then release! Modified Paths: -------------- trunk/lib/bitstring.rb trunk/test/test_enum.rb trunk/test/test_operators.rb Modified: trunk/lib/bitstring.rb =================================================================== --- trunk/lib/bitstring.rb 2010-02-03 04:25:03 UTC (rev 8) +++ trunk/lib/bitstring.rb 2010-02-03 07:16:12 UTC (rev 9) @@ -236,8 +236,9 @@ # # ..but not all of them. Some just don't make sense for bitstrings. + # (.zip makes sense, but I'm going to defer it until I have a test for it.) # - undef :grep, :partition, :sort, :sort_by + undef :grep, :sort, :sort_by, :zip # # Boolean. Whether or not the bitstring is bounded and limited Modified: trunk/test/test_enum.rb =================================================================== --- trunk/test/test_enum.rb 2010-02-03 04:25:03 UTC (rev 8) +++ trunk/test/test_enum.rb 2010-02-03 07:16:12 UTC (rev 9) @@ -8,19 +8,13 @@ module Tests -#inject -#member? -#reject -#to_set -#zip - class Test_BitStrings < Test::Unit::TestCase # # The all? method returns true IFF every iteration of the block returns # a true value. # - def test_xxx_all?() + def test_010_all?() return unless (BitString.new.respond_to?(:all?)) TestVals.each do |sVal| # @@ -32,7 +26,7 @@ assert(! bs.all? { |v| false }, "Test unbounded '#{sVal}'.all? false == false") tick = 0 - assert(! bs.all? { |v| ((tick += 1) % 2) == 0 }, + assert(! bs.all? { |v| ((tick += 1) % 2).zero? }, "Test unbounded '#{sVal}'.all? sometimes == false") # # Repeat for bounded strings. @@ -43,7 +37,7 @@ assert(! bs.all? { |v| false }, "Test bounded '#{sVal}'.all? false == false") tick = 0 - assert(! bs.all? { |v| ((tick += 1) % 2) == 0 }, + assert(! bs.all? { |v| ((tick += 1) % 2).zero? }, "Test bounded '#{sVal}'.all? sometimes == false") end end @@ -52,7 +46,7 @@ # Test that the any? method works. (Returns true if any iteration of # the block does.) # - def test_xxx_any?() + def test_020_any?() return unless (BitString.new.respond_to?(:any?)) TestVals.each do |sVal| # @@ -80,7 +74,7 @@ end end - def test_xxx_collect() + def test_030_collect() return unless (BitString.new.respond_to?(:collect)) TestVals.each do |sVal| # @@ -108,7 +102,7 @@ # by the ifnone argument and returns its result; otherwise it returns # nil. # - def test_xxx_detect() + def test_040_detect() return unless (BitString.new.respond_to?(:detect)) TestVals.each do |sVal| # @@ -143,7 +137,7 @@ # # Like .each, only passes two arguments. # - def test_xxx_each_with_index() + def test_050_each_with_index() return unless (BitString.new.respond_to?(:each_with_index)) TestVals.each do |sVal| # @@ -172,7 +166,7 @@ # # Convert to an array. (Equivalent to .to_a ?) # - def test_xxx_entries() + def test_060_entries() return unless (BitString.new.respond_to?(:entries)) TestVals.each do |sVal| # @@ -194,7 +188,7 @@ end end - def test_xxx_find() + def test_070_find() # # Same as .detect(), don't bother to test. # @@ -204,7 +198,7 @@ # Like .find/.detect except it returns all matching values, not just # the first. # - def test_xxx_find_all() + def test_080_find_all() return unless (BitString.new.respond_to?(:find_all)) TestVals.each do |sVal| # @@ -217,7 +211,7 @@ # .population should have been tested in test_basic # assert_equal(bs.population(0), - bs.find_all { |v| v == 0 }.length, + bs.find_all { |v| v.zero? }.length, "Test unbounded '#{sVal}.find_all{0}.length " + "== population(0)") assert_equal(bs.population(1), @@ -226,11 +220,11 @@ "== population(1)") sVal_t = sVal.sub(/^0+(.)/, '\1').reverse.split(//) tick = 0 - sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2) == 0 } + sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2).zero? } sVal_t.collect! { |v| v.to_i(2) } tick = 0 assert_equal(sVal_t, - bs.find_all { |v| ((tick += 1) % 2) == 0 }, + bs.find_all { |v| ((tick += 1) % 2).zero? }, "Test unbounded '#{sVal}'.find_all(alt) works") # # Bounded. @@ -239,7 +233,7 @@ assert(bs.find_all { |v| false }.empty?, "Test bounded '#{sVal}'.find_all{false} == []") assert_equal(bs.population(0), - bs.find_all { |v| v == 0 }.length, + bs.find_all { |v| v.zero? }.length, "Test bounded '#{sVal}.find_all{0}.length " + "== population(0)") assert_equal(bs.population(1), @@ -248,11 +242,11 @@ "== population(1)") sVal_t = sVal.reverse.split(//) tick = 0 - sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2) == 0 } + sVal_t = sVal_t.find_all { |v| ((tick += 1) % 2).zero? } sVal_t.collect! { |v| v.to_i(2) } tick = 0 assert_equal(sVal_t, - bs.find_all { |v| ((tick += 1) % 2) == 0 }, + bs.find_all { |v| ((tick += 1) % 2).zero? }, "Test bounded '#{sVal}'.find_all(alt) works") end end @@ -260,7 +254,7 @@ # # No grep here.. # - def test_xxx_grep() + def test_090_grep() return unless (BitString.new.respond_to?(:grep)) assert(false, '###FAIL! .grep not supported but .respond_to? is true!') end @@ -268,7 +262,7 @@ # # Only 0 and 1 will ever succeed.. # - def test_xxx_include?() + def test_100_include?() return unless (BitString.new.respond_to?(:include?)) TestVals.each do |sVal| # @@ -307,7 +301,7 @@ # # Test .inject # - def test_xxx_inject() + def test_110_inject() return unless (BitString.new.respond_to?(:inject)) TestVals.each do |sVal| # @@ -327,7 +321,7 @@ # zeroes being stripped and the initial memo value being set # from the LSB. I think. # - result = bs.inject { |memo,val| memo + (val == 0 ? 1 : 0) } + result = bs.inject { |memo,val| memo + (val.zero? ? 1 : 0) } expected = bs.population(0) if (bs.population(1) == bs.length) # @@ -335,7 +329,7 @@ # the value of bs[0]. Adjust the expectation. # expected = bs[0] - elsif (bs[0] == 0) + elsif (bs[0].zero?) # # memo will start out as zero, taken from the first bit, which # won't be counted. .population did, though, so take it off. @@ -351,7 +345,7 @@ assert_equal(expected, result, "Test unbounded '#{sVal}'.inject { memo + 0s}") - result = bs.inject(-20) { |memo,val| memo + (val == 0 ? 1 : 0) } + result = bs.inject(-20) { |memo,val| memo + (val.zero? ? 1 : 0) } assert_equal(bs.population(0) - 20, result, "Test unbounded '#{sVal}'.inject(-20) { memo + 0s}") @@ -369,7 +363,7 @@ assert_equal(expected, result, "Test bounded '#{sVal}'.inject(-20) { memo + 1s}") - result = bs.inject { |memo,val| memo + (val == 0 ? 1 : 0) } + result = bs.inject { |memo,val| memo + (val.zero? ? 1 : 0) } expected = bs.population(0) if (bs.population(1) == bs.length) # @@ -377,7 +371,7 @@ # the value of bs[0]. Adjust the expectation. # expected = bs[0] - elsif (bs[0] == 0) + elsif (bs[0].zero?) # # memo will start out as zero, taken from the first bit, which # won't be counted. .population did, though, so take it off. @@ -393,27 +387,27 @@ assert_equal(expected, result, "Test bounded '#{sVal}'.inject { memo + 0s}") - result = bs.inject(-20) { |memo,val| memo + (val == 0 ? 1 : 0) } + result = bs.inject(-20) { |memo,val| memo + (val.zero? ? 1 : 0) } assert_equal(bs.population(0) - 20, result, "Test bounded '#{sVal}'.inject(-20) { memo + 0s}") end end - def test_xxx_map() + def test_120_map() # # Same as .collect so don't bother to test. # end - def test_xxx_max() + def test_130_max() return unless (BitString.new.respond_to?(:max)) TestVals.each do |sVal| # # Unbounded. # bs = BitString.new(sVal) - expected = bs.to_i == 0 ? 0 : 1 + expected = bs.to_i.zero? ? 0 : 1 assert_equal(expected, bs.max, "Test unbounded '#{sVal}'.max == #{expected}") @@ -421,19 +415,20 @@ # Bounded. # bs = BitString.new(sVal, sVal.length) - expected = bs.to_i == 0 ? 0 : 1 + expected = bs.to_i.zero? ? 0 : 1 assert_equal(expected, bs.max, "Test bounded '#{sVal}'.max == #{expected}") end end - def test_xxx_member?() - return unless (BitString.new.respond_to?(:member?)) - assert(true) + def test_140_member?() + # + # Same as .include? so don't bother to test. + # end - def test_xxx_min() + def test_150_min() return unless (BitString.new.respond_to?(:min)) TestVals.each do |sVal| # @@ -455,20 +450,122 @@ end end - def test_xxx_partition() + def test_160_partition() return unless (BitString.new.respond_to?(:partition)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + n0 = bs.population(0) + n1 = bs.population(1) + expected = [ Array.new(n0, 0), Array.new(n1, 1) ] + result = bs.partition { |val| val.zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.partition{0,1}") + expected.reverse! + result = bs.partition { |val| ! val.zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.partition{1,0}") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + n0 = bs.population(0) + n1 = bs.population(1) + expected = [ Array.new(n0, 0), Array.new(n1, 1) ] + result = bs.partition { |val| val.zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.partition{0,1}") + expected.reverse! + result = bs.partition { |val| ! val.zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.partition{1,0}") + end end - def test_xxx_reject() + def test_170_reject() return unless (BitString.new.respond_to?(:reject)) - assert(true) + TestVals.each do |sVal| + # + # Unbounded. + # + bs = BitString.new(sVal) + n0 = bs.population(0) + n1 = bs.population(1) + expected = Array.new(n0, 0) + result = bs.reject { |val| ! val.zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.reject {! 0}") + expected = Array.new(n1, 1) + result = bs.reject { |val| val.zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.reject {0}") + expected = [] + bs.to_a.each_with_index do |val,pos| + expected.push(val) unless (pos.%(2).zero?) + end + tick = -1 + result = bs.reject { |val| tick += 1; tick.%(2).zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.reject(%2)") + expected = [] + bs.to_a.each_with_index do |val,pos| + expected.push(val) unless (pos.%(3).zero?) + end + tick = -1 + result = bs.reject { |val| tick += 1; tick.%(3).zero? } + assert_equal(expected, + result, + "Test unbounded '#{sVal}'.reject(%3)") + # + # Bounded. + # + bs = BitString.new(sVal, sVal.length) + n0 = bs.population(0) + n1 = bs.population(1) + expected = Array.new(n0, 0) + result = bs.reject { |val| ! val.zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.reject {! 0}") + expected = Array.new(n1, 1) + result = bs.reject { |val| val.zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.reject {0}") + expected = [] + bs.to_a.each_with_index do |val,pos| + expected.push(val) unless (pos.%(2).zero?) + end + tick = -1 + result = bs.reject { |val| tick += 1; tick.%(2).zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.reject(%2)") + expected = [] + bs.to_a.each_with_index do |val,pos| + expected.push(val) unless (pos.%(3).zero?) + end + tick = -1 + result = bs.reject { |val| tick += 1; tick.%(3).zero? } + assert_equal(expected, + result, + "Test bounded '#{sVal}'.reject(%3)") + end end # # Test the select() method. # - def test_xxx_select() + def test_180_select() TestVals.each do |sVal| bs = BitString.new(sVal) aVal = bs.select { |bit| true } @@ -492,7 +589,7 @@ # # slice() # - def test_xxx_slice() + def test_190_slice() return unless (BitString.new.respond_to?(:slice)) TestVals.each do |sVal| bs = BitString.new(sVal) @@ -522,7 +619,7 @@ # # slice!() # - def test_xxx_slice!() + def test_200_slice!() return unless (BitString.new.respond_to?(:slice!)) TestVals.each do |sVal| sVal_r = sVal.reverse @@ -546,19 +643,27 @@ end end - def test_xxx_sort() + def test_210_sort() return unless (BitString.new.respond_to?(:sort)) - assert(true) + assert(false, '###FAIL! .sort not supported but .respond_to? is true!') end - def test_xxx_sort_by() + # + # .sort_by *might* make sense for bitstrings, but leave the + # determination for another time. + # + def test_220_sort_by() return unless (BitString.new.respond_to?(:sort_by)) - assert(true) + assert(false, '###FAIL! .sort_by not supported but .respond_to? is true!') end - def test_xxx_zip() + # + # .zip makes sense for bitstrings, but writing the tests is likely + # to be a bit complicated. Punt for now. + # + def test_230_zip() return unless (BitString.new.respond_to?(:zip)) - assert(true) + assert(false, '###FAIL! .zip not supported but .respond_to? is true!') end end # class Test_BitStrings Modified: trunk/test/test_operators.rb =================================================================== --- trunk/test/test_operators.rb 2010-02-03 04:25:03 UTC (rev 8) +++ trunk/test/test_operators.rb 2010-02-03 07:16:12 UTC (rev 9) @@ -83,34 +83,72 @@ end # def test_001_AND() def test_002_LT() - # Not supported for BitString + return unless (BitString.new.respond_to?(:<)) + assert(false, '###FAIL! .< not supported but .respond_to? is true!') end # def test_002_LT() def test_003_ShiftLeft() + return unless (BitString.new.respond_to?(:<<)) + TestVals.each do |sVal| + # + # Start with unbounded strings. + # + rVal = sVal.to_i(2).to_s(2) + bs = BitString.new(sVal) + (sVal.length * 2).times do |i| + expected = (rVal + '0' * i).to_i(2).to_s(2) + assert_equal(expected, + (bs << i).to_s, + "Test unbounded '#{sVal}' << #{i} == #{expected}") + end + # + # Now the bounded ones. + # + l = sVal.length + bs = BitString.new(sVal, l) + rVal = bs.to_s + (sVal.length * 2).times do |i| + expected = (rVal + '0' * i)[-l,l] + assert_equal(expected, + (bs << i).to_s, + "Test bounded '#{sVal}' << #{i} == #{expected}") + end + end end # def test_003_ShiftLeft() def test_004_LEQ() - # Not supported for BitString + return unless (BitString.new.respond_to?(:<=)) + assert(false, '###FAIL! .<= not supported but .respond_to? is true!') end # def test_004_LEQ() def test_005_GT() - # Not supported for BitString + return unless (BitString.new.respond_to?(:>)) + assert(false, '###FAIL! .> not supported but .respond_to? is true!') end # def test_005_GT() def test_006_GEQ() - # Not supported for BitString + return unless (BitString.new.respond_to?(:>=)) + assert(false, '###FAIL! .>= not supported but .respond_to? is true!') end # def test_006_GEQ() def test_007_ShiftRight() + return unless (BitString.new.respond_to?(:>>)) + assert(true) end # def test_007_ShiftRight() def test_008_XOR() + return unless (BitString.new.respond_to?(:^)) + assert(true) end # def test_008_XOR() def test_009_OR() + return unless (BitString.new.respond_to?(:|)) + assert(true) end # def test_009_OR() def test_010_NOT() + return unless (BitString.new.respond_to?(:~)) + assert(true) end # def test_010_NOT() end # class Test_BitStrings From nobody at rubyforge.org Thu Feb 4 20:35:09 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 4 Feb 2010 20:35:09 -0500 (EST) Subject: [Bitstring-commits] [11] trunk/lib/bitstring/operators.rb: Dammit, missed one. Message-ID: <20100205013509.40E2218582C9@rubyforge.org> Revision: 11 Author: coar Date: 2010-02-04 20:35:08 -0500 (Thu, 04 Feb 2010) Log Message: ----------- Dammit, missed one. Always close your editor windows first! Modified Paths: -------------- trunk/lib/bitstring/operators.rb Modified: trunk/lib/bitstring/operators.rb =================================================================== --- trunk/lib/bitstring/operators.rb 2010-02-05 01:34:41 UTC (rev 10) +++ trunk/lib/bitstring/operators.rb 2010-02-05 01:35:08 UTC (rev 11) @@ -27,31 +27,6 @@ #++ #-- -# @TODO items (or at least look at) -# -# Methods (unique to bitstrings): -# & # Bitwise AND -# < # Less-than -# << # Shift left -# <= # Less-than or equal -# > # Greater-than -# >= # Greater-than or equal -# >> # Shift right -# [] # Indexed access -# []= # Indexed setting -# ^ # Bitwise XOR -# | # Bitwise inclusive OR -# ~ # Bitwise NOT -# -# Methods (based on Array): -# * # Meaningless for bitstrings. -# + # Meaningless for bitstrings. -# - # Meaningless for bitstrings. -# <=> # Meaningless for bitstrings. -# -#++ - -#-- # Re-open the class to add the operator methods #++ From nobody at rubyforge.org Thu Feb 4 20:41:05 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 4 Feb 2010 20:41:05 -0500 (EST) Subject: [Bitstring-commits] [12] trunk/lib/bitstring.rb: gem build not all that flexible with version numbering I guess.. Message-ID: <20100205014105.BB8B918582BF@rubyforge.org> Revision: 12 Author: coar Date: 2010-02-04 20:41:05 -0500 (Thu, 04 Feb 2010) Log Message: ----------- gem build not all that flexible with version numbering I guess.. Modified Paths: -------------- trunk/lib/bitstring.rb Modified: trunk/lib/bitstring.rb =================================================================== --- trunk/lib/bitstring.rb 2010-02-05 01:35:08 UTC (rev 11) +++ trunk/lib/bitstring.rb 2010-02-05 01:41:05 UTC (rev 12) @@ -59,7 +59,7 @@ # # Versionomy object for the class, recording the current version. # - Version = Versionomy.parse('v1.0.0') + Version = Versionomy.parse('1.0.0') # # Version number as a simple readable string. From nobody at rubyforge.org Thu Feb 4 20:41:51 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 4 Feb 2010 20:41:51 -0500 (EST) Subject: [Bitstring-commits] [13] trunk/dist/bitstring-1.0.0.gem: Gem built, add it Message-ID: <20100205014151.DD90018582C2@rubyforge.org> Revision: 13 Author: coar Date: 2010-02-04 20:41:51 -0500 (Thu, 04 Feb 2010) Log Message: ----------- Gem built, add it Added Paths: ----------- trunk/dist/bitstring-1.0.0.gem Added: trunk/dist/bitstring-1.0.0.gem =================================================================== (Binary files differ) Property changes on: trunk/dist/bitstring-1.0.0.gem ___________________________________________________________________ Added: svn:mime-type + application/octet-stream From nobody at rubyforge.org Thu Feb 4 20:51:02 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 4 Feb 2010 20:51:02 -0500 (EST) Subject: [Bitstring-commits] [14] tags/release-1.0.0/: Tagging v1.0.0 Message-ID: <20100205015102.C919F1858267@rubyforge.org> Revision: 14 Author: coar Date: 2010-02-04 20:51:02 -0500 (Thu, 04 Feb 2010) Log Message: ----------- Tagging v1.0.0 Added Paths: ----------- tags/release-1.0.0/ From nobody at rubyforge.org Thu Feb 4 20:34:41 2010 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Thu, 4 Feb 2010 20:34:41 -0500 (EST) Subject: [Bitstring-commits] [10] trunk: Check in what will become v1.0.0 Message-ID: <20100205013441.94C1318582BF@rubyforge.org> Revision: 10 Author: coar Date: 2010-02-04 20:34:41 -0500 (Thu, 04 Feb 2010) Log Message: ----------- Check in what will become v1.0.0 Modified Paths: -------------- trunk/Changelog.txt trunk/PostInstall.txt trunk/README.txt trunk/bitstring.gemspec trunk/doc/classes/BitString.html trunk/doc/created.rid trunk/doc/files/lib/bitstring/operators_rb.html trunk/doc/files/lib/bitstring_rb.html trunk/lib/bitstring/operators.rb trunk/lib/bitstring.rb trunk/test/test_operators.rb Modified: trunk/Changelog.txt =================================================================== --- trunk/Changelog.txt 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/Changelog.txt 2010-02-05 01:34:41 UTC (rev 10) @@ -1,10 +1,10 @@ -*- mode: change-log; mode: auto-fill; -*- -0.1.0 2010-01-30 +1.0.0 2010-02-04 Initial release as a Ruby gem + +0.1.0 o Added population() and select(). o Added the example fragments. - -0.1.0 2010-01-29 o Added mask() and each(). o Added the [start,length]= handling. (FREQ #27742) o Fixed a problem with the reporting of the BadDigit internal Modified: trunk/PostInstall.txt =================================================================== --- trunk/PostInstall.txt 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/PostInstall.txt 2010-02-05 01:34:41 UTC (rev 10) @@ -2,4 +2,6 @@ For more information on BitString, see http://bitstring.rubyforge.org/ If you use this package, please let the developers know what you -think! +think! See the mailing lists, trackers, and forums at the URL above. + +Thanks! Modified: trunk/README.txt =================================================================== --- trunk/README.txt 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/README.txt 2010-02-05 01:34:41 UTC (rev 10) @@ -1,7 +1,8 @@ BitString - 'Arrays' of bits for Ruby ===================================== -* http://rubyforge.org/projects/bitstring/ +* http://rubyforge.org/projects/bitstring/ - project page +* http://bitstring.rubyforge.org/rdoc/ - RDoc documentation DESCRIPTION: ------------ Modified: trunk/bitstring.gemspec =================================================================== --- trunk/bitstring.gemspec 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/bitstring.gemspec 2010-02-05 01:34:41 UTC (rev 10) @@ -44,14 +44,13 @@ s.email = 'The.Rodent.of.Unusual.Size at GMail.Com' s.date = Time.now.strftime('%Y-%m-%d') - s.description = %q{FTO is an extensible Ruby library for formatting text strings. In function it is similar to printf(3); however, the syntax of the format effectors (sometimes called 'format descriptors') and the selection of effectors bundled with the package are based on the SYS$FAO user-mode system service found on OpenVMS.} - s.summary = %q{An extensible Ruby library for formatting text strings.} + s.description = %q{This package provides the BitString class. Bit strings are something like Arrays constrained to only contain values of 0 and 1, and something like Integers. They can consist of a specific number of bits, or be arbitrarily expandable.} + s.summary = %q{An extensible Ruby class for handling sequences of bits.} s.email = %q{The.Rodent.of.Unusual.Size at GMail.Com} # s.extra_rdoc_files = ["README.rdoc", "CONTRIBUTORS.rdoc"] # s.executables = ["file1", "file2"] # s.default_executable = %q{file1} - s.add_dependency('locale', '>= 2.0.5') s.add_dependency('versionomy', '>= 0.3.0') s.homepage = %q{http://bitstring.rubyforge.org/} s.rubyforge_project = 'bitstring' Modified: trunk/doc/classes/BitString.html =================================================================== --- trunk/doc/classes/BitString.html 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/doc/classes/BitString.html 2010-02-05 01:34:41 UTC (rev 10) @@ -260,11 +260,11 @@ onclick="toggleCode('M000012-source');return false;">[Source]

-     # File lib/bitstring.rb, line 907
-907:   def self.mask(bits=1)
-908:     new._raise(NoDeficitBits) if (bits < 0)
-909:     vMask = 2**bits - 1
-910:   end
+     # File lib/bitstring.rb, line 908
+908:   def self.mask(bits=1)
+909:     new._raise(NoDeficitBits) if (bits < 0)
+910:     vMask = 2**bits - 1
+911:   end
 
@@ -330,61 +330,61 @@ onclick="toggleCode('M000001-source');return false;">[Source]

-     # File lib/bitstring.rb, line 288
-288:   def initialize(*args_p, &block)
-289:     #
-290:     # Two constructor scenarios:
-291:     #
-292:     # 1. With a block and an optional length (defaults to 1)
-293:     # 2. No block, and with value and length both optional.
-294:     #
-295:     # We don't do any type-checking on the arguments until later.
-296:     #
-297:     unless (block.nil?)
-298:       #
-299:       # We got a block; set up the constraints.  Bitstrings constructed
-300:       # this way are bounded.
-301:       #
-302:       unless (args_p.length < 2)
-303:         raise ArgumentError.new('only bitstring length ' +
-304:                                 'may be specified with a block')
-305:       end
-306:       @bounded = true
-307:       @length = args_p.length > 0 ? args_p[0] : 1
-308:     else
-309:       #
-310:       # Get value and possibly length from the argument list.
-311:       #
-312:       unless (args_p.length < 3)
-313:         raise ArgumentError.new('wrong number of arguments ' +
-314:                                 '(must be 2 or fewer)')
-315:       end
-316:       val = args_p[0] || 0
-317:       @length = args_p[1] if (@bounded = ! args_p[1].nil?)
-318:     end
-319:     #
-320:     # Now do some validation on the arguments.
-321:     #
-322:     if (@bounded)
-323:       unless ((@length = @length.to_i) > 0)
-324:         raise ArgumentError.new('bitstring length must be greater than 0')
-325:       end
-326:     end
-327:     if (block.nil?)
-328:       #
-329:       # We weren't passed a block, so get the info directly from the argument
-330:       # list.
-331:       #
-332:       @value = _arg2int(val)
-333:     else      
-334:       #
-335:       # We were passed a block, so invoke it for each bit position to
-336:       # determine that bit's value from the LSB of the result.
-337:       #
-338:       @value = 0
-339:       @length.times { |i| self[i] = block.call(i).to_i & 1 }
-340:     end
-341:   end
+     # File lib/bitstring.rb, line 289
+289:   def initialize(*args_p, &block)
+290:     #
+291:     # Two constructor scenarios:
+292:     #
+293:     # 1. With a block and an optional length (defaults to 1)
+294:     # 2. No block, and with value and length both optional.
+295:     #
+296:     # We don't do any type-checking on the arguments until later.
+297:     #
+298:     unless (block.nil?)
+299:       #
+300:       # We got a block; set up the constraints.  Bitstrings constructed
+301:       # this way are bounded.
+302:       #
+303:       unless (args_p.length < 2)
+304:         raise ArgumentError.new('only bitstring length ' +
+305:                                 'may be specified with a block')
+306:       end
+307:       @bounded = true
+308:       @length = args_p.length > 0 ? args_p[0] : 1
+309:     else
+310:       #
+311:       # Get value and possibly length from the argument list.
+312:       #
+313:       unless (args_p.length < 3)
+314:         raise ArgumentError.new('wrong number of arguments ' +
+315:                                 '(must be 2 or fewer)')
+316:       end
+317:       val = args_p[0] || 0
+318:       @length = args_p[1] if (@bounded = ! args_p[1].nil?)
+319:     end
+320:     #
+321:     # Now do some validation on the arguments.
+322:     #
+323:     if (@bounded)
+324:       unless ((@length = @length.to_i) > 0)
+325:         raise ArgumentError.new('bitstring length must be greater than 0')
+326:       end
+327:     end
+328:     if (block.nil?)
+329:       #
+330:       # We weren't passed a block, so get the info directly from the argument
+331:       # list.
+332:       #
+333:       @value = _arg2int(val)
+334:     else      
+335:       #
+336:       # We were passed a block, so invoke it for each bit position to
+337:       # determine that bit's value from the LSB of the result.
+338:       #
+339:       @value = 0
+340:       @length.times { |i| self[i] = block.call(i).to_i & 1 }
+341:     end
+342:   end
 
@@ -530,13 +530,14 @@

Description

-Perform an equality check against another bitstring. The value and the -boundedness must both match to be considered equal. +Perform an equality check against another bitstring or representation of +one. The value and the boundedness must both match to be considered equal.

Arguments

-
compstring
BitString. Bitstring to compare -against. +
compstring
Array, BitString, +Integer, or String. Bitstring (or something representing +one) against which to compare.
@@ -545,16 +546,29 @@ bs1 = BitString.new('111111111') bs2 = BitString.new('111111111', 9) bs1 == bs2 - => false + => false # Boundedness doesn't match bs1 = BitString.new('111111111') bs2 = BitString.new('111111111') bs1 == bs2 - => true + => true # Values and boundedness match bs1 = BitString.new('111111111') bs1 == '111111111' - => false + => true # When converted to an unbounded bitstring, it matches + + bs1 = BitString.new('111111111') + bs1 == '0000000111111111' + => true # When converted to an unbounded bitstring, it matches + + bs1 = BitString.new('111111111') + bs1 == 511 + => true # When converted to an unbounded bitstring, it matches + + bs1 = BitString.new('111111111', 9) + bs1 == '1000111111111' + => false # When converted to a bounded bitstring (because bs1 is), + # lengths and values don't match

Exceptions

@@ -564,12 +578,25 @@ onclick="toggleCode('M000034-source');return false;">[Source]

-     # File lib/bitstring/operators.rb, line 473
-473:   def ==(value)
-474:     (self.class == value.class) &&
-475:       (self.bounded? == value.bounded?) &&
-476:       (@value == value.to_i)
-477:   end
+     # File lib/bitstring/operators.rb, line 487
+487:   def ==(value)
+488:     #
+489:     # Bitstring/bitstring comparison
+490:     #
+491:     unless (value.class == self.class)
+492:       value = _arg2int(value)
+493:       if (self.bounded?)
+494:         bits = [self.length, value.to_s(2).length].max
+495:         value = self.class.new(value, bits)
+496:       else
+497:         value = self.class.new(value)
+498:       end
+499:     end
+500:     ((self.class == value.class) &&
+501:      (self.bounded? == value.bounded?) &&
+502:      (self.length == value.length) &&
+503:      (@value == value.to_i))
+504:   end
 
@@ -957,10 +984,10 @@ onclick="toggleCode('M000002-source');return false;">[Source]

-     # File lib/bitstring.rb, line 564
-564:   def bounded?()
-565:     @bounded
-566:   end
+     # File lib/bitstring.rb, line 565
+565:   def bounded?()
+566:     @bounded
+567:   end
 
@@ -1002,12 +1029,12 @@ onclick="toggleCode('M000003-source');return false;">[Source]

-     # File lib/bitstring.rb, line 590
-590:   def clear()
-591:     bs = dup
-592:     bs.from_i(0)
-593:     bs
-594:   end
+     # File lib/bitstring.rb, line 591
+591:   def clear()
+592:     bs = dup
+593:     bs.from_i(0)
+594:     bs
+595:   end
 
@@ -1049,11 +1076,11 @@ onclick="toggleCode('M000004-source');return false;">[Source]

-     # File lib/bitstring.rb, line 618
-618:   def clear!()
-619:     @value = 0
-620:     self
-621:   end
+     # File lib/bitstring.rb, line 619
+619:   def clear!()
+620:     @value = 0
+621:     self
+622:   end
 
@@ -1102,11 +1129,11 @@ onclick="toggleCode('M000005-source');return false;">[Source]

-     # File lib/bitstring.rb, line 647
-647:   def each(&block)
-648:     self.length.times { |bit| block.call(self[bit]) }
-649:     self
-650:   end
+     # File lib/bitstring.rb, line 648
+648:   def each(&block)
+649:     self.length.times { |bit| block.call(self[bit]) }
+650:     self
+651:   end
 
@@ -1150,17 +1177,17 @@ onclick="toggleCode('M000006-source');return false;">[Source]

-     # File lib/bitstring.rb, line 675
-675:   def from_i(newval)
-676:     unless (newval.respond_to?(:to_i))
-677:       what = newval.respond_to?(:to_s) ? newval.to_s : newval.inspect
-678:       _raise(UnInterable, newval)
-679:     end
-680:     newval = newval.to_i
-681:     newval &= 2**@length - 1 if (bounded?)
-682:     @value = newval
-683:     self
-684:   end
+     # File lib/bitstring.rb, line 676
+676:   def from_i(newval)
+677:     unless (newval.respond_to?(:to_i))
+678:       what = newval.respond_to?(:to_s) ? newval.to_s : newval.inspect
+679:       _raise(UnInterable, newval)
+680:     end
+681:     newval = newval.to_i
+682:     newval &= 2**@length - 1 if (bounded?)
+683:     @value = newval
+684:     self
+685:   end
 
@@ -1237,36 +1264,36 @@ onclick="toggleCode('M000007-source');return false;">[Source]

-     # File lib/bitstring.rb, line 722
-722:   def grow(bits=1, defval=0, direction=HIGH_END)
-723:     unless (bits.kind_of?(Integer))
-724:       _raise(BitsRInts)
-725:     end
-726:     unless (defval.respond_to?(:to_i))
-727:       what = defval.respond_to?(:to_s) ? defval.to_s : defval.inspect
-728:       _raise(UnInterable, defval)
-729:     end
-730:     unless ([HIGH_END, LOW_END].include?(direction))
-731:       _raise(NeedGPS)
-732:     end
-733:     unless (bits >= 0)
-734:       _raise(NoDeficitBits)
-735:     end
-736:     unless ((direction == LOW_END) || bounded?)
-737:       _raise(UnboundedNonsense)
-738:     end
-739:     return dup if (bits == 0)
-740: 
-741:     value = @value
-742:     vMask = 2**bits - 1
-743:     if (direction == HIGH_END)
-744:       vMask *= 2**@length if (bounded?)
-745:     elsif (direction == LOW_END)
-746:       value *= (2**bits)
-747:     end
-748:     value |= vMask if (defval == 1)
-749:     bounded? ? self.class.new(value, @length + bits) : self.class.new(value)
-750:   end
+     # File lib/bitstring.rb, line 723
+723:   def grow(bits=1, defval=0, direction=HIGH_END)
+724:     unless (bits.kind_of?(Integer))
+725:       _raise(BitsRInts)
+726:     end
+727:     unless (defval.respond_to?(:to_i))
+728:       what = defval.respond_to?(:to_s) ? defval.to_s : defval.inspect
+729:       _raise(UnInterable, defval)
+730:     end
+731:     unless ([HIGH_END, LOW_END].include?(direction))
+732:       _raise(NeedGPS)
+733:     end
+734:     unless (bits >= 0)
+735:       _raise(NoDeficitBits)
+736:     end
+737:     unless ((direction == LOW_END) || bounded?)
+738:       _raise(UnboundedNonsense)
+739:     end
+740:     return dup if (bits == 0)
+741: 
+742:     value = @value
+743:     vMask = 2**bits - 1
+744:     if (direction == HIGH_END)
+745:       vMask *= 2**@length if (bounded?)
+746:     elsif (direction == LOW_END)
+747:       value *= (2**bits)
+748:     end
+749:     value |= vMask if (defval == 1)
+750:     bounded? ? self.class.new(value, @length + bits) : self.class.new(value)
+751:   end
 
@@ -1338,13 +1365,13 @@ onclick="toggleCode('M000008-source');return false;">[Source]

-     # File lib/bitstring.rb, line 784
-784:   def grow!(bits=1, defval=0, direction=HIGH_END)
-785:     bs = grow(bits, defval, direction)
-786:     @length = bs.length if (bs.bounded?)
-787:     @value = bs.to_i
-788:     self
-789:   end
+     # File lib/bitstring.rb, line 785
+785:   def grow!(bits=1, defval=0, direction=HIGH_END)
+786:     bs = grow(bits, defval, direction)
+787:     @length = bs.length if (bs.bounded?)
+788:     @value = bs.to_i
+789:     self
+790:   end
 
@@ -1393,10 +1420,10 @@ onclick="toggleCode('M000009-source');return false;">[Source]

-     # File lib/bitstring.rb, line 819
-819:   def length()
-820:     bounded? ? @length : @value.to_s(2).length
-821:   end
+     # File lib/bitstring.rb, line 820
+820:   def length()
+821:     bounded? ? @length : @value.to_s(2).length
+822:   end
 
@@ -1439,10 +1466,10 @@ onclick="toggleCode('M000010-source');return false;">[Source]

-     # File lib/bitstring.rb, line 846
-846:   def lsb()
-847:     self[0]
-848:   end
+     # File lib/bitstring.rb, line 847
+847:   def lsb()
+848:     self[0]
+849:   end
 
@@ -1505,14 +1532,14 @@ onclick="toggleCode('M000011-source');return false;">[Source]

-     # File lib/bitstring.rb, line 880
-880:   def mask(bits=self.length, direction=HIGH_END)
-881:     _raise(OuttasightIndex, bits) if (bits > self.length)
-882:     _raise(NoDeficitBits) if (bits < 0)
-883:     vMask = 2**bits - 1
-884:     vMask *= 2**(self.length - bits) if (direction == HIGH_END)
-885:     vMask
-886:   end
+     # File lib/bitstring.rb, line 881
+881:   def mask(bits=self.length, direction=HIGH_END)
+882:     _raise(OuttasightIndex, bits) if (bits > self.length)
+883:     _raise(NoDeficitBits) if (bits < 0)
+884:     vMask = 2**bits - 1
+885:     vMask *= 2**(self.length - bits) if (direction == HIGH_END)
+886:     vMask
+887:   end
 
@@ -1558,14 +1585,14 @@ onclick="toggleCode('M000013-source');return false;">[Source]

-     # File lib/bitstring.rb, line 936
-936:   def msb()
-937:     unless (bounded?)
-938:       _raise(UnboundedNonsense,
-939:              'most significant bit only applies to bounded bitstrings')
-940:     end
-941:     self[@length - 1]
-942:   end
+     # File lib/bitstring.rb, line 937
+937:   def msb()
+938:     unless (bounded?)
+939:       _raise(UnboundedNonsense,
+940:              'most significant bit only applies to bounded bitstrings')
+941:     end
+942:     self[@length - 1]
+943:   end
 
@@ -1619,11 +1646,11 @@ onclick="toggleCode('M000014-source');return false;">[Source]

-     # File lib/bitstring.rb, line 972
-972:   def population(val)
-973:     val = _arg2int(val) & 1
-974:     self.select { |bval| bval == val }.length
-975:   end
+     # File lib/bitstring.rb, line 973
+973:   def population(val)
+974:     val = _arg2int(val) & 1
+975:     self.select { |bval| bval == val }.length
+976:   end
 
@@ -1679,20 +1706,20 @@ onclick="toggleCode('M000015-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1009
-1009:   def resize(bits)
-1010:     unless (bits.kind_of?(Integer))
-1011:       _raise(BitsRInts)
-1012:     end
-1013:     unless (bits > 0)
-1014:       _raise(NoDeficitBits)
-1015:     end
-1016:     value = @value
-1017:     length = self.length
-1018:     bs = self.class.new(value, length)
-1019:     diffbits = bits - length
-1020:     diffbits < 0 ? bs.shrink!(-diffbits) : bs.grow!(diffbits)
-1021:   end
+      # File lib/bitstring.rb, line 1010
+1010:   def resize(bits)
+1011:     unless (bits.kind_of?(Integer))
+1012:       _raise(BitsRInts)
+1013:     end
+1014:     unless (bits > 0)
+1015:       _raise(NoDeficitBits)
+1016:     end
+1017:     value = @value
+1018:     length = self.length
+1019:     bs = self.class.new(value, length)
+1020:     diffbits = bits - length
+1021:     diffbits < 0 ? bs.shrink!(-diffbits) : bs.grow!(diffbits)
+1022:   end
 
@@ -1746,14 +1773,14 @@ onclick="toggleCode('M000016-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1052
-1052:   def resize!(bits)
-1053:     bs = resize(bits)
-1054:     @bounded = true
-1055:     @length = bs.length
-1056:     @value = bs.to_i
-1057:     self
-1058:   end
+      # File lib/bitstring.rb, line 1053
+1053:   def resize!(bits)
+1054:     bs = resize(bits)
+1055:     @bounded = true
+1056:     @length = bs.length
+1057:     @value = bs.to_i
+1058:     self
+1059:   end
 
@@ -1805,35 +1832,35 @@ onclick="toggleCode('M000017-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1084
-1084:   def rotate(bits_p)
-1085:     unless (bounded?)
-1086:       _raise(UnboundedNonsense,
-1087:              'rotation only applies to bounded bitstrings')
-1088:     end
-1089: 
-1090:     value = @value
-1091:     length = @length
-1092:     bits = bits_p.to_i.abs % length
-1093:     vMask = (mult = 2**bits) - 1
-1094:     ldiff = length - bits
-1095:     if (bits_p > 0)
-1096:       #
-1097:       # Rotate right (toward the LSB)
-1098:       #
-1099:       residue = value & vMask
-1100:       value /= mult
-1101:       value |= residue * 2**ldiff
-1102:     elsif (bits_p < 0)
-1103:       #
-1104:       # Rotate left (toward the MSB)
-1105:       #
-1106:       vMask *= 2**ldiff
-1107:       residue = value & vMask
-1108:       value = ((value & ~vMask) * mult) | (residue / 2**ldiff)
-1109:     end
-1110:     self.class.new(value, @length)
-1111:   end
+      # File lib/bitstring.rb, line 1085
+1085:   def rotate(bits_p)
+1086:     unless (bounded?)
+1087:       _raise(UnboundedNonsense,
+1088:              'rotation only applies to bounded bitstrings')
+1089:     end
+1090: 
+1091:     value = @value
+1092:     length = @length
+1093:     bits = bits_p.to_i.abs % length
+1094:     vMask = (mult = 2**bits) - 1
+1095:     ldiff = length - bits
+1096:     if (bits_p > 0)
+1097:       #
+1098:       # Rotate right (toward the LSB)
+1099:       #
+1100:       residue = value & vMask
+1101:       value /= mult
+1102:       value |= residue * 2**ldiff
+1103:     elsif (bits_p < 0)
+1104:       #
+1105:       # Rotate left (toward the MSB)
+1106:       #
+1107:       vMask *= 2**ldiff
+1108:       residue = value & vMask
+1109:       value = ((value & ~vMask) * mult) | (residue / 2**ldiff)
+1110:     end
+1111:     self.class.new(value, @length)
+1112:   end
 
@@ -1881,11 +1908,11 @@ onclick="toggleCode('M000018-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1137
-1137:   def rotate!(bits_p)
-1138:     @value = rotate(bits_p).to_i
-1139:     self
-1140:   end
+      # File lib/bitstring.rb, line 1138
+1138:   def rotate!(bits_p)
+1139:     @value = rotate(bits_p).to_i
+1140:     self
+1141:   end
 
@@ -1939,14 +1966,14 @@ onclick="toggleCode('M000019-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1172
-1172:   def select(&block)
-1173:     result = []
-1174:     self.each do |val|
-1175:       result.push(val) if (block.call(val))
-1176:     end
-1177:     result
-1178:   end
+      # File lib/bitstring.rb, line 1173
+1173:   def select(&block)
+1174:     result = []
+1175:     self.each do |val|
+1176:       result.push(val) if (block.call(val))
+1177:     end
+1178:     result
+1179:   end
 
@@ -2007,32 +2034,32 @@ onclick="toggleCode('M000020-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1212
-1212:   def shrink(bits=1, direction=HIGH_END)
-1213:     unless (bits.kind_of?(Integer))
-1214:       _raise(BitsRInts)
-1215:     end
-1216:     unless (bits >= 0)
-1217:       _raise(NoDeficitBits)
-1218:     end
-1219:     unless ([HIGH_END, LOW_END].include?(direction))
-1220:       _raise(NeedGPS)
-1221:     end
-1222:     return dup if (bits == 0)
-1223: 
-1224:     if (bounded? && (bits >= @length))
-1225:       _raise(RuntimeError, 'shrink count greater than bitstring size')
-1226:     end
-1227:     value = @value
-1228:     length = bounded? ? @length - bits : nil
-1229:     if (direction == LOW_END)
-1230:       value /= 2**bits
-1231:     else
-1232:       _raise(UnboundedNonsense) unless (bounded?)
-1233:       value &= 2**length - 1
-1234:     end
-1235:     bounded? ? self.class.new(value, length) : self.class.new(value)
-1236:   end
+      # File lib/bitstring.rb, line 1213
+1213:   def shrink(bits=1, direction=HIGH_END)
+1214:     unless (bits.kind_of?(Integer))
+1215:       _raise(BitsRInts)
+1216:     end
+1217:     unless (bits >= 0)
+1218:       _raise(NoDeficitBits)
+1219:     end
+1220:     unless ([HIGH_END, LOW_END].include?(direction))
+1221:       _raise(NeedGPS)
+1222:     end
+1223:     return dup if (bits == 0)
+1224: 
+1225:     if (bounded? && (bits >= @length))
+1226:       _raise(RuntimeError, 'shrink count greater than bitstring size')
+1227:     end
+1228:     value = @value
+1229:     length = bounded? ? @length - bits : nil
+1230:     if (direction == LOW_END)
+1231:       value /= 2**bits
+1232:     else
+1233:       _raise(UnboundedNonsense) unless (bounded?)
+1234:       value &= 2**length - 1
+1235:     end
+1236:     bounded? ? self.class.new(value, length) : self.class.new(value)
+1237:   end
 
@@ -2093,13 +2120,13 @@ onclick="toggleCode('M000021-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1269
-1269:   def shrink!(bits=1, direction=HIGH_END)
-1270:     bs = shrink(bits, direction)
-1271:     @length = bs.length if (bs.bounded?)
-1272:     @value = bs.to_i
-1273:     self
-1274:   end
+      # File lib/bitstring.rb, line 1270
+1270:   def shrink!(bits=1, direction=HIGH_END)
+1271:     bs = shrink(bits, direction)
+1272:     @length = bs.length if (bs.bounded?)
+1273:     @value = bs.to_i
+1274:     self
+1275:   end
 
@@ -2151,10 +2178,10 @@ onclick="toggleCode('M000022-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1297
-1297:   def slice(*args)
-1298:     self[*args]
-1299:   end
+      # File lib/bitstring.rb, line 1298
+1298:   def slice(*args)
+1299:     self[*args]
+1300:   end
 
@@ -2220,14 +2247,14 @@ onclick="toggleCode('M000023-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1333
-1333:   def slice!(*args)
-1334:     bs = self[*args]
-1335:     @value = bs.to_i
-1336:     @bounded = bs.bounded?
-1337:     @length = bs.length if (bs.bounded?)
-1338:     self
-1339:   end
+      # File lib/bitstring.rb, line 1334
+1334:   def slice!(*args)
+1335:     bs = self[*args]
+1336:     @value = bs.to_i
+1337:     @bounded = bs.bounded?
+1338:     @length = bs.length if (bs.bounded?)
+1339:     self
+1340:   end
 
@@ -2266,10 +2293,10 @@ onclick="toggleCode('M000024-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1360
-1360:   def to_i()
-1361:     @value.to_i
-1362:   end
+      # File lib/bitstring.rb, line 1361
+1361:   def to_i()
+1362:     @value.to_i
+1363:   end
 
@@ -2314,10 +2341,10 @@ onclick="toggleCode('M000025-source');return false;">[Source]

-      # File lib/bitstring.rb, line 1389
-1389:   def to_s()
-1390:     _zfill(@value, @length)
-1391:   end
+      # File lib/bitstring.rb, line 1390
+1390:   def to_s()
+1391:     _zfill(@value, @length)
+1392:   end
 
Modified: trunk/doc/created.rid =================================================================== --- trunk/doc/created.rid 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/doc/created.rid 2010-02-05 01:34:41 UTC (rev 10) @@ -1 +1 @@ -Mon, 01 Feb 2010 01:05:29 -0500 +Thu, 04 Feb 2010 20:19:57 -0500 Modified: trunk/doc/files/lib/bitstring/operators_rb.html =================================================================== --- trunk/doc/files/lib/bitstring/operators_rb.html 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/doc/files/lib/bitstring/operators_rb.html 2010-02-05 01:34:41 UTC (rev 10) @@ -56,7 +56,7 @@ Last Update: - Sat Jan 30 23:21:50 -0500 2010 + Thu Feb 04 18:32:44 -0500 2010 Modified: trunk/doc/files/lib/bitstring_rb.html =================================================================== --- trunk/doc/files/lib/bitstring_rb.html 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/doc/files/lib/bitstring_rb.html 2010-02-05 01:34:41 UTC (rev 10) @@ -56,7 +56,7 @@ Last Update: - Sun Jan 31 02:28:56 -0500 2010 + Wed Feb 03 00:27:26 -0500 2010 Modified: trunk/lib/bitstring/operators.rb =================================================================== --- trunk/lib/bitstring/operators.rb 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/lib/bitstring/operators.rb 2010-02-05 01:34:41 UTC (rev 10) @@ -442,38 +442,65 @@ # # === Description # - # Perform an equality check against another bitstring. The value and - # the boundedness must both match to be considered equal. + # Perform an equality check against another bitstring or representation + # of one. The value and the boundedness must both match to be considered + # equal. # # call-seq: # bitstring == compstring => Boolean # bitstring.==(compstring) => Boolean # # === Arguments - # [compstring] BitString. Bitstring to compare against. + # [compstring] Array, BitString, Integer, or String. Bitstring (or something representing one) against which to compare. # # === Examples # bs1 = BitString.new('111111111') # bs2 = BitString.new('111111111', 9) # bs1 == bs2 - # => false + # => false # Boundedness doesn't match # # bs1 = BitString.new('111111111') # bs2 = BitString.new('111111111') # bs1 == bs2 - # => true + # => true # Values and boundedness match # # bs1 = BitString.new('111111111') # bs1 == '111111111' - # => false + # => true # When converted to an unbounded bitstring, it matches # + # bs1 = BitString.new('111111111') + # bs1 == '0000000111111111' + # => true # When converted to an unbounded bitstring, it matches + # + # bs1 = BitString.new('111111111') + # bs1 == 511 + # => true # When converted to an unbounded bitstring, it matches + # + # bs1 = BitString.new('111111111', 9) + # bs1 == '1000111111111' + # => false # When converted to a bounded bitstring (because bs1 is), + # # lengths and values don't match + # # === Exceptions # None. # def ==(value) - (self.class == value.class) && - (self.bounded? == value.bounded?) && - (@value == value.to_i) + # + # Bitstring/bitstring comparison + # + unless (value.class == self.class) + value = _arg2int(value) + if (self.bounded?) + bits = [self.length, value.to_s(2).length].max + value = self.class.new(value, bits) + else + value = self.class.new(value) + end + end + ((self.class == value.class) && + (self.bounded? == value.bounded?) && + (self.length == value.length) && + (@value == value.to_i)) end # def == end # class BitString Modified: trunk/lib/bitstring.rb =================================================================== --- trunk/lib/bitstring.rb 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/lib/bitstring.rb 2010-02-05 01:34:41 UTC (rev 10) @@ -50,89 +50,7 @@ require 'bitstring/operators' -#-- -# @TODO items (or at least look at) # -# Methods (unique to bitstrings): -# rotate # Rotate a bounded bitstring -# rotate! # Rotate a bounded bitstring in place -# ones # Count of bits set to 1 -# zeroes # Count of bits set to 0 -# to_i # Convert to an integer value -# to_s # Represent as a string of '1' and '0' -# -# Methods (based on Array): -# all? # -# any? # -# assoc # -# at # -# clear # -# collect # -# collect! # -# compact # -# compact! # -# concat # -# delete # Meaningless for bitstrings -# delete_at # Meaningless for bitstrings -# delete_if # Meaningless for bitstrings -# detect # -# each # -# each_index # -# each_with_index # -# empty? # Meaningless for bitstrings -# entries # -# fetch # -# fill # -# find # -# find_all # -# first # -# flatten # -# flatten! # -# grep # -# include? # -# index # -# indexes # -# indices # -# inject # -# insert # -# join # -# last # -# length # -# map # -# map! # -# max # Meaningless for bitstrings -# member? # -# min # Meaningless for bitstrings -# nitems # -# pack # -# partition # -# pop # -# push # -# rassoc # -# reject # -# reject! # -# replace # -# reverse # -# reverse! # -# reverse_each # -# rindex # -# select # -# shift # -# size # -# sort # -# sort! # -# sort_by # -# to_ary # -# transpose # -# uniq # -# uniq! # -# unshift # -# values_at # -# zip # -# -#++ - -# # It's sort of like a fake a subclass of Integer solely to # differentiate bitstrings. # @@ -141,7 +59,7 @@ # # Versionomy object for the class, recording the current version. # - Version = Versionomy.parse('0.1.0a2') + Version = Versionomy.parse('v1.0.0') # # Version number as a simple readable string. Modified: trunk/test/test_operators.rb =================================================================== --- trunk/test/test_operators.rb 2010-02-03 07:16:12 UTC (rev 9) +++ trunk/test/test_operators.rb 2010-02-05 01:34:41 UTC (rev 10) @@ -12,6 +12,95 @@ class Test_BitStrings < Test::Unit::TestCase + def test_000_EQUAL() + # + # Test == comparison of bitstrings. + # + TestVals.each do |sVal| + # + # Compare two identically-created unbounded bitstrings + # + bs1 = BitString.new(sVal) + bs2 = BitString.new(sVal) + assert(bs1 == bs2, + "Test unbounded new('#{sVal}') == new('#{sVal}')") + unless (sVal.gsub(/0/, '').empty?) + bs2 = BitString.new(sVal + '0') + assert(bs1 != bs2, + "Test unbounded new('#{sVal}') != new('#{sVal}0')") + end + # + # Now against the string value. + # + assert(bs1 == sVal, + "Test unbounded new('#{sVal}') == '#{sVal}'") + unless (sVal.gsub(/0/, '').empty?) + assert(bs1 != (sVal + '0'), + "Test unbounded new('#{sVal}') != '#{sVal}0'") + end + # + # Now against the integer value. + # + assert(bs1 == sVal.to_i(2), + "Test unbounded new('#{sVal}') == #{sVal.to_i(2)}") + unless (sVal.gsub(/0/, '').empty?) + assert(bs1 != (sVal.to_i(2) * 2), + "Test unbounded new('#{sVal}') != #{sVal.to_i(2) * 2}") + end + # + # Now against the array representatione. + # + expected = sVal.split(//).collect { |val| val.to_i } + assert(bs1 == expected, + "Test unbounded new('#{sVal}') == #{expected.inspect}") + unless (sVal.gsub(/0/, '').empty?) + expected.push(0) + assert(bs1 != expected, + "Test unbounded new('#{sVal}') != #{expected.inspect}") + end + # + # Repeat for bounded bitstrings. + # + sVal_l = sVal.length + bs1 = BitString.new(sVal, sVal_l) + bs2 = BitString.new(sVal, sVal_l) + assert(bs1 == bs2, + "Test bounded new('#{sVal}') == new('#{sVal}')") + bs2 = BitString.new(sVal + '0', sVal_l + 1) + assert(bs1 != bs2, + "Test bounded new('#{sVal}') != new('#{sVal}0')") + # + # Now against the string value. + # + assert(bs1 == sVal, + "Test bounded new('#{sVal}') == '#{sVal}'") + unless (sVal.gsub(/0/, '').empty?) + assert(bs1 != (sVal + '0'), + "Test unbounded new('#{sVal}') != '#{sVal}0'") + end + # + # Now against the integer value. + # + assert(bs1 == sVal.to_i(2), + "Test unbounded new('#{sVal}') == #{sVal.to_i(2)}") + unless (sVal.gsub(/0/, '').empty?) + assert(bs1 != (sVal.to_i(2) * 2), + "Test unbounded new('#{sVal}') != #{sVal.to_i(2) * 2}") + end + # + # Now against the array representatione. + # + expected = sVal.split(//).collect { |val| val.to_i } + assert(bs1 == expected, + "Test unbounded new('#{sVal}') == #{expected.inspect}") + unless (sVal.gsub(/0/, '').empty?) + expected.push(0) + assert(bs1 != expected, + "Test unbounded new('#{sVal}') != #{expected.inspect}") + end + end + end # def test_001_AND() + def test_001_AND() # # Test ANDing with Array, String, BitString, and Integer values. @@ -133,22 +222,231 @@ def test_007_ShiftRight() return unless (BitString.new.respond_to?(:>>)) - assert(true) + TestVals.each do |sVal| + # + # Start with unbounded strings. + # + rVal = sVal.to_i(2).to_s(2) + bs = BitString.new(sVal) + (sVal.length * 2).times do |i| + expected = rVal[0,rVal.length-i] + expected = '0' if (expected.nil? || expected.empty?) + assert_equal(expected, + (bs >> i).to_s, + "Test unbounded '#{sVal}' >> #{i} == #{expected}") + end + # + # Now the bounded ones. + # + l = sVal.length + bs = BitString.new(sVal, l) + rVal = bs.to_s + (sVal.length * 2).times do |i| + expected = ('0' * [i,l].min) + rVal[0,[rVal.length-i,0].max] + assert_equal(expected, + (bs >> i).to_s, + "Test bounded '#{sVal}' >> #{i} == #{expected}") + end + end end # def test_007_ShiftRight() def test_008_XOR() return unless (BitString.new.respond_to?(:^)) - assert(true) + TestVals.each do |sVal| + sVal_l = sVal.length + # + # Start with unbounded strings. + # + xbs = BitString.new(sVal) + bs1 = xbs.dup + ybs = BitString.new(rand(2**sVal_l)) + bs2 = ybs.dup + bs1 = bs1 ^ bs2 + bs2 = bs1 ^ bs2 + bs1 = bs1 ^ bs2 + assert_equal(xbs.to_i, + bs2.to_i, + "Test unbounded A from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + assert_equal(ybs.to_i, + bs1.to_i, + "Test unbounded B from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + # + # Now with bounded ones. + # + xbs = BitString.new(sVal, sVal_l) + bs1 = xbs.dup + ybs = BitString.new(rand(2**sVal_l), sVal_l) + bs2 = ybs.dup + bs1 = bs1 ^ bs2 + bs2 = bs1 ^ bs2 + bs1 = bs1 ^ bs2 + assert_equal(xbs.to_i, + bs2.to_i, + "Test bounded A from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + assert_equal(ybs.to_i, + bs1.to_i, + "Test bounded B from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + # + # Now with bounded ones of different lengths. Note that + # XOR returns a bitstring the same length as its parent -- + # which means in the swap sequence below, both will end up + # with the length of the shorter string. + # + xbs = BitString.new(sVal, sVal_l) + bs1 = xbs.dup + ybs = BitString.new(rand(2**(sVal_l * 2)), sVal_l * 2) + bs2 = ybs.dup + bs1 = bs1 ^ bs2 + bs2 = bs1 ^ bs2 + bs1 = bs1 ^ bs2 + new_l = [sVal_l, ybs.length].min + assert_equal(xbs.resize(new_l).to_i, + bs2.resize(new_l).to_i, + "Test bounded A from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + assert_equal(ybs.resize(new_l).to_i, + bs1.resize(new_l).to_i, + "Test bounded B from A=A^B;B=A^B;A=A^B\n" + + "xbs=#{xbs.to_s}\n" + + "ybs=#{ybs.to_s}\n" + + "bs1=#{bs1.to_s}\n" + + "bs2=#{bs2.to_s}") + end end # def test_008_XOR() def test_009_OR() return unless (BitString.new.respond_to?(:|)) - assert(true) + TestVals.each do |sVal| + sVal_l = sVal.length + # + # Start with unbounded strings. + # + xbs = BitString.new(sVal) + ybs = BitString.new(rand(2**sVal_l)) + expected = BitString.new(xbs.to_i | ybs.to_i) + result = xbs | ybs + assert_equal(expected, + result, + "Test unbounded X from X=A|B\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + result = ybs | xbs + assert_equal(expected, + result, + "Test unbounded X from X=B|A\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + # + # Now with bounded ones with the same lengths. + # + xbs = BitString.new(sVal, sVal_l) + ybs = BitString.new(rand(2**sVal_l), sVal_l) + expected = BitString.new(xbs.to_i | ybs.to_i, sVal_l) + result = xbs | ybs + assert_equal(expected, + result, + "Test bounded X from X=A|B\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + result = ybs | xbs + assert_equal(expected, + result, + "Test bounded X from X=B|A\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + # + # Now with bounded ones of different lengths. Note that + # OR returns a bitstring the same length as its parent -- + # which means in the swap sequence below, both will end up + # with the length of the shorter string. + # + xbs = BitString.new(sVal, sVal_l) + ybs = BitString.new(rand(2**(sVal_l * 2)), sVal_l * 2) + expected = BitString.new((xbs.to_i | ybs.to_i) & xbs.mask, xbs.length) + result = xbs | ybs + assert_equal(expected, + result, + "Test bounded X from X=A|B (A.length != B.length)\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + expected = BitString.new((xbs.to_i | ybs.to_i) & ybs.mask, ybs.length) + result = ybs | xbs + assert_equal(expected, + result, + "Test bounded X from X=B|A (A.length != B.length)\n" + + "A =#{xbs.to_s}\n" + + "B =#{ybs.to_s}\n" + + "exp=#{expected.to_s}\n" + + "got=#{result.to_s}") + end end # def test_009_OR() def test_010_NOT() return unless (BitString.new.respond_to?(:~)) - assert(true) + TestVals.each do |sVal| + sVal_l = sVal.length + # + # Start with unbounded strings. + # + bs = BitString.new(sVal) + expected = bs.mask + result = (~ bs) | bs + assert_equal(expected, + result, + "Test unbounded (~ '#{sVal}') | '#{sVal}' " + + "== '#{expected.to_s}'") + # + # Move on to bounded ones, which are a little more problematic. + # Maybe. + # + bs = BitString.new(sVal, sVal_l) + expected = BitString.new(bs.mask, sVal_l) + result = (~ bs) | bs + assert_equal(expected, + result, + "Test bounded (~ '#{sVal}') | '#{sVal}' " + + "== '#{expected.to_s}'") + result = (~ bs) ^ bs + assert_equal(expected, + result, + "Test bounded (~ '#{sVal}') ^ '#{sVal}' " + + "== '#{expected.to_s}'") + expected = BitString.new(0, sVal_l) + result = (~ bs) & bs + assert_equal(expected, + result, + "Test bounded (~ '#{sVal}') & '#{sVal}' " + + "== '#{expected.to_s}'") + end end # def test_010_NOT() end # class Test_BitStrings