gir_ffi 0.0.6 → 0.0.7
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.
- data/History.txt +12 -0
- data/TODO.rdoc +10 -0
- data/examples/04_webkit.rb +16 -0
- data/lib/gir_ffi/arg_helper.rb +130 -38
- data/lib/gir_ffi/builder/argument.rb +552 -0
- data/lib/gir_ffi/{class_builder.rb → builder/class.rb} +89 -67
- data/lib/gir_ffi/{function_definition_builder.rb → builder/function.rb} +10 -10
- data/lib/gir_ffi/{module_builder.rb → builder/module.rb} +17 -16
- data/lib/gir_ffi/builder.rb +33 -28
- data/lib/gir_ffi/class_base.rb +7 -2
- data/lib/gir_ffi/i_base_info.rb +8 -0
- data/lib/gir_ffi/i_repository.rb +6 -0
- data/lib/gir_ffi/i_struct_info.rb +5 -1
- data/lib/gir_ffi/lib.rb +2 -0
- data/lib/gir_ffi/overrides/glib.rb +30 -0
- data/lib/gir_ffi/overrides/gobject.rb +143 -26
- data/tasks/test.rake +14 -0
- data/test/arg_helper_test.rb +19 -3
- data/test/builder_test.rb +85 -73
- data/test/class_builder_test.rb +15 -11
- data/test/function_definition_builder_test.rb +32 -49
- data/test/g_object_overrides_test.rb +103 -48
- data/test/{generated_everything_test.rb → generated_regress_test.rb} +229 -167
- data/test/i_object_info_test.rb +2 -2
- data/test/i_repository_test.rb +2 -2
- data/test/lib/Makefile.am +30 -0
- data/test/lib/autogen.sh +87 -0
- data/test/lib/configure.ac +30 -0
- data/test/lib/m4/jhflags.m4 +21 -0
- data/test/module_builder_test.rb +10 -10
- data/test/test_helper.rb +14 -10
- metadata +22 -12
- data/lib/gir_ffi/argument_builder.rb +0 -382
@@ -2,8 +2,77 @@ module GirFFI
|
|
2
2
|
module Overrides
|
3
3
|
module GObject
|
4
4
|
|
5
|
-
def self.included
|
5
|
+
def self.included base
|
6
6
|
base.extend ClassMethods
|
7
|
+
extend_classes(base)
|
8
|
+
attach_non_introspectable_functions(base)
|
9
|
+
build_extra_classes(base)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.extend_classes base
|
13
|
+
base::InitiallyUnowned.extend InitiallyUnownedClassMethods
|
14
|
+
base::Value.class_eval {
|
15
|
+
include ValueInstanceMethods
|
16
|
+
extend ValueClassMethods
|
17
|
+
}
|
18
|
+
base::Closure.class_eval {
|
19
|
+
include ClosureInstanceMethods
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.attach_non_introspectable_functions base
|
24
|
+
base::Lib.attach_function :g_signal_connect_data,
|
25
|
+
[:pointer, :string, base::Callback, :pointer, base::ClosureNotify,
|
26
|
+
base::ConnectFlags],
|
27
|
+
:ulong
|
28
|
+
base::Lib.attach_function :g_closure_set_marshal,
|
29
|
+
[:pointer, base::ClosureMarshal], :void
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.build_extra_classes base
|
33
|
+
klass = Class.new(base::Closure) do
|
34
|
+
const_set :BLOCK_STORE, {}
|
35
|
+
|
36
|
+
const_set :Struct, Class.new(FFI::Struct) {
|
37
|
+
layout :parent, base::Closure::Struct, 0,
|
38
|
+
:blockhash, :int64
|
39
|
+
}
|
40
|
+
|
41
|
+
def self.new &block
|
42
|
+
raise ArgumentError unless block_given?
|
43
|
+
wrap(new_simple(self::Struct.size, nil).to_ptr).tap do |it|
|
44
|
+
# XXX: Check that this methods is fool-proof!
|
45
|
+
h = block.hash
|
46
|
+
self::BLOCK_STORE[h] = block
|
47
|
+
it[:blockhash] = h
|
48
|
+
it.set_marshal Proc.new {|*args| marshaller(*args)}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.marshaller(closure, return_value, n_param_values,
|
53
|
+
param_values, invocation_hint, marshal_data)
|
54
|
+
rclosure = self.wrap(closure.to_ptr)
|
55
|
+
|
56
|
+
args = []
|
57
|
+
n_param_values.times {|i|
|
58
|
+
gv = ::GObject::Value.wrap(param_values.to_ptr +
|
59
|
+
i * ::GObject::Value::Struct.size)
|
60
|
+
args << gv.ruby_value
|
61
|
+
}
|
62
|
+
|
63
|
+
r = rclosure.invoke_block(*args)
|
64
|
+
return_value.set_ruby_value r unless return_value.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
def block
|
68
|
+
self.class::BLOCK_STORE[self[:blockhash]]
|
69
|
+
end
|
70
|
+
|
71
|
+
def invoke_block *args
|
72
|
+
block.call(*args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
base.const_set :RubyClosure, klass
|
7
76
|
end
|
8
77
|
|
9
78
|
module ClassMethods
|
@@ -18,29 +87,6 @@ module GirFFI
|
|
18
87
|
type_from_instance_pointer instance.to_ptr
|
19
88
|
end
|
20
89
|
|
21
|
-
def wrap_in_g_value val
|
22
|
-
gvalue = ::GObject::Value.new
|
23
|
-
case val
|
24
|
-
when true, false
|
25
|
-
gvalue.init ::GObject.type_from_name("gboolean")
|
26
|
-
gvalue.set_boolean val
|
27
|
-
else
|
28
|
-
nil
|
29
|
-
end
|
30
|
-
gvalue
|
31
|
-
end
|
32
|
-
|
33
|
-
def unwrap_g_value gvalue
|
34
|
-
gtype = gvalue[:g_type]
|
35
|
-
gtypename = ::GObject.type_name gtype
|
36
|
-
case gtypename
|
37
|
-
when "gboolean"
|
38
|
-
gvalue.get_boolean
|
39
|
-
else
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
90
|
def signal_emit object, signal, *args
|
45
91
|
type = type_from_instance object
|
46
92
|
id = signal_lookup signal, type
|
@@ -64,12 +110,16 @@ module GirFFI
|
|
64
110
|
|
65
111
|
rettype = GirFFI::Builder.itypeinfo_to_ffitype sig.return_type
|
66
112
|
|
113
|
+
# FIXME: Why are these all pointers?
|
67
114
|
argtypes = [:pointer] + sig.args.map {|arg| :pointer} + [:pointer]
|
68
115
|
|
69
116
|
callback = FFI::Function.new rettype, argtypes,
|
70
117
|
&(Helper.signal_callback_args(sig, object.class, &block))
|
118
|
+
::GObject::Lib::CALLBACKS << callback
|
119
|
+
|
120
|
+
data_ptr = GirFFI::ArgHelper.object_to_inptr data
|
71
121
|
|
72
|
-
|
122
|
+
::GObject::Lib.g_signal_connect_data object, signal, callback, data_ptr, nil, 0
|
73
123
|
end
|
74
124
|
end
|
75
125
|
|
@@ -150,7 +200,7 @@ module GirFFI
|
|
150
200
|
arg = args.shift
|
151
201
|
if info.type.tag == :interface
|
152
202
|
iface = info.type.interface
|
153
|
-
kls = GirFFI::Builder.build_class
|
203
|
+
kls = GirFFI::Builder.build_class iface
|
154
204
|
result << kls.wrap(arg)
|
155
205
|
else
|
156
206
|
result << arg
|
@@ -174,6 +224,73 @@ module GirFFI
|
|
174
224
|
end
|
175
225
|
end
|
176
226
|
|
227
|
+
module InitiallyUnownedClassMethods
|
228
|
+
def constructor_wrap ptr
|
229
|
+
super.tap {|obj| GirFFI::GObject.object_ref_sink obj}
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
module ValueClassMethods
|
234
|
+
def wrap_ruby_value val
|
235
|
+
self.new.set_ruby_value val
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
module ValueInstanceMethods
|
240
|
+
def set_ruby_value val
|
241
|
+
if current_gtype == 0
|
242
|
+
init_for_ruby_value val
|
243
|
+
end
|
244
|
+
|
245
|
+
case current_gtype_name
|
246
|
+
when "gboolean"
|
247
|
+
set_boolean val
|
248
|
+
when "gint"
|
249
|
+
set_int val
|
250
|
+
else
|
251
|
+
nil
|
252
|
+
end
|
253
|
+
self
|
254
|
+
end
|
255
|
+
|
256
|
+
def init_for_ruby_value val
|
257
|
+
case val
|
258
|
+
when true, false
|
259
|
+
init ::GObject.type_from_name("gboolean")
|
260
|
+
when Integer
|
261
|
+
init ::GObject.type_from_name("gint")
|
262
|
+
end
|
263
|
+
self
|
264
|
+
end
|
265
|
+
|
266
|
+
def current_gtype
|
267
|
+
self[:g_type]
|
268
|
+
end
|
269
|
+
|
270
|
+
def current_gtype_name
|
271
|
+
::GObject.type_name current_gtype
|
272
|
+
end
|
273
|
+
|
274
|
+
def ruby_value
|
275
|
+
case current_gtype_name
|
276
|
+
when "gboolean"
|
277
|
+
get_boolean
|
278
|
+
when "gint"
|
279
|
+
get_int
|
280
|
+
else
|
281
|
+
nil
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
module ClosureInstanceMethods
|
287
|
+
def set_marshal marshal
|
288
|
+
_v1 = GirFFI::ArgHelper.wrap_in_callback_args_mapper(
|
289
|
+
"GObject", "ClosureMarshal", marshal)
|
290
|
+
::GObject::Lib::CALLBACKS << _v1
|
291
|
+
::GObject::Lib.g_closure_set_marshal self, _v1
|
292
|
+
end
|
293
|
+
end
|
177
294
|
end
|
178
295
|
end
|
179
296
|
end
|
data/tasks/test.rake
CHANGED
@@ -8,6 +8,20 @@ namespace :test do
|
|
8
8
|
t.ruby_opts += ["-w"]
|
9
9
|
end
|
10
10
|
|
11
|
+
desc 'Build Regress test library and typelib'
|
12
|
+
task :lib => "test/lib/Makefile" do
|
13
|
+
sh %{cd test/lib && make}
|
14
|
+
end
|
15
|
+
|
16
|
+
task :run => :lib
|
17
|
+
end
|
18
|
+
|
19
|
+
file "test/lib/Makefile" => "test/lib/configure" do
|
20
|
+
sh %{cd test/lib && ./configure}
|
21
|
+
end
|
22
|
+
|
23
|
+
file "test/lib/configure" do
|
24
|
+
sh %{cd test/lib && NOCONFIGURE=1 ./autogen.sh}
|
11
25
|
end
|
12
26
|
|
13
27
|
desc 'Alias to test:run'
|
data/test/arg_helper_test.rb
CHANGED
@@ -120,17 +120,33 @@ class ArgHelperTest < Test::Unit::TestCase
|
|
120
120
|
|
121
121
|
context "The object_pointer_to_object method" do
|
122
122
|
setup do
|
123
|
-
GirFFI.setup :
|
124
|
-
@o =
|
123
|
+
GirFFI.setup :Regress
|
124
|
+
@o = Regress::TestSubObj.new
|
125
125
|
@o2 = GirFFI::ArgHelper.object_pointer_to_object @o.to_ptr
|
126
126
|
end
|
127
127
|
|
128
128
|
should "return an object of the correct class" do
|
129
|
-
assert_instance_of
|
129
|
+
assert_instance_of Regress::TestSubObj, @o2
|
130
130
|
end
|
131
131
|
|
132
132
|
should "return an object pointing to the original struct" do
|
133
133
|
assert_equal @o.to_ptr, @o2.to_ptr
|
134
134
|
end
|
135
135
|
end
|
136
|
+
|
137
|
+
context "The map_single_callback_arg method" do
|
138
|
+
should "correctly map a :struct type" do
|
139
|
+
GirFFI.setup :GObject
|
140
|
+
|
141
|
+
cl = GObject::Closure.new_simple GObject::Closure::Struct.size, nil
|
142
|
+
|
143
|
+
cinfo = GirFFI::IRepository.default.find_by_name 'GObject', 'ClosureMarshal'
|
144
|
+
ainfo = cinfo.args[0]
|
145
|
+
|
146
|
+
r = GirFFI::ArgHelper.map_single_callback_arg cl.to_ptr, ainfo
|
147
|
+
|
148
|
+
assert_instance_of GObject::Closure, r
|
149
|
+
assert_equal r.to_ptr, cl.to_ptr
|
150
|
+
end
|
151
|
+
end
|
136
152
|
end
|
data/test/builder_test.rb
CHANGED
@@ -2,15 +2,18 @@ require File.expand_path('test_helper.rb', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
class BuilderTest < Test::Unit::TestCase
|
4
4
|
context "The GirFFI::Builder module" do
|
5
|
+
setup do
|
6
|
+
@gir = GirFFI::IRepository.default
|
7
|
+
end
|
8
|
+
|
5
9
|
context "building GObject::Object" do
|
6
10
|
setup do
|
7
11
|
cleanup_module :GObject
|
8
|
-
GirFFI::Builder.build_class 'GObject', 'Object'
|
12
|
+
GirFFI::Builder.build_class @gir.find_by_name('GObject', 'Object')
|
9
13
|
end
|
10
14
|
|
11
15
|
should "create a Lib module in the parent namespace ready to attach functions from gobject-2.0" do
|
12
|
-
|
13
|
-
expected = gir.shared_library('GObject')
|
16
|
+
expected = @gir.shared_library('GObject')
|
14
17
|
assert_equal [expected], GObject::Lib.ffi_libraries.map(&:name)
|
15
18
|
end
|
16
19
|
|
@@ -20,7 +23,7 @@ class BuilderTest < Test::Unit::TestCase
|
|
20
23
|
|
21
24
|
should "not replace existing classes" do
|
22
25
|
oldclass = GObject::Object
|
23
|
-
GirFFI::Builder.build_class 'GObject', 'Object'
|
26
|
+
GirFFI::Builder.build_class @gir.find_by_name('GObject', 'Object')
|
24
27
|
assert_equal oldclass, GObject::Object
|
25
28
|
end
|
26
29
|
end
|
@@ -29,7 +32,7 @@ class BuilderTest < Test::Unit::TestCase
|
|
29
32
|
setup do
|
30
33
|
cleanup_module :Gtk
|
31
34
|
cleanup_module :GObject
|
32
|
-
GirFFI::Builder.build_class 'Gtk', 'Window'
|
35
|
+
GirFFI::Builder.build_class @gir.find_by_name('Gtk', 'Window')
|
33
36
|
end
|
34
37
|
|
35
38
|
should "build Gtk namespace" do
|
@@ -39,22 +42,21 @@ class BuilderTest < Test::Unit::TestCase
|
|
39
42
|
|
40
43
|
should "build parent classes also" do
|
41
44
|
assert Gtk.const_defined? :Widget
|
42
|
-
assert Gtk.const_defined? :Object
|
43
45
|
assert Object.const_defined? :GObject
|
44
46
|
assert GObject.const_defined? :InitiallyUnowned
|
45
47
|
assert GObject.const_defined? :Object
|
46
48
|
end
|
47
49
|
|
48
|
-
should "set up
|
50
|
+
should "set up inheritance chain" do
|
51
|
+
ancestors = Gtk::Window.ancestors
|
49
52
|
assert_equal [
|
50
53
|
Gtk::Window,
|
51
54
|
Gtk::Bin,
|
52
55
|
Gtk::Container,
|
53
|
-
Gtk::Widget
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
], Gtk::Window.ancestors[0..6]
|
56
|
+
Gtk::Widget
|
57
|
+
], ancestors[0..3]
|
58
|
+
assert ancestors.include? GObject::InitiallyUnowned
|
59
|
+
assert ancestors.include? GObject::Object
|
58
60
|
end
|
59
61
|
|
60
62
|
should "create a Gtk::Window#to_ptr method" do
|
@@ -66,6 +68,17 @@ class BuilderTest < Test::Unit::TestCase
|
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
71
|
+
context "built Gtk::Widget" do
|
72
|
+
setup do
|
73
|
+
cleanup_module :Gtk
|
74
|
+
GirFFI::Builder.build_class @gir.find_by_name('Gtk', 'Widget')
|
75
|
+
end
|
76
|
+
|
77
|
+
should "not have regular #new as a constructor" do
|
78
|
+
assert_raises(NoMethodError) { Gtk::Widget.new }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
69
82
|
context "building Gtk" do
|
70
83
|
setup do
|
71
84
|
cleanup_module :Gtk
|
@@ -74,8 +87,7 @@ class BuilderTest < Test::Unit::TestCase
|
|
74
87
|
|
75
88
|
should "create a Lib module ready to attach functions from gtk-x11-2.0" do
|
76
89
|
# The Gtk module has more than one library on my current machine.
|
77
|
-
|
78
|
-
expected = (gir.shared_library 'Gtk').split(',')
|
90
|
+
expected = (@gir.shared_library 'Gtk').split(',')
|
79
91
|
assert_equal expected.sort, Gtk::Lib.ffi_libraries.map(&:name).sort
|
80
92
|
end
|
81
93
|
|
@@ -102,9 +114,8 @@ class BuilderTest < Test::Unit::TestCase
|
|
102
114
|
end
|
103
115
|
|
104
116
|
should "have correct introspection data" do
|
105
|
-
gir
|
106
|
-
gir.
|
107
|
-
go2 = gir.find_by_name "Gtk", "main"
|
117
|
+
@gir.require "Gtk", nil
|
118
|
+
go2 = @gir.find_by_name "Gtk", "main"
|
108
119
|
assert_equal go2, @go
|
109
120
|
end
|
110
121
|
|
@@ -147,62 +158,67 @@ class BuilderTest < Test::Unit::TestCase
|
|
147
158
|
|
148
159
|
end
|
149
160
|
|
150
|
-
context "looking at
|
161
|
+
context "looking at Regress.test_callback_destroy_notify" do
|
151
162
|
setup do
|
163
|
+
cleanup_module :GLib
|
152
164
|
cleanup_module :GObject
|
165
|
+
cleanup_module :Regress
|
166
|
+
GirFFI::Builder.build_module 'GLib'
|
153
167
|
GirFFI::Builder.build_module 'GObject'
|
154
|
-
|
168
|
+
GirFFI::Builder.build_module 'Regress'
|
169
|
+
@go = get_function_introspection_data 'Regress', 'test_callback_destroy_notify'
|
155
170
|
end
|
156
171
|
|
157
172
|
should "have the correct types of the arguments for the attached function" do
|
158
173
|
argtypes = GirFFI::Builder.send(:ffi_function_argument_types, @go)
|
159
|
-
assert_equal [
|
174
|
+
assert_equal [Regress::TestCallbackUserData, :pointer, GLib::DestroyNotify],
|
160
175
|
argtypes
|
161
176
|
end
|
162
177
|
|
163
178
|
should "define ffi callback types :Callback and :ClosureNotify" do
|
164
|
-
|
165
|
-
|
166
|
-
|
179
|
+
Regress.gir_ffi_builder.setup_function 'test_callback_destroy_notify'
|
180
|
+
tcud = Regress::Lib.find_type :TestCallbackUserData
|
181
|
+
dn = GLib::Lib.find_type :DestroyNotify
|
167
182
|
|
168
|
-
assert_equal FFI.find_type(:
|
169
|
-
assert_equal FFI.find_type(:void),
|
170
|
-
assert_equal [],
|
171
|
-
assert_equal [FFI.find_type(:pointer)
|
183
|
+
assert_equal FFI.find_type(:int32), tcud.result_type
|
184
|
+
assert_equal FFI.find_type(:void), dn.result_type
|
185
|
+
assert_equal [FFI.find_type(:pointer)], tcud.param_types
|
186
|
+
assert_equal [FFI.find_type(:pointer)], dn.param_types
|
172
187
|
end
|
173
188
|
|
189
|
+
# FIXME: Test passes but does not test what it claims to test.
|
174
190
|
should "define ffi enum type ConnectFlags" do
|
175
191
|
assert_equal({:after => 1, :swapped => 2}, GObject::ConnectFlags.to_h)
|
176
192
|
end
|
177
193
|
end
|
178
194
|
|
179
|
-
context "building
|
195
|
+
context "building Regress::TestStructA" do
|
180
196
|
setup do
|
181
197
|
@fieldnames = [:some_int, :some_int8, :some_double, :some_enum]
|
182
|
-
GirFFI::Builder.build_class '
|
198
|
+
GirFFI::Builder.build_class @gir.find_by_name('Regress', 'TestStructA')
|
183
199
|
end
|
184
200
|
|
185
201
|
should "set up the correct struct members" do
|
186
202
|
assert_equal @fieldnames,
|
187
|
-
|
203
|
+
Regress::TestStructA::Struct.members
|
188
204
|
end
|
189
205
|
|
190
206
|
should "set up struct members with the correct offset" do
|
191
|
-
info =
|
207
|
+
info = @gir.find_by_name 'Regress', 'TestStructA'
|
192
208
|
assert_equal info.fields.map{|f| [f.name.to_sym, f.offset]},
|
193
|
-
|
209
|
+
Regress::TestStructA::Struct.offsets
|
194
210
|
end
|
195
211
|
|
196
212
|
should "set up struct members with the correct types" do
|
197
|
-
tags = [:int, :int8, :double,
|
213
|
+
tags = [:int, :int8, :double, Regress::TestEnum]
|
198
214
|
assert_equal tags.map {|t| FFI.find_type t},
|
199
|
-
@fieldnames.map {|f|
|
215
|
+
@fieldnames.map {|f| Regress::TestStructA::Struct.layout[f].type}
|
200
216
|
end
|
201
217
|
end
|
202
218
|
|
203
219
|
context "building GObject::TypeCValue" do
|
204
220
|
setup do
|
205
|
-
GirFFI::Builder.build_class 'GObject', 'TypeCValue'
|
221
|
+
GirFFI::Builder.build_class @gir.find_by_name('GObject', 'TypeCValue')
|
206
222
|
end
|
207
223
|
|
208
224
|
should "set up the correct union members" do
|
@@ -222,106 +238,102 @@ class BuilderTest < Test::Unit::TestCase
|
|
222
238
|
|
223
239
|
context "building GObject::ValueArray" do
|
224
240
|
should "use provided constructor if present" do
|
225
|
-
GirFFI::Builder.build_class 'GObject', 'ValueArray'
|
241
|
+
GirFFI::Builder.build_class @gir.find_by_name('GObject', 'ValueArray')
|
226
242
|
assert_nothing_raised {
|
227
243
|
GObject::ValueArray.new 2
|
228
244
|
}
|
229
245
|
end
|
230
246
|
end
|
231
247
|
|
232
|
-
context "building
|
248
|
+
context "building Regress::TestBoxed" do
|
233
249
|
setup do
|
234
|
-
GirFFI::Builder.build_class '
|
250
|
+
GirFFI::Builder.build_class @gir.find_by_name('Regress', 'TestBoxed')
|
235
251
|
end
|
236
252
|
|
237
253
|
should "set up #wrap" do
|
238
|
-
assert
|
254
|
+
assert Regress::TestBoxed.respond_to? "wrap"
|
239
255
|
end
|
240
256
|
|
241
257
|
should "set up #allocate" do
|
242
|
-
assert
|
258
|
+
assert Regress::TestBoxed.respond_to? "allocate"
|
243
259
|
end
|
244
260
|
end
|
245
261
|
|
246
|
-
context "built
|
262
|
+
context "built Regress module" do
|
247
263
|
setup do
|
248
|
-
cleanup_module :
|
249
|
-
GirFFI::Builder.build_module '
|
264
|
+
cleanup_module :Regress
|
265
|
+
GirFFI::Builder.build_module 'Regress'
|
250
266
|
end
|
251
267
|
|
252
268
|
should "have a method_missing method" do
|
253
|
-
ms = (
|
269
|
+
ms = (Regress.public_methods - Module.public_methods).map(&:to_sym)
|
254
270
|
assert ms.include? :method_missing
|
255
271
|
end
|
256
272
|
|
257
273
|
should "autocreate the TestObj class" do
|
258
|
-
assert !
|
259
|
-
assert_nothing_raised {
|
260
|
-
assert
|
274
|
+
assert !Regress.const_defined?(:TestObj)
|
275
|
+
assert_nothing_raised {Regress::TestObj}
|
276
|
+
assert Regress.const_defined? :TestObj
|
261
277
|
end
|
262
278
|
|
263
279
|
should "know its own module builder" do
|
264
|
-
assert GirFFI::
|
280
|
+
assert GirFFI::Builder::Module === Regress.gir_ffi_builder
|
265
281
|
end
|
266
282
|
end
|
267
283
|
|
268
|
-
context "built
|
284
|
+
context "built Regress::TestObj" do
|
269
285
|
setup do
|
270
|
-
cleanup_module :
|
271
|
-
GirFFI::Builder.build_class '
|
286
|
+
cleanup_module :Regress
|
287
|
+
GirFFI::Builder.build_class @gir.find_by_name('Regress', 'TestObj')
|
272
288
|
end
|
273
289
|
|
274
290
|
should "make autocreated instance method available to all instances" do
|
275
|
-
o1 =
|
276
|
-
o2 =
|
291
|
+
o1 = Regress::TestObj.new_from_file("foo")
|
292
|
+
o2 = Regress::TestObj.new_from_file("foo")
|
277
293
|
o1.instance_method
|
278
|
-
|
294
|
+
Regress::TestObj.class_eval do
|
279
295
|
undef method_missing
|
280
296
|
end
|
281
297
|
assert_nothing_raised { o2.instance_method }
|
282
298
|
end
|
283
299
|
|
284
|
-
should "attach C functions to
|
285
|
-
o =
|
300
|
+
should "attach C functions to Regress::Lib" do
|
301
|
+
o = Regress::TestObj.new_from_file("foo")
|
286
302
|
o.instance_method
|
287
|
-
assert
|
288
|
-
end
|
289
|
-
|
290
|
-
should "not have regular #new as a constructor" do
|
291
|
-
assert_raises(NoMethodError) { Everything::TestObj.new }
|
303
|
+
assert Regress::Lib.respond_to? :regress_test_obj_instance_method
|
292
304
|
end
|
293
305
|
|
294
306
|
should "know its own GIR info" do
|
295
|
-
assert_equal 'TestObj',
|
307
|
+
assert_equal 'TestObj', Regress::TestObj.gir_info.name
|
296
308
|
end
|
297
309
|
|
298
310
|
should "know its own class builder" do
|
299
|
-
assert GirFFI::
|
311
|
+
assert GirFFI::Builder::Class === Regress::TestObj.gir_ffi_builder
|
300
312
|
end
|
301
313
|
|
302
314
|
context "its #torture_signature_0 method" do
|
303
315
|
should "have the correct types of the arguments for the attached function" do
|
304
|
-
info = get_method_introspection_data '
|
316
|
+
info = get_method_introspection_data 'Regress', 'TestObj',
|
305
317
|
'torture_signature_0'
|
306
|
-
assert_equal [:pointer, :
|
318
|
+
assert_equal [:pointer, :int32, :pointer, :pointer, :pointer, :pointer, :uint32],
|
307
319
|
GirFFI::Builder.send(:ffi_function_argument_types, info)
|
308
320
|
end
|
309
321
|
end
|
310
322
|
end
|
311
323
|
|
312
|
-
context "built
|
324
|
+
context "built Regress::TestSubObj" do
|
313
325
|
setup do
|
314
|
-
cleanup_module :
|
315
|
-
GirFFI::Builder.build_class '
|
326
|
+
cleanup_module :Regress
|
327
|
+
GirFFI::Builder.build_class @gir.find_by_name('Regress', 'TestSubObj')
|
316
328
|
end
|
317
329
|
|
318
330
|
should "autocreate parent class' set_bare inside the parent class" do
|
319
|
-
o1 =
|
320
|
-
o2 =
|
331
|
+
o1 = Regress::TestSubObj.new
|
332
|
+
o2 = Regress::TestObj.new_from_file("foo")
|
321
333
|
|
322
334
|
assert_nothing_raised {o1.set_bare(nil)}
|
323
335
|
|
324
|
-
|
336
|
+
Regress::TestObj.class_eval do
|
325
337
|
undef method_missing
|
326
338
|
end
|
327
339
|
|
@@ -329,9 +341,9 @@ class BuilderTest < Test::Unit::TestCase
|
|
329
341
|
end
|
330
342
|
|
331
343
|
should "use its own version of instance_method when parent's version has been created" do
|
332
|
-
obj =
|
344
|
+
obj = Regress::TestObj.new_from_file("foo")
|
333
345
|
assert_equal(-1, obj.instance_method)
|
334
|
-
subobj =
|
346
|
+
subobj = Regress::TestSubObj.new
|
335
347
|
assert_equal 0, subobj.instance_method
|
336
348
|
end
|
337
349
|
end
|
data/test/class_builder_test.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
require File.expand_path('test_helper.rb', File.dirname(__FILE__))
|
2
2
|
|
3
3
|
class ClassBuilderTest < Test::Unit::TestCase
|
4
|
-
context "The
|
5
|
-
|
4
|
+
context "The Builder::Class class" do
|
5
|
+
setup do
|
6
6
|
@gir = GirFFI::IRepository.default
|
7
|
+
end
|
8
|
+
|
9
|
+
should "use parent struct as default layout" do
|
7
10
|
@gir.require 'GObject', nil
|
8
11
|
|
9
12
|
stub(info = Object.new).parent { @gir.find_by_name 'GObject', 'Object' }
|
10
13
|
stub(info).fields { [] }
|
11
14
|
stub(info).type { :object }
|
15
|
+
stub(info).name { 'Bar' }
|
16
|
+
stub(info).namespace { 'Foo' }
|
12
17
|
|
13
|
-
@classbuilder = GirFFI::
|
14
|
-
@classbuilder.instance_eval { @info = info }
|
18
|
+
@classbuilder = GirFFI::Builder::Class.new info
|
15
19
|
|
16
20
|
spec = @classbuilder.send :layout_specification
|
17
21
|
assert_equal [:parent, GObject::Object::Struct, 0], spec
|
@@ -19,7 +23,7 @@ class ClassBuilderTest < Test::Unit::TestCase
|
|
19
23
|
|
20
24
|
context "for Gtk::Widget" do
|
21
25
|
setup do
|
22
|
-
@cbuilder = GirFFI::
|
26
|
+
@cbuilder = GirFFI::Builder::Class.new @gir.find_by_name('Gtk', 'Widget')
|
23
27
|
end
|
24
28
|
|
25
29
|
context "looking at Gtk::Widget#show" do
|
@@ -27,9 +31,9 @@ class ClassBuilderTest < Test::Unit::TestCase
|
|
27
31
|
@go = get_method_introspection_data 'Gtk', 'Widget', 'show'
|
28
32
|
end
|
29
33
|
|
30
|
-
should "delegate definition to
|
34
|
+
should "delegate definition to Builder::Function" do
|
31
35
|
code = @cbuilder.send :function_definition, @go
|
32
|
-
expected = GirFFI::
|
36
|
+
expected = GirFFI::Builder::Function.new(@go, Gtk::Lib).generate
|
33
37
|
assert_equal cws(expected), cws(code)
|
34
38
|
end
|
35
39
|
|
@@ -38,19 +42,19 @@ class ClassBuilderTest < Test::Unit::TestCase
|
|
38
42
|
|
39
43
|
context 'the find_signal method' do
|
40
44
|
should 'find the signal "test" for TestObj' do
|
41
|
-
builder = GirFFI::
|
45
|
+
builder = GirFFI::Builder::Class.new @gir.find_by_name('Regress', 'TestObj')
|
42
46
|
sig = builder.find_signal 'test'
|
43
47
|
assert_equal 'test', sig.name
|
44
48
|
end
|
45
49
|
|
46
50
|
should 'find the signal "test" for TestSubObj' do
|
47
|
-
builder = GirFFI::
|
51
|
+
builder = GirFFI::Builder::Class.new @gir.find_by_name('Regress', 'TestSubObj')
|
48
52
|
sig = builder.find_signal 'test'
|
49
53
|
assert_equal 'test', sig.name
|
50
54
|
end
|
51
55
|
|
52
56
|
should 'find the signal "changed" for Gtk::Entry' do
|
53
|
-
builder = GirFFI::
|
57
|
+
builder = GirFFI::Builder::Class.new @gir.find_by_name('Gtk', 'Entry')
|
54
58
|
sig = builder.find_signal 'changed'
|
55
59
|
assert_equal 'changed', sig.name
|
56
60
|
end
|
@@ -58,7 +62,7 @@ class ClassBuilderTest < Test::Unit::TestCase
|
|
58
62
|
|
59
63
|
context "for GObject::TypeCValue (a union)" do
|
60
64
|
setup do
|
61
|
-
@cbuilder = GirFFI::
|
65
|
+
@cbuilder = GirFFI::Builder::Class.new @gir.find_by_name('GObject', 'TypeCValue')
|
62
66
|
end
|
63
67
|
|
64
68
|
should "not raise an error looking for a method that doesn't exist" do
|