1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
#!/usr/bin/env ruby
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
module AllIntegers
def test_have_correct_num_bytes
all_classes do |int_class|
_(int_class.new.num_bytes).must_equal @nbytes
end
end
def test_have_a_sensible_value_of_zero
all_classes do |int_class|
_(int_class.new).must_equal 0
end
end
def test_avoid_underflow
all_classes do |int_class|
subject = int_class.new
subject.assign(min_value - 1)
_(subject).must_equal min_value
end
end
def test_avoid_overflow
all_classes do |int_class|
subject = int_class.new
subject.assign(max_value + 1)
_(subject).must_equal max_value
end
end
def test_assign_values
all_classes do |int_class|
subject = int_class.new
test_int = gen_test_int
subject.assign(test_int)
_(subject).must_equal test_int
end
end
def test_assign_values_from_other_int_objects
all_classes do |int_class|
src = int_class.new
src.assign(gen_test_int)
subject = int_class.new
subject.assign(src)
_(subject).must_equal src
end
end
def test_symmetrically_read_and_write_a_positive_number
all_classes do |int_class|
subject = int_class.new
subject.assign(gen_test_int)
_(subject.value_read_from_written).must_equal subject
end
end
def test_symmetrically_read_and_write_a_negative_number
all_classes do |int_class|
if @signed
subject = int_class.new
subject.assign(-gen_test_int)
_(subject.value_read_from_written).must_equal subject
end
end
end
def test_convert_a_positive_number_to_string
all_classes do |int_class|
val = gen_test_int
subject = int_class.new
subject.assign(val)
_(subject.to_binary_s).must_equal_binary int_to_binary_str(val)
end
end
def test_convert_a_negative_number_to_string
all_classes do |int_class|
if @signed
val = -gen_test_int
subject = int_class.new
subject.assign(val)
_(subject.to_binary_s).must_equal_binary int_to_binary_str(val)
end
end
end
def all_classes(&block)
@ints.each_pair do |int_class, nbytes|
@nbytes = nbytes
yield int_class
end
end
def min_value
if @signed
-max_value - 1
else
0
end
end
def max_value
if @signed
(1 << (@nbytes * 8 - 1)) - 1
else
(1 << (@nbytes * 8)) - 1
end
end
def gen_test_int
# resulting int is guaranteed to be +ve for signed or unsigned integers
(0 ... @nbytes).inject(0) { |val, i| (val << 8) | ((val + 0x11) % 0x100) }
end
def int_to_binary_str(val)
str = "".dup.force_encoding(Encoding::BINARY)
v = val & ((1 << (@nbytes * 8)) - 1)
@nbytes.times do
str.concat(v & 0xff)
v >>= 8
end
(@endian == :little) ? str : str.reverse
end
def create_mapping_of_class_to_nbits(endian, signed)
base = signed ? "Int" : "Uint"
endian_str = (endian == :little) ? "le" : "be"
result = {}
result[BinData.const_get("#{base}8")] = 1
(1 .. 20).each do |nbytes|
nbits = nbytes * 8
class_name = "#{base}#{nbits}#{endian_str}"
result[BinData.const_get(class_name)] = nbytes
end
result
end
end
describe "All signed big endian integers" do
include AllIntegers
before do
@endian = :big
@signed = true
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
end
end
describe "All unsigned big endian integers" do
include AllIntegers
before do
@endian = :big
@signed = false
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
end
end
describe "All signed little endian integers" do
include AllIntegers
before do
@endian = :little
@signed = true
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
end
end
describe "All unsigned little endian integers" do
include AllIntegers
before do
@endian = :little
@signed = false
@ints = create_mapping_of_class_to_nbits(@endian, @signed)
end
end
describe "Custom defined integers" do
it "fail unless bits are a multiple of 8" do
_ { BinData::Uint7le }.must_raise NameError
_ { BinData::Uint7be }.must_raise NameError
_ { BinData::Int7le }.must_raise NameError
_ { BinData::Int7be }.must_raise NameError
end
end
|