diff --git a/spec/packets/binary_accessor_spec.rb b/spec/packets/binary_accessor_spec.rb index 2bfc82bc0..bc4387967 100644 --- a/spec/packets/binary_accessor_spec.rb +++ b/spec/packets/binary_accessor_spec.rb @@ -16,7 +16,7 @@ module Cosmos describe BinaryAccessor do - describe "read" do + describe "read only" do before(:each) do @data = "\x80\x81\x82\x83\x84\x85\x86\x87\x00\x09\x0A\x0B\x0C\x0D\x0E\x0F" @@ -677,7 +677,7 @@ module Cosmos end # given big endian data end # describe "read_array" - describe "write" do + describe "write only" do before(:each) do @data = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -804,6 +804,36 @@ module Cosmos expect { BinaryAccessor.write(@baseline_data, 8, 800, :STRING, @data, :BIG_ENDIAN, :ERROR) }.to raise_error(ArgumentError, "16 byte buffer insufficient to write STRING at bit_offset 8 with bit_size 800") end + it "truncates the buffer for 0 bitsize" do + expect(@data.length).to eql 16 + BinaryAccessor.write("\x01\x02\x03", 8, 0, :BLOCK, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x00\x01\x02\x03") + expect(@data.length).to eql 4 + end + + it "expands the buffer for 0 bitsize" do + expect(@data.length).to eql 16 + BinaryAccessor.write("\x01\x02\x03", (14 * 8), 0, :BLOCK, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03") + expect(@data.length).to eql 17 + end + + it "writes a frozen string" do + buffer = "BLANKxxxWORLD" + string = "HELLO".freeze + # Specify 3 more bytes than given to exercise the padding logic + string = BinaryAccessor.write(string, 0, (string.length + 3)*8, :STRING, buffer, :BIG_ENDIAN, :ERROR) + expect(buffer).to eql("HELLO\x00\x00\x00WORLD") + expect(string).to eql("HELLO") + expect(string.frozen?).to be true + end + + it "complains about writing a frozen buffer" do + buffer = "BLANK WORLD".freeze + string = "HELLO" + expect {BinaryAccessor.write(string, 0, string.length*8, :STRING, buffer, :BIG_ENDIAN, :ERROR) }.to raise_error(RuntimeError, "can't modify frozen String") + end + it "writes aligned 8-bit unsigned integers" do 0.step((@data.length - 1) * 8, 8) do |bit_offset| @data = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" @@ -824,6 +854,27 @@ module Cosmos end end + it "converts floats when writing integers" do + @data = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + BinaryAccessor.write(1.0, 0, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) + BinaryAccessor.write(2.5, 8, 8, :INT, @data, :BIG_ENDIAN, :ERROR) + BinaryAccessor.write(4.99, 16, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x01\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + end + + it "converts integer strings when writing integers" do + @data = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + BinaryAccessor.write("1", 0, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) + BinaryAccessor.write("2", 8, 8, :INT, @data, :BIG_ENDIAN, :ERROR) + BinaryAccessor.write("4", 16, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x01\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + end + + it "complains about non-integer strings when writing integers" do + expect { BinaryAccessor.write("1.0", 0, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) }.to raise_error(ArgumentError) + expect { BinaryAccessor.write("abc123", 0, 8, :UINT, @data, :BIG_ENDIAN, :ERROR) }.to raise_error(ArgumentError) + end + describe "given big endian data" do it "writes 1-bit unsigned integers" do @@ -834,10 +885,12 @@ module Cosmos end it "writes 1-bit signed integers" do + @data[1] = "\x55" BinaryAccessor.write(0x1, 8, 1, :INT, @data, :BIG_ENDIAN, :ERROR) BinaryAccessor.write(0x0, 9, 1, :INT, @data, :BIG_ENDIAN, :ERROR) BinaryAccessor.write(0x1, 10, 1, :INT, @data, :BIG_ENDIAN, :ERROR) - expect(@data).to eql("\x00\xA0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + BinaryAccessor.write(0x0, 11, 1, :INT, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x00\xA5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") end it "writes 7-bit unsigned integers" do @@ -916,6 +969,11 @@ module Cosmos expect(@data).to eql(@baseline_data) end + it "writes aligned 32-bit negative integers" do + BinaryAccessor.write(-2147483648, 0, 32, :INT, @data, :BIG_ENDIAN, :ERROR_ALLOW_HEX) + expect(@data).to eql("\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + end + it "writes aligned 32-bit floats" do expected_array = [-1.189360e-038, -3.139169e-036, 8.301067e-040, 1.086646e-031] BinaryAccessor.write(expected_array[0], 0, 32, :FLOAT, @data, :BIG_ENDIAN, :ERROR) @@ -941,9 +999,12 @@ module Cosmos end it "writes 63-bit unsigned integers" do + @data[-1] = "\xFF" BinaryAccessor.write(0x8081828384858687 >> 1, 0, 63, :UINT, @data, :BIG_ENDIAN, :ERROR) - BinaryAccessor.write(0x00090A0B0C0D0E0F, 65, 63, :UINT, @data, :BIG_ENDIAN, :ERROR) - expect(@data).to eql("\x80\x81\x82\x83\x84\x85\x86\x86\x00\x09\x0A\x0B\x0C\x0D\x0E\x0F") + expect(@data).to eql("\x80\x81\x82\x83\x84\x85\x86\x86\x00\x00\x00\x00\x00\x00\x00\xFF") + @data[0] = "\xFF" + BinaryAccessor.write(0x08090A0B0C0D0E0F, 65, 63, :UINT, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\xFF\x81\x82\x83\x84\x85\x86\x86\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F") end it "writes 63-bit signed integers" do @@ -982,6 +1043,32 @@ module Cosmos expect(BinaryAccessor.read(64, 64, :FLOAT, @data, :BIG_ENDIAN)).to be_within(1.0e-308).of(expected_array[1]) end + it "converts integers to floats" do + BinaryAccessor.write(1, 0, 32, :FLOAT, @data, :BIG_ENDIAN, :ERROR) + value = BinaryAccessor.read(0, 32, :FLOAT, @data, :BIG_ENDIAN) + expect(value).to eql(1.0) + expect(value).to be_a(Float) + BinaryAccessor.write(4, 32, 64, :FLOAT, @data, :BIG_ENDIAN, :ERROR) + value = BinaryAccessor.read(32, 64, :FLOAT, @data, :BIG_ENDIAN) + expect(value).to eql(4.0) + expect(value).to be_a(Float) + end + + it "converts strings when writing floats" do + BinaryAccessor.write("1", 0, 32, :FLOAT, @data, :BIG_ENDIAN, :ERROR) + value = BinaryAccessor.read(0, 32, :FLOAT, @data, :BIG_ENDIAN) + expect(value).to eql(1.0) + expect(value).to be_a(Float) + BinaryAccessor.write("4.5", 32, 64, :FLOAT, @data, :BIG_ENDIAN, :ERROR) + value = BinaryAccessor.read(32, 64, :FLOAT, @data, :BIG_ENDIAN) + expect(value).to eql(4.5) + expect(value).to be_a(Float) + end + + it "complains about non-float strings when writing floats" do + expect { BinaryAccessor.write("abc123", 0, 32, :FLOAT, @data, :BIG_ENDIAN, :ERROR) }.to raise_error(ArgumentError) + end + it "complains about unaligned floats" do expect { BinaryAccessor.write(0.0, 17, 32, :FLOAT, @data, :BIG_ENDIAN, :ERROR) }.to raise_error(ArgumentError, "bit_offset 17 is not byte aligned for data_type FLOAT") end @@ -999,10 +1086,12 @@ module Cosmos end it "writes 1-bit unsigned integers" do + @data[1] = "\x55" BinaryAccessor.write(0x1, 8, 1, :UINT, @data, :LITTLE_ENDIAN, :ERROR) BinaryAccessor.write(0x0, 9, 1, :UINT, @data, :LITTLE_ENDIAN, :ERROR) BinaryAccessor.write(0x1, 10, 1, :UINT, @data, :LITTLE_ENDIAN, :ERROR) - expect(@data).to eql("\x00\xA0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") + BinaryAccessor.write(0x0, 11, 1, :INT, @data, :BIG_ENDIAN, :ERROR) + expect(@data).to eql("\x00\xA5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") end it "writes 1-bit signed integers" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 89ac32b7a..f8b1ebeb7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -36,6 +36,7 @@ end require 'rspec' require 'ruby-prof' +require 'benchmark/ips' require 'cosmos' require 'cosmos/utilities/logger' @@ -55,11 +56,6 @@ def exit(*args) end RSpec.configure do |config| - config.expect_with :rspec do |c| - # Explicitly enable the should and expect syntax - c.syntax = [:should, :expect] - end - # Store standard output global and CONSTANT since we will mess with them config.before(:all) do $saved_stdout_global = $stdout @@ -162,6 +158,15 @@ def capture_io end end end + if ENV.key?("BENCHMARK") + c.around(:each) do |example| + Benchmark.ips do |x| + x.report(example.metadata[:full_description]) do + example.run + end + end + end + end # This code causes a new profile file to be created for each test case which is excessive and hard to read # c.around(:each) do |example| # if ENV.key?("PROFILE")