gir_ffi 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/History.txt +11 -0
  2. data/README.rdoc +28 -14
  3. data/Rakefile +1 -1
  4. data/TODO.rdoc +3 -24
  5. data/examples/05_notification.rb +35 -0
  6. data/lib/gir_ffi/arg_helper.rb +15 -279
  7. data/lib/gir_ffi/builder/argument/base.rb +110 -0
  8. data/lib/gir_ffi/builder/argument/hash_table_base.rb +20 -0
  9. data/lib/gir_ffi/builder/argument/in_base.rb +19 -0
  10. data/lib/gir_ffi/builder/argument/in_out_base.rb +25 -0
  11. data/lib/gir_ffi/builder/argument/list_base.rb +16 -0
  12. data/lib/gir_ffi/builder/argument/out_base.rb +27 -0
  13. data/lib/gir_ffi/builder/argument.rb +167 -357
  14. data/lib/gir_ffi/builder/function.rb +2 -0
  15. data/lib/gir_ffi/builder/module.rb +2 -2
  16. data/lib/gir_ffi/builder/type/base.rb +7 -0
  17. data/lib/gir_ffi/builder/type/callback.rb +1 -8
  18. data/lib/gir_ffi/builder/type/constant.rb +1 -6
  19. data/lib/gir_ffi/builder/type/enum.rb +2 -7
  20. data/lib/gir_ffi/builder/type/interface.rb +12 -14
  21. data/lib/gir_ffi/builder/type/object.rb +32 -13
  22. data/lib/gir_ffi/builder/type/registered_type.rb +1 -78
  23. data/lib/gir_ffi/builder/type/struct.rb +2 -0
  24. data/lib/gir_ffi/builder/type/struct_based.rb +9 -24
  25. data/lib/gir_ffi/builder/type/unintrospectable.rb +63 -0
  26. data/lib/gir_ffi/builder/type/union.rb +8 -7
  27. data/lib/gir_ffi/builder/type/with_layout.rb +43 -0
  28. data/lib/gir_ffi/builder/type/with_methods.rb +61 -0
  29. data/lib/gir_ffi/builder.rb +39 -0
  30. data/lib/gir_ffi/callback_helper.rb +58 -0
  31. data/lib/gir_ffi/class_base.rb +17 -5
  32. data/lib/gir_ffi/i_repository.rb +0 -4
  33. data/lib/gir_ffi/in_out_pointer.rb +76 -0
  34. data/lib/gir_ffi/in_pointer.rb +46 -0
  35. data/lib/gir_ffi/interface_base.rb +12 -0
  36. data/lib/gir_ffi/module_base.rb +7 -3
  37. data/lib/gir_ffi/overrides/glib.rb +14 -3
  38. data/lib/gir_ffi/overrides/gobject.rb +37 -15
  39. data/lib/gir_ffi/overrides/gtk.rb +1 -1
  40. data/lib/gir_ffi/version.rb +1 -1
  41. data/lib/gir_ffi.rb +3 -0
  42. data/tasks/rdoc.rake +6 -0
  43. data/tasks/test.rake +22 -3
  44. data/tasks/yardoc.rake +6 -0
  45. data/test/arg_helper_test.rb +2 -72
  46. data/test/builder_test.rb +15 -19
  47. data/test/function_definition_builder_test.rb +30 -37
  48. data/test/g_object_overrides_test.rb +29 -1
  49. data/test/glib_overrides_test.rb +4 -0
  50. data/test/gtk_overrides_test.rb +21 -15
  51. data/test/i_repository_test.rb +2 -1
  52. data/test/{generated_gimarshallingtests_test.rb → integration/generated_gimarshallingtests_test.rb} +1 -1
  53. data/test/integration/generated_gio_test.rb +98 -0
  54. data/test/integration/generated_gobject_test.rb +30 -0
  55. data/test/{generated_gtk_test.rb → integration/generated_gtk_test.rb} +5 -5
  56. data/test/{generated_regress_test.rb → integration/generated_regress_test.rb} +19 -5
  57. data/test/interface_type_builder_test.rb +1 -1
  58. data/test/module_builder_test.rb +3 -3
  59. data/test/test_helper.rb +4 -9
  60. data/test/type_builder_test.rb +5 -5
  61. data/test/{dynamic_type_builder_test.rb → unintrospectable_type_builder_test.rb} +12 -8
  62. data/test/unit/builder_test.rb +31 -0
  63. data/test/unit/callback_helper_test.rb +19 -0
  64. data/test/unit/constant_builder_test.rb +5 -0
  65. data/test/unit/i_constant_info_test.rb +17 -0
  66. data/test/unit/in_out_pointer_test.rb +118 -0
  67. data/test/unit/in_pointer_test.rb +69 -0
  68. data/test/unit/object_type_builder_test.rb +20 -0
  69. metadata +47 -19
  70. data/lib/gir_ffi/builder/dynamic_type.rb +0 -41
  71. data/test/generated_gio_test.rb +0 -39
  72. data/test/generated_gobject_test.rb +0 -15
  73. data/test/object_type_builder_test.rb +0 -34
@@ -0,0 +1,58 @@
1
+ module GirFFI
2
+ module CallbackHelper
3
+ def self.wrap_in_callback_args_mapper namespace, name, prc
4
+ return prc if FFI::Function === prc
5
+ return nil if prc.nil?
6
+ info = IRepository.default.find_by_name namespace, name
7
+ return Proc.new do |*args|
8
+ prc.call(*map_callback_args(args, info))
9
+ end
10
+ end
11
+
12
+ def self.map_callback_args args, info
13
+ args.zip(info.args).map { |arg, inf|
14
+ map_single_callback_arg arg, inf }
15
+ end
16
+
17
+ # TODO: Use GirFFI::ReturnValue classes for mapping.
18
+ def self.map_single_callback_arg arg, info
19
+ case info.argument_type.tag
20
+ when :interface
21
+ map_interface_callback_arg arg, info
22
+ when :utf8
23
+ ArgHelper.ptr_to_utf8 arg
24
+ when :void
25
+ map_void_callback_arg arg
26
+ else
27
+ arg
28
+ end
29
+ end
30
+
31
+ def self.map_interface_callback_arg arg, info
32
+ iface = info.argument_type.interface
33
+ case iface.info_type
34
+ when :object
35
+ ArgHelper.object_pointer_to_object arg
36
+ when :struct
37
+ klass = GirFFI::Builder.build_class iface
38
+ klass.wrap arg
39
+ else
40
+ arg
41
+ end
42
+ end
43
+
44
+ def self.map_void_callback_arg arg
45
+ if arg.null?
46
+ nil
47
+ else
48
+ begin
49
+ # TODO: Use custom object store.
50
+ ObjectSpace._id2ref arg.address
51
+ rescue RangeError
52
+ arg
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -15,19 +15,19 @@ module GirFFI
15
15
  self.class.ffi_structure
16
16
  end
17
17
 
18
- def gir_ffi_builder
19
- self.class.gir_ffi_builder
18
+ def _builder
19
+ self.class._builder
20
20
  end
21
21
 
22
22
  def setup_and_call method, *arguments, &block
23
- unless gir_ffi_builder.setup_instance_method method.to_s
23
+ unless _builder.setup_instance_method method.to_s
24
24
  raise RuntimeError, "Unable to set up instance method #{method} in #{self}"
25
25
  end
26
26
  self.send method, *arguments, &block
27
27
  end
28
28
 
29
29
  def self.setup_and_call method, *arguments, &block
30
- unless gir_ffi_builder.setup_method method.to_s
30
+ unless _builder.setup_method method.to_s
31
31
  raise RuntimeError, "Unable to set up method #{method} in #{self}"
32
32
  end
33
33
  self.send method, *arguments, &block
@@ -42,10 +42,22 @@ module GirFFI
42
42
  self.const_get :GIR_INFO
43
43
  end
44
44
 
45
- def gir_ffi_builder
45
+ def _builder
46
46
  self.const_get :GIR_FFI_BUILDER
47
47
  end
48
48
 
49
+ def _find_signal name
50
+ _builder.find_signal name
51
+ end
52
+
53
+ def _setup_method name
54
+ _builder.setup_method name
55
+ end
56
+
57
+ def _setup_instance_method name
58
+ _builder.setup_instance_method name
59
+ end
60
+
49
61
  alias_method :_real_new, :new
50
62
  undef new
51
63
 
@@ -1,6 +1,5 @@
1
1
  require 'singleton'
2
2
  require 'gir_ffi/lib'
3
- require 'gir_ffi/g_object'
4
3
  require 'gir_ffi/g_error'
5
4
  require 'gir_ffi/i_base_info'
6
5
  require 'gir_ffi/i_callable_info'
@@ -53,7 +52,6 @@ module GirFFI
53
52
  }
54
53
 
55
54
  def initialize
56
- GObject.type_init
57
55
  @gobj = Lib::g_irepository_get_default
58
56
  end
59
57
 
@@ -63,12 +61,10 @@ module GirFFI
63
61
  self.instance
64
62
  end
65
63
 
66
- # TODO: Make sure GType is initialized first.
67
64
  def self.prepend_search_path path
68
65
  Lib.g_irepository_prepend_search_path path
69
66
  end
70
67
 
71
- # TODO: Make sure GType is initialized first.
72
68
  def self.type_tag_to_string type
73
69
  Lib.g_type_tag_to_string type
74
70
  end
@@ -0,0 +1,76 @@
1
+ module GirFFI
2
+ # The InOutPointer class handles conversion between ruby types and
3
+ # pointers for arguments with direction :inout and :out.
4
+ class InOutPointer < FFI::Pointer
5
+ def initialize ptr, type, ffi_type
6
+ super ptr
7
+ @ffi_type = ffi_type
8
+ @value_type = type
9
+ end
10
+
11
+ def to_value
12
+ value = self.send "get_#{@ffi_type}", 0
13
+ adjust_value_out value
14
+ end
15
+
16
+ private
17
+
18
+ def adjust_value_out value
19
+ case @value_type
20
+ when :gboolean
21
+ (value != 0)
22
+ when :utf8
23
+ ArgHelper.ptr_to_utf8 value
24
+ else
25
+ value
26
+ end
27
+ end
28
+
29
+ def self.for type
30
+ ffi_type = type_to_ffi_type type
31
+ ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
32
+ ptr.send "put_#{ffi_type}", 0, 0
33
+ self.new ptr, type, ffi_type
34
+ end
35
+
36
+ def self.from type, value
37
+ value = adjust_value_in type, value
38
+ ffi_type = type_to_ffi_type type
39
+ ptr = AllocationHelper.safe_malloc(FFI.type_size ffi_type)
40
+ ptr.send "put_#{ffi_type}", 0, value
41
+ self.new ptr, type, ffi_type
42
+ end
43
+
44
+ def self.from_array type, array
45
+ return nil if array.nil?
46
+ ptr = InPointer.from_array(type, array)
47
+ self.from :pointer, ptr
48
+ end
49
+
50
+ class << self
51
+ # TODO: Make separate module to hold type info.
52
+ def type_to_ffi_type type
53
+ case type
54
+ when :gboolean
55
+ :int32
56
+ when :utf8
57
+ :pointer
58
+ else
59
+ GirFFI::Builder::TAG_TYPE_MAP[type] || type
60
+ end
61
+ end
62
+
63
+ def adjust_value_in type, value
64
+ case type
65
+ when :gboolean
66
+ (value ? 1 : 0)
67
+ when :utf8
68
+ InPointer.from :utf8, value
69
+ else
70
+ value
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
@@ -0,0 +1,46 @@
1
+ module GirFFI
2
+ # The InPointer class handles conversion from ruby types to pointers for
3
+ # arguments with direction :in. This is used for arguments that are
4
+ # arrays, strings, or interfaces.
5
+ class InPointer < FFI::Pointer
6
+ def self.from_array type, ary
7
+ return nil if ary.nil?
8
+ return from_utf8_array ary if type == :utf8
9
+ return from_interface_pointer_array ary if type == :interface_pointer
10
+
11
+ ffi_type = GirFFI::Builder::TAG_TYPE_MAP[type] || type
12
+ block = ArgHelper.allocate_array_of_type ffi_type, ary.length
13
+ block.send "put_array_of_#{ffi_type}", 0, ary
14
+
15
+ self.new block
16
+ end
17
+
18
+ def self.from type, val
19
+ return nil if val.nil?
20
+ from_utf8 val
21
+ end
22
+
23
+ class << self
24
+
25
+ private
26
+
27
+ def from_utf8_array ary
28
+ ptr_ary = ary.map {|str| self.from :utf8, str}
29
+ ptr_ary << nil
30
+ self.from_array :pointer, ptr_ary
31
+ end
32
+
33
+ def from_interface_pointer_array ary
34
+ ptr_ary = ary.map {|ifc| ifc.to_ptr}
35
+ ptr_ary << nil
36
+ self.from_array :pointer, ptr_ary
37
+ end
38
+
39
+ def from_utf8 str
40
+ len = str.bytesize
41
+ ptr = AllocationHelper.safe_malloc(len + 1).write_string(str).put_char(len, 0)
42
+ self.new ptr
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,12 @@
1
+ module GirFFI
2
+ module InterfaceBase
3
+ def _builder
4
+ self.const_get :GIR_FFI_BUILDER
5
+ end
6
+
7
+ def _setup_instance_method name
8
+ _builder.setup_instance_method name
9
+ end
10
+ end
11
+ end
12
+
@@ -1,19 +1,23 @@
1
1
  module GirFFI
2
2
  module ModuleBase
3
3
  def method_missing method, *arguments, &block
4
- result = gir_ffi_builder.setup_function method.to_s
4
+ result = _setup_method method.to_s
5
5
  return super unless result
6
6
  self.send method, *arguments, &block
7
7
  end
8
8
 
9
9
  def const_missing classname
10
- klass = gir_ffi_builder.build_class classname.to_s
10
+ klass = _builder.build_namespaced_class classname.to_s
11
11
  return super if klass.nil?
12
12
  klass
13
13
  end
14
14
 
15
- def gir_ffi_builder
15
+ def _builder
16
16
  self.const_get :GIR_FFI_BUILDER
17
17
  end
18
+
19
+ def _setup_method name
20
+ _builder.setup_method name
21
+ end
18
22
  end
19
23
  end
@@ -39,20 +39,27 @@ module GirFFI
39
39
  def self.attach_non_introspectable_functions base
40
40
  base::Lib.attach_function :g_slist_prepend, [:pointer, :pointer],
41
41
  :pointer
42
+
42
43
  base::Lib.attach_function :g_list_append, [:pointer, :pointer],
43
44
  :pointer
45
+
44
46
  base::Lib.attach_function :g_hash_table_foreach,
45
47
  [:pointer, base::HFunc, :pointer], :void
46
48
  base::Lib.attach_function :g_hash_table_new,
47
49
  [base::HashFunc, base::EqualFunc], :pointer
48
50
  base::Lib.attach_function :g_hash_table_insert,
49
51
  [:pointer, :pointer, :pointer], :void
52
+
50
53
  base::Lib.attach_function :g_byte_array_new, [], :pointer
51
54
  base::Lib.attach_function :g_byte_array_append,
52
55
  [:pointer, :pointer, :uint], :pointer
56
+
53
57
  base::Lib.attach_function :g_array_new, [:int, :int, :uint], :pointer
54
58
  base::Lib.attach_function :g_array_append_vals,
55
59
  [:pointer, :pointer, :uint], :pointer
60
+
61
+ base::Lib.attach_function :g_main_loop_new,
62
+ [:pointer, :bool], :pointer
56
63
  end
57
64
 
58
65
  module ClassMethods
@@ -99,7 +106,7 @@ module GirFFI
99
106
 
100
107
  # FIXME: Turn into instance method
101
108
  def byte_array_append arr, data
102
- bytes = GirFFI::ArgHelper.utf8_to_inptr data
109
+ bytes = GirFFI::InPointer.from :utf8, data
103
110
  len = data.bytesize
104
111
  ::GLib::ByteArray.wrap(::GLib::Lib.g_byte_array_append arr.to_ptr, bytes, len)
105
112
  end
@@ -115,7 +122,7 @@ module GirFFI
115
122
 
116
123
  # FIXME: Turn into instance method
117
124
  def array_append_vals arr, data
118
- bytes = GirFFI::ArgHelper.typed_array_to_inptr arr.element_type, data
125
+ bytes = GirFFI::InPointer.from_array arr.element_type, data
119
126
  len = data.length
120
127
  res = ::GLib::Array.wrap(
121
128
  ::GLib::Lib.g_array_append_vals(arr.to_ptr, bytes, len))
@@ -123,6 +130,10 @@ module GirFFI
123
130
  res
124
131
  end
125
132
 
133
+ # FIXME: Turn into real constructor?
134
+ def main_loop_new context, is_running
135
+ ::GLib::MainLoop.wrap(::GLib::Lib.g_main_loop_new context, is_running)
136
+ end
126
137
  end
127
138
 
128
139
  module ListInstanceMethods
@@ -178,7 +189,7 @@ module GirFFI
178
189
 
179
190
  def cast_to_pointer type, it
180
191
  if type == :utf8
181
- GirFFI::ArgHelper.utf8_to_inptr it
192
+ GirFFI::InPointer.from :utf8, it
182
193
  else
183
194
  FFI::Pointer.new(it)
184
195
  end
@@ -105,7 +105,7 @@ module GirFFI
105
105
  end
106
106
 
107
107
  def signal_connect object, signal, data=nil, &block
108
- sig = object.class.gir_ffi_builder.find_signal signal
108
+ sig = object.class._find_signal signal
109
109
  if sig.nil?
110
110
  raise "Signal #{signal} is invalid for #{object}"
111
111
  end
@@ -115,8 +115,7 @@ module GirFFI
115
115
 
116
116
  rettype = GirFFI::Builder.itypeinfo_to_ffitype sig.return_type
117
117
 
118
- # FIXME: Why are these all pointers?
119
- argtypes = [:pointer] + sig.args.map {|arg| :pointer} + [:pointer]
118
+ argtypes = GirFFI::Builder.ffi_argument_types_for_signal sig
120
119
 
121
120
  callback = FFI::Function.new rettype, argtypes,
122
121
  &(Helper.signal_callback_args(sig, object.class, &block))
@@ -129,6 +128,10 @@ module GirFFI
129
128
  end
130
129
 
131
130
  module Helper
131
+ TAG_TYPE_TO_GTYPE_NAME_MAP = {
132
+ :utf8 => "gchararray"
133
+ }
134
+
132
135
  def self.signal_callback_args sig, klass, &block
133
136
  return Proc.new do |*args|
134
137
  mapped = cast_back_signal_arguments sig, klass, *args
@@ -137,7 +140,7 @@ module GirFFI
137
140
  end
138
141
 
139
142
  def self.signal_arguments_to_gvalue_array signal, instance, *rest
140
- sig = instance.class.gir_ffi_builder.find_signal signal
143
+ sig = instance.class._find_signal signal
141
144
 
142
145
  arr = ::GObject::ValueArray.new sig.n_args+1
143
146
 
@@ -155,7 +158,10 @@ module GirFFI
155
158
  end
156
159
 
157
160
  def self.signal_argument_to_gvalue info, arg
158
- if info.argument_type.tag == :interface
161
+ arg_type = info.argument_type
162
+ tag = arg_type.tag
163
+
164
+ if tag == :interface
159
165
  interface = info.argument_type.interface
160
166
 
161
167
  val = ::GObject::Value.new
@@ -165,13 +171,17 @@ module GirFFI
165
171
  val.set_boxed arg
166
172
  when :object
167
173
  val.set_instance arg
174
+ when :enum
175
+ val.set_enum arg
168
176
  else
169
177
  raise NotImplementedError, interface.info_type
170
178
  end
171
179
 
172
180
  return val
173
181
  else
174
- raise NotImplementedError
182
+ val = ::GObject::Value.new
183
+ val.init ::GObject.type_from_name(TAG_TYPE_TO_GTYPE_NAME_MAP[tag])
184
+ val.set_ruby_value arg
175
185
  end
176
186
  end
177
187
 
@@ -192,6 +202,7 @@ module GirFFI
192
202
  rval
193
203
  end
194
204
 
205
+ # TODO: Generate cast back methods using existing Argument builders.
195
206
  def self.cast_back_signal_arguments signalinfo, klass, *args
196
207
  result = []
197
208
 
@@ -202,14 +213,7 @@ module GirFFI
202
213
 
203
214
  # Extra arguments
204
215
  signalinfo.args.each do |info|
205
- arg = args.shift
206
- if info.argument_type.tag == :interface
207
- iface = info.argument_type.interface
208
- kls = GirFFI::Builder.build_class iface
209
- result << kls.wrap(arg)
210
- else
211
- result << arg
212
- end
216
+ result << cast_signal_argument(info, args.shift)
213
217
  end
214
218
 
215
219
  # User Data
@@ -227,6 +231,22 @@ module GirFFI
227
231
 
228
232
  return result
229
233
  end
234
+
235
+ def self.cast_signal_argument info, arg
236
+ arg_t = info.argument_type
237
+ if arg_t.tag == :interface
238
+ iface = arg_t.interface
239
+ kls = GirFFI::Builder.build_class iface
240
+ case iface.info_type
241
+ when :enum, :flags
242
+ kls[arg]
243
+ else
244
+ kls.wrap(arg)
245
+ end
246
+ else
247
+ arg
248
+ end
249
+ end
230
250
  end
231
251
 
232
252
  module InitiallyUnownedClassMethods
@@ -252,6 +272,8 @@ module GirFFI
252
272
  set_boolean val
253
273
  when "gint"
254
274
  set_int val
275
+ when "gchararray"
276
+ set_string val
255
277
  else
256
278
  nil
257
279
  end
@@ -296,7 +318,7 @@ module GirFFI
296
318
 
297
319
  module ClosureInstanceMethods
298
320
  def set_marshal marshal
299
- _v1 = GirFFI::ArgHelper.wrap_in_callback_args_mapper(
321
+ _v1 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper(
300
322
  "GObject", "ClosureMarshal", marshal)
301
323
  ::GObject::Lib::CALLBACKS << _v1
302
324
  ::GObject::Lib.g_closure_set_marshal self, _v1
@@ -3,7 +3,7 @@ module GirFFI
3
3
  module Gtk
4
4
 
5
5
  def self.included(base)
6
- base.gir_ffi_builder.setup_function "init"
6
+ base._setup_method "init"
7
7
  base.extend ClassMethods
8
8
  base.class_eval do
9
9
 
@@ -1,4 +1,4 @@
1
1
  module GirFFI
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.11"
3
3
  end
4
4
 
data/lib/gir_ffi.rb CHANGED
@@ -1,7 +1,10 @@
1
+ require 'gir_ffi/g_object'
1
2
  require 'gir_ffi/i_repository'
2
3
  require 'gir_ffi/builder'
3
4
 
4
5
  module GirFFI
6
+ GObject.type_init
7
+
5
8
  def self.setup module_name, version=nil
6
9
  module_name = module_name.to_s
7
10
  GirFFI::Builder.build_module module_name, version
data/tasks/rdoc.rake ADDED
@@ -0,0 +1,6 @@
1
+ require "rdoc/task"
2
+
3
+ RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force") do |rdoc|
4
+ rdoc.main = "README.rdoc"
5
+ rdoc.rdoc_files.include "README.rdoc", "DESIGN.rdoc", "TODO.rdoc", "lib/**/*.rb"
6
+ end
data/tasks/test.rake CHANGED
@@ -2,9 +2,21 @@ require 'rake/testtask'
2
2
 
3
3
  namespace :test do
4
4
 
5
+ Rake::TestTask.new(:integration) do |t|
6
+ t.libs = ['lib']
7
+ t.test_files = FileList['test/integration/*_test.rb']
8
+ t.ruby_opts += ["-w"]
9
+ end
10
+
5
11
  Rake::TestTask.new(:run) do |t|
6
12
  t.libs = ['lib']
7
- t.test_files = FileList['test/**/*_test.rb']
13
+ t.test_files = FileList['test/*_test.rb']
14
+ t.ruby_opts += ["-w"]
15
+ end
16
+
17
+ Rake::TestTask.new(:unit) do |t|
18
+ t.libs = ['lib']
19
+ t.test_files = FileList['test/unit/*_test.rb']
8
20
  t.ruby_opts += ["-w"]
9
21
  end
10
22
 
@@ -13,7 +25,14 @@ namespace :test do
13
25
  sh %{cd test/lib && make}
14
26
  end
15
27
 
28
+ task :integration => :lib
16
29
  task :run => :lib
30
+
31
+ desc 'Run rcov for the entire test suite'
32
+ task :coverage => :lib do
33
+ rm_f "coverage"
34
+ system "rcov", "-Ilib", "--exclude", "\.gem\/,\/gems\/", *FileList['test/**/*_test.rb']
35
+ end
17
36
  end
18
37
 
19
38
  file "test/lib/Makefile" => "test/lib/configure" do
@@ -24,5 +43,5 @@ file "test/lib/configure" do
24
43
  sh %{cd test/lib && NOCONFIGURE=1 ./autogen.sh}
25
44
  end
26
45
 
27
- desc 'Alias to test:run'
28
- task :test => 'test:run'
46
+ desc 'Run unit an integration tests'
47
+ task :test => ['test:unit', 'test:run', 'test:integration']
data/tasks/yardoc.rake ADDED
@@ -0,0 +1,6 @@
1
+ require 'yard'
2
+
3
+ YARD::Rake::YardocTask.new do |t|
4
+ t.files = ['lib/**/*.rb']
5
+ t.options = ['--private', '--protected', '--readme', 'README.rdoc', "--files", "DESIGN.rdoc,TODO.rdoc"]
6
+ end
@@ -1,54 +1,6 @@
1
1
  require File.expand_path('test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  class ArgHelperTest < MiniTest::Spec
4
- context "The gint32_to_inoutptr method's return value" do
5
- setup do
6
- @result = GirFFI::ArgHelper.gint32_to_inoutptr 24
7
- end
8
-
9
- should "be an FFI::Pointer" do
10
- assert_instance_of FFI::Pointer, @result
11
- end
12
-
13
- should "hold a pointer to the correct input value" do
14
- assert_equal 24, @result.read_int
15
- end
16
- end
17
-
18
- context "The utf8_array_to_inoutptr method" do
19
- context "when called with an array of strings" do
20
- setup do
21
- @result = GirFFI::ArgHelper.utf8_array_to_inoutptr ["foo", "bar", "baz"]
22
- end
23
-
24
- should "return an FFI::Pointer" do
25
- assert_instance_of FFI::Pointer, @result
26
- end
27
-
28
- should "return a pointer to an array of pointers to strings" do
29
- ptr = @result.read_pointer
30
- ary = ptr.read_array_of_pointer(3)
31
- assert_equal ["foo", "bar", "baz"], ary.map {|p| p.read_string}
32
- end
33
- end
34
- context "when called with nil" do
35
- should "return nil" do
36
- assert_nil GirFFI::ArgHelper.utf8_array_to_inoutptr nil
37
- end
38
- end
39
- end
40
-
41
- context "The outptr_to_gint32 method" do
42
- setup do
43
- @ptr = GirFFI::AllocationHelper.safe_malloc FFI.type_size(:int)
44
- @ptr.write_int 342
45
- end
46
-
47
- should "retrieve the correct integer value" do
48
- assert_equal 342, GirFFI::ArgHelper.outptr_to_gint32(@ptr)
49
- end
50
- end
51
-
52
4
  context "The outptr_to_utf8_array method" do
53
5
  context "when called with a valid pointer to a string array" do
54
6
  setup do
@@ -88,7 +40,8 @@ class ArgHelperTest < MiniTest::Spec
88
40
 
89
41
  context "when called with a pointer to null" do
90
42
  should "return nil" do
91
- ptr = GirFFI::ArgHelper.pointer_pointer.write_pointer nil
43
+ ptr = GirFFI::InOutPointer.for :pointer
44
+ assert ptr.read_pointer.null?
92
45
  assert_nil GirFFI::ArgHelper.outptr_to_utf8_array(ptr, 0)
93
46
  end
94
47
  end
@@ -110,14 +63,6 @@ class ArgHelperTest < MiniTest::Spec
110
63
  end
111
64
  end
112
65
 
113
- context "The pointer_outptr method" do
114
- should "return a pointer to a null pointer" do
115
- ptr = GirFFI::ArgHelper.pointer_outptr
116
- pptr = ptr.read_pointer
117
- assert pptr.null?
118
- end
119
- end
120
-
121
66
  context "The object_pointer_to_object method" do
122
67
  setup do
123
68
  GirFFI.setup :Regress
@@ -134,19 +79,4 @@ class ArgHelperTest < MiniTest::Spec
134
79
  end
135
80
  end
136
81
 
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
152
82
  end