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 207 208 209 210
|
#!/usr/bin/env ruby
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
describe BinData::Primitive do
it "is not registered" do
_ {
BinData::RegisteredClasses.lookup("Primitive")
}.must_raise BinData::UnRegisteredTypeError
end
end
describe BinData::Primitive, "all subclasses" do
class SubClassOfPrimitive < BinData::Primitive
expose_methods_for_testing
end
let(:obj) { SubClassOfPrimitive.new }
it "raise errors on unimplemented methods" do
_ { obj.set(nil) }.must_raise NotImplementedError
_ { obj.get }.must_raise NotImplementedError
end
end
describe BinData::Primitive, "when defining with errors" do
it "fails on non registered types" do
_ {
class BadTypePrimitive < BinData::Primitive
non_registered_type :a
end
}.must_raise_on_line TypeError, 2, "unknown type 'non_registered_type' in BadTypePrimitive"
end
it "fails on duplicate names" do
_ {
class DuplicateNamePrimitive < BinData::Primitive
int8 :a
int8 :b
int8 :a
end
}.must_raise_on_line SyntaxError, 4, "duplicate field 'a' in DuplicateNamePrimitive"
end
it "fails when field name shadows an existing method" do
_ {
class ExistingNamePrimitive < BinData::Primitive
int8 :object_id
end
}.must_raise_on_line SyntaxError, 2, "field 'object_id' shadows an existing method in ExistingNamePrimitive"
end
it "fails on unknown endian" do
_ {
class BadEndianPrimitive < BinData::Primitive
endian 'a bad value'
end
}.must_raise_on_line ArgumentError, 2, "unknown value for endian 'a bad value' in BadEndianPrimitive"
end
end
describe BinData::Primitive do
class PrimitiveWithEndian < BinData::Primitive
endian :little
int16 :a
def get; self.a; end
def set(v); self.a = v; end
end
let(:obj) { PrimitiveWithEndian.new }
it "assigns value" do
obj.value = 5
_(obj.value).must_equal 5
end
it "produces binary string" do
obj.assign(5)
_(obj.to_binary_s).must_equal_binary "\x05\x00"
end
it "reads value" do
obj.read("\x00\x01")
_(obj).must_equal 0x100
end
it "accepts standard parameters" do
obj = PrimitiveWithEndian.new(initial_value: 2)
_(obj.to_binary_s).must_equal_binary "\x02\x00"
end
it "returns num_bytes" do
_(obj.num_bytes).must_equal 2
end
it "raises error on missing methods" do
_ {
obj.does_not_exist
}.must_raise NoMethodError
end
it "uses read value whilst reading" do
obj = PrimitiveWithEndian.new(value: 2)
obj.read "\x05\x00"
_(obj).must_equal 2
obj.stub :reading?, true do
_(obj).must_equal 5
end
end
it "behaves as primitive" do
obj.assign(5)
_((2 + obj)).must_equal 7
end
end
describe BinData::Primitive, "requiring custom parameters" do
class PrimitiveWithCustom < BinData::Primitive
int8 :a, initial_value: :iv
def get; self.a; end
def set(v); self.a = v; end
end
it "passes parameters correctly" do
obj = PrimitiveWithCustom.new(iv: 5)
_(obj).must_equal 5
end
end
describe BinData::Primitive, "with custom mandatory parameters" do
class MandatoryPrimitive < BinData::Primitive
mandatory_parameter :arg1
uint8 :a, value: :arg1
def get; self.a; end
def set(v); self.a = v; end
end
it "raises error if mandatory parameter is not supplied" do
_ { MandatoryPrimitive.new }.must_raise ArgumentError
end
it "uses mandatory parameter" do
obj = MandatoryPrimitive.new(arg1: 5)
_(obj).must_equal 5
end
end
describe BinData::Primitive, "with custom default parameters" do
class DefaultPrimitive < BinData::Primitive
default_parameter arg1: 5
uint8 :a, value: :arg1
def get; self.a; end
def set(v); self.a = v; end
end
it "uses default parameter" do
obj = DefaultPrimitive.new
_(obj).must_equal 5
end
it "overrides default parameter" do
obj = DefaultPrimitive.new(arg1: 7)
_(obj).must_equal 7
end
end
describe BinData::Primitive, "subclassed with default parameter" do
class ParentDerivedPrimitive < BinData::Primitive
uint16be :a
def get; self.a; end
def set(v); self.a = v; end
end
class ChildDerivedPrimitive < ParentDerivedPrimitive
default_parameter initial_value: 5
end
it "overrides initial_value" do
a = ChildDerivedPrimitive.new(initial_value: 7)
_(a.to_binary_s).must_equal_binary "\000\007"
end
it "uses default parameter" do
a = ChildDerivedPrimitive.new
_(a.to_binary_s).must_equal_binary "\000\005"
end
end
describe BinData::Primitive, "with mutating #get and #set" do
class MutatingPrimitive < BinData::Primitive
uint16le :a
def get; self.a; end
def set(v); self.a = v.abs; end
end
it "#assign applies mutator" do
obj = MutatingPrimitive.new
obj.assign(-50)
_(obj.snapshot).must_equal 50
end
it "#to_binary_s applies mutator" do
obj = MutatingPrimitive.new
obj.assign(-50)
_(obj.to_binary_s).must_equal_binary "\062\000"
end
end
|