gir_ffi 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/History.txt +6 -0
  2. data/lib/ffi-glib.rb +1 -0
  3. data/lib/ffi-glib/array.rb +49 -10
  4. data/lib/ffi-glib/hash_table.rb +19 -5
  5. data/lib/ffi-glib/list.rb +4 -1
  6. data/lib/ffi-glib/list_methods.rb +8 -1
  7. data/lib/ffi-glib/s_list.rb +4 -1
  8. data/lib/ffi-glib/strv.rb +31 -0
  9. data/lib/ffi-gobject.rb +2 -35
  10. data/lib/ffi-gobject/base.rb +38 -0
  11. data/lib/ffi-gobject/object.rb +28 -30
  12. data/lib/ffi-gobject/value.rb +72 -56
  13. data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -1
  14. data/lib/ffi-gobject_introspection/lib.rb +3 -1
  15. data/lib/gir_ffi/arg_helper.rb +2 -19
  16. data/lib/gir_ffi/builder/argument.rb +239 -305
  17. data/lib/gir_ffi/builder/argument/base.rb +12 -9
  18. data/lib/gir_ffi/builder/argument/in_base.rb +2 -6
  19. data/lib/gir_ffi/builder/argument/in_out_base.rb +2 -5
  20. data/lib/gir_ffi/builder/argument/out_base.rb +0 -11
  21. data/lib/gir_ffi/builder/field.rb +55 -0
  22. data/lib/gir_ffi/builder/function.rb +7 -7
  23. data/lib/gir_ffi/builder/module.rb +5 -7
  24. data/lib/gir_ffi/builder/type/object.rb +0 -33
  25. data/lib/gir_ffi/builder/type/registered_type.rb +0 -16
  26. data/lib/gir_ffi/builder/type/struct_based.rb +3 -3
  27. data/lib/gir_ffi/builder/type/unintrospectable.rb +1 -1
  28. data/lib/gir_ffi/builder/type/with_layout.rb +26 -58
  29. data/lib/gir_ffi/builder/type/with_methods.rb +9 -11
  30. data/lib/gir_ffi/class_base.rb +24 -6
  31. data/lib/gir_ffi/ffi_ext/pointer.rb +15 -0
  32. data/lib/gir_ffi/in_pointer.rb +10 -5
  33. data/lib/gir_ffi/info_ext/i_field_info.rb +15 -0
  34. data/lib/gir_ffi/info_ext/i_type_info.rb +26 -0
  35. data/lib/gir_ffi/method_stubber.rb +18 -0
  36. data/lib/gir_ffi/type_map.rb +1 -0
  37. data/lib/gir_ffi/variable_name_generator.rb +2 -0
  38. data/lib/gir_ffi/version.rb +1 -1
  39. data/test/builder_test.rb +6 -5
  40. data/test/ffi-glib/array_test.rb +40 -5
  41. data/test/ffi-glib/hash_table_test.rb +27 -3
  42. data/test/ffi-glib/list_test.rb +23 -0
  43. data/test/ffi-glib/strv_test.rb +41 -0
  44. data/test/ffi-gobject/gobject_test.rb +26 -22
  45. data/test/ffi-gobject/value_test.rb +26 -1
  46. data/test/ffi-gobject_introspection/lib_test.rb +10 -0
  47. data/test/gir_ffi_test_helper.rb +1 -1
  48. data/test/integration/derived_classes_test.rb +31 -0
  49. data/test/integration/generated_gimarshallingtests_test.rb +29 -15
  50. data/test/integration/generated_gio_test.rb +5 -6
  51. data/test/integration/generated_regress_test.rb +11 -7
  52. data/test/integration/method_lookup_test.rb +32 -0
  53. data/test/interface_type_builder_test.rb +1 -1
  54. data/test/test_helper.rb +38 -0
  55. data/test/unit/argument_builder_test.rb +16 -4
  56. data/test/unit/class_base_test.rb +48 -0
  57. data/test/unit/function_builder_test.rb +144 -4
  58. data/test/unit/hash_table_element_type_provider_test.rb +16 -0
  59. data/test/unit/i_field_info_test.rb +39 -0
  60. data/test/unit/i_type_info_test.rb +23 -0
  61. data/test/unit/list_element_type_provider_test.rb +13 -0
  62. data/test/unit/module_builder_test.rb +1 -1
  63. data/test/unit/object_type_builder_test.rb +0 -17
  64. data/test/unit/struct_builder_test.rb +27 -39
  65. metadata +118 -60
  66. data/lib/gir_ffi/builder/argument/hash_table_base.rb +0 -20
  67. data/lib/gir_ffi/builder/argument/list_base.rb +0 -16
  68. data/test/class_base_test.rb +0 -10
  69. data/test/function_definition_builder_test.rb +0 -130
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::ClassBase do
4
+ describe "a simple descendant" do
5
+ before do
6
+ @klass = Class.new GirFFI::ClassBase
7
+ end
8
+
9
+ it "has #from as a pass-through method" do
10
+ result = @klass.from :foo
11
+ result.must_equal :foo
12
+ end
13
+ end
14
+
15
+ describe "a descendant with multiple builders" do
16
+ it "looks up class methods in all builders" do
17
+ mock(builder = Object.new).setup_method("foo") { true }
18
+ klass = Class.new GirFFI::ClassBase
19
+ klass.const_set :GIR_FFI_BUILDER, builder
20
+
21
+ mock(sub_builder = Object.new).setup_method("foo") { false }
22
+ sub_klass = Class.new klass do
23
+ def self.foo; end
24
+ end
25
+ sub_klass.const_set :GIR_FFI_BUILDER, sub_builder
26
+
27
+ sub_klass.setup_and_call :foo
28
+ end
29
+
30
+ it "looks up class methods in all builders" do
31
+ mock(builder = Object.new).setup_instance_method("foo") { true }
32
+ klass = Class.new GirFFI::ClassBase
33
+ klass.const_set :GIR_FFI_BUILDER, builder
34
+
35
+ mock(sub_builder = Object.new).setup_instance_method("foo") { false }
36
+ sub_klass = Class.new klass do
37
+ def foo; end
38
+ def initialize; end
39
+ def self.new; self._real_new; end
40
+ end
41
+ sub_klass.const_set :GIR_FFI_BUILDER, sub_builder
42
+
43
+ obj = sub_klass.new
44
+
45
+ obj.setup_and_call :foo
46
+ end
47
+ end
48
+ end
@@ -13,13 +13,13 @@ describe GirFFI::Builder::Function do
13
13
 
14
14
  it "builds a correct definition of Regress:test_array_fixed_out_objects" do
15
15
  go = get_introspection_data 'Regress', 'test_array_fixed_out_objects'
16
- fbuilder = GirFFI::Builder::Function.new go, Lib
16
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
17
17
  code = fbuilder.generate
18
18
 
19
19
  expected = <<-CODE
20
- def test_array_fixed_out_objects
20
+ def self.test_array_fixed_out_objects
21
21
  _v1 = GirFFI::InOutPointer.for_array [:pointer, ::Regress::TestObj]
22
- ::Lib.regress_test_array_fixed_out_objects _v1
22
+ DummyLib.regress_test_array_fixed_out_objects _v1
23
23
  _v2 = _v1.to_sized_array_value 2
24
24
  return _v2
25
25
  end
@@ -28,8 +28,148 @@ describe GirFFI::Builder::Function do
28
28
  assert_equal expected.reset_indentation, code
29
29
  end
30
30
 
31
- end
31
+ it "builds a correct definition for functions having a linked length argument" do
32
+ go = get_introspection_data 'Regress', 'test_array_gint16_in'
33
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
34
+ code = fbuilder.generate
35
+
36
+ expected = <<-CODE
37
+ def self.test_array_gint16_in ints
38
+ n_ints = ints.nil? ? 0 : ints.length
39
+ _v1 = n_ints
40
+ _v2 = GirFFI::InPointer.from_array :gint16, ints
41
+ _v3 = DummyLib.regress_test_array_gint16_in _v1, _v2
42
+ return _v3
43
+ end
44
+ CODE
45
+
46
+ assert_equal expected.reset_indentation, code
47
+ end
32
48
 
49
+ it "builds a correct definition for functions with callbacks" do
50
+ go = get_introspection_data 'Regress', 'test_callback_destroy_notify'
51
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
52
+ code = fbuilder.generate
53
+
54
+ expected = <<-CODE
55
+ def self.test_callback_destroy_notify callback, user_data, notify
56
+ _v1 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"Regress\", \"TestCallbackUserData\", callback
57
+ DummyLib::CALLBACKS << _v1
58
+ _v2 = GirFFI::ArgHelper.object_to_inptr user_data
59
+ _v3 = GirFFI::CallbackHelper.wrap_in_callback_args_mapper \"GLib\", \"DestroyNotify\", notify
60
+ DummyLib::CALLBACKS << _v3
61
+ _v4 = DummyLib.regress_test_callback_destroy_notify _v1, _v2, _v3
62
+ return _v4
63
+ end
64
+ CODE
33
65
 
66
+ assert_equal expected.reset_indentation, code
67
+ end
68
+
69
+ it "builds correct definition for constructors" do
70
+ go = get_method_introspection_data 'Regress', 'TestObj', 'new_from_file'
71
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
72
+ code = fbuilder.generate
34
73
 
74
+ expected = <<-CODE
75
+ def self.new_from_file x
76
+ _v1 = GirFFI::InPointer.from :utf8, x
77
+ _v2 = FFI::MemoryPointer.new(:pointer).write_pointer nil
78
+ _v3 = DummyLib.regress_test_obj_new_from_file _v1, _v2
79
+ GirFFI::ArgHelper.check_error(_v2)
80
+ _v4 = self.constructor_wrap(_v3)
81
+ return _v4
82
+ end
83
+ CODE
84
+
85
+ assert_equal expected.reset_indentation, code
86
+ end
87
+
88
+ it "creates a call to GObject::Value#from for functions that take a GValue" do
89
+ go = get_introspection_data 'GIMarshallingTests', 'gvalue_in'
90
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
91
+ code = fbuilder.generate
92
+
93
+ expected = <<-CODE
94
+ def self.gvalue_in value
95
+ _v1 = ::GObject::Value.from value
96
+ DummyLib.gi_marshalling_tests_gvalue_in _v1
97
+
98
+ end
99
+ CODE
100
+
101
+ assert_equal expected.reset_indentation, code
102
+ end
103
+
104
+ it "builds correct definition for functions with a nullable input array" do
105
+ go = get_introspection_data 'Regress', 'test_array_int_null_in'
106
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
107
+ code = fbuilder.generate
35
108
 
109
+ expected = <<-CODE
110
+ def self.test_array_int_null_in arr
111
+ _v1 = GirFFI::InPointer.from_array :gint32, arr
112
+ len = arr.nil? ? 0 : arr.length
113
+ _v2 = len
114
+ DummyLib.regress_test_array_int_null_in _v1, _v2
115
+
116
+ end
117
+ CODE
118
+
119
+ assert_equal expected.reset_indentation, code
120
+ end
121
+
122
+ it "builds correct definition for functions with a nullable output array" do
123
+ go = get_introspection_data 'Regress', 'test_array_int_null_out'
124
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
125
+ code = fbuilder.generate
126
+
127
+ expected = <<-CODE
128
+ def self.test_array_int_null_out
129
+ _v1 = GirFFI::InOutPointer.for_array :gint32
130
+ _v2 = GirFFI::InOutPointer.for :gint32
131
+ DummyLib.regress_test_array_int_null_out _v1, _v2
132
+ _v3 = _v2.to_value
133
+ _v4 = _v1.to_sized_array_value _v3
134
+ return _v4
135
+ end
136
+ CODE
137
+
138
+ assert_equal expected.reset_indentation, code
139
+ end
140
+
141
+ it "builds the correct definition for a method with an inout array with size argument" do
142
+ go = get_method_introspection_data 'GIMarshallingTests', 'Object', 'method_array_inout'
143
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
144
+ code = fbuilder.generate
145
+
146
+ expected = <<-CODE
147
+ def method_array_inout ints
148
+ _v1 = GirFFI::InOutPointer.from_array :gint32, ints
149
+ length = ints.length
150
+ _v2 = GirFFI::InOutPointer.from :gint32, length
151
+ DummyLib.gi_marshalling_tests_object_method_array_inout self, _v1, _v2
152
+ _v3 = _v2.to_value
153
+ _v4 = _v1.to_sized_array_value _v3
154
+ return _v4
155
+ end
156
+ CODE
157
+
158
+ assert_equal expected.reset_indentation, code
159
+ end
160
+
161
+ it "builds a correct definition for a simple method" do
162
+ go = get_method_introspection_data 'Gtk', 'Widget', 'show'
163
+ fbuilder = GirFFI::Builder::Function.new go, DummyLib
164
+ code = fbuilder.generate
165
+
166
+ expected = <<-CODE
167
+ def show
168
+ DummyLib.gtk_widget_show self
169
+
170
+ end
171
+ CODE
172
+
173
+ assert_equal expected.reset_indentation, code
174
+ end
175
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::Builder::HashTableElementTypeProvider do
4
+ describe "#elm_t" do
5
+ it "returns a string with an array of the first two subtype tags" do
6
+ builder = Object.new
7
+ builder.extend GirFFI::Builder::HashTableElementTypeProvider
8
+
9
+ stub(builder).subtype_tag(0) { :foo }
10
+ stub(builder).subtype_tag(1) { :bar }
11
+
12
+ assert_equal "[:foo, :bar]", builder.elm_t
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::InfoExt::IFieldInfo do
4
+ describe "#layout_specification" do
5
+ it "returns an array of name, typespec and offset" do
6
+ testclass = Class.new do
7
+ include GirFFI::InfoExt::IFieldInfo
8
+ end
9
+
10
+ mock(type = Object.new).layout_specification_type { :bar }
11
+
12
+ field = testclass.new
13
+ mock(field).name { "foo" }
14
+ mock(field).field_type { type }
15
+ mock(field).offset { 0 }
16
+
17
+ result = field.layout_specification
18
+
19
+ assert_equal [:foo, :bar, 0], result
20
+ end
21
+
22
+ it "keeps a complex typespec intact" do
23
+ testclass = Class.new do
24
+ include GirFFI::InfoExt::IFieldInfo
25
+ end
26
+
27
+ mock(type = Object.new).layout_specification_type { [:bar, 2] }
28
+
29
+ field = testclass.new
30
+ mock(field).name { "foo" }
31
+ mock(field).field_type { type }
32
+ mock(field).offset { 0 }
33
+
34
+ result = field.layout_specification
35
+
36
+ assert_equal [:foo, [:bar, 2], 0], result
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::InfoExt::ITypeInfo do
4
+ describe "#layout_specification_type" do
5
+ it "returns an array with elements subtype and size for type :array" do
6
+ testclass = Class.new do
7
+ include GirFFI::InfoExt::ITypeInfo
8
+ end
9
+
10
+ mock(subtype = Object.new).layout_specification_type { :foo }
11
+
12
+ type = testclass.new
13
+ mock(type).array_fixed_size { 2 }
14
+ mock(type).param_type(0) { subtype }
15
+
16
+ mock(GirFFI::Builder).itypeinfo_to_ffitype(type) { :array }
17
+
18
+ result = type.layout_specification_type
19
+
20
+ assert_equal [:foo, 2], result
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
+
3
+ describe GirFFI::Builder::ListElementTypeProvider do
4
+ describe "#elm_t" do
5
+ it "returns a string with just the first subtype tag" do
6
+ builder = Object.new
7
+ builder.extend GirFFI::Builder::ListElementTypeProvider
8
+ mock(builder).subtype_tag { :foo }
9
+
10
+ assert_equal ":foo", builder.elm_t
11
+ end
12
+ end
13
+ end
@@ -54,7 +54,7 @@ describe GirFFI::Builder::Module do
54
54
  describe "for a :function argument" do
55
55
  it "creates a GirFFI::Builder::Function object" do
56
56
  builder = GirFFI::Builder::Module.new "Foo"
57
- mock(builder).libmodule { Lib }
57
+ mock(builder).libmodule { DummyLib }
58
58
 
59
59
  stub(info = Object.new).info_type { :function }
60
60
 
@@ -1,23 +1,6 @@
1
1
  require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe GirFFI::Builder::Type::Object do
4
- before do
5
- GirFFI.setup :Regress
6
- end
7
-
8
- describe "#setup_method" do
9
- it "sets up singleton methods defined in a class's parent" do
10
- info = get_introspection_data 'Regress', 'TestSubObj'
11
- assert_nil info.find_method "static_method"
12
- parent = info.parent
13
- assert_not_nil parent.find_method "static_method"
14
-
15
- b = GirFFI::Builder::Type::Object.new(info)
16
- b.setup_method "static_method"
17
- pass
18
- end
19
- end
20
-
21
4
  describe "#find_property" do
22
5
  it "finds a property specified on the class itself" do
23
6
  builder = GirFFI::Builder::Type::Object.new(
@@ -1,5 +1,6 @@
1
1
  require File.expand_path('../gir_ffi_test_helper.rb', File.dirname(__FILE__))
2
2
 
3
+ # FIXME: Test WithLayout directly, rather than through Struct.
3
4
  describe GirFFI::Builder::Type::Struct do
4
5
  describe "#pretty_print" do
5
6
  describe "for a struct with no methods" do
@@ -16,7 +17,7 @@ describe GirFFI::Builder::Type::Struct do
16
17
 
17
18
  describe "for a struct with a method" do
18
19
  it "returns a class block with the pretty printed method inside" do
19
- # FIXME: Loads of mocks. Make info objects create their own builders.
20
+ # FIXME: Loads of mocks.
20
21
 
21
22
  # Function info and its builder
22
23
  stub(func_info = Object.new).info_type { :function }
@@ -42,28 +43,34 @@ describe GirFFI::Builder::Type::Struct do
42
43
 
43
44
  describe "for a struct with a simple layout" do
44
45
  before do
45
- stub(@type = Object.new).pointer? { false }
46
- stub(@type).tag { :gint32 }
46
+ @field = Object.new
47
47
 
48
- stub(field = Object.new).field_type { @type }
49
- stub(field).name { "bar" }
50
- stub(field).offset { 0 }
51
- stub(field).writable? { true }
52
-
53
- stub(@struct = Object.new).safe_name { 'Bar' }
48
+ @struct = Object.new
49
+ stub(@struct).safe_name { 'Bar' }
54
50
  stub(@struct).namespace { 'Foo' }
55
- stub(@struct).fields { [ field ] }
56
- stub(@struct).find_method { }
51
+ stub(@struct).fields { [ @field ] }
57
52
 
58
53
  @builder = GirFFI::Builder::Type::Struct.new @struct
59
54
  end
60
55
 
61
56
  it "creates the correct layout specification" do
57
+ mock(@field).layout_specification { [:bar, :int32, 0] }
62
58
  spec = @builder.send :layout_specification
63
59
  assert_equal [:bar, :int32, 0], spec
64
60
  end
65
61
 
66
62
  it "creates getter and setter methods" do
63
+ # FIXME: Loads of stubs.
64
+
65
+ stub(type = Object.new).pointer? { false }
66
+ stub(type).tag { :gint32 }
67
+
68
+ stub(@field).field_type { type }
69
+ stub(@field).name { "bar" }
70
+ stub(@field).writable? { true }
71
+
72
+ stub(@struct).find_method { }
73
+
67
74
  m = Module.new { module Lib; end }
68
75
  stub(GirFFI::Builder).build_module('Foo') { m }
69
76
 
@@ -80,35 +87,18 @@ describe GirFFI::Builder::Type::Struct do
80
87
  end
81
88
  end
82
89
 
83
- describe "for a struct with a layout with a fixed-length array" do
84
- before do
85
- stub(subtype = Object.new).pointer? { false }
86
- stub(subtype).tag { :foo }
87
-
88
- stub(@type = Object.new).pointer? { false }
89
- stub(@type).tag { :array }
90
- stub(@type).array_fixed_size { 2 }
91
- stub(@type).param_type { subtype }
90
+ describe "for a struct with a layout with a complex type" do
91
+ it "does not flatten the complex type specification" do
92
+ mock(simplefield = Object.new).layout_specification { [:bar, :foo, 0] }
93
+ mock(complexfield = Object.new).layout_specification { [:baz, [:qux, 2], 0] }
94
+ mock(struct = Object.new).fields { [ simplefield, complexfield ] }
92
95
 
93
- stub(field = Object.new).field_type { @type }
94
- stub(field).name { "bar" }
95
- stub(field).offset { 0 }
96
+ stub(struct).safe_name { 'Bar' }
97
+ stub(struct).namespace { 'Foo' }
96
98
 
97
- stub(@struct = Object.new).safe_name { 'Bar' }
98
- stub(@struct).namespace { 'Foo' }
99
- stub(@struct).fields { [ field ] }
100
- end
101
-
102
- it "creates the correct ffi type for the array" do
103
- builder = GirFFI::Builder::Type::Struct.new @struct
104
- spec = builder.send :itypeinfo_to_ffitype_for_struct, @type
105
- assert_equal [:foo, 2], spec
106
- end
107
-
108
- it "creates the correct layout specification" do
109
- builder = GirFFI::Builder::Type::Struct.new @struct
99
+ builder = GirFFI::Builder::Type::Struct.new struct
110
100
  spec = builder.send :layout_specification
111
- assert_equal [:bar, [:foo, 2], 0], spec
101
+ assert_equal [:bar, :foo, 0, :baz, [:qux, 2], 0], spec
112
102
  end
113
103
  end
114
104
 
@@ -130,5 +120,3 @@ describe GirFFI::Builder::Type::Struct do
130
120
  end
131
121
  end
132
122
  end
133
-
134
-