gir_ffi 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/History.txt +8 -0
  2. data/README.md +1 -1
  3. data/TODO.rdoc +12 -4
  4. data/lib/ffi-glib.rb +0 -5
  5. data/lib/ffi-glib/list.rb +1 -1
  6. data/lib/ffi-glib/s_list.rb +1 -1
  7. data/lib/ffi-gobject.rb +2 -3
  8. data/lib/ffi-gobject/closure.rb +4 -3
  9. data/lib/ffi-gobject_introspection/i_base_info.rb +11 -14
  10. data/lib/ffi-gobject_introspection/i_constant_info.rb +1 -1
  11. data/lib/ffi-gobject_introspection/i_function_info.rb +0 -6
  12. data/lib/ffi-gobject_introspection/lib.rb +8 -2
  13. data/lib/gir_ffi.rb +5 -0
  14. data/lib/gir_ffi/arg_helper.rb +1 -1
  15. data/lib/gir_ffi/argument_builder.rb +161 -0
  16. data/lib/gir_ffi/base_argument_builder.rb +146 -0
  17. data/lib/gir_ffi/builder/field.rb +7 -5
  18. data/lib/gir_ffi/builder/module.rb +3 -14
  19. data/lib/gir_ffi/builder/property.rb +0 -2
  20. data/lib/gir_ffi/builder/type/callback.rb +0 -8
  21. data/lib/gir_ffi/builder/type/constant.rb +0 -4
  22. data/lib/gir_ffi/builder/type/enum.rb +0 -4
  23. data/lib/gir_ffi/builder/type/interface.rb +0 -4
  24. data/lib/gir_ffi/builder/type/object.rb +0 -1
  25. data/lib/gir_ffi/builder/type/struct_based.rb +0 -6
  26. data/lib/gir_ffi/builder/type/union.rb +0 -4
  27. data/lib/gir_ffi/builder/type/with_layout.rb +0 -1
  28. data/lib/gir_ffi/builder/type/with_methods.rb +1 -7
  29. data/lib/gir_ffi/callback.rb +9 -0
  30. data/lib/gir_ffi/callback_helper.rb +8 -1
  31. data/lib/gir_ffi/class_base.rb +6 -26
  32. data/lib/gir_ffi/error_argument_builder.rb +17 -0
  33. data/lib/gir_ffi/{builder/function.rb → function_builder.rb} +14 -11
  34. data/lib/gir_ffi/in_out_pointer.rb +29 -36
  35. data/lib/gir_ffi/in_pointer.rb +1 -1
  36. data/lib/gir_ffi/info_ext.rb +6 -0
  37. data/lib/gir_ffi/info_ext/i_field_info.rb +0 -2
  38. data/lib/gir_ffi/info_ext/i_type_info.rb +29 -10
  39. data/lib/gir_ffi/info_ext/safe_constant_name.rb +21 -0
  40. data/lib/gir_ffi/info_ext/safe_function_name.rb +13 -0
  41. data/lib/gir_ffi/interface_base.rb +1 -11
  42. data/lib/gir_ffi/module_base.rb +0 -10
  43. data/lib/gir_ffi/null_argument_builder.rb +9 -0
  44. data/lib/gir_ffi/return_value_builder.rb +75 -0
  45. data/lib/gir_ffi/setter_argument_info.rb +16 -0
  46. data/lib/gir_ffi/type_map.rb +10 -1
  47. data/lib/gir_ffi/version.rb +1 -1
  48. data/tasks/test.rake +61 -0
  49. data/test/base_test_helper.rb +0 -2
  50. data/test/ffi-gobject/value_test.rb +15 -0
  51. data/test/ffi-gobject_introspection/i_base_info_test.rb +31 -6
  52. data/test/ffi-gobject_introspection/i_function_info_test.rb +0 -17
  53. data/test/ffi-gobject_introspection/lib_test.rb +0 -55
  54. data/test/ffi-gobject_test.rb +2 -1
  55. data/test/gir_ffi/argument_builder_test.rb +414 -0
  56. data/test/gir_ffi/base_argument_builder_test.rb +13 -0
  57. data/test/gir_ffi/builder/module_test.rb +4 -40
  58. data/test/gir_ffi/builder/type/callback_test.rb +0 -27
  59. data/test/gir_ffi/builder/type/constant_test.rb +0 -12
  60. data/test/gir_ffi/builder/type/enum_test.rb +0 -20
  61. data/test/gir_ffi/builder/type/interface_test.rb +0 -11
  62. data/test/gir_ffi/builder/type/object_test.rb +2 -2
  63. data/test/gir_ffi/builder/type/struct_test.rb +0 -39
  64. data/test/gir_ffi/builder/type/unintrospectable_test.rb +1 -1
  65. data/test/gir_ffi/builder/type/union_test.rb +0 -11
  66. data/test/gir_ffi/builder_test.rb +3 -11
  67. data/test/gir_ffi/callback_helper_test.rb +7 -0
  68. data/test/gir_ffi/{builder/function_test.rb → function_builder_test.rb} +16 -28
  69. data/test/gir_ffi/in_out_pointer_test.rb +0 -20
  70. data/test/gir_ffi/info_ext/i_type_info_test.rb +112 -26
  71. data/test/gir_ffi/info_ext/safe_constant_name_test.rb +16 -0
  72. data/test/gir_ffi/info_ext/safe_function_name_test.rb +22 -0
  73. data/test/gir_ffi/return_value_builder_test.rb +355 -0
  74. data/test/integration/generated_gimarshallingtests_test.rb +608 -296
  75. data/test/integration/generated_regress_test.rb +879 -494
  76. metadata +35 -24
  77. data/lib/gir_ffi/builder/argument.rb +0 -569
  78. data/lib/gir_ffi/builder/argument/base.rb +0 -151
  79. data/lib/gir_ffi/builder/argument/in_base.rb +0 -14
  80. data/lib/gir_ffi/builder/argument/in_out_base.rb +0 -18
  81. data/lib/gir_ffi/builder/argument/out_base.rb +0 -15
  82. data/test/gir_ffi/builder/argument/base_test.rb +0 -55
  83. data/test/integration/pretty_print_test.rb +0 -33
@@ -90,26 +90,6 @@ describe GirFFI::InOutPointer do
90
90
  end
91
91
  end
92
92
 
93
- describe "::for_array" do
94
- it "handles :gint32" do
95
- @ptr = GirFFI::InOutPointer.for_array :gint32
96
- assert_equal :pointer, @ptr.value_type
97
- assert_equal :gint32, @ptr.sub_type
98
- end
99
-
100
- it "handles GObject" do
101
- @ptr = GirFFI::InOutPointer.for_array GObject::Object
102
- assert_equal :pointer, @ptr.value_type
103
- assert_equal GObject::Object, @ptr.sub_type
104
- end
105
-
106
- it "handles pointer to GObject" do
107
- @ptr = GirFFI::InOutPointer.for_array [:pointer, GObject::Object]
108
- assert_equal :pointer, @ptr.value_type
109
- assert_equal [:pointer, GObject::Object], @ptr.sub_type
110
- end
111
- end
112
-
113
93
  describe "#to_value" do
114
94
  it "returns the held value" do
115
95
  ptr = GirFFI::InOutPointer.from :gint32, 123
@@ -4,51 +4,49 @@ describe GirFFI::InfoExt::ITypeInfo do
4
4
  let(:testclass) { Class.new do
5
5
  include GirFFI::InfoExt::ITypeInfo
6
6
  end }
7
+ let(:type_info) { testclass.new }
8
+ let(:elmtype_info) { testclass.new }
9
+ let(:keytype_info) { testclass.new }
10
+ let(:valtype_info) { testclass.new }
7
11
 
8
12
  describe "#layout_specification_type" do
9
13
  it "returns an array with elements subtype and size for type :array" do
10
- mock(subtype = Object.new).layout_specification_type { :foo }
14
+ mock(elmtype_info).layout_specification_type { :foo }
11
15
 
12
- type = testclass.new
13
- mock(type).array_fixed_size { 2 }
14
- mock(type).param_type(0) { subtype }
16
+ mock(type_info).array_fixed_size { 2 }
17
+ mock(type_info).param_type(0) { elmtype_info }
15
18
 
16
- mock(GirFFI::Builder).itypeinfo_to_ffitype(type) { :array }
17
-
18
- result = type.layout_specification_type
19
+ mock(GirFFI::Builder).itypeinfo_to_ffitype(type_info) { :array }
19
20
 
21
+ result = type_info.layout_specification_type
20
22
  assert_equal [:foo, 2], result
21
23
  end
22
24
  end
23
25
 
24
26
  describe "#element_type" do
25
27
  it "returns the element type for lists" do
26
- type_info = testclass.new
27
- mock(elm_type = Object.new).tag { :foo }
28
+ mock(elmtype_info).tag { :foo }
28
29
 
29
30
  mock(type_info).tag {:glist}
30
- mock(type_info).param_type(0) { elm_type }
31
+ mock(type_info).param_type(0) { elmtype_info }
31
32
 
32
33
  result = type_info.element_type
33
34
  result.must_equal :foo
34
35
  end
35
36
 
36
37
  it "returns the key and value types for ghashes" do
37
- type_info = testclass.new
38
- mock(key_type = Object.new).tag { :foo }
39
- mock(val_type = Object.new).tag { :bar }
38
+ mock(keytype_info).tag { :foo }
39
+ mock(valtype_info).tag { :bar }
40
40
 
41
41
  mock(type_info).tag {:ghash}
42
- mock(type_info).param_type(0) { key_type }
43
- mock(type_info).param_type(1) { val_type }
42
+ mock(type_info).param_type(0) { keytype_info }
43
+ mock(type_info).param_type(1) { valtype_info }
44
44
 
45
45
  result = type_info.element_type
46
46
  result.must_equal [:foo, :bar]
47
47
  end
48
48
 
49
49
  it "returns nil for other types" do
50
- type_info = testclass.new
51
-
52
50
  mock(type_info).tag {:foo}
53
51
 
54
52
  result = type_info.element_type
@@ -56,8 +54,6 @@ describe GirFFI::InfoExt::ITypeInfo do
56
54
  end
57
55
 
58
56
  it "returns :gpointer if the element type is a pointer with tag :void" do
59
- type_info = testclass.new
60
-
61
57
  stub(elm_type = Object.new).tag { :void }
62
58
  stub(elm_type).pointer? { true }
63
59
 
@@ -71,21 +67,111 @@ describe GirFFI::InfoExt::ITypeInfo do
71
67
  describe "#type_specification" do
72
68
  describe "for a simple type" do
73
69
  it "returns the type tag" do
74
- type_info = testclass.new
75
- mock(type_info).tag { :uint32 }
70
+ stub(type_info).tag { :uint32 }
71
+
76
72
  type_info.type_specification.must_equal ":uint32"
77
73
  end
78
74
  end
79
75
 
80
- describe "for a zero-terminated array" do
81
- it "returns the pair [:strv, element_type]" do
82
- type_info = testclass.new
83
- mock(type_info).tag { :array }
84
- stub(type_info).element_type { :utf8 }
76
+ describe "for a zero-terminated utf8 array" do
77
+ it "returns the pair [:strv, :utf8]" do
78
+ stub(elmtype_info).tag { :utf8 }
79
+ stub(elmtype_info).pointer? { true }
80
+
81
+ stub(type_info).tag { :array }
82
+ stub(type_info).param_type(0) { elmtype_info }
85
83
  stub(type_info).zero_terminated? { true }
86
84
  stub(type_info).array_type { :c }
85
+
87
86
  type_info.type_specification.must_equal "[:strv, :utf8]"
88
87
  end
89
88
  end
89
+
90
+ describe "for a zero-terminated array" do
91
+ it "returns the pair [:zero_terminated, element_type]" do
92
+ stub(elmtype_info).tag { :foo }
93
+ stub(elmtype_info).pointer? { false }
94
+
95
+ stub(type_info).tag { :array }
96
+ stub(type_info).param_type(0) { elmtype_info }
97
+ stub(type_info).zero_terminated? { true }
98
+ stub(type_info).array_type { :c }
99
+
100
+ type_info.type_specification.must_equal "[:zero_terminated, :foo]"
101
+ end
102
+ end
103
+
104
+ describe "for a fixed length c-like array of type :foo" do
105
+ it "returns the pair [:c, :foo]" do
106
+ mock(elmtype_info).tag { :foo }
107
+ mock(elmtype_info).pointer? { false }
108
+
109
+ mock(type_info).tag { :array }
110
+ stub(type_info).param_type(0) { elmtype_info }
111
+ stub(type_info).zero_terminated? { false }
112
+ stub(type_info).array_type { :c }
113
+
114
+ type_info.type_specification.must_equal "[:c, :foo]"
115
+ end
116
+ end
117
+
118
+ end
119
+
120
+ describe "#subtype_tag_or_class_name" do
121
+ describe "for a simple type" do
122
+ it "returns the string ':void'" do
123
+ mock(subtype = Object.new).tag { :void }
124
+ mock(subtype).pointer? { false }
125
+
126
+ mock(info = testclass.new).param_type(0) { subtype }
127
+
128
+ assert_equal ":void", info.subtype_tag_or_class_name
129
+ end
130
+ end
131
+
132
+ describe "for an array of simple type :foo" do
133
+ it "returns the string ':foo'" do
134
+ mock(subtype = Object.new).tag { :foo }
135
+ mock(subtype).pointer? { false }
136
+
137
+ mock(info = testclass.new).param_type(0) { subtype }
138
+
139
+ assert_equal ":foo", info.subtype_tag_or_class_name
140
+ end
141
+ end
142
+
143
+ describe "for an array of :utf8" do
144
+ it "returns the string ':utf8'" do
145
+ mock(subtype = Object.new).tag { :utf8 }
146
+ mock(subtype).pointer? { true }
147
+
148
+ mock(info = testclass.new).param_type(0) { subtype }
149
+
150
+ assert_equal ":utf8", info.subtype_tag_or_class_name
151
+ end
152
+ end
153
+
154
+ describe "for an array of an interface class" do
155
+ it "returns the interface's full class name" do
156
+ mock(subtype = Object.new).tag { :interface }
157
+ mock(subtype).interface_type_name { "-full-type-name-" }
158
+ mock(subtype).pointer? { false }
159
+
160
+ mock(info = testclass.new).param_type(0) { subtype }
161
+
162
+ assert_equal "-full-type-name-", info.subtype_tag_or_class_name
163
+ end
164
+ end
165
+
166
+ describe "for an array of pointer to simple type :foo" do
167
+ it "returns the string '[:pointer, :foo]'" do
168
+ mock(subtype = Object.new).tag { :foo }
169
+ mock(subtype).pointer? { true }
170
+
171
+ mock(info = testclass.new).param_type(0) { subtype }
172
+
173
+ assert_equal "[:pointer, :foo]", info.subtype_tag_or_class_name
174
+ end
175
+ end
90
176
  end
91
177
  end
@@ -0,0 +1,16 @@
1
+ require 'gir_ffi_test_helper'
2
+
3
+ describe GirFFI::InfoExt::SafeConstantName do
4
+ let(:testclass) { Class.new do
5
+ include GirFFI::InfoExt::SafeConstantName
6
+ end }
7
+ let(:info) { testclass.new }
8
+
9
+ describe "#safe_name" do
10
+ it "makes names starting with an underscore safe" do
11
+ mock(info).name { "_foo" }
12
+
13
+ assert_equal "Private___foo", info.safe_name
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ require 'gir_ffi_test_helper'
2
+
3
+ describe GirFFI::InfoExt::SafeFunctionName do
4
+ let(:testclass) { Class.new do
5
+ include GirFFI::InfoExt::SafeFunctionName
6
+ end }
7
+ let(:info) { testclass.new }
8
+
9
+ describe "#safe_name" do
10
+ it "keeps lower case names lower case" do
11
+ mock(info).name { "foo" }
12
+
13
+ assert_equal "foo", info.safe_name
14
+ end
15
+
16
+ it "returns a non-empty string if name is empty" do
17
+ mock(info).name { "" }
18
+
19
+ assert_equal "_", info.safe_name
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,355 @@
1
+ require 'gir_ffi_test_helper'
2
+
3
+ describe GirFFI::ReturnValueBuilder do
4
+ let(:type_info) { Object.new }
5
+ let(:var_gen) { GirFFI::VariableNameGenerator.new }
6
+ let(:for_constructor) { "irrelevant" }
7
+ let(:builder) { GirFFI::ReturnValueBuilder.new(var_gen,
8
+ type_info,
9
+ for_constructor) }
10
+
11
+ before do
12
+ stub(type_info).interface_type_name { 'Bar::Foo' }
13
+ end
14
+
15
+ describe "for :gint32" do
16
+ before do
17
+ stub(type_info).flattened_tag { :gint32 }
18
+ end
19
+
20
+ it "has no statements in #post" do
21
+ builder.post.must_equal []
22
+ end
23
+
24
+ it "returns the result of the c function directly" do
25
+ builder.callarg.must_equal "_v1"
26
+ builder.retval.must_equal "_v1"
27
+ end
28
+ end
29
+
30
+ describe "for :struct" do
31
+ before do
32
+ stub(type_info).flattened_tag { :struct }
33
+ end
34
+
35
+ it "wraps the result in #post" do
36
+ builder.callarg.must_equal "_v1"
37
+ builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ]
38
+ end
39
+
40
+ it "returns the wrapped result" do
41
+ builder.callarg.must_equal "_v1"
42
+ builder.retval.must_equal "_v2"
43
+ end
44
+ end
45
+
46
+ describe "for :union" do
47
+ before do
48
+ stub(type_info).flattened_tag { :union }
49
+ end
50
+
51
+ it "wraps the result in #post" do
52
+ builder.callarg.must_equal "_v1"
53
+ builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ]
54
+ end
55
+
56
+ it "returns the wrapped result" do
57
+ builder.callarg.must_equal "_v1"
58
+ builder.retval.must_equal "_v2"
59
+ end
60
+ end
61
+
62
+ describe "for :interface" do
63
+ before do
64
+ stub(type_info).flattened_tag { :interface }
65
+ end
66
+
67
+ describe "when the method is not a constructor" do
68
+ let(:for_constructor) { false }
69
+
70
+ it "wraps the result in #post" do
71
+ builder.callarg.must_equal "_v1"
72
+ builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ]
73
+ end
74
+
75
+ it "returns the wrapped result" do
76
+ builder.callarg.must_equal "_v1"
77
+ builder.retval.must_equal "_v2"
78
+ end
79
+ end
80
+
81
+ describe "when the method is a constructor" do
82
+ let(:for_constructor) { true }
83
+
84
+ it "wraps the result in #post" do
85
+ builder.callarg.must_equal "_v1"
86
+ builder.post.must_equal [ "_v2 = self.constructor_wrap(_v1)" ]
87
+ end
88
+
89
+ it "returns the wrapped result" do
90
+ builder.callarg.must_equal "_v1"
91
+ builder.retval.must_equal "_v2"
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "for :object" do
97
+ before do
98
+ stub(type_info).flattened_tag { :object }
99
+ end
100
+
101
+ describe "when the method is not a constructor" do
102
+ let(:for_constructor) { false }
103
+
104
+ it "wraps the result in #post" do
105
+ builder.callarg.must_equal "_v1"
106
+ builder.post.must_equal [ "_v2 = Bar::Foo.wrap(_v1)" ]
107
+ end
108
+
109
+ it "returns the wrapped result" do
110
+ builder.callarg.must_equal "_v1"
111
+ builder.retval.must_equal "_v2"
112
+ end
113
+ end
114
+
115
+ describe "when the method is a constructor" do
116
+ let(:for_constructor) { true }
117
+
118
+ it "wraps the result in #post" do
119
+ builder.callarg.must_equal "_v1"
120
+ builder.post.must_equal [ "_v2 = self.constructor_wrap(_v1)" ]
121
+ end
122
+
123
+ it "returns the wrapped result" do
124
+ builder.callarg.must_equal "_v1"
125
+ builder.retval.must_equal "_v2"
126
+ end
127
+ end
128
+ end
129
+
130
+ describe "for :strv" do
131
+ before do
132
+ stub(type_info).flattened_tag { :strv }
133
+ end
134
+
135
+ it "wraps the result in #post" do
136
+ builder.callarg.must_equal "_v1"
137
+ builder.post.must_equal [ "_v2 = GLib::Strv.wrap(_v1)" ]
138
+ end
139
+
140
+ it "returns the wrapped result" do
141
+ builder.callarg.must_equal "_v1"
142
+ builder.retval.must_equal "_v2"
143
+ end
144
+ end
145
+
146
+ describe "for :zero_terminated" do
147
+ before do
148
+ stub(type_info).flattened_tag { :zero_terminated }
149
+ end
150
+
151
+ it "wraps the result in #post" do
152
+ builder.callarg.must_equal "_v1"
153
+ # FIXME: This is almost certainly wrong, but matches original behavior.
154
+ builder.post.must_equal [ "_v2 = GirFFI::InPointer.wrap(_v1)" ]
155
+ end
156
+
157
+ it "returns the wrapped result" do
158
+ builder.callarg.must_equal "_v1"
159
+ builder.retval.must_equal "_v2"
160
+ end
161
+ end
162
+
163
+ describe "for :byte_array" do
164
+ before do
165
+ stub(type_info).flattened_tag { :byte_array }
166
+ end
167
+
168
+ it "wraps the result in #post" do
169
+ builder.callarg.must_equal "_v1"
170
+ builder.post.must_equal [ "_v2 = GLib::ByteArray.wrap(_v1)" ]
171
+ end
172
+
173
+ it "returns the wrapped result" do
174
+ builder.callarg.must_equal "_v1"
175
+ builder.retval.must_equal "_v2"
176
+ end
177
+ end
178
+
179
+ describe "for :ptr_array" do
180
+ before do
181
+ stub(type_info).flattened_tag { :ptr_array }
182
+ end
183
+
184
+ it "wraps the result in #post" do
185
+ builder.callarg.must_equal "_v1"
186
+ builder.post.must_equal [ "_v2 = GLib::PtrArray.wrap(_v1)" ]
187
+ end
188
+
189
+ it "returns the wrapped result" do
190
+ builder.callarg.must_equal "_v1"
191
+ builder.retval.must_equal "_v2"
192
+ end
193
+ end
194
+
195
+ describe "for :glist" do
196
+ before do
197
+ stub(type_info).flattened_tag { :glist }
198
+ stub(type_info).element_type { :foo }
199
+ end
200
+
201
+ it "wraps the result in #post" do
202
+ builder.callarg.must_equal "_v1"
203
+ builder.post.must_equal [ "_v2 = GLib::List.wrap(:foo, _v1)" ]
204
+ end
205
+
206
+ it "returns the wrapped result" do
207
+ builder.callarg.must_equal "_v1"
208
+ builder.retval.must_equal "_v2"
209
+ end
210
+ end
211
+
212
+ describe "for :gslist" do
213
+ before do
214
+ stub(type_info).flattened_tag { :gslist }
215
+ stub(type_info).element_type { :foo }
216
+ end
217
+
218
+ it "wraps the result in #post" do
219
+ builder.callarg.must_equal "_v1"
220
+ builder.post.must_equal [ "_v2 = GLib::SList.wrap(:foo, _v1)" ]
221
+ end
222
+
223
+ it "returns the wrapped result" do
224
+ builder.callarg.must_equal "_v1"
225
+ builder.retval.must_equal "_v2"
226
+ end
227
+ end
228
+
229
+ describe "for :ghash" do
230
+ before do
231
+ stub(type_info).flattened_tag { :ghash }
232
+ stub(type_info).element_type { [:foo, :bar] }
233
+ end
234
+
235
+ it "wraps the result in #post" do
236
+ builder.callarg.must_equal "_v1"
237
+ builder.post.must_equal [ "_v2 = GLib::HashTable.wrap([:foo, :bar], _v1)" ]
238
+ end
239
+
240
+ it "returns the wrapped result" do
241
+ builder.callarg.must_equal "_v1"
242
+ builder.retval.must_equal "_v2"
243
+ end
244
+ end
245
+
246
+ describe "for :array" do
247
+ before do
248
+ stub(type_info).flattened_tag { :array }
249
+ stub(type_info).element_type { :foo }
250
+ end
251
+
252
+ it "wraps the result in #post" do
253
+ builder.callarg.must_equal "_v1"
254
+ builder.post.must_equal [ "_v2 = GLib::Array.wrap(:foo, _v1)" ]
255
+ end
256
+
257
+ it "returns the wrapped result" do
258
+ builder.callarg.must_equal "_v1"
259
+ builder.retval.must_equal "_v2"
260
+ end
261
+ end
262
+
263
+ describe "for :c" do
264
+ describe "with fixed size" do
265
+ before do
266
+ stub(type_info).flattened_tag { :c }
267
+ stub(type_info).subtype_tag_or_class_name { ":foo" }
268
+ stub(type_info).array_fixed_size { 3 }
269
+ end
270
+
271
+ it "converts the result in #post" do
272
+ builder.callarg.must_equal "_v1"
273
+ builder.post.must_equal [ "_v2 = GirFFI::ArgHelper.ptr_to_typed_array :foo, _v1, 3" ]
274
+ end
275
+
276
+ it "returns the wrapped result" do
277
+ builder.callarg.must_equal "_v1"
278
+ builder.retval.must_equal "_v2"
279
+ end
280
+ end
281
+
282
+ describe "with separate size parameter" do
283
+ let(:length_argument) { Object.new }
284
+ before do
285
+ stub(type_info).flattened_tag { :c }
286
+ stub(type_info).subtype_tag_or_class_name { ":foo" }
287
+ stub(type_info).array_fixed_size { -1 }
288
+
289
+ stub(length_argument).retname { "bar" }
290
+ builder.length_arg = length_argument
291
+ end
292
+
293
+ it "converts the result in #post" do
294
+ builder.callarg.must_equal "_v1"
295
+ builder.post.must_equal [ "_v2 = GirFFI::ArgHelper.ptr_to_typed_array :foo, _v1, bar" ]
296
+ end
297
+
298
+ it "returns the wrapped result" do
299
+ builder.callarg.must_equal "_v1"
300
+ builder.retval.must_equal "_v2"
301
+ end
302
+ end
303
+ end
304
+
305
+ describe "for :utf8" do
306
+ before do
307
+ stub(type_info).flattened_tag { :utf8 }
308
+ end
309
+
310
+ it "converts the result in #post" do
311
+ builder.callarg.must_equal "_v1"
312
+ builder.post.must_equal [ "_v2 = GirFFI::ArgHelper.ptr_to_utf8(_v1)" ]
313
+ end
314
+
315
+ it "returns the converted result" do
316
+ builder.callarg.must_equal "_v1"
317
+ builder.retval.must_equal "_v2"
318
+ end
319
+ end
320
+
321
+ describe "for :void pointer" do
322
+ before do
323
+ stub(type_info).flattened_tag { :void }
324
+ stub(type_info).pointer? { true }
325
+ end
326
+
327
+ it "has no statements in #post" do
328
+ builder.post.must_equal []
329
+ end
330
+
331
+ it "returns the result of the c function directly" do
332
+ builder.callarg.must_equal "_v1"
333
+ builder.retval.must_equal "_v1"
334
+ end
335
+ end
336
+
337
+ describe "for :void" do
338
+ before do
339
+ stub(type_info).flattened_tag { :void }
340
+ stub(type_info).pointer? { false }
341
+ end
342
+
343
+ it "has no statements in #post" do
344
+ builder.post.must_equal []
345
+ end
346
+
347
+ it "does not capture the result of the c function" do
348
+ builder.cvar.must_be_nil
349
+ end
350
+
351
+ it "returns nothing" do
352
+ builder.retval.must_be_nil
353
+ end
354
+ end
355
+ end