spec/array_spec.rb in bindata-0.9.3 vs spec/array_spec.rb in bindata-0.10.0

- old
+ new

@@ -1,12 +1,11 @@ #!/usr/bin/env ruby require File.expand_path(File.dirname(__FILE__)) + '/spec_common' +require File.expand_path(File.dirname(__FILE__)) + '/example' require 'bindata/array' -require 'bindata/bits' require 'bindata/int' -require 'bindata/struct' describe BinData::Array, "when instantiating" do it "should ensure mandatory parameters are supplied" do args = {} lambda { BinData::Array.new(args) }.should raise_error(ArgumentError) @@ -25,15 +24,15 @@ end end describe BinData::Array, "with no elements" do before(:each) do - @data = BinData::Array.new(:type => :int8) + @data = BinData::Array.new(:type => :example_single) end - it "should not be a single_value" do - @data.should_not be_single_value + it "should be clear" do + @data.should be_clear end it "should return zero length" do @data.length.should be_zero end @@ -55,34 +54,55 @@ end it "should return [] for the last n elements" do @data.last(3).should == [] end - - it "should append an element" do - @data.append(99) - @data.length.should == 1 - @data.last.should == 99 - end end describe BinData::Array, "with several elements" do before(:each) do - type = [:int16le, {:initial_value => lambda { index + 1 }}] + type = [:example_single, {:initial_value => lambda { index + 1 }}] @data = BinData::Array.new(:type => type, :initial_length => 5) end - it "should not be a single_value" do - @data.should_not be_single_value + it "should have correct debug name" do + @data[2].debug_name.should == "obj[2]" end + it "should have correct offset" do + @data[2].offset.should == ExampleSingle.new.num_bytes * 2 + end + it "should return a correct snapshot" do @data.snapshot.should == [1, 2, 3, 4, 5] end + it "should assign primitive values" do + @data.assign([4, 5, 6]) + @data.snapshot.should == [4, 5, 6] + end + + it "should assign bindata objects" do + o1 = ExampleSingle.new + o1.value = 4 + o2 = ExampleSingle.new + o2.value = 5 + o3 = ExampleSingle.new + o3.value = 6 + @data.assign([o1, o2, o3]) + @data.snapshot.should == [4, 5, 6] + end + + it "should assign bindata array" do + array = BinData::Array.new(:type => :example_single) + array.push(4, 5, 6) + @data.assign(array) + @data.snapshot.should == [4, 5, 6] + end + it "should coerce to ::Array if required" do - ((1..7).to_a - @data).should == [6, 7] + [0].concat(@data).should == [0, 1, 2, 3, 4, 5] end it "should return the first element" do @data.first.should == 1 end @@ -109,15 +129,15 @@ @data.length.should == 5 @data.size.should == 5 end it "should have correct num_bytes" do - @data.num_bytes.should == 10 + @data.num_bytes.should == 5 * ExampleSingle.new.num_bytes end it "should have correct num_bytes for individual elements" do - @data.num_bytes(0).should == 2 + @data.num_bytes(0).should == ExampleSingle.new.num_bytes end it "should be able to directly access elements" do @data[1] = 8 @data[1].should == 8 @@ -133,16 +153,10 @@ it "should be able to use methods from Enumerable" do @data.select { |x| (x % 2) == 0 }.should == [2, 4] end - it "should automatically extend" do - @data[9] = 3 - @data[8].should == 9 - @data.length.should == 10 - end - it "should clear" do @data[1] = 8 @data.clear @data.collect.should == [1, 2, 3, 4, 5] end @@ -151,172 +165,175 @@ @data[1] = 8 @data.clear(1) @data[1].should == 2 end - it "should clear a single element out of range without extending" do - @data.clear(9) - @data.length.should == 5 - end - it "should be clear upon creation" do - @data.clear?.should be_true + @data.should be_clear end it "should be clear if all elements are clear" do @data[1] = 8 @data.clear(1) - @data.clear?.should be_true + @data.should be_clear end it "should test clear status of individual elements" do @data[1] = 8 @data.clear?(0).should be_true @data.clear?(1).should be_false end - it "should test clear status of out of range elements without extending" do - @data.clear?(9).should be_true - @data.length.should == 5 - end - - it "should read and write correctly" do - io = StringIO.new + it "should symmetrically read and write" do @data[1] = 8 - @data.write(io) + str = @data.to_binary_s @data.clear - io.rewind @data[1].should == 2 - @data.read(io) + @data.read(str) @data[1].should == 8 end - it "should append an element" do - @data.append(99) - @data.length.should == 6 - @data.last.should == 99 + it "should identify index of elements" do + @data.index(3).should == 2 end + + it "should return nil for index of non existent element" do + @data.index(42).should be_nil + end end -describe BinData::Array, "containing structs" do +describe BinData::Array, "when accessing elements" do before(:each) do - type = [:struct, {:fields => [[:int8, :a, - {:initial_value => lambda { parent.index }}], - [:int8, :b]]}] + type = [:example_single, {:initial_value => lambda { index + 1 }}] @data = BinData::Array.new(:type => type, :initial_length => 5) + @data[0] = 1 + @data[1] = 2 + @data[2] = 3 + @data[3] = 4 + @data[4] = 5 end - it "should access elements, not values" do - @data[3].a.should == 3 + it "should insert with positive indexes" do + @data.insert(2, 30, 40) + @data.snapshot.should == [1, 2, 30, 40, 3, 4, 5] end - it "should access multiple elements with slice" do - @data.slice(2, 3).collect { |x| x.a }.should == [2, 3, 4] + it "should insert with negative indexes" do + @data.insert(-2, 30, 40) + @data.snapshot.should == [1, 2, 3, 4, 30, 40, 5] end - it "should not be able to modify elements" do - lambda { @data[1] = 3 }.should raise_error(NoMethodError) + it "should push" do + @data.push(30, 40) + @data.snapshot.should == [1, 2, 3, 4, 5, 30, 40] end - it "should interate over each element" do - @data.collect { |s| s.a }.should == [0, 1, 2, 3, 4] + it "should concat" do + @data.concat([30, 40]) + @data.snapshot.should == [1, 2, 3, 4, 5, 30, 40] end - it "should be able to append elements" do - obj = @data.append - obj.a = 3 - obj.b = 5 + it "should unshift" do + @data.unshift(30, 40) + @data.snapshot.should == [30, 40, 1, 2, 3, 4, 5] + end - @data.last.a.should == 3 - @data.last.b.should == 5 + it "should automatically extend on [index]" do + @data[9].should == 10 + @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] end + + it "should automatically extend on []=" do + @data[9] = 30 + @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 30] + end + + it "should automatically extend on insert" do + @data.insert(7, 30, 40) + @data.snapshot.should == [1, 2, 3, 4, 5, 6, 7, 30, 40] + end + + it "should not extend on at" do + @data.at(9).should be_nil + @data.length.should == 5 + end + + it "should not extend on [start, length]" do + @data[9, 2].should be_nil + @data.length.should == 5 + end + + it "should not extend on [range]" do + @data[9 .. 10].should be_nil + @data.length.should == 5 + end + + it "should not extend on clear" do + @data.clear(9) + @data.length.should == 5 + end + + it "should not extend on clear?" do + @data.clear?(9).should be_true + @data.length.should == 5 + end + + it "should not extend on num_bytes" do + @data.num_bytes(9).should == 0 + @data.length.should == 5 + end + + it "should raise error on bad input to []" do + lambda { @data["a"] }.should raise_error(TypeError) + lambda { @data[1, "a"] }.should raise_error(TypeError) + end end describe BinData::Array, "with :read_until containing +element+" do before(:each) do read_until = lambda { element == 5 } @data = BinData::Array.new(:type => :int8, :read_until => read_until) end - it "should append to an empty array" do - @data.append(3) - @data.first.should == 3 - end - it "should read until the sentinel is reached" do - io = StringIO.new("\x01\x02\x03\x04\x05\x06\x07") - @data.read(io) + str = "\x01\x02\x03\x04\x05\x06\x07" + @data.read(str) @data.length.should == 5 end end describe BinData::Array, "with :read_until containing +array+ and +index+" do before(:each) do - read_until = lambda { index >=2 and array[index - 2] == 5 } + read_until = lambda { index >= 2 and array[index - 2] == 5 } @data = BinData::Array.new(:type => :int8, :read_until => read_until) end it "should read until the sentinel is reached" do - io = StringIO.new("\x01\x02\x03\x04\x05\x06\x07\x08") - @data.read(io) + str = "\x01\x02\x03\x04\x05\x06\x07\x08" + @data.read(str) @data.length.should == 7 end end describe BinData::Array, "with :read_until => :eof" do it "should read records until eof" do obj = BinData::Array.new(:type => :int8, :read_until => :eof) - data = "\x01\x02\x03" - obj.read(data) + str = "\x01\x02\x03" + obj.read(str) obj.snapshot.should == [1, 2, 3] end it "should read records until eof, ignoring partial records" do obj = BinData::Array.new(:type => :int16be, :read_until => :eof) - data = "\x00\x01\x00\x02\x03" - obj.read(data) + str = "\x00\x01\x00\x02\x03" + obj.read(str) obj.snapshot.should == [1, 2] end end -describe BinData::Array, "of bits" do - before(:each) do - @data = BinData::Array.new(:type => :bit1, :initial_length => 15) - end - - it "should read" do - str = [0b0001_0100, 0b1000_1000].pack("CC") - @data.read(str) - @data[0].should == 0 - @data[1].should == 0 - @data[2].should == 0 - @data[3].should == 1 - @data[4].should == 0 - @data[5].should == 1 - @data[6].should == 0 - @data[7].should == 0 - @data[8].should == 1 - @data[9].should == 0 - @data[10].should == 0 - @data[11].should == 0 - @data[12].should == 1 - @data[13].should == 0 - @data[14].should == 0 - end - - it "should write" do - @data[3] = 1 - @data.to_s.should == [0b0001_0000, 0b0000_0000].pack("CC") - end - - it "should return num_bytes" do - @data.num_bytes.should == 2 - end -end - describe BinData::Array, "nested within an Array" do before(:each) do nested_array_params = { :type => [:int8, { :initial_value => :index }], :initial_length => lambda { index + 1 } } @data = BinData::Array.new(:type => [:array, nested_array_params], @@ -331,6 +348,5 @@ str = "\x04\x05\x06\x07\x08\x09" @data.read(str) @data.snapshot.should == [ [4], [5, 6], [7, 8, 9] ] end end -