# frozen_string_literal: true require "gir_ffi_test_helper" describe GirFFI::Builders::ReturnValueBuilder do let(:var_gen) { GirFFI::VariableNameGenerator.new } let(:type_info) { method_info.return_type } let(:ownership_transfer) { method_info.caller_owns } let(:return_type_info) { GirFFI::ReturnValueInfo.new(type_info, ownership_transfer, false) } let(:builder) do GirFFI::Builders::ReturnValueBuilder.new(var_gen, return_type_info) end describe "for :gint32" do let(:method_info) do get_introspection_data("GIMarshallingTests", "int_return_min") end it "has no statements in #post_conversion" do _(builder.post_conversion).must_equal [] end it "returns the result of the c function directly" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v1" end end describe "for :struct" do describe "with transfer :nothing" do let(:method_info) do get_method_introspection_data("GIMarshallingTests", "BoxedStruct", "returnv") end it "wraps and copies the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GIMarshallingTests::BoxedStruct.wrap_copy(_v1)"] end it "returns the copied result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end end describe "for :union" do let(:method_info) do get_method_introspection_data("GIMarshallingTests", "Union", "returnv") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GIMarshallingTests::Union.wrap_copy(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :interface" do let(:method_info) do get_method_introspection_data("Gio", "File", "new_for_commandline_arg") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = Gio::File.wrap(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :object" do describe "with full ownership transfer" do let(:method_info) do get_method_introspection_data("GIMarshallingTests", "Object", "full_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GIMarshallingTests::Object.wrap(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "with no ownership transfer" do let(:method_info) do get_method_introspection_data("GIMarshallingTests", "Object", "none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion) .must_equal ["_v2 = GIMarshallingTests::Object.wrap(_v1).tap { |it| it && it.ref }"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end end describe "for :strv" do let(:method_info) do get_method_introspection_data("GLib", "KeyFile", "get_locale_string_list") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::Strv.wrap(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :zero_terminated" do let(:method_info) do get_method_introspection_data("GLib", "Variant", "dup_bytestring") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GirFFI::ZeroTerminated.wrap(:guint8, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :byte_array" do let(:method_info) do get_introspection_data("GIMarshallingTests", "bytearray_full_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::ByteArray.wrap(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :ptr_array" do let(:method_info) do get_introspection_data("GIMarshallingTests", "gptrarray_utf8_none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::PtrArray.wrap(:utf8, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :glist" do let(:method_info) do get_introspection_data("GIMarshallingTests", "glist_int_none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::List.wrap(:gint32, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :gslist" do let(:method_info) do get_introspection_data("GIMarshallingTests", "gslist_int_none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::SList.wrap(:gint32, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :ghash" do let(:method_info) do get_introspection_data("GIMarshallingTests", "ghashtable_int_none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::HashTable.wrap([:gint32, :gint32], _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :array" do let(:method_info) do get_introspection_data("GIMarshallingTests", "garray_int_none_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::Array.wrap(:gint32, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :error" do let(:method_info) do get_introspection_data("GIMarshallingTests", "gerror_return") end it "wraps the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GLib::Error.wrap(_v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for :c" do describe "with fixed size" do let(:method_info) do get_introspection_data("GIMarshallingTests", "array_fixed_int_return") end it "converts the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GirFFI::SizedArray.wrap(:gint32, 4, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "with separate size parameter" do let(:length_argument) { Object.new } let(:method_info) do get_method_introspection_data("GIMarshallingTests", "Object", "method_array_return") end before do allow(length_argument).to receive(:post_converted_name).and_return "bar" builder.length_arg = length_argument end it "converts the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GirFFI::SizedArray.wrap(:gint32, bar, _v1)"] end it "returns the wrapped result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end end describe "for :utf8" do describe "with no transfer" do let(:method_info) do get_introspection_data("GIMarshallingTests", "utf8_none_return") end it "converts the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = _v1.to_utf8"] end it "returns the converted result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "with full transfer" do let(:method_info) do get_introspection_data("GIMarshallingTests", "utf8_full_return") end it "autoreleases and converts the result in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion) .must_equal ["_v2 = GirFFI::AllocationHelper.free_after _v1, &:to_utf8"] end it "returns the converted result" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end end describe "for :void pointer" do let(:ownership_transfer) { :nothing } let(:callback_info) do get_introspection_data("GIMarshallingTests", "CallbackIntInt") end let(:type_info) { callback_info.args[1].argument_type } it "has no statements in #post_conversion" do _(builder.post_conversion).must_equal [] end it "returns the result of the c function directly" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v1" end end describe "for :void" do let(:method_info) do get_method_introspection_data("Regress", "TestObj", "null_out") end it "has no statements in #post_conversion" do _(builder.post_conversion).must_equal [] end it "marks itself as irrelevant" do _(builder.relevant?).must_equal false end it "returns nothing" do _(builder.return_value_name).must_be_nil end end describe "for a closure argument" do let(:ownership_transfer) { :nothing } let(:callback_info) do get_introspection_data("Regress", "TestCallbackUserData") end let(:type_info) { callback_info.args[0].argument_type } before do builder.mark_as_user_data :dummy end it "fetches the stored object in #post_conversion" do _(builder.capture_variable_name).must_equal "_v1" _(builder.post_conversion).must_equal ["_v2 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_v1)"] end it "returns the stored object" do _(builder.capture_variable_name).must_equal "_v1" _(builder.return_value_name).must_equal "_v2" end end describe "for a skipped return value" do let(:method_info) do get_method_introspection_data("Regress", "TestObj", "skip_return_val") end let(:return_type_info) { GirFFI::ReturnValueInfo.new(type_info, :nothing, true) } it "has no statements in #post_conversion" do _(builder.post_conversion).must_equal [] end it "marks itself as irrelevant" do _(builder.relevant?).must_equal false end it "returns nothing" do _(builder.return_value_name).must_be_nil end end end