require 'gir_ffi_test_helper'

describe GirFFI::Builder::Type::Unintrospectable do
  describe "building the GLocalFile type" do
    before do
      # Ensure existence of GLocalFile type
      GirFFI.setup :Gio
      unless Gio::Lib.respond_to? :g_file_new_for_path
        Gio.setup_method "file_new_for_path"
      end
      ptr = GirFFI::InPointer.from :utf8, '/'
      Gio::Lib.g_file_new_for_path(ptr)

      @gtype = GObject.type_from_name 'GLocalFile'
      @bldr = GirFFI::Builder::Type::Unintrospectable.new(@gtype)
      @klass = @bldr.build_class
    end

    it "builds a class" do
      assert_instance_of Class, @klass
    end

    it "builds a class derived from GObject::Object" do
      assert_includes @klass.ancestors, GObject::Object
    end

    it "builds a class derived from Gio::File" do
      assert_includes @klass.ancestors, Gio::File
    end

    it "returns the same class when built again" do
      other_bldr = GirFFI::Builder::Type::Unintrospectable.new(@gtype)
      other_klass = other_bldr.build_class

      assert_equal @klass, other_klass
    end

    describe "its #find_signal method" do
      it "raises correct error for a signal that doesn't exist" do
        msg = nil
        begin
          @bldr.find_signal "foo"
        rescue RuntimeError => e
          msg = e.message
        end
        assert_match(/^Signal/, msg)
      end
    end
  end

  # FIXME: Testing a private method, and with rather a lot of
  # mocking, too.
  describe "#interfaces" do
    it "skips interfaces that have no introspection data" do
      bldr = GirFFI::Builder::Type::Unintrospectable.new(:some_type)

      mock(bldr).interface_gtypes { [:foo, :bar ] }
      mock(gir = Object.new).find_by_gtype(:foo) { :foo_info }
      mock(gir).find_by_gtype(:bar) { nil }
      bldr.instance_eval { @gir = gir }
      mock(GirFFI::Builder).build_class(:foo_info) { :foo_module }

      result = bldr.send :interfaces
      result.must_equal [:foo_module]
    end
  end
end
