# frozen_string_literal: true require 'gir_ffi_test_helper' require 'gir_ffi/in_pointer' describe GirFFI::InPointer do describe '.from_array' do it 'returns nil when passed nil' do result = GirFFI::InPointer.from_array :gint32, nil assert_nil result end it 'handles type tag :GType' do GirFFI::InPointer.from_array :GType, [2] end it 'handles enum types' do e = Module.new do extend GirFFI::EnumBase self::Enum = FFI::Enum.new [:foo, :bar, :baz], :qux end ptr = GirFFI::InPointer.from_array e, [:bar, :foo, :baz] ptr.read_array_of_int32(3).must_equal [1, 0, 2] end it 'handles struct types' do e = Class.new(GirFFI::StructBase) do self::Struct = Class.new(GirFFI::Struct) do layout :foo, :int32, :bar, :int32 end end struct = e::Struct.allocate struct[:foo] = 42 struct[:bar] = 24 ptr = GirFFI::InPointer.from_array e, [struct] ptr.wont_equal struct.to_ptr new_struct = e::Struct.new ptr new_struct[:foo].must_equal 42 new_struct[:bar].must_equal 24 end it 'handles typed pointers' do p1 = GirFFI::InPointer.from :gint32, 42 p2 = GirFFI::InPointer.from :gint32, 24 ptr = GirFFI::InPointer.from_array [:pointer, :gint32], [p1, p2] ptr.read_array_of_pointer(2).must_equal [p1, p2] end it 'handles pointer casting' do ptr = GirFFI::InPointer.from_array [:pointer, :gint32], [42, 24] ptr.read_array_of_pointer(2).map(&:address).must_equal [42, 24] end end describe 'an instance created with .from_array :gint32' do before do @result = GirFFI::InPointer.from_array :gint32, [24, 13] end it 'holds a pointer to the correct input values' do assert_equal 24, @result.get_int(0) assert_equal 13, @result.get_int(4) end it 'is an instance of FFI::MemoryPointer' do @result.must_be_instance_of FFI::MemoryPointer end it 'is zero-terminated' do assert_equal 0, @result.get_int(8) end end describe 'an instance created with .from_array :utf8' do before do @result = GirFFI::InPointer.from_array :utf8, %w(foo bar baz) end it 'returns an array of pointers to strings' do ary = @result.read_array_of_pointer(3) assert_equal %w(foo bar baz), ary.map(&:read_string) end end describe 'an instance created with .from_array :filename' do before do @result = GirFFI::InPointer.from_array :filename, %w(foo bar baz) end it 'returns an array of pointers to strings' do ary = @result.read_array_of_pointer(3) assert_equal %w(foo bar baz), ary.map(&:read_string) end end describe 'an instance created with .from :utf8' do before do @result = GirFFI::InPointer.from :utf8, 'foo' end it 'returns a pointer to the given string' do assert_equal 'foo', @result.read_string end it 'is an instance of FFI::MemoryPointer' do @result.must_be_instance_of FFI::MemoryPointer end end describe 'an instance created with .from :guint32' do before do @result = GirFFI::InPointer.from :guint32, 12_345 end it 'returns a pointer with an address equal to the given value' do assert_equal 12_345, @result.address end it 'is an instance of FFI::Pointer' do @result.must_be_instance_of FFI::Pointer end end describe 'an instance created with .from :filename' do before do @result = GirFFI::InPointer.from :filename, 'foo' end it 'returns a pointer to the given string' do assert_equal 'foo', @result.read_string end end describe '.from' do it 'returns nil when passed nil' do result = GirFFI::InPointer.from :foo, nil assert_nil result end it "sets the pointer's address to the passed value for type :gint8" do result = GirFFI::InPointer.from :gint8, 23 assert_equal 23, result.address end it 'handles enum types' do e = Module.new do self::Enum = FFI::Enum.new [:foo, :bar, :baz], :qux def self.[](val) self::Enum[val] end end ptr = GirFFI::InPointer.from e, :bar ptr.address.must_equal 1 end describe 'for type :void' do it 'returns the result of to_ptr' do obj = Object.new def obj.to_ptr :test_value end GirFFI::InPointer.from(:void, obj).must_equal :test_value end it 'returns nil when passed nil' do GirFFI::InPointer.from(:void, nil).must_equal nil end end describe 'for types that are classes' do it 'returns the result of to_ptr' do klass = Class.new obj = klass.new def obj.to_ptr :test_value end GirFFI::InPointer.from(klass, obj).must_equal :test_value end end end end