1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#
# This file is part of ruby-ffi.
#
# This code is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License version 3 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# version 3 for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
#
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
LibTest::TestUnion.members.all? { |m| LibTest::TestUnion.offset_of(m) == 0 }.should 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'
(@u[type[1]] - LibTest.send("union_align_#{k}", @u.to_ptr)).abs.should < 0.00001
else
@u[type[1]].should 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'
(@u[type[1]] - type[2]).abs.should < 0.00001
else
@u[type[1]].should eq type[2]
end
end
end
it 'should return a size equals to the size of the biggest field' do
LibTest::TestUnion.size.should eq LibTest.union_size
end
end
|