blob: 45bf7ec8e95650ceddd02b6a90af149cf770bc57 [file] [log] [blame]
#
# This file is part of ruby-ffi.
# For licensing, see LICENSE.SPECS
#
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
module LibTest
Types = {
's8' => [:char, :c, 1],
's16' => [:short, :s, 0xff0],
's32' => [:int, :i, 0xff00],
's64' => [:long_long, :j, 0xffff00],
'long' => [:long, :l, 0xffff],
'f32' => [:float, :f, 1.0001],
'f64' => [:double, :d, 1.000000001]
}
class TestUnion < FFI::Union
layout( :a, [:char, 10],
:i, :int,
:f, :float,
:d, :double,
:s, :short,
:l, :long,
:j, :long_long,
:c, :char )
end
Types.keys.each do |k|
attach_function "union_align_#{k}", [ :pointer ], Types[k][0]
attach_function "union_make_union_with_#{k}", [ Types[k][0] ], :pointer
end
attach_function :union_size, [], :uint
end
describe 'Union' do
before do
@u = LibTest::TestUnion.new
end
it 'should place all the fields at offset 0' do
expect(LibTest::TestUnion.members.all? { |m| LibTest::TestUnion.offset_of(m) == 0 }).to be true
end
LibTest::Types.each do |k, type|
it "should correctly align/write a #{type[0]} value" do
@u[type[1]] = type[2]
if k == 'f32' or k == 'f64'
expect((@u[type[1]] - LibTest.send("union_align_#{k}", @u.to_ptr)).abs).to be < 0.00001
else
expect(@u[type[1]]).to eq(LibTest.send("union_align_#{k}", @u.to_ptr))
end
end
end
LibTest::Types.each do |k, type|
it "should read a #{type[0]} value from memory" do
@u = LibTest::TestUnion.new(LibTest.send("union_make_union_with_#{k}", type[2]))
if k == 'f32' or k == 'f64'
expect((@u[type[1]] - type[2]).abs).to be < 0.00001
else
expect(@u[type[1]]).to eq(type[2])
end
end
end
it 'should return a size equals to the size of the biggest field' do
expect(LibTest::TestUnion.size).to eq(LibTest.union_size)
end
end