gir_ffi 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +10 -0
  3. data/Rakefile +9 -1
  4. data/TODO.md +4 -0
  5. data/lib/ffi-glib.rb +5 -0
  6. data/lib/ffi-glib/bytes.rb +49 -0
  7. data/lib/ffi-glib/container_class_methods.rb +1 -4
  8. data/lib/ffi-glib/error.rb +17 -0
  9. data/lib/ffi-gobject/value.rb +6 -3
  10. data/lib/ffi-gobject_introspection/i_callback_info.rb +0 -1
  11. data/lib/ffi-gobject_introspection/i_constant_info.rb +10 -10
  12. data/lib/ffi-gobject_introspection/i_repository.rb +20 -20
  13. data/lib/ffi-gobject_introspection/i_vfunc_info.rb +7 -0
  14. data/lib/ffi-gobject_introspection/lib.rb +1 -7
  15. data/lib/gir_ffi/arg_helper.rb +23 -2
  16. data/lib/gir_ffi/builders/argument_builder.rb +15 -1
  17. data/lib/gir_ffi/builders/base_argument_builder.rb +1 -0
  18. data/lib/gir_ffi/builders/callback_argument_builder.rb +49 -7
  19. data/lib/gir_ffi/builders/callback_return_value_builder.rb +6 -2
  20. data/lib/gir_ffi/builders/closure_convertor.rb +1 -1
  21. data/lib/gir_ffi/builders/null_convertor.rb +1 -0
  22. data/lib/gir_ffi/builders/property_builder.rb +1 -1
  23. data/lib/gir_ffi/builders/return_value_builder.rb +1 -1
  24. data/lib/gir_ffi/builders/type_builder.rb +9 -9
  25. data/lib/gir_ffi/builders/vfunc_builder.rb +3 -1
  26. data/lib/gir_ffi/callback_base.rb +6 -0
  27. data/lib/gir_ffi/error_argument_info.rb +12 -3
  28. data/lib/gir_ffi/error_type_info.rb +21 -0
  29. data/lib/gir_ffi/ffi_ext/pointer.rb +5 -6
  30. data/lib/gir_ffi/glib_error.rb +18 -0
  31. data/lib/gir_ffi/in_pointer.rb +1 -1
  32. data/lib/gir_ffi/info_ext/i_type_info.rb +44 -30
  33. data/lib/gir_ffi/info_ext/i_vfunc_info.rb +13 -1
  34. data/lib/gir_ffi/type_map.rb +30 -29
  35. data/lib/gir_ffi/user_defined_type_info.rb +1 -0
  36. data/lib/gir_ffi/version.rb +1 -1
  37. data/lib/gir_ffi/vfunc_base.rb +1 -0
  38. data/lib/gir_ffi/zero_terminated.rb +3 -8
  39. data/test/base_test_helper.rb +1 -0
  40. data/test/ffi-glib/array_test.rb +2 -2
  41. data/test/ffi-glib/bytes_test.rb +54 -0
  42. data/test/ffi-glib/ptr_array_test.rb +2 -2
  43. data/test/ffi-gobject/value_test.rb +4 -4
  44. data/test/ffi-gobject_introspection/i_repository_test.rb +1 -1
  45. data/test/gir_ffi/builders/callback_argument_builder_test.rb +44 -0
  46. data/test/gir_ffi/builders/callback_builder_test.rb +1 -1
  47. data/test/gir_ffi/builders/callback_return_value_builder_test.rb +74 -0
  48. data/test/gir_ffi/builders/function_builder_test.rb +23 -2
  49. data/test/gir_ffi/builders/property_builder_test.rb +15 -0
  50. data/test/gir_ffi/builders/return_value_builder_test.rb +26 -26
  51. data/test/gir_ffi/builders/signal_builder_test.rb +5 -5
  52. data/test/gir_ffi/builders/union_builder_test.rb +2 -1
  53. data/test/gir_ffi/builders/vfunc_builder_test.rb +125 -4
  54. data/test/gir_ffi/error_type_info_test.rb +48 -0
  55. data/test/gir_ffi/in_pointer_test.rb +1 -1
  56. data/test/gir_ffi/sized_array_test.rb +2 -2
  57. data/test/integration/generated_gimarshallingtests_test.rb +199 -31
  58. data/test/integration/generated_regress_test.rb +37 -33
  59. metadata +214 -202
@@ -12,7 +12,7 @@ describe GirFFI::Builders::SignalBuilder do
12
12
  expected = <<-CODE.reset_indentation
13
13
  def self.call_with_argument_mapping(_proc, _instance, _user_data)
14
14
  _v1 = Regress::TestObj.wrap(_instance)
15
- _v2 = GirFFI::ArgHelper::OBJECT_STORE[_user_data.address]
15
+ _v2 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_user_data)
16
16
  _proc.call(_v1, _v2)
17
17
  end
18
18
  CODE
@@ -32,7 +32,7 @@ describe GirFFI::Builders::SignalBuilder do
32
32
  def self.call_with_argument_mapping(_proc, _instance, i, _user_data)
33
33
  _v1 = Regress::TestObj.wrap(_instance)
34
34
  _v2 = i
35
- _v3 = GirFFI::ArgHelper::OBJECT_STORE[_user_data.address]
35
+ _v3 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_user_data)
36
36
  _v4 = _proc.call(_v1, _v2, _v3)
37
37
  return _v4
38
38
  end
@@ -51,7 +51,7 @@ describe GirFFI::Builders::SignalBuilder do
51
51
  def self.call_with_argument_mapping(_proc, _instance, result, _user_data)
52
52
  _v1 = Gio::MountOperation.wrap(_instance)
53
53
  _v2 = Gio::MountOperationResult.wrap(result)
54
- _v3 = GirFFI::ArgHelper::OBJECT_STORE[_user_data.address]
54
+ _v3 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_user_data)
55
55
  _proc.call(_v1, _v2, _v3)
56
56
  end
57
57
  CODE
@@ -71,7 +71,7 @@ describe GirFFI::Builders::SignalBuilder do
71
71
  def self.call_with_argument_mapping(_proc, _instance, arr, len, _user_data)
72
72
  _v1 = Regress::TestObj.wrap(_instance)
73
73
  _v2 = len
74
- _v3 = GirFFI::ArgHelper::OBJECT_STORE[_user_data.address]
74
+ _v3 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_user_data)
75
75
  _v4 = GirFFI::SizedArray.wrap(:guint32, _v2, arr)
76
76
  _proc.call(_v1, _v4, _v3)
77
77
  end
@@ -92,7 +92,7 @@ describe GirFFI::Builders::SignalBuilder do
92
92
  def self.call_with_argument_mapping(_proc, _instance, i, _user_data)
93
93
  _v1 = Regress::TestObj.wrap(_instance)
94
94
  _v2 = i
95
- _v3 = GirFFI::ArgHelper::OBJECT_STORE[_user_data.address]
95
+ _v3 = GirFFI::ArgHelper::OBJECT_STORE.fetch(_user_data)
96
96
  _v4 = _proc.call(_v1, _v2, _v3)
97
97
  _v5 = GLib::Array.from(:gint32, _v4)
98
98
  return _v5
@@ -12,8 +12,9 @@ describe GirFFI::Builders::UnionBuilder do
12
12
 
13
13
  describe "#layout_specification" do
14
14
  it "returns the correct layout for GObject::TypeCValue" do
15
+ long_type = FFI.type_size(:long) == 8 ? :int64 : :int32
15
16
  builder.layout_specification.must_equal [:v_int, :int32, 0,
16
- :v_long, :int64, 0,
17
+ :v_long, long_type, 0,
17
18
  :v_int64, :int64, 0,
18
19
  :v_double, :double, 0,
19
20
  :v_pointer, :pointer, 0]
@@ -4,6 +4,12 @@ describe GirFFI::Builders::VFuncBuilder do
4
4
  let(:builder) { GirFFI::Builders::VFuncBuilder.new vfunc_info }
5
5
 
6
6
  describe "#mapping_method_definition" do
7
+ let(:result) { builder.mapping_method_definition }
8
+
9
+ before do
10
+ skip unless vfunc_info
11
+ end
12
+
7
13
  describe "for a vfunc with only one argument" do
8
14
  let(:vfunc_info) {
9
15
  get_vfunc_introspection_data "GIMarshallingTests", "Object", "method_int8_in" }
@@ -17,7 +23,7 @@ describe GirFFI::Builders::VFuncBuilder do
17
23
  end
18
24
  CODE
19
25
 
20
- builder.mapping_method_definition.must_equal expected
26
+ result.must_equal expected
21
27
  end
22
28
  end
23
29
 
@@ -26,7 +32,6 @@ describe GirFFI::Builders::VFuncBuilder do
26
32
  get_vfunc_introspection_data "GIMarshallingTests", "Object", "vfunc_return_enum" }
27
33
 
28
34
  it "returns a valid mapping method including receiver" do
29
- skip unless vfunc_info
30
35
  expected = <<-CODE.reset_indentation
31
36
  def self.call_with_argument_mapping(_proc, _instance)
32
37
  _v1 = GIMarshallingTests::Object.wrap(_instance)
@@ -36,9 +41,125 @@ describe GirFFI::Builders::VFuncBuilder do
36
41
  end
37
42
  CODE
38
43
 
39
- builder.mapping_method_definition.must_equal expected
44
+ result.must_equal expected
45
+ end
46
+ end
47
+
48
+ describe "for a vfunc with a callback argument" do
49
+ let(:vfunc_info) {
50
+ get_vfunc_introspection_data "GIMarshallingTests", "Object", "vfunc_with_callback" }
51
+
52
+ it "returns a valid mapping method including receiver" do
53
+ expected = <<-CODE.reset_indentation
54
+ def self.call_with_argument_mapping(_proc, _instance, callback, callback_data)
55
+ _v1 = GIMarshallingTests::Object.wrap(_instance)
56
+ _v2 = GIMarshallingTests::CallbackIntInt.wrap(callback)
57
+ _v3 = GirFFI::ArgHelper::OBJECT_STORE.fetch(callback_data)
58
+ _proc.call(_v1, _v2, _v3)
59
+ end
60
+ CODE
61
+
62
+ result.must_equal expected
63
+ end
64
+ end
65
+
66
+ describe "for a vfunc with an out argument allocated by them, the caller" do
67
+ let(:vfunc_info) {
68
+ get_vfunc_introspection_data("GIMarshallingTests", "Object",
69
+ "method_int8_arg_and_out_caller") }
70
+
71
+ it "returns a valid mapping method including receiver" do
72
+ expected = <<-CODE.reset_indentation
73
+ def self.call_with_argument_mapping(_proc, _instance, arg, out)
74
+ _v1 = GIMarshallingTests::Object.wrap(_instance)
75
+ _v2 = arg
76
+ _v3 = GirFFI::InOutPointer.new(:gint8, out)
77
+ _v4 = _proc.call(_v1, _v2)
78
+ _v3.set_value _v4
79
+ end
80
+ CODE
81
+
82
+ result.must_equal expected
83
+ end
84
+ end
85
+
86
+ describe "for a vfunc with an out argument allocated by us, the callee" do
87
+ let(:vfunc_info) {
88
+ get_vfunc_introspection_data("GIMarshallingTests", "Object",
89
+ "method_int8_arg_and_out_callee") }
90
+
91
+ it "returns a valid mapping method including receiver" do
92
+ expected = <<-CODE.reset_indentation
93
+ def self.call_with_argument_mapping(_proc, _instance, arg, out)
94
+ _v1 = GIMarshallingTests::Object.wrap(_instance)
95
+ _v2 = arg
96
+ _v3 = GirFFI::InOutPointer.new(:gint8).tap { |ptr| out.put_pointer 0, ptr }
97
+ _v4 = _proc.call(_v1, _v2)
98
+ _v3.set_value _v4
99
+ end
100
+ CODE
101
+
102
+ result.must_equal expected
103
+ end
104
+ end
105
+
106
+ describe "for a vfunc with an error argument" do
107
+ let(:vfunc_info) {
108
+ get_vfunc_introspection_data("GIMarshallingTests", "Object",
109
+ "vfunc_meth_with_err")
110
+ }
111
+
112
+ it "returns a valid mapping method including receiver" do
113
+ expected = <<-CODE.reset_indentation
114
+ def self.call_with_argument_mapping(_proc, _instance, x, _error)
115
+ _v1 = GIMarshallingTests::Object.wrap(_instance)
116
+ _v2 = x
117
+ _v3 = GirFFI::InOutPointer.new([:pointer, :error], _error)
118
+ begin
119
+ _v4 = _proc.call(_v1, _v2)
120
+ rescue => _v5
121
+ _v3.set_value GLib::Error.from(_v5)
122
+ end
123
+ return _v4
124
+ end
125
+ CODE
126
+
127
+ result.must_equal expected
40
128
  end
41
129
  end
42
130
  end
43
- end
44
131
 
132
+ describe "#argument_ffi_types" do
133
+ let(:result) { builder.argument_ffi_types }
134
+
135
+ before do
136
+ skip unless vfunc_info
137
+ end
138
+
139
+ describe "for a vfunc with only one argument" do
140
+ let(:vfunc_info) {
141
+ get_vfunc_introspection_data "GIMarshallingTests", "Object", "method_int8_in" }
142
+
143
+ it "returns the correct FFI types including :pointer for the receiver" do
144
+ result.must_equal [:pointer, :int8]
145
+ end
146
+ end
147
+ end
148
+
149
+ describe "#return_ffi_type" do
150
+ let(:result) { builder.return_ffi_type }
151
+
152
+ before do
153
+ skip unless vfunc_info
154
+ end
155
+
156
+ describe "for a vfunc returning an object" do
157
+ let(:vfunc_info) {
158
+ get_vfunc_introspection_data "GIMarshallingTests", "Object", "vfunc_return_object_transfer_full" }
159
+
160
+ it "returns :pointer" do
161
+ result.must_equal :pointer
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,48 @@
1
+ require 'gir_ffi_test_helper'
2
+ require 'gir_ffi/error_type_info'
3
+
4
+ describe GirFFI::ErrorTypeInfo do
5
+ let(:instance) { GirFFI::ErrorTypeInfo.new }
6
+
7
+ describe "#array_length" do
8
+ it "returns the correct value" do
9
+ instance.array_length.must_equal(-1)
10
+ end
11
+ end
12
+
13
+ describe "#tag_or_class" do
14
+ it "returns the correct value" do
15
+ instance.tag_or_class.must_equal [:pointer, :error]
16
+ end
17
+ end
18
+
19
+ describe "#pointer?" do
20
+ it "returns the correct value" do
21
+ instance.pointer?.must_equal true
22
+ end
23
+ end
24
+
25
+ describe "#flattened_tag" do
26
+ it "returns the correct value" do
27
+ instance.flattened_tag.must_equal :error
28
+ end
29
+ end
30
+
31
+ describe "#extra_conversion_arguments" do
32
+ it "returns the correct value" do
33
+ instance.extra_conversion_arguments.must_equal []
34
+ end
35
+ end
36
+
37
+ describe "#argument_class_name" do
38
+ it "returns the correct value" do
39
+ instance.argument_class_name.must_equal 'GLib::Error'
40
+ end
41
+ end
42
+
43
+ describe "#needs_ruby_to_c_conversion_for_callbacks?" do
44
+ it "returns the correct value" do
45
+ instance.needs_ruby_to_c_conversion_for_callbacks?.must_equal true
46
+ end
47
+ end
48
+ end
@@ -188,7 +188,7 @@ describe GirFFI::InPointer do
188
188
  it "stores the string in GirFFI::ArgHelper::OBJECT_STORE" do
189
189
  str = "Foo"
190
190
  ptr = GirFFI::InPointer.from_closure_data(str)
191
- result = GirFFI::ArgHelper::OBJECT_STORE[ptr.address]
191
+ result = GirFFI::ArgHelper::OBJECT_STORE.fetch(ptr)
192
192
  result.must_equal str
193
193
  end
194
194
  end
@@ -44,7 +44,7 @@ describe GirFFI::SizedArray do
44
44
  end
45
45
 
46
46
  it "raises an error if the array has the wrong number of elements" do
47
- lambda { GirFFI::SizedArray.from :gint32, 4, [3, 2, 1] }.must_raise ArgumentError
47
+ proc { GirFFI::SizedArray.from :gint32, 4, [3, 2, 1] }.must_raise ArgumentError
48
48
  end
49
49
 
50
50
  it "uses the array's size if passed -1 as the size" do
@@ -62,7 +62,7 @@ describe GirFFI::SizedArray do
62
62
 
63
63
  it "raises an error if the argument has the wrong number of elements" do
64
64
  arr = GirFFI::SizedArray.from :gint32, 3, [3, 2, 1]
65
- lambda { GirFFI::SizedArray.from :gint32, 4, arr }.must_raise ArgumentError
65
+ proc { GirFFI::SizedArray.from :gint32, 4, arr }.must_raise ArgumentError
66
66
  end
67
67
  end
68
68
 
@@ -56,7 +56,9 @@ describe GIMarshallingTests do
56
56
 
57
57
  res = GIMarshallingTests::BoxedStruct.inout bx
58
58
 
59
- assert_equal 42, bx.long_
59
+ # TODO: Deal with the fact that bx is now invalid (at least with
60
+ # gobject-introspection 1.40).
61
+
60
62
  assert_equal 0, res.long_
61
63
  end
62
64
 
@@ -275,9 +277,13 @@ describe GIMarshallingTests do
275
277
 
276
278
  it "has a working function #full_inout" do
277
279
  ob = GIMarshallingTests::Object.new 42
280
+
278
281
  res = GIMarshallingTests::Object.full_inout ob
282
+
283
+ # TODO: Deal with the fact that ob is now invalid
284
+
279
285
  assert_instance_of GIMarshallingTests::Object, res
280
- ob.wont_equal res
286
+ res.int.must_equal 0
281
287
  end
282
288
 
283
289
  it "has a working function #full_out" do
@@ -291,7 +297,7 @@ describe GIMarshallingTests do
291
297
  end
292
298
 
293
299
  it "has a working function #inout_same" do
294
- skip "This function is only found in the header"
300
+ skip "This function is defined in the header but not implemented"
295
301
  end
296
302
 
297
303
  it "has a working function #none_inout" do
@@ -319,33 +325,108 @@ describe GIMarshallingTests do
319
325
  let(:instance) { GIMarshallingTests::Object.new 42 }
320
326
 
321
327
  it "has a working method #call_vfunc_with_callback" do
322
- # NOTE: To call this method, the callback slot vfunc_with_callback has to
323
- # be filled in the GIMarshallingTests::Object class structure. The
324
- # GIMarshallingTests library doesn't do this.
325
- skip "Needs vfunc setup"
328
+ skip unless get_method_introspection_data("GIMarshallingTests", "Object",
329
+ "call_vfunc_with_callback")
330
+ cb = nil
331
+ user_data = nil
332
+ result = nil
333
+
334
+ derived_instance = make_derived_instance do |info|
335
+ info.install_vfunc_implementation :vfunc_with_callback, proc { |obj, callback, callback_data|
336
+ cb = callback
337
+ user_data = callback_data.address
338
+ result = callback.call(42, callback_data)
339
+ }
340
+ end
341
+ derived_instance.call_vfunc_with_callback
342
+
343
+ user_data.must_equal 0xdeadbeef
344
+ # TODO: Change implementation of CallbackBase so that this becomes an
345
+ # instance of GIMarshallingTests::CallbackIntInt
346
+ cb.must_be_instance_of FFI::Function
347
+ result.must_equal 42
326
348
  end
327
349
 
328
350
  it "has a working method #full_in" do
329
- skip "This function is only found in the header"
351
+ skip "This function is defined in the header but not implemented"
330
352
  end
331
353
 
332
354
  it "has a working method #get_ref_info_for_vfunc_in_object_transfer_full" do
333
- skip "Needs vfunc setup"
355
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
356
+ "vfunc_in_object_transfer_full")
357
+ obj = nil
358
+ derived_instance = make_derived_instance do |info|
359
+ info.install_vfunc_implementation :vfunc_in_object_transfer_full, proc {|this, object|
360
+ obj = object
361
+ }
362
+ end
363
+ result = derived_instance.
364
+ get_ref_info_for_vfunc_in_object_transfer_full GIMarshallingTests::Object.get_gtype
365
+ result.must_equal [1, false]
366
+ obj.must_be_instance_of GIMarshallingTests::Object
334
367
  end
368
+
335
369
  it "has a working method #get_ref_info_for_vfunc_in_object_transfer_none" do
336
- skip "Needs vfunc setup"
370
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
371
+ "vfunc_in_object_transfer_none")
372
+ klass = nil
373
+ derived_instance = make_derived_instance do |info|
374
+ info.install_vfunc_implementation :vfunc_in_object_transfer_none, proc {|this, object|
375
+ klass = object.class
376
+ }
377
+ end
378
+ result = derived_instance.
379
+ get_ref_info_for_vfunc_in_object_transfer_none GIMarshallingTests::Object.get_gtype
380
+ result.must_equal [1, false]
381
+ klass.must_equal GIMarshallingTests::Object
337
382
  end
383
+
338
384
  it "has a working method #get_ref_info_for_vfunc_out_object_transfer_full" do
339
- skip "Needs vfunc setup"
385
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
386
+ "vfunc_out_object_transfer_full")
387
+ derived_instance = make_derived_instance do |info|
388
+ info.install_vfunc_implementation :vfunc_out_object_transfer_full, proc {|obj|
389
+ GIMarshallingTests::Object.new 42
390
+ }
391
+ end
392
+ result = derived_instance.get_ref_info_for_vfunc_out_object_transfer_full
393
+ result.must_equal [1, false]
340
394
  end
395
+
341
396
  it "has a working method #get_ref_info_for_vfunc_out_object_transfer_none" do
342
- skip "Needs vfunc setup"
397
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
398
+ "vfunc_out_object_transfer_none")
399
+ derived_instance = make_derived_instance do |info|
400
+ info.install_vfunc_implementation :vfunc_out_object_transfer_none, proc {|obj|
401
+ GIMarshallingTests::Object.new 42
402
+ }
403
+ end
404
+ result = derived_instance.get_ref_info_for_vfunc_out_object_transfer_none
405
+ result.must_equal [1, false]
343
406
  end
407
+
344
408
  it "has a working method #get_ref_info_for_vfunc_return_object_transfer_full" do
345
- skip "Needs vfunc setup"
409
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
410
+ "vfunc_return_object_transfer_full")
411
+ derived_instance = make_derived_instance do |info|
412
+ info.install_vfunc_implementation :vfunc_return_object_transfer_full, proc {|obj|
413
+ GIMarshallingTests::Object.new 42
414
+ }
415
+ end
416
+ result = derived_instance.get_ref_info_for_vfunc_return_object_transfer_full
417
+ result.must_equal [1, false]
346
418
  end
419
+
347
420
  it "has a working method #get_ref_info_for_vfunc_return_object_transfer_none" do
348
- skip "Needs vfunc setup"
421
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
422
+ "vfunc_return_object_transfer_none")
423
+ derived_instance = make_derived_instance do |info|
424
+ info.install_vfunc_implementation :vfunc_return_object_transfer_none, proc {|obj|
425
+ GIMarshallingTests::Object.new 42
426
+ }
427
+ end
428
+ result = derived_instance.get_ref_info_for_vfunc_return_object_transfer_none
429
+ result.must_equal [1, false]
349
430
  end
350
431
 
351
432
  it "has a working method #int8_in" do
@@ -356,8 +437,9 @@ describe GIMarshallingTests do
356
437
  derived_instance.int.must_equal 23
357
438
  end
358
439
 
440
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=727665
359
441
  it "has a working method #int8_out" do
360
- skip "Needs vfunc setup"
442
+ skip "Introspection data is not generated correctly"
361
443
  end
362
444
 
363
445
  it "has a working method #method" do
@@ -386,11 +468,27 @@ describe GIMarshallingTests do
386
468
  end
387
469
 
388
470
  it "has a working method #method_int8_arg_and_out_callee" do
389
- skip "Needs vfunc setup"
471
+ skip unless get_method_introspection_data("GIMarshallingTests", "Object",
472
+ "method_int8_arg_and_out_callee")
473
+ derived_instance = make_derived_instance do |info|
474
+ info.install_vfunc_implementation :method_int8_arg_and_out_callee, proc { |obj, arg|
475
+ 2 * arg
476
+ }
477
+ end
478
+ result = derived_instance.method_int8_arg_and_out_callee 32
479
+ result.must_equal 64
390
480
  end
391
481
 
392
482
  it "has a working method #method_int8_arg_and_out_caller" do
393
- skip "Needs vfunc setup"
483
+ skip unless get_method_introspection_data("GIMarshallingTests", "Object",
484
+ "method_int8_arg_and_out_caller")
485
+ derived_instance = make_derived_instance do |info|
486
+ info.install_vfunc_implementation :method_int8_arg_and_out_caller, proc { |obj, arg|
487
+ 2 * arg
488
+ }
489
+ end
490
+ result = derived_instance.method_int8_arg_and_out_caller 32
491
+ result.must_equal 64
394
492
  end
395
493
 
396
494
  it "has a working method #method_int8_in" do
@@ -418,7 +516,7 @@ describe GIMarshallingTests do
418
516
  end
419
517
 
420
518
  it "has a working method #method_variant_array_in" do
421
- skip "This function is only found in the header"
519
+ skip "This function is defined in the header but not implemented"
422
520
  end
423
521
 
424
522
  it "has a working method #method_with_default_implementation" do
@@ -438,15 +536,48 @@ describe GIMarshallingTests do
438
536
  end
439
537
 
440
538
  it "has a working method #vfunc_array_out_parameter" do
441
- skip "Needs vfunc setup"
539
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
540
+ "vfunc_array_out_parameter")
541
+ derived_instance = make_derived_instance do |info|
542
+ info.install_vfunc_implementation :vfunc_array_out_parameter, proc {|obj|
543
+ [1.1, 2.2, 3.3]
544
+ }
545
+ end
546
+ result = derived_instance.vfunc_array_out_parameter
547
+ arr = result.to_a
548
+ arr.length.must_equal 3
549
+ arr[0].must_be_close_to 1.1
550
+ arr[1].must_be_close_to 2.2
551
+ arr[2].must_be_close_to 3.3
442
552
  end
443
553
 
444
554
  it "has a working method #vfunc_caller_allocated_out_parameter" do
445
- skip "Needs vfunc setup"
555
+ skip unless get_vfunc_introspection_data("GIMarshallingTests", "Object",
556
+ "vfunc_caller_allocated_out_parameter")
557
+ derived_instance = make_derived_instance do |info|
558
+ info.install_vfunc_implementation :vfunc_caller_allocated_out_parameter, proc {|obj|
559
+ "Hello!"
560
+ }
561
+ end
562
+ result = derived_instance.vfunc_caller_allocated_out_parameter
563
+ result.get_value.must_equal "Hello!"
446
564
  end
447
565
 
448
566
  it "has a working method #vfunc_meth_with_error" do
449
- skip "Needs vfunc setup"
567
+ derived_instance = make_derived_instance do |info|
568
+ info.install_vfunc_implementation :vfunc_meth_with_err, proc {|object, x|
569
+ raise "This is not the answer!" unless x == 42
570
+ true
571
+ }
572
+ end
573
+ result = derived_instance.vfunc_meth_with_error 42
574
+ result.must_equal true
575
+
576
+ err = proc { derived_instance.vfunc_meth_with_error(21) }.
577
+ must_raise GirFFI::GLibError
578
+ err.message.must_equal "This is not the answer!"
579
+ err.domain.must_equal "gir_ffi"
580
+ err.code.must_equal 0
450
581
  end
451
582
 
452
583
  it "has a working method #vfunc_multiple_out_parameters" do
@@ -510,14 +641,30 @@ describe GIMarshallingTests do
510
641
 
511
642
  it "has a working method #vfunc_return_value_only" do
512
643
  derived_instance = make_derived_instance do |info|
513
- info.install_vfunc_implementation :vfunc_return_value_only, proc {|obj| 0xdeadbeef }
644
+ info.install_vfunc_implementation :vfunc_return_value_only, proc {|obj| 0x1234_5678 }
514
645
  end
515
646
  result = derived_instance.vfunc_return_value_only
516
- result.must_equal 0xdeadbeef
647
+ result.must_equal 0x1234_5678
517
648
  end
518
649
 
519
650
  it "has a working method #vfunc_with_callback" do
520
- skip "Needs vfunc setup"
651
+ skip unless get_method_introspection_data("GIMarshallingTests", "Object",
652
+ "vfunc_with_callback")
653
+
654
+ result = 1
655
+
656
+ derived_instance = make_derived_instance do |info|
657
+ info.install_vfunc_implementation :vfunc_with_callback, proc { |obj, callback, callback_data|
658
+ callback.call(42, callback_data)
659
+ }
660
+ end
661
+
662
+ derived_instance.vfunc_with_callback proc { |val, user_data| result = val + user_data }, 23
663
+
664
+ # The current implementation of the vfunc_with_callback method currently
665
+ # doesn't actually call the virtual function vfunc_with_callback.
666
+ result.must_equal 1
667
+ result.wont_equal 42 + 23
521
668
  end
522
669
 
523
670
  describe "its 'int' property" do
@@ -1413,7 +1560,7 @@ describe GIMarshallingTests do
1413
1560
  end
1414
1561
 
1415
1562
  it "has a working function #callback_return_value_only" do
1416
- result = GIMarshallingTests.callback_return_value_only lambda { 42 }
1563
+ result = GIMarshallingTests.callback_return_value_only proc { 42 }
1417
1564
  result.must_equal 42
1418
1565
  end
1419
1566
 
@@ -1595,10 +1742,15 @@ describe GIMarshallingTests do
1595
1742
  end
1596
1743
 
1597
1744
  it "has a working function #gbytes_full_return" do
1598
- skip "GBytes is not supported yet"
1745
+ skip unless get_introspection_data 'GIMarshallingTests', 'gbytes_full_return'
1746
+ res = GIMarshallingTests.gbytes_full_return
1747
+ res.to_a.must_equal [0, 49, 0xFF, 51]
1599
1748
  end
1749
+
1600
1750
  it "has a working function #gbytes_none_in" do
1601
- skip "GBytes is not supported yet"
1751
+ skip unless get_introspection_data 'GIMarshallingTests', 'gbytes_none_in'
1752
+ GIMarshallingTests.gbytes_none_in [0, 49, 0xFF, 51]
1753
+ pass
1602
1754
  end
1603
1755
 
1604
1756
  it "has a working function #gclosure_in" do
@@ -1637,8 +1789,10 @@ describe GIMarshallingTests do
1637
1789
  begin
1638
1790
  GIMarshallingTests.gerror
1639
1791
  flunk "Error should have been raised"
1640
- rescue RuntimeError => e
1792
+ rescue GirFFI::GLibError => e
1641
1793
  e.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE
1794
+ e.domain.must_equal GIMarshallingTests::CONSTANT_GERROR_DOMAIN
1795
+ e.code.must_equal GIMarshallingTests::CONSTANT_GERROR_CODE
1642
1796
  end
1643
1797
  end
1644
1798
 
@@ -1646,8 +1800,10 @@ describe GIMarshallingTests do
1646
1800
  begin
1647
1801
  GIMarshallingTests.gerror_array_in [1, 2, 3]
1648
1802
  flunk "Error should have been raised"
1649
- rescue RuntimeError => e
1803
+ rescue GirFFI::GLibError => e
1650
1804
  e.message.must_equal GIMarshallingTests::CONSTANT_GERROR_MESSAGE
1805
+ e.domain.must_equal GIMarshallingTests::CONSTANT_GERROR_DOMAIN
1806
+ e.code.must_equal GIMarshallingTests::CONSTANT_GERROR_CODE
1651
1807
  end
1652
1808
  end
1653
1809
 
@@ -1987,7 +2143,12 @@ describe GIMarshallingTests do
1987
2143
  end
1988
2144
 
1989
2145
  it "has a working function #gvalue_flat_array_round_trip" do
1990
- skip "Passing structs by-value is not supported yet"
2146
+ skip "Fails on JRuby" if RUBY_PLATFORM == 'java'
2147
+ result = GIMarshallingTests.gvalue_flat_array_round_trip 42, "42", true
2148
+ arr = result.to_a
2149
+ arr[0].get_value.must_equal 42
2150
+ arr[1].get_value.must_equal "42"
2151
+ arr[2].get_value.must_equal true
1991
2152
  end
1992
2153
 
1993
2154
  it "has a working function #gvalue_in" do
@@ -2353,6 +2514,7 @@ describe GIMarshallingTests do
2353
2514
  res.must_be_instance_of GIMarshallingTests::OverridesStruct
2354
2515
  end
2355
2516
 
2517
+ # See https://bugzilla.gnome.org/show_bug.cgi?id=728409
2356
2518
  it "has a working function #param_spec_in_bool" do
2357
2519
  skip "param_spec_in_bool tests the wrong type"
2358
2520
  ps = GObject.param_spec_boolean "mybool", "nick", "blurb", true, :readable
@@ -2506,7 +2668,13 @@ describe GIMarshallingTests do
2506
2668
  end
2507
2669
 
2508
2670
  it "has a working function #test_interface_test_int8_in" do
2509
- skip "Needs implementation of TestInterface"
2671
+ derived_klass.class_eval { include GIMarshallingTests::Interface }
2672
+ instance = make_derived_instance do |info|
2673
+ info.install_vfunc_implementation :test_int8_in, proc {|obj, in_| obj.int = in_ }
2674
+ end
2675
+ instance.int.must_equal 0
2676
+ GIMarshallingTests.test_interface_test_int8_in instance, 8
2677
+ instance.int.must_equal 8
2510
2678
  end
2511
2679
 
2512
2680
  it "has a working function #time_t_in" do