require 'gir_ffi_test_helper' # FIXME: Test WithLayout directly, rather than through Struct. describe GirFFI::Builder::Type::Struct do describe "for a struct with a simple layout" do before do @field = Object.new @struct = Object.new stub(@struct).safe_name { 'Bar' } stub(@struct).namespace { 'Foo' } stub(@struct).fields { [ @field ] } @builder = GirFFI::Builder::Type::Struct.new @struct end it "creates the correct layout specification" do mock(@field).layout_specification { [:bar, :int32, 0] } spec = @builder.send :layout_specification assert_equal [:bar, :int32, 0], spec end it "creates getter and setter methods" do # FIXME: Loads of stubs. stub(type = Object.new).pointer? { false } stub(type).tag { :gint32 } stub(type).flattened_tag { :gint32 } stub(@field).field_type { type } stub(@field).name { "bar" } stub(@field).writable? { true } stub(@struct).find_method { } m = Module.new { module Lib; end } stub(GirFFI::Builder).build_module('Foo') { m } c = Class.new c::Struct = Class.new refute c.method_defined?(:bar) refute c.method_defined?(:bar=) @builder.instance_eval { @klass = c @structklass = c::Struct } @builder.send :setup_field_accessors assert c.method_defined?(:bar) assert c.method_defined?(:bar=) end end describe "for a struct with a layout with a complex type" do it "does not flatten the complex type specification" do mock(simplefield = Object.new).layout_specification { [:bar, :foo, 0] } mock(complexfield = Object.new).layout_specification { [:baz, [:qux, 2], 0] } mock(struct = Object.new).fields { [ simplefield, complexfield ] } stub(struct).safe_name { 'Bar' } stub(struct).namespace { 'Foo' } builder = GirFFI::Builder::Type::Struct.new struct spec = builder.send :layout_specification assert_equal [:bar, :foo, 0, :baz, [:qux, 2], 0], spec end end describe "for a struct without defined fields" do it "uses a single field of the parent struct type as the default layout" do @gir = GObjectIntrospection::IRepository.default @gir.require 'GObject', nil stub(info = Object.new).parent { @gir.find_by_name 'GObject', 'Object' } stub(info).fields { [] } stub(info).info_type { :object } stub(info).safe_name { 'Bar' } stub(info).namespace { 'Foo' } @classbuilder = GirFFI::Builder::Type::Object.new info spec = @classbuilder.send :layout_specification assert_equal [:parent, GObject::Object::Struct, 0], spec end end end