gir_ffi 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. data/History.txt +14 -0
  2. data/README.rdoc +3 -1
  3. data/examples/02_hello_world.rb +1 -0
  4. data/examples/03_upgraded_hello_world.rb +2 -1
  5. data/examples/05_notification.rb +2 -2
  6. data/examples/hard_coded.rb +31 -8
  7. data/lib/ffi-glib/array.rb +1 -1
  8. data/lib/ffi-glib/container_class_methods.rb +25 -0
  9. data/lib/ffi-glib/hash_table.rb +41 -38
  10. data/lib/ffi-glib/list.rb +15 -22
  11. data/lib/ffi-glib/list_methods.rb +16 -16
  12. data/lib/ffi-glib/ptr_array.rb +20 -15
  13. data/lib/ffi-glib/s_list.rb +15 -23
  14. data/lib/ffi-glib.rb +7 -0
  15. data/lib/ffi-gobject/base.rb +0 -13
  16. data/lib/ffi-gobject/object.rb +6 -0
  17. data/lib/ffi-gobject/ruby_style.rb +21 -0
  18. data/lib/ffi-gobject.rb +44 -0
  19. data/lib/ffi-gobject_introspection/i_object_info.rb +7 -0
  20. data/lib/ffi-gobject_introspection/lib.rb +1 -0
  21. data/lib/gir_ffi/arg_helper.rb +8 -6
  22. data/lib/gir_ffi/builder/argument.rb +1 -1
  23. data/lib/gir_ffi/builder/field.rb +6 -3
  24. data/lib/gir_ffi/builder/property.rb +28 -0
  25. data/lib/gir_ffi/builder/type/base.rb +6 -4
  26. data/lib/gir_ffi/builder/type/interface.rb +1 -0
  27. data/lib/gir_ffi/builder/type/object.rb +26 -1
  28. data/lib/gir_ffi/builder/type/registered_type.rb +9 -1
  29. data/lib/gir_ffi/builder/type/unintrospectable.rb +26 -8
  30. data/lib/gir_ffi/builder/type/user_defined.rb +119 -0
  31. data/lib/gir_ffi/builder/type/with_layout.rb +3 -3
  32. data/lib/gir_ffi/builder.rb +5 -0
  33. data/lib/gir_ffi/class_base.rb +6 -6
  34. data/lib/gir_ffi/info_ext/i_property_info.rb +12 -0
  35. data/lib/gir_ffi/info_ext/i_type_info.rb +4 -0
  36. data/lib/gir_ffi/user_defined/i_base_info.rb +7 -0
  37. data/lib/gir_ffi/user_defined/i_object_info.rb +13 -0
  38. data/lib/gir_ffi/user_defined/i_property_info.rb +9 -0
  39. data/lib/gir_ffi/user_defined/i_registered_type_info.rb +10 -0
  40. data/lib/gir_ffi/version.rb +1 -1
  41. data/lib/gir_ffi.rb +6 -0
  42. data/tasks/test.rake +12 -2
  43. data/test/builder_test.rb +0 -124
  44. data/test/ffi-glib/hash_table_test.rb +0 -14
  45. data/test/ffi-glib/list_test.rb +0 -13
  46. data/test/ffi-glib/ptr_array_test.rb +26 -8
  47. data/test/ffi-glib/s_list_test.rb +4 -4
  48. data/test/ffi-gobject/g_object_overrides_test.rb +16 -32
  49. data/test/ffi-gobject/gobject_test.rb +28 -1
  50. data/test/ffi-gobject/object_class_test.rb +21 -0
  51. data/test/ffi-gobject/object_test.rb +4 -0
  52. data/test/ffi-gobject/ruby_style_test.rb +38 -0
  53. data/test/ffi-gobject_introspection/i_constant_info_test.rb +5 -5
  54. data/test/ffi-gobject_introspection/i_repository_test.rb +4 -4
  55. data/test/ffi-gtk/gtk_test.rb +36 -0
  56. data/test/gir_ffi_test_helper.rb +8 -4
  57. data/test/integration/derived_classes_test.rb +34 -18
  58. data/test/integration/generated_gimarshallingtests_test.rb +20 -23
  59. data/test/integration/generated_gio_test.rb +5 -0
  60. data/test/integration/generated_gobject_test.rb +2 -2
  61. data/test/integration/generated_gtk_test.rb +1 -1
  62. data/test/integration/generated_pango_test.rb +20 -0
  63. data/test/integration/generated_regress_test.rb +1003 -955
  64. data/test/integration/pretty_print_test.rb +3 -1
  65. data/test/test_helper.rb +5 -0
  66. data/test/type_builder_test.rb +2 -19
  67. data/test/unit/arg_helper_test.rb +87 -1
  68. data/test/unit/builder_test.rb +113 -1
  69. data/test/unit/function_builder_test.rb +6 -5
  70. data/test/unit/gir_ffi_test.rb +69 -0
  71. data/test/unit/in_out_pointer_test.rb +3 -3
  72. data/test/unit/in_pointer_test.rb +1 -1
  73. data/test/unit/interface_builder_test.rb +16 -0
  74. data/test/unit/object_type_builder_test.rb +15 -0
  75. data/test/unit/struct_builder_test.rb +5 -1
  76. data/test/{unintrospectable_type_builder_test.rb → unit/unintrospectable_type_builder_test.rb} +18 -1
  77. data/test/unit/user_defined_object_info_test.rb +18 -0
  78. data/test/unit/user_defined_property_info_test.rb +14 -0
  79. data/test/unit/user_defined_registered_type_info_test.rb +10 -0
  80. data/test/unit/user_defined_type_builder_test.rb +41 -0
  81. metadata +34 -17
  82. data/tasks/notes.rake +0 -121
  83. data/tasks/rdoc.rake +0 -9
  84. data/tasks/yardoc.rake +0 -9
  85. data/test/arg_helper_test.rb +0 -33
  86. data/test/gtk_overrides_test.rb +0 -35
  87. data/test/interface_type_builder_test.rb +0 -17
@@ -19,8 +19,8 @@ module GirFFI
19
19
  return nil if obj.nil?
20
20
  return obj if obj.is_a? FFI::Pointer
21
21
 
22
- OBJECT_STORE[obj.object_id] = obj
23
- FFI::Pointer.new(obj.object_id)
22
+ FFI::Pointer.new(obj.object_id).tap {|ptr|
23
+ OBJECT_STORE[ptr.address] = obj }
24
24
  end
25
25
 
26
26
  def self.ptr_to_typed_array type, ptr, size
@@ -31,8 +31,7 @@ module GirFFI
31
31
  elsif type == :utf8
32
32
  ptr_to_utf8_array ptr, size
33
33
  else
34
- ffi_type = TypeMap.map_basic_type type
35
- ptr.send "get_array_of_#{ffi_type}", 0, size
34
+ self.send "ptr_to_#{type}_array", ptr, size
36
35
  end
37
36
  end
38
37
 
@@ -41,6 +40,7 @@ module GirFFI
41
40
  ffi_type = TypeMap.map_basic_type type
42
41
  defn =
43
42
  "def self.ptr_to_#{type}_array ptr, size
43
+ return [] if ptr.nil? or ptr.null?
44
44
  ptr.get_array_of_#{ffi_type}(0, size)
45
45
  end"
46
46
  eval defn
@@ -50,12 +50,13 @@ module GirFFI
50
50
  setup_ptr_to_type_array_handler_for SIMPLE_G_TYPES
51
51
 
52
52
  def self.ptr_to_utf8_array ptr, size
53
+ return [] if ptr.nil? or ptr.null?
53
54
  ptrs = ptr.read_array_of_pointer(size)
54
-
55
55
  ptrs.map { |pt| ptr_to_utf8 pt }
56
56
  end
57
57
 
58
58
  def self.ptr_to_interface_array klass, ptr, size
59
+ return [] if ptr.nil? or ptr.null?
59
60
  struct_size = klass.ffi_structure.size
60
61
  size.times.map do |idx|
61
62
  klass.wrap(ptr + struct_size * idx)
@@ -63,6 +64,7 @@ module GirFFI
63
64
  end
64
65
 
65
66
  def self.ptr_to_interface_pointer_array klass, ptr, size
67
+ return [] if ptr.nil? or ptr.null?
66
68
  ptrs = ptr.read_array_of_pointer(size)
67
69
  ptrs.map do |optr|
68
70
  klass.wrap(optr)
@@ -87,7 +89,7 @@ module GirFFI
87
89
  class << self
88
90
  sz = FFI.type_size(:size_t) * 8
89
91
  type = "guint#{sz}"
90
- alias_method :ptr_to_gtype_array, "ptr_to_#{type}_array"
92
+ alias_method :ptr_to_GType_array, "ptr_to_#{type}_array"
91
93
  end
92
94
 
93
95
  def self.check_error errpp
@@ -546,7 +546,7 @@ module GirFFI::Builder
546
546
  def post
547
547
  size = array_size
548
548
 
549
- [ "#{retname} = GirFFI::ArgHelper.ptr_to_#{subtype_tag}_array #{cvar}, #{size}" ]
549
+ [ "#{retname} = GirFFI::ArgHelper.ptr_to_typed_array #{subtype_tag_or_class_name}, #{cvar}, #{size}" ]
550
550
  end
551
551
  end
552
552
 
@@ -5,9 +5,10 @@ module GirFFI
5
5
  module Builder
6
6
  # Creates field getter and setter code for a given IFieldInfo.
7
7
  class Field
8
- def initialize field_info, lib_module
8
+ def initialize field_info, lib_module, struct_class
9
9
  @info = field_info
10
10
  @libmodule = lib_module
11
+ @struct_class = struct_class
11
12
  end
12
13
 
13
14
  def getter_def
@@ -15,7 +16,8 @@ module GirFFI
15
16
 
16
17
  return <<-CODE
17
18
  def #{@info.name}
18
- #{builder.cvar} = @struct[#{field_symbol.inspect}]
19
+ struct = #{@struct_class}.new @struct.to_ptr
20
+ #{builder.cvar} = struct[#{field_symbol.inspect}]
19
21
  #{builder.post.join("\n")}
20
22
  #{builder.retval}
21
23
  end
@@ -29,7 +31,8 @@ module GirFFI
29
31
  return <<-CODE
30
32
  def #{name}= #{builder.inarg}
31
33
  #{builder.pre.join("\n")}
32
- @struct[#{name.to_sym.inspect}] = #{builder.callarg}
34
+ struct = #{@struct_class}.new @struct.to_ptr
35
+ struct[#{name.to_sym.inspect}] = #{builder.callarg}
33
36
  end
34
37
  CODE
35
38
  end
@@ -0,0 +1,28 @@
1
+ require 'gir_ffi/info_ext/i_property_info'
2
+
3
+ module GirFFI
4
+ module Builder
5
+ # Creates property getter and setter code for a given IPropertyInfo.
6
+ class Property
7
+ def initialize property_info
8
+ @info = property_info
9
+ end
10
+
11
+ def getter_def
12
+ return <<-CODE
13
+ def #{@info.getter_name}
14
+ get_property "#{@info.name}"
15
+ end
16
+ CODE
17
+ end
18
+
19
+ def setter_def
20
+ return <<-CODE
21
+ def #{@info.getter_name}= value
22
+ set_property "#{@info.name}", value
23
+ end
24
+ CODE
25
+ end
26
+ end
27
+ end
28
+ end
@@ -19,11 +19,9 @@ module GirFFI
19
19
  @klass
20
20
  end
21
21
 
22
- private
22
+ attr_reader :info
23
23
 
24
- def info
25
- @info
26
- end
24
+ private
27
25
 
28
26
  def namespace_module
29
27
  @namespace_module ||= Builder.build_module @namespace
@@ -38,6 +36,10 @@ module GirFFI
38
36
  Class.new parent
39
37
  }
40
38
  end
39
+
40
+ def gir
41
+ @gir ||= GObjectIntrospection::IRepository.default
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -28,6 +28,7 @@ module GirFFI
28
28
  @klass.extend InterfaceBase
29
29
  setup_constants
30
30
  stub_methods
31
+ setup_gtype_getter
31
32
  end
32
33
  end
33
34
  end
@@ -1,4 +1,7 @@
1
1
  require 'gir_ffi/builder/type/struct_based'
2
+ require 'gir_ffi/builder/property'
3
+ require 'gir_ffi/info_ext/i_property_info'
4
+
2
5
  module GirFFI
3
6
  module Builder
4
7
  module Type
@@ -30,7 +33,15 @@ module GirFFI
30
33
  private
31
34
 
32
35
  def setup_class
33
- super
36
+ setup_layout
37
+ setup_constants
38
+ stub_methods
39
+ setup_gtype_getter
40
+ if info.fundamental?
41
+ setup_field_accessors
42
+ else
43
+ setup_property_accessors
44
+ end
34
45
  setup_vfunc_invokers
35
46
  setup_interfaces
36
47
  end
@@ -47,6 +58,20 @@ module GirFFI
47
58
  @parent
48
59
  end
49
60
 
61
+ def setup_property_accessors
62
+ info.properties.each do |prop|
63
+ setup_accessors_for_property_info prop
64
+ end
65
+ end
66
+
67
+ def setup_accessors_for_property_info prop
68
+ builder = Builder::Property.new prop
69
+ unless has_instance_method prop.getter_name
70
+ @klass.class_eval builder.getter_def
71
+ end
72
+ @klass.class_eval builder.setter_def
73
+ end
74
+
50
75
  def setup_vfunc_invokers
51
76
  info.vfuncs.each do |vfinfo|
52
77
  invoker = vfinfo.invoker
@@ -20,10 +20,14 @@ module GirFFI
20
20
  const_defined_for @klass, :GIR_FFI_BUILDER
21
21
  end
22
22
 
23
+ def target_gtype
24
+ info.g_type
25
+ end
26
+
23
27
  # TODO: Rename the created method, or use a constant.
24
28
  # FIXME: Only used in some of the subclases. Make mixin?
25
29
  def setup_gtype_getter
26
- gtype = info.g_type
30
+ gtype = target_gtype
27
31
  return if gtype.nil?
28
32
  @klass.instance_eval "
29
33
  def self.get_gtype
@@ -45,6 +49,10 @@ module GirFFI
45
49
  nil
46
50
  end
47
51
 
52
+ def fields
53
+ info.fields
54
+ end
55
+
48
56
  def superclass
49
57
  unless defined? @superclass
50
58
  if parent
@@ -18,12 +18,19 @@ module GirFFI
18
18
  def instantiate_class
19
19
  CACHE[@gtype] ||= Class.new(superclass)
20
20
  @klass = CACHE[@gtype]
21
+ @structklass = get_or_define_class @klass, :Struct, layout_superclass
21
22
  setup_class unless already_set_up
22
23
  end
23
24
 
25
+ def target_gtype
26
+ @gtype
27
+ end
28
+
24
29
  def setup_class
25
30
  setup_constants
31
+ setup_layout
26
32
  setup_interfaces
33
+ setup_gtype_getter
27
34
  end
28
35
 
29
36
  def setup_instance_method method
@@ -32,15 +39,30 @@ module GirFFI
32
39
 
33
40
  private
34
41
 
42
+ def superclass
43
+ GirFFI::Builder.build_by_gtype parent_gtype
44
+ end
45
+
35
46
  def parent
36
- parent_type = ::GObject.type_parent @gtype
37
- gir.find_by_gtype(parent_type)
47
+ gir.find_by_gtype parent_gtype
48
+ end
49
+
50
+ def parent_gtype
51
+ GObject.type_parent @gtype
52
+ end
53
+
54
+ def fields
55
+ []
38
56
  end
39
57
 
40
58
  def interface_infos
41
- ::GObject.type_interfaces(@gtype).map do |gtype|
59
+ interface_gtypes.map do |gtype|
42
60
  gir.find_by_gtype gtype
43
- end
61
+ end.compact
62
+ end
63
+
64
+ def interface_gtypes
65
+ ::GObject.type_interfaces(@gtype)
44
66
  end
45
67
 
46
68
  def interfaces
@@ -52,10 +74,6 @@ module GirFFI
52
74
  def signal_definers
53
75
  interface_infos
54
76
  end
55
-
56
- def gir
57
- @gir ||= GObjectIntrospection::IRepository.default
58
- end
59
77
  end
60
78
  end
61
79
  end
@@ -0,0 +1,119 @@
1
+ require 'gir_ffi/user_defined/i_object_info'
2
+ require 'gir_ffi/user_defined/i_property_info'
3
+ require 'gir_ffi/builder/type/object'
4
+
5
+ module GirFFI
6
+ module Builder
7
+ module Type
8
+
9
+ # Implements the creation of GObject subclasses from Ruby.
10
+ class UserDefined < Object
11
+ def initialize klass, &block
12
+ @block = block
13
+ @klass_before_set_up = klass
14
+ end
15
+
16
+ def instantiate_class
17
+ @klass = @klass_before_set_up
18
+ @info = GirFFI::UserDefined::IObjectInfo.new
19
+
20
+ self.instance_eval(&@block) if @block
21
+
22
+ parent_type = @klass.get_gtype
23
+ @parent = gir.find_by_gtype(parent_type)
24
+
25
+ query_result = GObject.type_query parent_type
26
+ type_info = GObject::TypeInfo.new
27
+ type_info.class_size = query_result.class_size
28
+ type_info.instance_size = query_result.instance_size
29
+ properties.each do
30
+ type_info.instance_size += FFI.type_size(:int32)
31
+ end
32
+
33
+ new_type = GObject.type_register_static parent_type, @klass.name, type_info, 0
34
+
35
+ # TODO: Check that class ultimately derives from GObject.
36
+ @gtype = new_type
37
+ @structklass = get_or_define_class @klass, :Struct, layout_superclass
38
+ setup_class unless already_set_up
39
+ end
40
+
41
+ def setup_class
42
+ setup_layout
43
+ setup_constants
44
+ #stub_methods
45
+ setup_gtype_getter
46
+ setup_property_accessors
47
+ #setup_vfunc_invokers
48
+ #setup_interfaces
49
+ setup_constructor
50
+ end
51
+
52
+ private
53
+
54
+ def target_gtype
55
+ @gtype
56
+ end
57
+
58
+ def parent
59
+ @parent
60
+ end
61
+
62
+ def install_property pspec
63
+ pinfo = GirFFI::UserDefined::IPropertyInfo.new
64
+ pinfo.name = pspec.parent_instance.get_name
65
+ properties << pinfo
66
+ end
67
+
68
+ def properties
69
+ info.properties
70
+ end
71
+
72
+ def layout_specification
73
+ parent_spec = [:parent, superclass::Struct, 0]
74
+ offset = superclass::Struct.size
75
+ fields_spec = properties.map do |pinfo|
76
+ spec = [pinfo.name.to_sym, :int32, offset]
77
+ offset += FFI.type_size(:int32)
78
+ spec
79
+ end.flatten(1)
80
+ parent_spec + fields_spec
81
+ end
82
+
83
+ def setup_property_accessors
84
+ properties.each do |pinfo|
85
+ setup_accessors_for_param_info pinfo
86
+ end
87
+ end
88
+
89
+ def setup_accessors_for_param_info pinfo
90
+ code = <<-CODE
91
+ def #{pinfo.name}
92
+ @struct[:#{pinfo.name}]
93
+ end
94
+ def #{pinfo.name}= val
95
+ @struct[:#{pinfo.name}] = val
96
+ end
97
+ CODE
98
+
99
+ @klass.class_eval code
100
+ end
101
+
102
+ def method_introspection_data method
103
+ nil
104
+ end
105
+
106
+ def setup_constructor
107
+ code = <<-CODE
108
+ def self.new
109
+ gptr = GObject::Lib.g_object_newv #{@gtype}, 0, nil
110
+ self.wrap(gptr)
111
+ end
112
+ CODE
113
+ @klass.class_eval code
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+
@@ -26,7 +26,7 @@ module GirFFI
26
26
  end
27
27
 
28
28
  def base_layout_specification
29
- info.fields.map { |finfo| finfo.layout_specification }.flatten(1)
29
+ fields.map { |finfo| finfo.layout_specification }.flatten(1)
30
30
  end
31
31
 
32
32
  def layout_specification
@@ -39,7 +39,7 @@ module GirFFI
39
39
  end
40
40
 
41
41
  def setup_accessors_for_field_info finfo
42
- builder = Builder::Field.new(finfo, lib)
42
+ builder = Builder::Field.new(finfo, lib, @structklass)
43
43
  unless has_instance_method finfo.name
44
44
  @klass.class_eval builder.getter_def
45
45
  end
@@ -47,7 +47,7 @@ module GirFFI
47
47
  end
48
48
 
49
49
  def setup_field_accessors
50
- info.fields.each do |finfo|
50
+ fields.each do |finfo|
51
51
  setup_accessors_for_field_info finfo
52
52
  end
53
53
  end
@@ -61,6 +61,11 @@ module GirFFI
61
61
 
62
62
  def self.ffi_function_return_type info
63
63
  rt = info.return_type
64
+ # FIXME: Workaround for older gobject-introspection not identifying all
65
+ # objects as being pointers.
66
+ if rt.tag == :interface and rt.interface.info_type == :object
67
+ return :pointer
68
+ end
64
69
  itypeinfo_to_ffitype rt
65
70
  end
66
71
 
@@ -9,10 +9,6 @@ module GirFFI
9
9
  extend Forwardable
10
10
  def_delegators :@struct, :to_ptr
11
11
 
12
- def initialize(*args)
13
- @struct = ffi_structure.new(*args)
14
- end
15
-
16
12
  def ffi_structure
17
13
  self.class.ffi_structure
18
14
  end
@@ -81,7 +77,9 @@ module GirFFI
81
77
 
82
78
  def wrap ptr
83
79
  return nil if ptr.nil? or ptr.null?
84
- _real_new ptr.to_ptr
80
+ obj = _real_new
81
+ obj.instance_variable_set :@struct, ffi_structure.new(ptr.to_ptr)
82
+ obj
85
83
  end
86
84
 
87
85
  # TODO: Only makes sense for :objects.
@@ -90,7 +88,9 @@ module GirFFI
90
88
  end
91
89
 
92
90
  def allocate
93
- _real_new
91
+ obj = _real_new
92
+ obj.instance_variable_set :@struct, ffi_structure.new
93
+ obj
94
94
  end
95
95
 
96
96
  # Pass-through casting method. This may become a type checking
@@ -0,0 +1,12 @@
1
+ module GirFFI
2
+ module InfoExt
3
+ module IPropertyInfo
4
+ def getter_name
5
+ name.gsub(/-/, '_')
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ GObjectIntrospection::IPropertyInfo.send :include, GirFFI::InfoExt::IPropertyInfo
12
+
@@ -14,6 +14,10 @@ module GirFFI
14
14
  :int
15
15
  when :array
16
16
  subtype = param_type(0).layout_specification_type
17
+ # XXX Don't use pointer directly to appease JRuby.
18
+ if subtype == :pointer
19
+ subtype = :"uint#{FFI.type_size(:pointer)*8}"
20
+ end
17
21
  [subtype, array_fixed_size]
18
22
  else
19
23
  ffitype
@@ -0,0 +1,7 @@
1
+ module GirFFI
2
+ module UserDefined
3
+ class IBaseInfo
4
+ attr_accessor :name
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'gir_ffi/user_defined/i_registered_type_info'
2
+
3
+ module GirFFI
4
+ module UserDefined
5
+ class IObjectInfo < IRegisteredTypeInfo
6
+ attr_accessor :properties
7
+ def initialize
8
+ @properties = []
9
+ end
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,9 @@
1
+ require 'gir_ffi/user_defined/i_base_info'
2
+
3
+ module GirFFI
4
+ module UserDefined
5
+ class IPropertyInfo < IBaseInfo
6
+ attr_accessor :property_type
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'gir_ffi/user_defined/i_base_info'
2
+
3
+ module GirFFI
4
+ module UserDefined
5
+ class IRegisteredTypeInfo < IBaseInfo
6
+ end
7
+ end
8
+ end
9
+
10
+
@@ -1,4 +1,4 @@
1
1
  module GirFFI
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.0"
3
3
  end
4
4
 
data/lib/gir_ffi.rb CHANGED
@@ -13,6 +13,12 @@ module GirFFI
13
13
  module_name = module_name.to_s
14
14
  GirFFI::Builder.build_module module_name, version
15
15
  end
16
+
17
+ def self.define_type klass, &block
18
+ Builder::Type::UserDefined.new(klass, &block).build_class
19
+
20
+ klass.get_gtype
21
+ end
16
22
  end
17
23
 
18
24
  require 'ffi-glib'
data/tasks/test.rake CHANGED
@@ -38,13 +38,22 @@ namespace :test do
38
38
  t.ruby_opts += ["-w"]
39
39
  end
40
40
 
41
+ Rake::TestTask.new(:gtk) do |t|
42
+ t.libs = ['lib']
43
+ t.test_files = FileList['test/ffi-gtk/*_test.rb']
44
+ t.ruby_opts += ["-w"]
45
+ end
46
+
41
47
  desc 'Build Regress test library and typelib'
42
48
  task :lib => "test/lib/Makefile" do
43
49
  sh %{cd test/lib && make}
44
50
  end
45
51
 
46
- task :integration => :lib
47
52
  task :run => :lib
53
+ task :unit => :lib
54
+ task :glib => :lib
55
+ task :gobject => :lib
56
+ task :integration => :lib
48
57
 
49
58
  desc 'Run rcov for the entire test suite'
50
59
  task :coverage => :lib do
@@ -63,4 +72,5 @@ end
63
72
 
64
73
  desc 'Run unit an integration tests'
65
74
  task :test => ['test:gobjectintrospection',
66
- 'test:unit', 'test:run', 'test:glib', 'test:gobject', 'test:integration']
75
+ 'test:unit', 'test:run', 'test:glib', 'test:gobject', 'test:gtk',
76
+ 'test:integration']