spec/struct_spec.rb in bindata-0.8.1 vs spec/struct_spec.rb in bindata-0.9.0
- old
+ new
@@ -1,225 +1,136 @@
#!/usr/bin/env ruby
require File.expand_path(File.dirname(__FILE__)) + '/spec_common'
require 'bindata'
-describe "A Struct with hidden fields" do
- before(:all) do
- eval <<-END
- class HiddenStruct < BinData::Struct
- hide :b, 'c'
- int8 :a
- int8 'b', :initial_value => 10
- int8 :c
- int8 :d, :value => :b
- end
- END
- @obj = HiddenStruct.new
+describe BinData::Struct, "with hidden fields" do
+ before(:each) do
+ @params = { :hide => [:b, 'c'],
+ :fields => [
+ [:int8, :a],
+ [:int8, 'b', {:initial_value => 10}],
+ [:int8, :c],
+ [:int8, :d, {:value => :b}]] }
+ @obj = BinData::Struct.new(@params)
end
+ it "should not include hidden names in all_possible_field_names" do
+ params = BinData::SanitizedParameters.new(BinData::Struct, @params)
+ BinData::Struct.all_possible_field_names(params).should == ["a", "d"]
+ end
+
it "should only show fields that aren't hidden" do
@obj.field_names.should == ["a", "d"]
end
it "should be able to access hidden fields directly" do
- @obj.b.should eql(10)
+ @obj.b.should == 10
@obj.c = 15
- @obj.c.should eql(15)
+ @obj.c.should == 15
@obj.should respond_to(:b=)
end
it "should not include hidden fields in snapshot" do
@obj.b = 5
@obj.snapshot.should == {"a" => 0, "d" => 5}
end
end
-describe "A Struct that delegates" do
- before(:all) do
- eval <<-END
- class DelegateStruct < BinData::Struct
- delegate :b
- int8 :a, :initial_value => :num
- int8 'b', :initial_value => 7
- int8 :c, :value => :b
- end
- END
- @obj = DelegateStruct.new(:num => 5)
- end
-
- it "should access custom parameters" do
- @obj.a.should eql(5)
- @obj.b.should eql(7)
- end
-
- it "should have correct num_bytes" do
- @obj.num_bytes.should eql(3)
- end
-
- it "should delegate snapshot" do
- @obj.value = 6
- @obj.snapshot.should eql(6)
- end
-
- it "should delegate single_value?" do
- @obj.should be_a_single_value
- end
-
- it "should delegate methods" do
- @obj.should respond_to(:value)
- @obj.value = 9
- @obj.c.should eql(9)
- end
-
- it "should identify accepted parameters" do
- @obj.accepted_parameters.should include(:check_value)
- @obj.accepted_parameters.should include(:initial_value)
- @obj.accepted_parameters.should include(:value)
- @obj.accepted_parameters.should_not include(:endian)
- end
-
- it "should pass params when creating" do
- obj = DelegateStruct.new(:initial_value => :val, :val => 14)
- obj.value.should eql(14)
- end
-end
-
-describe "A Struct with nested delegation" do
- before(:all) do
- eval <<-END
- class DelegateOuterStruct < BinData::Struct
- endian :little
- delegate :b
- int8 :a
- struct :b, :delegate => :y,
- :fields => [[:int8, :x], [:int32, :y], [:int8, :z]]
- end
- END
- @obj = DelegateOuterStruct.new(:initial_value => 7)
- end
-
- it "should followed nested delegation" do
- @obj.should be_a_single_value
- @obj.field_names.should eql([])
- end
-
- it "should forward parameters" do
- @obj.should respond_to(:value)
- @obj.value.should eql(7)
- end
-
- it "should identify accepted parameters" do
- @obj.accepted_parameters.should include(:check_value)
- @obj.accepted_parameters.should include(:initial_value)
- @obj.accepted_parameters.should include(:value)
- end
-end
-
-describe "Defining a Struct" do
- before(:all) do
- end
+describe BinData::Struct do
it "should fail on non registered types" do
+ params = {:fields => [[:non_registered_type, :a]]}
lambda {
- eval <<-END
- class BadType < BinData::Struct
- non_registerd_type :a
- end
- END
+ BinData::Struct.new(params)
}.should raise_error(TypeError)
+ end
+ it "should fail on all_possible_field_names with unsanitized parameters" do
+ params = {:fields => [[:int8, :a], [:int8, :b]]}
lambda {
- BinData::Struct.new(:fields => [[:non_registered_type, :a]])
- }.should raise_error(TypeError)
-
- lambda {
- BinData::Struct.new(:delegate => :a,
- :fields => [[:non_registered_type, :a]])
- }.should raise_error(TypeError)
+ BinData::Struct.all_possible_field_names(params)
+ }.should raise_error(ArgumentError)
end
it "should fail on duplicate names" do
+ params = {:fields => [[:int8, :a], [:int8, :b], [:int8, :a]]}
lambda {
- eval <<-END
- class DuplicateName < BinData::Struct
- int8 :a
- int8 :b
- int8 :a
- end
- END
- }.should raise_error(SyntaxError)
+ BinData::Struct.new(params)
+ }.should raise_error(NameError)
end
- it "should fail on reserved names" do
+ it "should fail on duplicate names in nested structs" do
+ params = {:fields => [[:int8, :a],
+ [:struct, nil, {:fields => [[:int8, :a]]}]]}
lambda {
- eval <<-END
- class ReservedName < BinData::Struct
- int8 :a
- int8 :invert # from Hash.instance_methods
- end
- END
+ BinData::Struct.new(params)
}.should raise_error(NameError)
+ end
+ it "should fail on duplicate names in triple nested structs" do
+ params = {:fields => [[:int8, :a],
+ [:struct, nil, {:fields => [
+ [:struct, nil, {:fields => [[:int8, :a]]}]]}]]}
lambda {
- # :invert is from Hash.instance_methods
- BinData::Struct.new(:fields => [[:int8, :a], [:int8, :invert]])
+ BinData::Struct.new(params)
}.should raise_error(NameError)
end
- it "should fail on reserved names of delegated fields" do
+ it "should fail on reserved names" do
+ # note that #invert is from Hash.instance_methods
+ params = {:fields => [[:int8, :a], [:int8, :invert]]}
lambda {
- # :value is from Int8.instance_methods
- BinData::Struct.new(:delegate => :a,
- :fields => [[:int8, :a], [:int8, :value]])
+ BinData::Struct.new(params)
}.should raise_error(NameError)
end
it "should fail when field name shadows an existing method" do
+ # note that #invert is from Hash.instance_methods
+ params = {:fields => [[:int8, :object_id]]}
lambda {
- eval <<-END
- class ExistingName < BinData::Struct
- int8 :object_id
- end
- END
+ BinData::Struct.new(params)
}.should raise_error(NameError)
-
- lambda {
- BinData::Struct.new(:fields => [[:int8, :object_id]])
- }.should raise_error(NameError)
end
it "should fail on unknown endian" do
+ params = {:endian => 'bad value', :fields => []}
lambda {
- eval <<-END
- class BadEndian < BinData::Struct
- endian 'a bad value'
- end
- END
+ BinData::Struct.new(params)
}.should raise_error(ArgumentError)
end
end
-describe "A Struct with multiple fields" do
+describe BinData::Struct, "with multiple fields" do
before(:each) do
- fields = [ [:int8, :a], [:int8, :b] ]
- @obj = BinData::Struct.new(:fields => fields)
+ @params = { :fields => [ [:int8, :a], [:int8, :b] ] }
+ @obj = BinData::Struct.new(@params)
@obj.a = 1
@obj.b = 2
end
it "should return num_bytes" do
- @obj.num_bytes(:a).should eql(1)
- @obj.num_bytes(:b).should eql(1)
- @obj.num_bytes.should eql(2)
+ @obj.num_bytes(:a).should == 1
+ @obj.num_bytes(:b).should == 1
+ @obj.num_bytes.should == 2
end
it "should identify accepted parameters" do
- @obj.accepted_parameters.should include(:delegate)
- @obj.accepted_parameters.should include(:endian)
+ BinData::Struct.accepted_parameters.should include(:fields)
+ BinData::Struct.accepted_parameters.should include(:hide)
+ BinData::Struct.accepted_parameters.should include(:endian)
end
+ it "should return all possible field names" do
+ params = BinData::SanitizedParameters.new(BinData::Struct, @params)
+ BinData::Struct.all_possible_field_names(params).should == ["a", "b"]
+ end
+
+ it "should return field names" do
+ @obj.field_names.should == ["a", "b"]
+ end
+
it "should clear" do
@obj.a = 6
@obj.clear
@obj.clear?.should be_true
end
@@ -235,25 +146,25 @@
it "should write ordered" do
io = StringIO.new
@obj.write(io)
io.rewind
- io.read.should eql("\x01\x02")
+ io.read.should == "\x01\x02"
end
it "should read ordered" do
io = StringIO.new "\x03\x04"
@obj.read(io)
- @obj.a.should eql(3)
- @obj.b.should eql(4)
+ @obj.a.should == 3
+ @obj.b.should == 4
end
it "should return a snapshot" do
snap = @obj.snapshot
- snap.a.should eql(1)
- snap.b.should eql(2)
+ snap.a.should == 1
+ snap.b.should == 2
snap.should == { "a" => 1, "b" => 2 }
end
it "should return field_names" do
@obj.field_names.should == ["a", "b"]
@@ -262,64 +173,67 @@
it "should fail on unknown method call" do
lambda { @obj.does_not_exist }.should raise_error(NoMethodError)
end
end
-describe "A Struct with nested structs" do
- before(:all) do
- eval <<-END
- class StructInner1 < BinData::Struct
- int8 :w, :initial_value => 3
- int8 :x, :value => :the_val
- end
+describe BinData::Struct, "with nested structs" do
+ before(:each) do
+ inner1 = [ [:int8, :w, {:initial_value => 3}],
+ [:int8, :x, {:value => :the_val}] ]
- class StructInner2 < BinData::Struct
- int8 :y, :value => lambda { parent.b.w }
- int8 :z
- end
+ inner2 = [ [:int8, :y, {:value => lambda { parent.b.w }}],
+ [:int8, :z] ]
- class StructOuter < BinData::Struct
- int8 :a, :initial_value => 6
- struct_inner1 :b, :the_val => :a
- struct_inner2 nil
- end
- END
- @obj = StructOuter.new
+ @params = { :fields => [
+ [:int8, :a, {:initial_value => 6}],
+ [:struct, :b, {:fields => inner1, :the_val => :a}],
+ [:struct, nil, {:fields => inner2}]] }
+ @obj = BinData::Struct.new(@params)
end
it "should included nested field names" do
@obj.field_names.should == ["a", "b", "y", "z"]
end
+ it "should return all possible field names" do
+ params = BinData::SanitizedParameters.new(BinData::Struct, @params)
+ all_params = BinData::Struct.all_possible_field_names(params)
+ all_params.should == ["a", "b", "y", "z"]
+ end
+
it "should access nested fields" do
- @obj.a.should eql(6)
- @obj.b.w.should eql(3)
- @obj.b.x.should eql(6)
- @obj.y.should eql(3)
+ @obj.a.should == 6
+ @obj.b.w.should == 3
+ @obj.b.x.should == 6
+ @obj.y.should == 3
end
it "should return correct offset of" do
- @obj.offset_of("b").should eql(1)
- @obj.offset_of("y").should eql(3)
- @obj.offset_of("z").should eql(4)
+ @obj.offset_of("b").should == 1
+ @obj.offset_of("y").should == 3
+ @obj.offset_of("z").should == 4
end
end
-describe "A Struct with an endian defined" do
- before(:all) do
- eval <<-END
- class StructWithEndian < BinData::Struct
- endian :little
+describe BinData::Struct, "with an endian defined" do
+ before(:each) do
+ @obj = BinData::Struct.new(:endian => :little,
+ :fields => [
+ [:uint16, :a],
+ [:float, :b],
+ [:array, :c,
+ {:type => :int8, :initial_length => 2}],
+ [:choice, :d,
+ {:choices => [[:uint16], [:uint32]],
+ :selection => 1}],
+ [:struct, :e,
+ {:fields => [[:uint16, :f],
+ [:uint32be, :g]]}],
+ [:struct, :h,
+ {:fields => [
+ [:struct, :i,
+ {:fields => [[:uint16, :j]]}]]}]])
- uint16 :a
- float :b
- array :c, :type => :int8, :initial_length => 2
- choice :d, :choices => [ [:uint16], [:uint32] ], :selection => 1
- struct :e, :fields => [ [:uint16, :f], [:uint32be, :g] ]
- struct :h, :fields => [ [:struct, :i, {:fields => [[:uint16, :j]]}] ]
- end
- END
- @obj = StructWithEndian.new
end
it "should use correct endian" do
@obj.a = 1
@obj.b = 2.0