# frozen_string_literal: true require "gir_ffi_test_helper" GirFFI.setup :GIMarshallingTests describe GirFFI::BoxedBase do describe "initialize" do it "sets up the held struct pointer" do # NOTE: GObject::Value uses the generic constructor, unlike # GIMarshallingTests::BoxedStruct, which has its own constructor. value = GObject::Value.new _(value.to_ptr).wont_be_nil end end describe "copy_from" do it "returns a copy with owned false" do original = GIMarshallingTests::BoxedStruct.new copy = GIMarshallingTests::BoxedStruct.copy_from(original) ptr = copy.to_ptr _(ptr).wont_be :==, original.to_ptr _(ptr).wont_be :autorelease? if ptr.respond_to? :autorelease? _(copy.struct).wont_be :owned? end end describe "wrap_own" do it "wraps and owns the supplied pointer" do original = GIMarshallingTests::BoxedStruct.new copy = GIMarshallingTests::BoxedStruct.wrap_own(original.to_ptr) ptr = copy.to_ptr _(ptr).must_equal original.to_ptr _(ptr).wont_be :autorelease? if ptr.respond_to? :autorelease? _(copy.struct).must_be :owned? end end describe "upon garbage collection" do it "frees and disowns the underlying struct if it is owned" do skip "cannot be reliably tested on JRuby and Rubinius" if jruby? || rubinius? allow(GObject).to receive(:boxed_free) gtype = GIMarshallingTests::BoxedStruct.gtype owned_struct = GIMarshallingTests::BoxedStruct.new.struct owned_ptr = owned_struct.to_ptr unowned_struct = GIMarshallingTests::BoxedStruct.new.struct unowned_struct.owned = false unowned_ptr = unowned_struct.to_ptr GC.start # Creating a new object is sometimes needed to trigger enough garbage collection. GIMarshallingTests::BoxedStruct.new sleep 1 GC.start GC.start expect(GObject).to have_received(:boxed_free).with(gtype, owned_ptr) expect(GObject).not_to have_received(:boxed_free).with(gtype, unowned_ptr) _(owned_struct).wont_be :owned? end end end