gir_ffi 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +8 -0
  3. data/Gemfile +2 -0
  4. data/README.md +2 -2
  5. data/Rakefile +3 -1
  6. data/TODO.md +7 -19
  7. data/lib/ffi-glib/byte_array.rb +1 -1
  8. data/lib/ffi-glib/list.rb +1 -1
  9. data/lib/ffi-glib/main_loop.rb +8 -8
  10. data/lib/ffi-glib/s_list.rb +1 -1
  11. data/lib/ffi-gobject/object.rb +8 -6
  12. data/lib/ffi-gobject/value.rb +2 -2
  13. data/lib/ffi-gobject.rb +5 -1
  14. data/lib/ffi-gobject_introspection/i_arg_info.rb +1 -1
  15. data/lib/ffi-gobject_introspection/i_base_info.rb +1 -1
  16. data/lib/ffi-gobject_introspection/i_callable_info.rb +2 -2
  17. data/lib/ffi-gobject_introspection/i_constant_info.rb +2 -2
  18. data/lib/ffi-gobject_introspection/i_enum_info.rb +2 -2
  19. data/lib/ffi-gobject_introspection/i_field_info.rb +1 -1
  20. data/lib/ffi-gobject_introspection/i_interface_info.rb +9 -9
  21. data/lib/ffi-gobject_introspection/i_object_info.rb +19 -14
  22. data/lib/ffi-gobject_introspection/i_property_info.rb +1 -1
  23. data/lib/ffi-gobject_introspection/i_repository.rb +1 -1
  24. data/lib/ffi-gobject_introspection/i_struct_info.rb +2 -2
  25. data/lib/ffi-gobject_introspection/i_type_info.rb +1 -1
  26. data/lib/ffi-gobject_introspection/i_union_info.rb +3 -3
  27. data/lib/ffi-gobject_introspection/i_vfunc_info.rb +2 -2
  28. data/lib/gir_ffi/builders/argument_builder.rb +2 -1
  29. data/lib/gir_ffi/builders/base_argument_builder.rb +1 -1
  30. data/lib/gir_ffi/builders/boxed_builder.rb +6 -0
  31. data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +7 -1
  32. data/lib/gir_ffi/builders/field_builder.rb +2 -4
  33. data/lib/gir_ffi/builders/object_builder.rb +20 -9
  34. data/lib/gir_ffi/builders/type_builder.rb +1 -1
  35. data/lib/gir_ffi/builders/unintrospectable_builder.rb +8 -0
  36. data/lib/gir_ffi/builders/with_layout.rb +0 -6
  37. data/lib/gir_ffi/core.rb +2 -1
  38. data/lib/gir_ffi/ffi_ext/pointer.rb +1 -1
  39. data/lib/gir_ffi/info_ext/i_type_info.rb +10 -12
  40. data/lib/gir_ffi/object_base.rb +4 -2
  41. data/lib/gir_ffi/property_not_found_error.rb +12 -0
  42. data/lib/gir_ffi/signal_not_found_error.rb +12 -0
  43. data/lib/gir_ffi/sized_array.rb +4 -4
  44. data/lib/gir_ffi/type_map.rb +1 -1
  45. data/lib/gir_ffi/unintrospectable_boxed_info.rb +2 -1
  46. data/lib/gir_ffi/unintrospectable_signal_info.rb +39 -0
  47. data/lib/gir_ffi/version.rb +2 -1
  48. data/lib/gir_ffi-base/gobject/lib.rb +1 -1
  49. data/tasks/rubocop.rake +5 -0
  50. data/tasks/test.rake +7 -0
  51. data/test/ffi-gobject/object_test.rb +29 -1
  52. data/test/ffi-gobject_introspection/i_object_info_test.rb +16 -0
  53. data/test/ffi-gobject_test.rb +3 -6
  54. data/test/gir_ffi/builders/argument_builder_test.rb +2 -2
  55. data/test/gir_ffi/builders/object_builder_test.rb +25 -12
  56. data/test/gir_ffi/builders/unintrospectable_builder_test.rb +21 -15
  57. data/test/integration/generated_gimarshallingtests_test.rb +16 -13
  58. data/test/integration/generated_gio_test.rb +2 -1
  59. data/test/integration/generated_gobject_test.rb +11 -1
  60. data/test/integration/generated_gst_test.rb +18 -0
  61. data/test/integration/generated_regress_test.rb +6 -8
  62. metadata +21 -2
@@ -9,6 +9,8 @@ module GirFFI
9
9
  # Convertor for fields for field getters. Used when building getter
10
10
  # methods.
11
11
  class GetterArgumentBuilder < BaseArgumentBuilder
12
+ attr_reader :array_length_idx
13
+
12
14
  def initialize(var_gen, field_argument_info, field_info,
13
15
  array_length_idx: -1)
14
16
  super(var_gen, field_argument_info)
@@ -49,10 +51,6 @@ module GirFFI
49
51
  end
50
52
  end
51
53
 
52
- def array_length_idx
53
- @array_length_idx
54
- end
55
-
56
54
  private
57
55
 
58
56
  def field_offset
@@ -21,13 +21,11 @@ module GirFFI
21
21
  end
22
22
 
23
23
  def find_signal(signal_name)
24
- seek_in_ancestor_infos { |info| info.find_signal signal_name } or
25
- raise "Signal #{signal_name} not found"
24
+ seek_in_ancestor_infos { |info| info.find_signal signal_name }
26
25
  end
27
26
 
28
27
  def find_property(property_name)
29
- seek_in_ancestor_infos { |info| info.find_property property_name } or
30
- raise "Property #{property_name} not found"
28
+ seek_in_ancestor_infos { |info| info.find_property property_name }
31
29
  end
32
30
 
33
31
  def object_class_struct
@@ -38,6 +36,15 @@ module GirFFI
38
36
  @ancestor_infos ||= [info] + info.interfaces + parent_ancestor_infos
39
37
  end
40
38
 
39
+ def eligible_fields
40
+ info.fields.reject do |finfo|
41
+ fname = finfo.name
42
+ fname == 'parent_instance' ||
43
+ info.find_instance_method("get_#{fname}") ||
44
+ info.find_property(fname)
45
+ end
46
+ end
47
+
41
48
  protected
42
49
 
43
50
  def object_class_struct_info
@@ -51,11 +58,8 @@ module GirFFI
51
58
  setup_layout
52
59
  setup_constants
53
60
  stub_methods
54
- if info.fundamental?
55
- setup_field_accessors
56
- else
57
- setup_property_accessors
58
- end
61
+ setup_field_accessors
62
+ setup_property_accessors
59
63
  setup_vfunc_invokers
60
64
  setup_interfaces
61
65
  provide_initializer
@@ -91,6 +95,12 @@ module GirFFI
91
95
  @parent_ancestor_infos ||= parent_builder.ancestor_infos
92
96
  end
93
97
 
98
+ def setup_field_accessors
99
+ eligible_fields.each do |finfo|
100
+ FieldBuilder.new(finfo).build
101
+ end
102
+ end
103
+
94
104
  def setup_property_accessors
95
105
  info.properties.each do |prop|
96
106
  PropertyBuilder.new(prop).build
@@ -119,6 +129,7 @@ module GirFFI
119
129
  def provide_initializer
120
130
  return if info.find_method 'new'
121
131
 
132
+ # FIXME: Only valid if the object descends from GObject::Object
122
133
  klass.class_eval "
123
134
  def initialize(properties = {})
124
135
  base_initialize(properties)
@@ -29,7 +29,7 @@ module GirFFI
29
29
  union: UnionBuilder,
30
30
  unintrospectable_boxed: UnintrospectableBoxedBuilder,
31
31
  unintrospectable: UnintrospectableBuilder
32
- }
32
+ }.freeze
33
33
 
34
34
  def self.build(info)
35
35
  builder_for(info).build_class
@@ -1,4 +1,5 @@
1
1
  require 'gir_ffi/builders/object_builder'
2
+ require 'gir_ffi/unintrospectable_signal_info'
2
3
 
3
4
  module GirFFI
4
5
  module Builders
@@ -19,6 +20,13 @@ module GirFFI
19
20
  def setup_instance_method(_method)
20
21
  false
21
22
  end
23
+
24
+ def find_signal(signal_name)
25
+ info = super
26
+ return info if info
27
+ signal_id = GObject.signal_lookup signal_name, target_gtype
28
+ return UnintrospectableSignalInfo.new(signal_id) if signal_id > 0
29
+ end
22
30
  end
23
31
  end
24
32
  end
@@ -34,12 +34,6 @@ module GirFFI
34
34
  fields.map(&:layout_specification).flatten(1)
35
35
  end
36
36
 
37
- def setup_field_accessors
38
- fields.each do |finfo|
39
- FieldBuilder.new(finfo).build
40
- end
41
- end
42
-
43
37
  def klass
44
38
  @klass ||= get_or_define_class namespace_module, @classname, superclass
45
39
  end
data/lib/gir_ffi/core.rb CHANGED
@@ -14,8 +14,9 @@ require 'gir_ffi/in_out_pointer'
14
14
  require 'gir_ffi/sized_array'
15
15
  require 'gir_ffi/zero_terminated'
16
16
  require 'gir_ffi/arg_helper'
17
- require 'gir_ffi/user_defined_type_info'
18
17
  require 'gir_ffi/builder'
18
+ require 'gir_ffi/user_defined_type_info'
19
+ require 'gir_ffi/builders/user_defined_builder'
19
20
  require 'gir_ffi/version'
20
21
 
21
22
  # Main module containing classes and modules needed for generating GLib and
@@ -16,7 +16,7 @@ module GirFFI
16
16
 
17
17
  # FIXME: Should probably not be here.
18
18
  def to_object
19
- return nil if self.null?
19
+ return nil if null?
20
20
  gtype = GObject.type_from_instance_pointer self
21
21
  Builder.build_by_gtype(gtype).direct_wrap self
22
22
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'gir_ffi/builder_helper'
2
3
 
3
4
  module GirFFI
@@ -16,17 +17,14 @@ module GirFFI
16
17
  strv: GObject::TYPE_STRV,
17
18
  utf8: GObject::TYPE_STRING,
18
19
  void: GObject::TYPE_NONE
19
- }
20
+ }.freeze
20
21
  end
21
22
 
22
23
  def gtype
23
- if tag == :interface
24
- return interface.gtype
25
- elsif (type = ITypeInfo.flattened_tag_to_gtype_map[flattened_tag])
26
- return type
27
- else
28
- raise "Can't find GType for #{flattened_tag} pointer? = #{pointer?}"
29
- end
24
+ return interface.gtype if tag == :interface
25
+ type = ITypeInfo.flattened_tag_to_gtype_map[flattened_tag]
26
+ return type if type
27
+ raise "Can't find GType for #{flattened_tag} pointer? = #{pointer?}"
30
28
  end
31
29
 
32
30
  def make_g_value
@@ -86,7 +84,7 @@ module GirFFI
86
84
  utf8: 'GirFFI::InPointer',
87
85
  void: 'GirFFI::InPointer',
88
86
  zero_terminated: 'GirFFI::ZeroTerminated'
89
- }
87
+ }.freeze
90
88
 
91
89
  # TODO: Use class rather than class name
92
90
  def argument_class_name
@@ -133,13 +131,13 @@ module GirFFI
133
131
  TAGS_NEEDING_RUBY_TO_C_CONVERSION = [
134
132
  :array, :c, :callback, :error, :ghash, :glist, :gslist, :object,
135
133
  :ptr_array, :struct, :strv, :utf8, :void, :zero_terminated
136
- ]
134
+ ].freeze
137
135
 
138
136
  TAGS_NEEDING_C_TO_RUBY_CONVERSION = [
139
137
  :array, :byte_array, :c, :error, :filename, :ghash, :glist, :gslist,
140
138
  :interface, :object, :ptr_array, :struct, :strv, :union, :utf8,
141
139
  :zero_terminated
142
- ]
140
+ ].freeze
143
141
 
144
142
  def needs_ruby_to_c_conversion_for_functions?
145
143
  TAGS_NEEDING_RUBY_TO_C_CONVERSION.include?(flattened_tag)
@@ -180,7 +178,7 @@ module GirFFI
180
178
  end
181
179
  end
182
180
 
183
- GOBJECT_VALUE_NAME = 'GObject::Value'
181
+ GOBJECT_VALUE_NAME = 'GObject::Value'.freeze
184
182
 
185
183
  def gvalue?
186
184
  argument_class_name == GOBJECT_VALUE_NAME
@@ -43,7 +43,8 @@ module GirFFI
43
43
  # @return [GObjectIntrospection::IPropertyInfo] The property's info
44
44
  #
45
45
  def self.find_property(name)
46
- gir_ffi_builder.find_property name
46
+ gir_ffi_builder.find_property name or
47
+ raise GirFFI::PropertyNotFoundError.new(name, self)
47
48
  end
48
49
 
49
50
  #
@@ -54,7 +55,8 @@ module GirFFI
54
55
  # @return [GObjectIntrospection::ISignalInfo] The signal's info
55
56
  #
56
57
  def self.find_signal(name)
57
- gir_ffi_builder.find_signal name
58
+ gir_ffi_builder.find_signal name or
59
+ raise GirFFI::SignalNotFoundError.new(name, self)
58
60
  end
59
61
 
60
62
  def self.object_class
@@ -0,0 +1,12 @@
1
+ module GirFFI
2
+ # Exception class to be raised when a property is not found.
3
+ class PropertyNotFoundError < RuntimeError
4
+ attr_reader :property_name
5
+
6
+ def initialize(property_name, klass)
7
+ @property_name = property_name
8
+ @klass = klass
9
+ super "Property '#{property_name}' not found in #{klass}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module GirFFI
2
+ # Exception class to be raised when a signal is not found.
3
+ class SignalNotFoundError < RuntimeError
4
+ attr_reader :signal_name
5
+
6
+ def initialize(signal_name, klass)
7
+ @signal_name = signal_name
8
+ @klass = klass
9
+ super "Signal '#{signal_name}' not found in #{klass}"
10
+ end
11
+ end
12
+ end
@@ -42,6 +42,10 @@ module GirFFI
42
42
  pointer.put_bytes(0, value.to_ptr.read_bytes(size), 0, size)
43
43
  end
44
44
 
45
+ def self.wrap(element_type, size, pointer)
46
+ new element_type, size, pointer unless pointer.null?
47
+ end
48
+
45
49
  private
46
50
 
47
51
  def element_ffi_type
@@ -52,10 +56,6 @@ module GirFFI
52
56
  @element_size ||= FFI.type_size element_ffi_type
53
57
  end
54
58
 
55
- def self.wrap(element_type, size, pointer)
56
- new element_type, size, pointer unless pointer.null?
57
- end
58
-
59
59
  class << self
60
60
  def from(element_type, size, item)
61
61
  return unless item
@@ -36,7 +36,7 @@ module GirFFI
36
36
  gfloat: :float,
37
37
  gdouble: :double,
38
38
  void: :void
39
- }
39
+ }.freeze
40
40
 
41
41
  def self.map_basic_type(type)
42
42
  sym = type.to_sym
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'gir_ffi/info_ext/full_type_name'
2
3
 
3
4
  module GirFFI
@@ -18,7 +19,7 @@ module GirFFI
18
19
  GObject.type_name g_type
19
20
  end
20
21
 
21
- DEFAULT_BOXED_NAMESPACE = 'GLib'
22
+ DEFAULT_BOXED_NAMESPACE = 'GLib'.freeze
22
23
 
23
24
  def namespace
24
25
  DEFAULT_BOXED_NAMESPACE
@@ -0,0 +1,39 @@
1
+ module GirFFI
2
+ # Represents a signal not found in the GIR, conforming, as needed, to the
3
+ # interface of GObjectIntrospection::ISignalInfo.
4
+ class UnintrospectableSignalInfo
5
+ attr_reader :signal_id
6
+
7
+ def initialize(signal_id)
8
+ @signal_id = signal_id
9
+ end
10
+
11
+ def name
12
+ GObject.signal_name signal_id
13
+ end
14
+
15
+ def wrap_in_closure(&block)
16
+ GObject::RubyClosure.new(&block)
17
+ end
18
+
19
+ def arguments_to_gvalues(instance, arguments)
20
+ param_gtypes = signal_query.param_types || []
21
+
22
+ argument_gvalues = param_gtypes.zip(arguments).map do |gtype, arg|
23
+ GObject::Value.for_gtype(gtype).tap { |it| it.set_value arg }
24
+ end
25
+
26
+ argument_gvalues.unshift GObject::Value.wrap_instance(instance)
27
+ end
28
+
29
+ def gvalue_for_return_value
30
+ GObject::Value.for_gtype signal_query.return_type
31
+ end
32
+
33
+ private
34
+
35
+ def signal_query
36
+ @signal_query ||= GObject.signal_query signal_id
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  # Current GirFFI version
2
3
  module GirFFI
3
- VERSION = '0.9.0'
4
+ VERSION = '0.9.1'.freeze
4
5
  end
@@ -1,7 +1,7 @@
1
1
  require 'ffi/bit_masks'
2
2
 
3
3
  # NOTE: Monkey-patch BitMask to work on JRuby.
4
- class FFI::BitMasks::BitMask
4
+ FFI::BitMasks::BitMask.class_eval do
5
5
  def reference_required?
6
6
  false
7
7
  end
@@ -0,0 +1,5 @@
1
+ require 'rubocop/rake_task'
2
+
3
+ RuboCop::RakeTask.new do |task|
4
+ task.options << '--display-cop-names'
5
+ end
data/tasks/test.rake CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rake/testtask'
2
+ require 'cucumber/rake/task'
2
3
 
3
4
  require 'rexml/document'
4
5
  require 'rexml/streamlistener'
@@ -185,6 +186,10 @@ namespace :test do
185
186
  make_stub_file 'Utility'
186
187
  make_stub_file 'WarnLib'
187
188
  end
189
+
190
+ Cucumber::Rake::Task.new(:features) do |t|
191
+ t.cucumber_opts = 'features --format pretty'
192
+ end
188
193
  end
189
194
 
190
195
  file "test/lib/Makefile" => "test/lib/configure" do
@@ -194,3 +199,5 @@ end
194
199
  file "test/lib/configure" => ["test/lib/autogen.sh", "test/lib/configure.ac"] do
195
200
  sh %{cd test/lib && ./autogen.sh}
196
201
  end
202
+
203
+ task test: 'test:all'
@@ -19,7 +19,7 @@ describe GObject::Object do
19
19
  end
20
20
 
21
21
  it 'raises an error for properties that do not exist' do
22
- proc { GObject::Object.new(dog: 'bark') }.must_raise ArgumentError
22
+ proc { GObject::Object.new(dog: 'bark') }.must_raise GirFFI::PropertyNotFoundError
23
23
  end
24
24
  end
25
25
 
@@ -27,6 +27,34 @@ describe GObject::Object do
27
27
  it 'is overridden to have arity 1' do
28
28
  GObject::Object.instance_method('get_property').arity.must_equal 1
29
29
  end
30
+
31
+ it 'raises an error for a property that does not exist' do
32
+ instance = GObject::Object.new
33
+ proc { instance.get_property 'foo-bar' }.must_raise GirFFI::PropertyNotFoundError
34
+ end
35
+ end
36
+
37
+ describe '#get_property_extended' do
38
+ it 'raises an error for a property that does not exist' do
39
+ instance = GObject::Object.new
40
+ proc { instance.get_property_extended 'foo-bar' }.
41
+ must_raise GirFFI::PropertyNotFoundError
42
+ end
43
+ end
44
+
45
+ describe '#set_property' do
46
+ it 'raises an error for a property that does not exist' do
47
+ instance = GObject::Object.new
48
+ proc { instance.set_property 'foo-bar', 123 }.must_raise GirFFI::PropertyNotFoundError
49
+ end
50
+ end
51
+
52
+ describe '#set_property_extended' do
53
+ it 'raises an error for a property that does not exist' do
54
+ instance = GObject::Object.new
55
+ proc { instance.set_property_extended 'foo-bar', 123 }.
56
+ must_raise GirFFI::PropertyNotFoundError
57
+ end
30
58
  end
31
59
 
32
60
  describe 'automatic accessor methods' do
@@ -23,6 +23,22 @@ describe GObjectIntrospection::IObjectInfo do
23
23
  end
24
24
  end
25
25
 
26
+ describe '#find_property' do
27
+ let(:object_info) { get_introspection_data('GObject', 'Binding') }
28
+
29
+ it 'finds a property by name string' do
30
+ object_info.find_property('source-property').wont_be_nil
31
+ end
32
+
33
+ it 'finds a property by snake case string' do
34
+ object_info.find_property('source_property').wont_be_nil
35
+ end
36
+
37
+ it 'finds a property by name symbol' do
38
+ object_info.find_property(:source).wont_be_nil
39
+ end
40
+ end
41
+
26
42
  describe '#type_name' do
27
43
  it 'returns the correct name' do
28
44
  object_info.type_name.must_equal 'GObject'
@@ -86,9 +86,8 @@ describe GObject do
86
86
 
87
87
  it 'does not allow connecting an invalid signal' do
88
88
  o = Regress::TestSubObj.new
89
- assert_raises RuntimeError do
90
- GObject.signal_connect(o, 'not-really-a-signal') {}
91
- end
89
+ proc { GObject.signal_connect(o, 'not-really-a-signal') {} }.
90
+ must_raise GirFFI::SignalNotFoundError
92
91
  end
93
92
 
94
93
  it 'handles return values' do
@@ -100,9 +99,7 @@ describe GObject do
100
99
 
101
100
  it 'requires a block' do
102
101
  o = Regress::TestSubObj.new
103
- assert_raises ArgumentError do
104
- GObject.signal_connect o, 'test'
105
- end
102
+ proc { GObject.signal_connect o, 'test' }.must_raise ArgumentError
106
103
  end
107
104
 
108
105
  it 'allows specifying signal detail' do
@@ -344,7 +344,7 @@ describe GirFFI::Builders::ArgumentBuilder do
344
344
  end
345
345
 
346
346
  it 'has the correct value for method_argument_name' do
347
- builder.method_argument_name.must_equal "#{arg_info.name}"
347
+ builder.method_argument_name.must_equal arg_info.name
348
348
  end
349
349
 
350
350
  it 'has the correct value for #pre_conversion' do
@@ -435,7 +435,7 @@ describe GirFFI::Builders::ArgumentBuilder do
435
435
 
436
436
  it 'has the correct value for #pre_conversion' do
437
437
  builder.pre_conversion.must_equal [
438
- "GirFFI::ArgHelper.check_fixed_array_size 4, ints, \"ints\"",
438
+ 'GirFFI::ArgHelper.check_fixed_array_size 4, ints, "ints"',
439
439
  '_v1 = GirFFI::InOutPointer.for [:pointer, :c]',
440
440
  '_v1.set_value GirFFI::SizedArray.from(:gint32, 4, ints)'
441
441
  ]
@@ -9,6 +9,10 @@ describe GirFFI::Builders::ObjectBuilder do
9
9
  GirFFI::Builders::ObjectBuilder.new(
10
10
  get_introspection_data('Regress', 'TestSubObj'))
11
11
  end
12
+ let(:param_spec_builder) do
13
+ GirFFI::Builders::ObjectBuilder.new(
14
+ get_introspection_data('GObject', 'ParamSpec'))
15
+ end
12
16
 
13
17
  describe '#find_signal' do
14
18
  it 'finds the signal "test" for TestObj' do
@@ -27,14 +31,8 @@ describe GirFFI::Builders::ObjectBuilder do
27
31
  sig.name.must_equal 'changed'
28
32
  end
29
33
 
30
- it "raises an error for a signal that doesn't exist" do
31
- msg = nil
32
- begin
33
- obj_builder.find_signal 'foo'
34
- rescue RuntimeError => e
35
- msg = e.message
36
- end
37
- assert_match(/^Signal/, msg)
34
+ it "returns nil for a signal that doesn't exist" do
35
+ obj_builder.find_signal('foo').must_be_nil
38
36
  end
39
37
  end
40
38
 
@@ -49,10 +47,8 @@ describe GirFFI::Builders::ObjectBuilder do
49
47
  prop.name.must_equal 'int'
50
48
  end
51
49
 
52
- it 'raises an error if the property is not found' do
53
- proc do
54
- sub_obj_builder.find_property('this-property-does-not-exist')
55
- end.must_raise RuntimeError
50
+ it 'returns nil if the property is not found' do
51
+ sub_obj_builder.find_property('this-property-does-not-exist').must_be_nil
56
52
  end
57
53
  end
58
54
 
@@ -86,4 +82,21 @@ describe GirFFI::Builders::ObjectBuilder do
86
82
  assert_equal [:parent, GObject::Object::Struct, 0], spec
87
83
  end
88
84
  end
85
+
86
+ describe '#eligible_fields' do
87
+ it 'skips fields that have a matching getter method' do
88
+ result = param_spec_builder.eligible_fields
89
+ result.map(&:name).wont_include 'name'
90
+ end
91
+
92
+ it 'skips fields that have a matching property' do
93
+ result = obj_builder.eligible_fields
94
+ result.map(&:name).wont_include 'hash_table'
95
+ end
96
+
97
+ it 'skips the parent instance field' do
98
+ result = obj_builder.eligible_fields
99
+ result.map(&:name).wont_include 'parent_instance'
100
+ end
101
+ end
89
102
  end
@@ -1,15 +1,13 @@
1
1
  require 'gir_ffi_test_helper'
2
2
 
3
+ GirFFI.setup :Gio
4
+ GirFFI.setup :Gst
5
+ Gst.init []
6
+
3
7
  describe GirFFI::Builders::UnintrospectableBuilder do
4
8
  describe 'building the GLocalFile type' do
5
9
  before do
6
- # Ensure existence of GLocalFile type
7
- GirFFI.setup :Gio
8
- unless Gio::Lib.respond_to? :g_file_new_for_path
9
- Gio.setup_method 'file_new_for_path'
10
- end
11
- ptr = GirFFI::InPointer.from :utf8, '/'
12
- Gio::Lib.g_file_new_for_path(ptr)
10
+ Gio.file_new_for_path '/'
13
11
 
14
12
  @gtype = GObject.type_from_name 'GLocalFile'
15
13
  @info = GirFFI::UnintrospectableTypeInfo.new(@gtype)
@@ -37,14 +35,8 @@ describe GirFFI::Builders::UnintrospectableBuilder do
37
35
  end
38
36
 
39
37
  describe 'its #find_signal method' do
40
- it "raises correct error for a signal that doesn't exist" do
41
- msg = nil
42
- begin
43
- @bldr.find_signal 'foo'
44
- rescue RuntimeError => e
45
- msg = e.message
46
- end
47
- assert_match(/^Signal/, msg)
38
+ it "returns nil for a signal that doesn't exist" do
39
+ @bldr.find_signal('foo').must_be_nil
48
40
  end
49
41
 
50
42
  it 'finds signals in ancestor classes' do
@@ -59,4 +51,18 @@ describe GirFFI::Builders::UnintrospectableBuilder do
59
51
  end
60
52
  end
61
53
  end
54
+
55
+ describe 'building the GstFakeSink type' do
56
+ let(:instance) { Gst::ElementFactory.make('fakesink', 'sink') }
57
+ let(:klass) { instance.class }
58
+ let(:builder) { klass.gir_ffi_builder }
59
+
60
+ describe 'its #find_signal method' do
61
+ it 'finds signals that are not defined in the GIR' do
62
+ signal = builder.find_signal 'handoff'
63
+ signal.wont_be_nil
64
+ signal.name.must_equal 'handoff'
65
+ end
66
+ end
67
+ end
62
68
  end