test/io_test.rb in bindata-1.6.0 vs test/io_test.rb in bindata-1.8.0

- old
+ new

@@ -1,66 +1,46 @@ #!/usr/bin/env ruby require File.expand_path(File.join(File.dirname(__FILE__), "common")) -describe BinData::IO, "reading from non seekable stream" do +describe BinData::IO::Read, "reading from non seekable stream" do before do @rd, @wr = IO::pipe - if fork - # parent - @wr.close - @io = BinData::IO.new(@rd) - else - # child - begin - @rd.close - @wr.write "a" * 5000 - @wr.write "b" * 5000 - @wr.close - rescue Exception - # ignore it - ensure - exit! - end - end + @io = BinData::IO::Read.new(@rd) + @wr.write "a" * 2000 + @wr.write "b" * 2000 + @wr.close end after do @rd.close - Process.wait end - it "always has an offset of 0" do + it "has correct offset" do @io.readbytes(10) - @io.offset.must_equal 0 + @io.offset.must_equal 10 end it "seeks correctly" do - @io.seekbytes(4999) + @io.seekbytes(1999) @io.readbytes(5).must_equal "abbbb" end - it "returns zero for num bytes remaining" do - @io.num_bytes_remaining.must_equal 0 + it "#num_bytes_remaining raises IOError" do + lambda { + @io.num_bytes_remaining + }.must_raise IOError end end -describe BinData::IO, "when reading" do +describe BinData::IO::Read, "when reading" do let(:stream) { StringIO.new "abcdefghij" } - let(:io) { BinData::IO.new(stream) } + let(:io) { BinData::IO::Read.new(stream) } - it "wraps strings in StringIO" do - io.raw_io.class.must_equal StringIO - end - - it "does not wrap IO objects" do - io.raw_io.must_equal stream - end - - it "raises error when io is BinData::IO" do + it "raises error when io is BinData::IO::Read" do lambda { - BinData::IO.new(BinData::IO.new("")) + BinData::IO::Read.new(BinData::IO::Read.new("")) }.must_raise ArgumentError end it "returns correct offset" do stream.seek(3, IO::SEEK_CUR) @@ -98,21 +78,73 @@ io.readbytes(20) }.must_raise IOError end end -describe BinData::IO, "when writing" do - let(:stream) { StringIO.new } - let(:io) { BinData::IO.new(stream) } +describe BinData::IO::Read, "#with_buffer" do + let(:stream) { StringIO.new "abcdefghijklmnopqrst" } + let(:io) { BinData::IO::Read.new(stream) } - it "does not wrap IO objects" do - io.raw_io.must_equal stream + it "consumes entire buffer on short reads" do + io.with_buffer(10) do + io.readbytes(4).must_equal "abcd" + end + io.offset.must_equal(10) end + it "consumes entire buffer on read_all_bytes" do + io.with_buffer(10) do + io.read_all_bytes.must_equal "abcdefghij" + end + io.offset.must_equal(10) + end + + it "restricts large reads" do + io.with_buffer(10) do + lambda { + io.readbytes(15) + }.must_raise IOError + end + end + + it "is nestable" do + io.with_buffer(10) do + io.readbytes(2).must_equal "ab" + io.with_buffer(5) do + io.read_all_bytes.must_equal "cdefg" + end + io.offset.must_equal(2 + 5) + end + io.offset.must_equal(10) + end + + it "restricts large nested buffers" do + io.with_buffer(10) do + io.readbytes(2).must_equal "ab" + io.with_buffer(20) do + io.read_all_bytes.must_equal "cdefghij" + io.offset.must_equal(10) + end + end + io.offset.must_equal(10) + end + + it "restricts large seeks" do + io.with_buffer(10) do + io.seekbytes(15) + end + io.offset.must_equal(10) + end +end + +describe BinData::IO::Write, "when writing" do + let(:stream) { StringIO.new } + let(:io) { BinData::IO::Write.new(stream) } + it "raises error when io is BinData::IO" do lambda { - BinData::IO.new(BinData::IO.new("")) + BinData::IO::Write.new(BinData::IO::Write.new("")) }.must_raise ArgumentError end it "writes correctly" do io.writebytes("abcd") @@ -126,15 +158,47 @@ stream.value.must_equal "abcd" end end -describe BinData::IO, "reading bits in big endian" do +describe BinData::IO::Write, "#with_buffer" do + let(:stream) { StringIO.new } + let(:io) { BinData::IO::Write.new(stream) } + + it "pads entire buffer on short reads" do + io.with_buffer(10) do + io.writebytes "abcde" + end + + stream.value.must_equal "abcde\0\0\0\0\0" + end + + it "discards excess on large writes" do + io.with_buffer(5) do + io.writebytes "abcdefghij" + end + + stream.value.must_equal "abcde" + end + + it "is nestable" do + io.with_buffer(10) do + io.with_buffer(5) do + io.writebytes "abc" + end + io.writebytes "de" + end + + stream.value.must_equal "abc\0\0de\0\0\0" + end +end + +describe BinData::IO::Read, "reading bits in big endian" do let(:b1) { 0b1111_1010 } let(:b2) { 0b1100_1110 } let(:b3) { 0b0110_1010 } - let(:io) { BinData::IO.new([b1, b2, b3].pack("CCC")) } + let(:io) { BinData::IO::Read.new([b1, b2, b3].pack("CCC")) } it "reads a bitfield less than 1 byte" do io.readbits(3, :big).must_equal 0b111 end @@ -172,15 +236,15 @@ io.reset_read_bits io.readbits(3, :big).must_equal 0b110 end end -describe BinData::IO, "reading bits in little endian" do +describe BinData::IO::Read, "reading bits in little endian" do let(:b1) { 0b1111_1010 } let(:b2) { 0b1100_1110 } let(:b3) { 0b0110_1010 } - let(:io) { BinData::IO.new([b1, b2, b3].pack("CCC")) } + let(:io) { BinData::IO::Read.new([b1, b2, b3].pack("CCC")) } it "reads a bitfield less than 1 byte" do io.readbits(3, :little).must_equal 0b010 end @@ -221,11 +285,11 @@ end class BitWriterHelper def initialize @stringio = BinData::IO.create_string_io - @io = BinData::IO.new(@stringio) + @io = BinData::IO::Write.new(@stringio) end def writebits(val, nbits, endian) @io.writebits(val, nbits, endian) end @@ -239,11 +303,11 @@ @stringio.rewind @stringio.read end end -describe BinData::IO, "writing bits in big endian" do +describe BinData::IO::Write, "writing bits in big endian" do let(:io) { BitWriterHelper.new } it "writes a bitfield less than 1 byte" do io.writebits(0b010, 3, :big) io.value.must_equal [0b0100_0000].pack("C") @@ -284,11 +348,11 @@ io.value.must_equal [0b1010_0000, 0b1011_1111, 0b0100_0000].pack("CCC") end end -describe BinData::IO, "writing bits in little endian" do +describe BinData::IO::Write, "writing bits in little endian" do let(:io) { BitWriterHelper.new } it "writes a bitfield less than 1 byte" do io.writebits(0b010, 3, :little) io.value.must_equal [0b0000_0010].pack("C") @@ -329,20 +393,22 @@ io.value.must_equal [0b0000_0101, 0b1011_1111, 0b0000_0001].pack("CCC") end end -describe BinData::IO, "with changing endian" do +describe BinData::IO::Read, "with changing endian" do it "does not mix different endianess when reading" do b1 = 0b0110_1010 b2 = 0b1110_0010 str = [b1, b2].pack("CC") - io = BinData::IO.new(str) + io = BinData::IO::Read.new(str) io.readbits(3, :big).must_equal 0b011 io.readbits(4, :little).must_equal 0b0010 end +end +describe BinData::IO::Write, "with changing endian" do it "does not mix different endianess when writing" do io = BitWriterHelper.new io.writebits(0b110, 3, :big) io.writebits(0b010, 3, :little) io.value.must_equal [0b1100_0000, 0b0000_0010].pack("CC")