gir_ffi 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|