gir_ffi 0.8.6 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +18 -0
- data/README.md +3 -4
- data/lib/ffi-glib.rb +1 -0
- data/lib/ffi-glib/container_class_methods.rb +12 -0
- data/lib/ffi-glib/destroy_notify.rb +15 -0
- data/lib/ffi-glib/main_loop.rb +23 -4
- data/lib/ffi-gobject.rb +4 -2
- data/lib/ffi-gobject/object.rb +31 -16
- data/lib/ffi-gobject/object_class.rb +4 -0
- data/lib/ffi-gobject/value.rb +3 -3
- data/lib/ffi-gobject_introspection/i_flags_info.rb +0 -1
- data/lib/gir_ffi-base/gobject/lib.rb +10 -0
- data/lib/gir_ffi/arg_helper.rb +1 -22
- data/lib/gir_ffi/boxed_base.rb +1 -0
- data/lib/gir_ffi/builder.rb +7 -1
- data/lib/gir_ffi/builders/argument_builder.rb +21 -9
- data/lib/gir_ffi/builders/argument_builder_collection.rb +28 -9
- data/lib/gir_ffi/builders/base_argument_builder.rb +36 -12
- data/lib/gir_ffi/builders/base_method_builder.rb +1 -1
- data/lib/gir_ffi/builders/callback_argument_builder.rb +4 -0
- data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +3 -2
- data/lib/gir_ffi/builders/constructor_builder.rb +1 -1
- data/lib/gir_ffi/builders/enum_builder.rb +4 -4
- data/lib/gir_ffi/builders/error_argument_builder.rb +4 -0
- data/lib/gir_ffi/builders/field_builder.rb +23 -9
- data/lib/gir_ffi/builders/flags_builder.rb +28 -0
- data/lib/gir_ffi/builders/full_c_to_ruby_convertor.rb +18 -0
- data/lib/gir_ffi/builders/module_builder.rb +1 -0
- data/lib/gir_ffi/builders/null_argument_builder.rb +9 -1
- data/lib/gir_ffi/builders/object_builder.rb +7 -4
- data/lib/gir_ffi/builders/property_builder.rb +2 -2
- data/lib/gir_ffi/builders/return_value_builder.rb +4 -4
- data/lib/gir_ffi/builders/struct_builder.rb +10 -2
- data/lib/gir_ffi/builders/type_builder.rb +12 -9
- data/lib/gir_ffi/builders/unintrospectable_boxed_builder.rb +26 -0
- data/lib/gir_ffi/builders/user_defined_builder.rb +2 -2
- data/lib/gir_ffi/builders/with_layout.rb +1 -1
- data/lib/gir_ffi/callback_base.rb +13 -5
- data/lib/gir_ffi/core.rb +1 -0
- data/lib/gir_ffi/error_argument_info.rb +4 -0
- data/lib/gir_ffi/flags_base.rb +63 -0
- data/lib/gir_ffi/in_pointer.rb +1 -3
- data/lib/gir_ffi/info_ext/i_type_info.rb +6 -0
- data/lib/gir_ffi/object_base.rb +9 -1
- data/lib/gir_ffi/object_store.rb +26 -0
- data/lib/gir_ffi/unintrospectable_boxed_info.rb +31 -0
- data/lib/gir_ffi/unintrospectable_type_info.rb +5 -0
- data/lib/gir_ffi/user_defined_type_info.rb +19 -0
- data/lib/gir_ffi/version.rb +1 -1
- data/test/ffi-glib/destroy_notify_test.rb +13 -0
- data/test/ffi-glib/main_loop_test.rb +3 -3
- data/test/ffi-gobject/object_class_test.rb +8 -0
- data/test/ffi-gobject/object_test.rb +23 -5
- data/test/ffi-gobject/value_test.rb +19 -5
- data/test/ffi-gobject_test.rb +2 -2
- data/test/gir_ffi/builders/argument_builder_test.rb +12 -2
- data/test/gir_ffi/builders/constructor_builder_test.rb +4 -4
- data/test/gir_ffi/builders/function_builder_test.rb +46 -3
- data/test/gir_ffi/builders/object_builder_test.rb +25 -0
- data/test/gir_ffi/builders/property_builder_test.rb +4 -4
- data/test/gir_ffi/builders/struct_builder_test.rb +15 -13
- data/test/gir_ffi/builders/unintrospectable_boxed_builder_test.rb +33 -0
- data/test/gir_ffi/builders/unintrospectable_builder_test.rb +6 -0
- data/test/gir_ffi/builders/user_defined_builder_test.rb +7 -1
- data/test/gir_ffi/callback_base_test.rb +12 -2
- data/test/gir_ffi/object_base_test.rb +14 -0
- data/test/integration/callback_exceptions_test.rb +61 -0
- data/test/integration/generated_gimarshallingtests_test.rb +70 -70
- data/test/integration/generated_gio_test.rb +1 -1
- data/test/integration/generated_gobject_test.rb +1 -1
- data/test/integration/generated_gtop_test.rb +5 -1
- data/test/integration/generated_regress_test.rb +83 -102
- data/test/integration/generated_warnlib_test.rb +2 -2
- metadata +42 -4
@@ -73,11 +73,18 @@ describe GObject::Value do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
describe '#set_value' do
|
76
|
-
it 'handles char values' do
|
76
|
+
it 'handles signed char values' do
|
77
77
|
value = -83
|
78
78
|
gv = GObject::Value.for_gtype GObject::TYPE_CHAR
|
79
79
|
gv.set_value value
|
80
|
-
gv.
|
80
|
+
gv.get_schar.must_equal value
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'handles unsigned char values' do
|
84
|
+
value = 174
|
85
|
+
gv = GObject::Value.for_gtype GObject::TYPE_UCHAR
|
86
|
+
gv.set_value value
|
87
|
+
gv.get_uchar.must_equal value
|
81
88
|
end
|
82
89
|
|
83
90
|
it 'handles enum values presented as symbols' do
|
@@ -178,10 +185,17 @@ describe GObject::Value do
|
|
178
185
|
assert_equal true, result
|
179
186
|
end
|
180
187
|
|
181
|
-
it 'unwraps a char' do
|
182
|
-
value =
|
188
|
+
it 'unwraps a signed char' do
|
189
|
+
value = -42
|
183
190
|
gv = GObject::Value.for_gtype GObject::TYPE_CHAR
|
184
|
-
gv.
|
191
|
+
gv.set_schar value
|
192
|
+
gv.get_value.must_equal value
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'unwraps an unsigned char' do
|
196
|
+
value = 173
|
197
|
+
gv = GObject::Value.for_gtype GObject::TYPE_UCHAR
|
198
|
+
gv.set_uchar value
|
185
199
|
gv.get_value.must_equal value
|
186
200
|
end
|
187
201
|
|
data/test/ffi-gobject_test.rb
CHANGED
@@ -23,7 +23,7 @@ describe GObject do
|
|
23
23
|
callback = FFI::Function.new(:bool, argtypes) { |_a, _b, _c, _d| true }
|
24
24
|
::GObject::Lib.g_signal_connect_data s, 'incoming', callback, nil, nil, 0
|
25
25
|
rv = GObject.signal_emit s, 'incoming'
|
26
|
-
assert_equal true, rv
|
26
|
+
assert_equal true, rv
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'passes in extra arguments' do
|
@@ -95,7 +95,7 @@ describe GObject do
|
|
95
95
|
s = Gio::SocketService.new
|
96
96
|
GObject.signal_connect(s, 'incoming') { true }
|
97
97
|
rv = GObject.signal_emit s, 'incoming'
|
98
|
-
assert_equal true, rv
|
98
|
+
assert_equal true, rv
|
99
99
|
end
|
100
100
|
|
101
101
|
it 'requires a block' do
|
@@ -42,6 +42,10 @@ describe GirFFI::Builders::ArgumentBuilder do
|
|
42
42
|
builder.closure = false
|
43
43
|
end
|
44
44
|
|
45
|
+
it 'has the correct value for method_argument_name' do
|
46
|
+
builder.method_argument_name.must_equal arg_info.name
|
47
|
+
end
|
48
|
+
|
45
49
|
it 'has the correct value for #pre_conversion' do
|
46
50
|
builder.pre_conversion.must_equal ['_v1 = GirFFI::InPointer.from(:void, user_data)']
|
47
51
|
end
|
@@ -53,11 +57,17 @@ describe GirFFI::Builders::ArgumentBuilder do
|
|
53
57
|
|
54
58
|
describe 'when it is a closure' do
|
55
59
|
before do
|
56
|
-
|
60
|
+
callback = Object.new
|
61
|
+
allow(callback).to receive(:call_argument_name).and_return 'foo'
|
62
|
+
builder.closure = callback
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'has the correct value for method_argument_name' do
|
66
|
+
builder.method_argument_name.must_be_nil
|
57
67
|
end
|
58
68
|
|
59
69
|
it 'has the correct value for #pre_conversion' do
|
60
|
-
builder.pre_conversion.must_equal ['_v1 = GirFFI::InPointer.from_closure_data(
|
70
|
+
builder.pre_conversion.must_equal ['_v1 = GirFFI::InPointer.from_closure_data(foo.object_id)']
|
61
71
|
end
|
62
72
|
|
63
73
|
it 'has the correct value for #post_conversion' do
|
@@ -9,9 +9,9 @@ describe GirFFI::Builders::ConstructorBuilder do
|
|
9
9
|
let(:function_info) { get_method_introspection_data 'Regress', 'TestObj', 'new' }
|
10
10
|
it 'builds a constructor' do
|
11
11
|
code.must_equal <<-CODE.reset_indentation
|
12
|
-
def self.new(*args)
|
12
|
+
def self.new(*args, &block)
|
13
13
|
obj = allocate
|
14
|
-
obj.__send__ :initialize, *args
|
14
|
+
obj.__send__ :initialize, *args, &block
|
15
15
|
obj
|
16
16
|
end
|
17
17
|
CODE
|
@@ -22,10 +22,10 @@ describe GirFFI::Builders::ConstructorBuilder do
|
|
22
22
|
let(:function_info) { get_method_introspection_data 'Regress', 'TestObj', 'new_from_file' }
|
23
23
|
it 'builds a custom constructor' do
|
24
24
|
code.must_equal <<-CODE.reset_indentation
|
25
|
-
def self.new_from_file(*args)
|
25
|
+
def self.new_from_file(*args, &block)
|
26
26
|
raise NoMethodError unless self == Regress::TestObj
|
27
27
|
obj = allocate
|
28
|
-
obj.__send__ :initialize_from_file, *args
|
28
|
+
obj.__send__ :initialize_from_file, *args, &block
|
29
29
|
obj
|
30
30
|
end
|
31
31
|
CODE
|
@@ -39,10 +39,10 @@ describe GirFFI::Builders::FunctionBuilder do
|
|
39
39
|
let(:function_info) { get_introspection_data 'Regress', 'test_callback_destroy_notify' }
|
40
40
|
it 'builds a correct definition' do
|
41
41
|
code.must_equal <<-CODE.reset_indentation
|
42
|
-
def self.test_callback_destroy_notify(callback
|
42
|
+
def self.test_callback_destroy_notify(&callback)
|
43
43
|
_v1 = Regress::TestCallbackUserData.from(callback)
|
44
|
-
_v2 = GirFFI::InPointer.from_closure_data(
|
45
|
-
_v3 = GLib::DestroyNotify.
|
44
|
+
_v2 = GirFFI::InPointer.from_closure_data(_v1.object_id)
|
45
|
+
_v3 = GLib::DestroyNotify.default
|
46
46
|
_v4 = Regress::Lib.regress_test_callback_destroy_notify _v1, _v2, _v3
|
47
47
|
return _v4
|
48
48
|
end
|
@@ -62,6 +62,49 @@ describe GirFFI::Builders::FunctionBuilder do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
describe 'for functions that return a GValue' do
|
66
|
+
let(:function_info) { get_introspection_data 'GIMarshallingTests', 'gvalue_return' }
|
67
|
+
it 'creates a call to #get_value' do
|
68
|
+
code.must_equal <<-CODE.reset_indentation
|
69
|
+
def self.gvalue_return
|
70
|
+
_v1 = GIMarshallingTests::Lib.gi_marshalling_tests_gvalue_return
|
71
|
+
_v2 = GObject::Value.wrap(_v1).get_value
|
72
|
+
return _v2
|
73
|
+
end
|
74
|
+
CODE
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'for functions that have a GValue out argument' do
|
79
|
+
let(:function_info) { get_introspection_data 'GIMarshallingTests', 'gvalue_out' }
|
80
|
+
it 'creates a call to #get_value' do
|
81
|
+
code.must_equal <<-CODE.reset_indentation
|
82
|
+
def self.gvalue_out
|
83
|
+
_v1 = GirFFI::InOutPointer.for [:pointer, GObject::Value]
|
84
|
+
GIMarshallingTests::Lib.gi_marshalling_tests_gvalue_out _v1
|
85
|
+
_v2 = GObject::Value.wrap(_v1.to_value).get_value
|
86
|
+
return _v2
|
87
|
+
end
|
88
|
+
CODE
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'for functions that have a caller-allocated GValue out argument' do
|
93
|
+
let(:function_info) { get_introspection_data 'GIMarshallingTests', 'gvalue_out_caller_allocates' }
|
94
|
+
|
95
|
+
it 'creates a call to #get_value' do
|
96
|
+
skip unless function_info
|
97
|
+
code.must_equal <<-CODE.reset_indentation
|
98
|
+
def self.gvalue_out_caller_allocates
|
99
|
+
_v1 = GObject::Value.new
|
100
|
+
GIMarshallingTests::Lib.gi_marshalling_tests_gvalue_out_caller_allocates _v1
|
101
|
+
_v2 = _v1.get_value
|
102
|
+
return _v2
|
103
|
+
end
|
104
|
+
CODE
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
65
108
|
describe 'for functions with a nullable input array' do
|
66
109
|
let(:function_info) { get_introspection_data 'Regress', 'test_array_int_null_in' }
|
67
110
|
it 'builds correct definition' do
|
@@ -60,5 +60,30 @@ describe GirFFI::Builders::ObjectBuilder do
|
|
60
60
|
it 'returns the class struct type' do
|
61
61
|
obj_builder.object_class_struct.must_equal Regress::TestObjClass
|
62
62
|
end
|
63
|
+
|
64
|
+
it 'returns the parent struct type for classes without their own struct' do
|
65
|
+
binding_info = get_introspection_data 'GObject', 'Binding'
|
66
|
+
builder = GirFFI::Builders::ObjectBuilder.new binding_info
|
67
|
+
builder.object_class_struct.must_equal GObject::ObjectClass
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: Improve this spec to use less mocking
|
72
|
+
describe 'for a struct without defined fields' do
|
73
|
+
it 'uses a single field of the parent struct type as the default layout' do
|
74
|
+
@gir = GObjectIntrospection::IRepository.default
|
75
|
+
@gir.require 'GObject', nil
|
76
|
+
|
77
|
+
allow(info = Object.new).to receive(:parent).and_return @gir.find_by_name 'GObject', 'Object'
|
78
|
+
allow(info).to receive(:fields).and_return []
|
79
|
+
allow(info).to receive(:info_type).and_return :object
|
80
|
+
allow(info).to receive(:safe_name).and_return 'Bar'
|
81
|
+
allow(info).to receive(:namespace).and_return 'Foo'
|
82
|
+
|
83
|
+
@classbuilder = GirFFI::Builders::ObjectBuilder.new info
|
84
|
+
|
85
|
+
spec = @classbuilder.send :layout_specification
|
86
|
+
assert_equal [:parent, GObject::Object::Struct, 0], spec
|
87
|
+
end
|
63
88
|
end
|
64
89
|
end
|
@@ -8,7 +8,7 @@ describe GirFFI::Builders::PropertyBuilder do
|
|
8
8
|
it 'generates the correct getter definition' do
|
9
9
|
expected = <<-CODE.reset_indentation
|
10
10
|
def list
|
11
|
-
_v1 = get_property("list")
|
11
|
+
_v1 = get_property("list")
|
12
12
|
_v2 = GLib::List.wrap(:utf8, _v1)
|
13
13
|
_v2
|
14
14
|
end
|
@@ -34,7 +34,7 @@ describe GirFFI::Builders::PropertyBuilder do
|
|
34
34
|
it 'generates the correct getter definition' do
|
35
35
|
expected = <<-CODE.reset_indentation
|
36
36
|
def hash_table
|
37
|
-
_v1 = get_property("hash-table")
|
37
|
+
_v1 = get_property("hash-table")
|
38
38
|
_v2 = GLib::HashTable.wrap([:utf8, :gint8], _v1)
|
39
39
|
_v2
|
40
40
|
end
|
@@ -68,7 +68,7 @@ describe GirFFI::Builders::PropertyBuilder do
|
|
68
68
|
it 'generates the correct getter definition' do
|
69
69
|
expected = <<-CODE.reset_indentation
|
70
70
|
def some_strv
|
71
|
-
get_property("some-strv")
|
71
|
+
get_property("some-strv")
|
72
72
|
end
|
73
73
|
CODE
|
74
74
|
|
@@ -92,7 +92,7 @@ describe GirFFI::Builders::PropertyBuilder do
|
|
92
92
|
it 'generates the correct getter definition' do
|
93
93
|
expected = <<-CODE.reset_indentation
|
94
94
|
def string
|
95
|
-
get_property("string")
|
95
|
+
get_property("string")
|
96
96
|
end
|
97
97
|
CODE
|
98
98
|
|
@@ -46,21 +46,23 @@ describe GirFFI::Builders::StructBuilder do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
describe '
|
50
|
-
it '
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
allow(info).to receive(:fields).and_return []
|
56
|
-
allow(info).to receive(:info_type).and_return :object
|
57
|
-
allow(info).to receive(:safe_name).and_return 'Bar'
|
58
|
-
allow(info).to receive(:namespace).and_return 'Foo'
|
49
|
+
describe '#superclass' do
|
50
|
+
it 'returns StructBase for a normal struct' do
|
51
|
+
info = get_introspection_data 'Regress', 'TestStructA'
|
52
|
+
builder = GirFFI::Builders::StructBuilder.new info
|
53
|
+
builder.superclass.must_equal GirFFI::StructBase
|
54
|
+
end
|
59
55
|
|
60
|
-
|
56
|
+
it 'returns the GObject parent class for a type class' do
|
57
|
+
info = get_introspection_data 'GIMarshallingTests', 'SubSubObjectClass'
|
58
|
+
builder = GirFFI::Builders::StructBuilder.new info
|
59
|
+
builder.superclass.must_equal GIMarshallingTests::SubObjectClass
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
it 'returns ObjectClass for InitiallyUnownedClass' do
|
63
|
+
info = get_introspection_data 'GObject', 'InitiallyUnownedClass'
|
64
|
+
builder = GirFFI::Builders::StructBuilder.new info
|
65
|
+
builder.superclass.must_equal GObject::ObjectClass
|
64
66
|
end
|
65
67
|
end
|
66
68
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'gir_ffi_test_helper'
|
2
|
+
|
3
|
+
GirFFI.setup :GIMarshallingTests
|
4
|
+
|
5
|
+
describe GirFFI::Builders::UnintrospectableBoxedBuilder do
|
6
|
+
let(:instance) { GIMarshallingTests::PropertiesObject.new }
|
7
|
+
let(:property) { instance.object_class.find_property 'some-boxed-glist' }
|
8
|
+
let(:gtype) { property.value_type }
|
9
|
+
let(:info) { GirFFI::UnintrospectableBoxedInfo.new(gtype) }
|
10
|
+
let(:bldr) { GirFFI::Builders::UnintrospectableBoxedBuilder.new(info) }
|
11
|
+
let(:klass) { bldr.build_class }
|
12
|
+
|
13
|
+
before do
|
14
|
+
skip unless get_property_introspection_data('GIMarshallingTests',
|
15
|
+
'PropertiesObject',
|
16
|
+
'some-boxed-glist')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'builds a class' do
|
20
|
+
klass.must_be_instance_of Class
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'builds a class derived from GirFFI::BoxedBase' do
|
24
|
+
klass.ancestors.must_include GirFFI::BoxedBase
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns the same class when built again' do
|
28
|
+
other_bldr = GirFFI::Builders::UnintrospectableBoxedBuilder.new(info)
|
29
|
+
other_klass = other_bldr.build_class
|
30
|
+
|
31
|
+
other_klass.must_equal klass
|
32
|
+
end
|
33
|
+
end
|
@@ -52,5 +52,11 @@ describe GirFFI::Builders::UnintrospectableBuilder do
|
|
52
52
|
signal.name.must_equal 'notify'
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
describe '#object_class_struct' do
|
57
|
+
it 'returns the parent class struct' do
|
58
|
+
@bldr.object_class_struct.must_equal GObject::ObjectClass
|
59
|
+
end
|
60
|
+
end
|
55
61
|
end
|
56
62
|
end
|
@@ -44,7 +44,7 @@ describe GirFFI::Builders::UserDefinedBuilder do
|
|
44
44
|
it 'makes the property retrievable using #get_property' do
|
45
45
|
obj = klass.new
|
46
46
|
obj.foo = 13
|
47
|
-
obj.get_property('foo').
|
47
|
+
obj.get_property('foo').must_equal 13
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'makes the property settable using #set_property' do
|
@@ -121,4 +121,10 @@ describe GirFFI::Builders::UserDefinedBuilder do
|
|
121
121
|
GObject.type_from_instance(obj).must_equal klass.gtype
|
122
122
|
end
|
123
123
|
end
|
124
|
+
|
125
|
+
describe '#object_class_struct' do
|
126
|
+
it 'returns the parent class struct' do
|
127
|
+
builder.object_class_struct.must_equal GIMarshallingTests::ObjectClass
|
128
|
+
end
|
129
|
+
end
|
124
130
|
end
|
@@ -3,8 +3,18 @@ require 'gir_ffi_test_helper'
|
|
3
3
|
describe GirFFI::CallbackBase do
|
4
4
|
describe '.store_callback' do
|
5
5
|
it 'stores the passed in proc in CALLBACKS' do
|
6
|
-
|
7
|
-
GirFFI::CallbackBase
|
6
|
+
dummy_proc = 'some-callback'
|
7
|
+
GirFFI::CallbackBase.store_callback dummy_proc
|
8
|
+
GirFFI::CallbackBase::CALLBACKS[dummy_proc.object_id].must_equal dummy_proc
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.drop_callback' do
|
13
|
+
it 'removes the corresponding proc from CALLBACKS' do
|
14
|
+
dummy_proc = 'some-callback'
|
15
|
+
GirFFI::CallbackBase.store_callback dummy_proc
|
16
|
+
GirFFI::CallbackBase.drop_callback dummy_proc.object_id
|
17
|
+
GirFFI::CallbackBase::CALLBACKS[dummy_proc.object_id].must_be_nil
|
8
18
|
end
|
9
19
|
end
|
10
20
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'gir_ffi_test_helper'
|
2
2
|
|
3
|
+
GirFFI.setup :Regress
|
4
|
+
|
3
5
|
describe GirFFI::ObjectBase do
|
4
6
|
let(:derived_class) { Class.new GirFFI::ObjectBase }
|
5
7
|
|
@@ -15,4 +17,16 @@ describe GirFFI::ObjectBase do
|
|
15
17
|
derived_class.to_ffi_type.must_equal derived_class
|
16
18
|
end
|
17
19
|
end
|
20
|
+
|
21
|
+
describe '.object_class' do
|
22
|
+
it 'returns an object of the class struct type' do
|
23
|
+
Regress::TestObj.object_class.must_be_instance_of Regress::TestObjClass
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'caches its result' do
|
27
|
+
first = Regress::TestObj.object_class
|
28
|
+
second = Regress::TestObj.object_class
|
29
|
+
second.must_be :eql?, first
|
30
|
+
end
|
31
|
+
end
|
18
32
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'gir_ffi_test_helper'
|
2
|
+
|
3
|
+
GirFFI.setup :Regress
|
4
|
+
|
5
|
+
class CallbackTestException < RuntimeError; end
|
6
|
+
|
7
|
+
describe 'An exception in a callback' do
|
8
|
+
describe 'for signals' do
|
9
|
+
let(:object) { Regress::TestSubObj.new }
|
10
|
+
|
11
|
+
before do
|
12
|
+
object.signal_connect 'test' do
|
13
|
+
raise CallbackTestException, 'Boom'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'when the signal is emitted synchronously' do
|
18
|
+
it 'raises an error' do
|
19
|
+
proc { GObject.signal_emit object, 'test' }.must_raise CallbackTestException
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'when the signal is emitted during an event loop' do
|
24
|
+
it 'causes loop run to be terminated with an exception' do
|
25
|
+
main_loop = GLib::MainLoop.new nil, false
|
26
|
+
|
27
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 1 do
|
28
|
+
GObject.signal_emit object, 'test'
|
29
|
+
false
|
30
|
+
end
|
31
|
+
# Guard against runaway loop
|
32
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 500 do
|
33
|
+
main_loop.quit
|
34
|
+
end
|
35
|
+
proc do
|
36
|
+
main_loop.run
|
37
|
+
end.must_raise CallbackTestException
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'for other callbacks' do
|
43
|
+
describe 'when the callback occurs during an event loop' do
|
44
|
+
it 'causes loop run to be terminated with an exception' do
|
45
|
+
main_loop = GLib::MainLoop.new nil, false
|
46
|
+
|
47
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 1 do
|
48
|
+
raise CallbackTestException, 'Boom'
|
49
|
+
end
|
50
|
+
# Guard against runaway loop
|
51
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 500 do
|
52
|
+
main_loop.quit
|
53
|
+
end
|
54
|
+
|
55
|
+
proc do
|
56
|
+
main_loop.run
|
57
|
+
end.must_raise CallbackTestException
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|