gir_ffi 0.10.2 → 0.11.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.
- checksums.yaml +4 -4
- data/Changelog.md +13 -0
- data/Gemfile +9 -4
- data/README.md +3 -2
- data/Rakefile +2 -1
- data/lib/ffi-glib/byte_array.rb +1 -1
- data/lib/ffi-glib/main_loop.rb +2 -1
- data/lib/ffi-glib/strv.rb +5 -2
- data/lib/ffi-glib/variant.rb +3 -5
- data/lib/ffi-glib.rb +4 -0
- data/lib/ffi-gobject/closure.rb +8 -10
- data/lib/ffi-gobject/object.rb +9 -6
- data/lib/ffi-gobject/param_spec.rb +4 -0
- data/lib/ffi-gobject/value.rb +13 -16
- data/lib/ffi-gobject_introspection/gobject_type_init.rb +18 -0
- data/lib/ffi-gobject_introspection/i_callable_info.rb +1 -5
- data/lib/ffi-gobject_introspection/i_constant_info.rb +3 -3
- data/lib/ffi-gobject_introspection/i_repository.rb +3 -47
- data/lib/ffi-gobject_introspection/i_vfunc_info.rb +3 -11
- data/lib/ffi-gobject_introspection/lib.rb +8 -31
- data/lib/{gir_ffi-base/glib → ffi-gobject_introspection}/strv.rb +9 -13
- data/lib/ffi-gobject_introspection.rb +47 -2
- data/lib/gir_ffi/allocation_helper.rb +1 -19
- data/lib/gir_ffi/arg_helper.rb +36 -26
- data/lib/{gir_ffi-base/glib → gir_ffi}/boolean.rb +7 -5
- data/lib/gir_ffi/boxed_base.rb +5 -23
- data/lib/gir_ffi/builder.rb +3 -3
- data/lib/gir_ffi/builders/argument_builder.rb +7 -8
- data/lib/gir_ffi/builders/base_argument_builder.rb +0 -1
- data/lib/gir_ffi/builders/callback_argument_builder.rb +2 -2
- data/lib/gir_ffi/builders/callback_return_value_builder.rb +21 -13
- data/lib/gir_ffi/builders/field_builder.rb +4 -10
- data/lib/gir_ffi/builders/module_builder.rb +6 -4
- data/lib/gir_ffi/builders/object_builder.rb +16 -16
- data/lib/gir_ffi/builders/struct_builder.rb +4 -6
- data/lib/gir_ffi/builders/struct_like.rb +1 -1
- data/lib/gir_ffi/builders/user_defined_builder.rb +83 -23
- data/lib/gir_ffi/builders/vfunc_argument_builder.rb +12 -17
- data/lib/gir_ffi/class_base.rb +0 -4
- data/lib/gir_ffi/core.rb +16 -13
- data/lib/gir_ffi/enum_base.rb +2 -41
- data/lib/gir_ffi/enum_like_base.rb +48 -0
- data/lib/gir_ffi/ffi_ext/pointer.rb +1 -1
- data/lib/gir_ffi/flags_base.rb +2 -41
- data/lib/gir_ffi/in_out_pointer.rb +1 -1
- data/lib/gir_ffi/in_pointer.rb +4 -4
- data/lib/gir_ffi/info_ext/i_type_info.rb +14 -5
- data/lib/gir_ffi/info_ext/i_vfunc_info.rb +8 -0
- data/lib/gir_ffi/module_base.rb +4 -0
- data/lib/gir_ffi/receiver_argument_info.rb +1 -1
- data/lib/gir_ffi/sized_array.rb +6 -6
- data/lib/gir_ffi/struct_base.rb +1 -6
- data/lib/gir_ffi/struct_like_base.rb +54 -45
- data/lib/gir_ffi/type_map.rb +6 -7
- data/lib/gir_ffi/union_base.rb +1 -1
- data/lib/gir_ffi/{user_defined_type_info.rb → user_defined_object_info.rb} +1 -2
- data/lib/gir_ffi/user_defined_property_info.rb +80 -2
- data/lib/gir_ffi/version.rb +1 -1
- data/lib/gir_ffi-base/gobject/lib.rb +0 -1
- data/lib/gir_ffi-base/gobject.rb +3 -5
- data/lib/gir_ffi-base.rb +3 -8
- data/tasks/test.rake +17 -3
- data/test/base_test_helper.rb +39 -23
- data/test/ffi-glib/closure_test.rb +37 -0
- data/test/ffi-glib/main_loop_test.rb +24 -0
- data/test/ffi-glib/ruby_closure_test.rb +0 -5
- data/test/ffi-gobject/object_test.rb +6 -10
- data/test/ffi-gobject/param_spec_test.rb +17 -5
- data/test/ffi-gobject/value_test.rb +15 -6
- data/test/ffi-gobject_introspection/gobject_type_init_test.rb +25 -0
- data/test/ffi-gobject_introspection/i_base_info_test.rb +1 -1
- data/test/ffi-gobject_introspection/i_repository_test.rb +18 -0
- data/test/ffi-gobject_introspection/i_vfunc_info_test.rb +40 -0
- data/test/{gir_ffi-base/glib → ffi-gobject_introspection}/strv_test.rb +8 -8
- data/test/gir_ffi/allocation_helper_test.rb +35 -0
- data/test/gir_ffi/arg_helper_test.rb +102 -7
- data/test/gir_ffi/boolean_test.rb +34 -0
- data/test/gir_ffi/boxed_base_test.rb +46 -6
- data/test/gir_ffi/builder_test.rb +88 -29
- data/test/gir_ffi/builders/argument_builder_test.rb +19 -0
- data/test/gir_ffi/builders/callback_argument_builder_test.rb +17 -0
- data/test/gir_ffi/builders/callback_return_value_builder_test.rb +1 -1
- data/test/gir_ffi/builders/field_builder_test.rb +2 -1
- data/test/gir_ffi/builders/struct_builder_test.rb +42 -25
- data/test/gir_ffi/builders/user_defined_builder_test.rb +365 -17
- data/test/gir_ffi/builders/vfunc_argument_builder_test.rb +100 -0
- data/test/gir_ffi/builders/vfunc_builder_test.rb +5 -3
- data/test/{gir_ffi_test.rb → gir_ffi/core_test.rb} +8 -6
- data/test/gir_ffi/in_out_pointer_test.rb +1 -1
- data/test/gir_ffi/receiver_argument_info_test.rb +32 -0
- data/test/gir_ffi/sized_array_test.rb +34 -0
- data/test/gir_ffi/struct_base_test.rb +4 -32
- data/test/gir_ffi/struct_like_base_test.rb +164 -0
- data/test/gir_ffi/union_base_test.rb +4 -20
- data/test/gir_ffi/{user_defined_type_info_test.rb → user_defined_object_info_test.rb} +10 -10
- data/test/gir_ffi/user_defined_property_info_test.rb +22 -5
- data/test/gir_ffi/version_test.rb +1 -1
- data/test/integration/callback_exceptions_test.rb +2 -0
- data/test/integration/derived_classes_test.rb +2 -0
- data/test/integration/generated_everything_test.rb +22 -0
- data/test/integration/generated_gimarshallingtests_test.rb +23 -21
- data/test/integration/generated_gio_test.rb +2 -0
- data/test/integration/generated_glib_test.rb +2 -0
- data/test/integration/generated_gst_test.rb +2 -0
- data/test/integration/generated_gtop_test.rb +2 -0
- data/test/integration/generated_regress_test.rb +113 -29
- data/test/integration/generated_secret_test.rb +2 -0
- data/test/integration/generated_warnlib_test.rb +2 -0
- data/test/integration/method_lookup_test.rb +2 -0
- data/test/introspection_test_helper.rb +15 -0
- metadata +21 -27
- data/lib/gir_ffi-base/glib.rb +0 -8
- data/test/gir_ffi-base/glib/boolean_test.rb +0 -34
data/lib/gir_ffi-base/gobject.rb
CHANGED
@@ -5,12 +5,10 @@ raise 'The module GObject was already defined elsewhere' if Kernel.const_defined
|
|
5
5
|
|
6
6
|
require 'gir_ffi-base/gobject/lib'
|
7
7
|
|
8
|
-
# The part of the GObject namespace that is needed by
|
8
|
+
# The part of the GObject namespace that is needed by GirFFI.
|
9
|
+
#
|
10
|
+
# :reek:TooManyConstants: because it needs to hold the type constants.
|
9
11
|
module GObject
|
10
|
-
def self.type_init
|
11
|
-
Lib.g_type_init
|
12
|
-
end
|
13
|
-
|
14
12
|
def self.type_from_name(name)
|
15
13
|
Lib.g_type_from_name name
|
16
14
|
end
|
data/lib/gir_ffi-base.rb
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
#
|
3
|
-
# This section contains code that is needed by
|
4
|
-
#
|
5
|
-
# loaded.
|
3
|
+
# This section contains code that is needed by GirFFI, but belongs in modules
|
4
|
+
# that can only be created fully once GirFFI is fully loaded.
|
6
5
|
|
7
|
-
#
|
8
|
-
require 'gir_ffi-base/glib/strv'
|
6
|
+
# Some base GObject functions and constants are needed by GirFFI.
|
9
7
|
require 'gir_ffi-base/gobject'
|
10
|
-
|
11
|
-
# GLib::Boolean is needed by GirFFI.
|
12
|
-
require 'gir_ffi-base/glib/boolean'
|
data/tasks/test.rake
CHANGED
@@ -132,8 +132,7 @@ namespace :test do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
define_test_task(:main) do |t|
|
135
|
-
t.test_files = FileList['test/
|
136
|
-
'test/gir_ffi/**/*_test.rb']
|
135
|
+
t.test_files = FileList['test/gir_ffi/**/*_test.rb']
|
137
136
|
end
|
138
137
|
|
139
138
|
define_test_task(:overrides) do |t|
|
@@ -190,6 +189,22 @@ namespace :test do
|
|
190
189
|
Cucumber::Rake::Task.new(:features) do |t|
|
191
190
|
t.cucumber_opts = 'features --format pretty'
|
192
191
|
end
|
192
|
+
|
193
|
+
desc 'Run mutant'
|
194
|
+
|
195
|
+
task mutant: :lib do
|
196
|
+
command = <<-EOS
|
197
|
+
RUBY_THREAD_VM_STACK_SIZE=64000 \
|
198
|
+
bundle exec mutant \
|
199
|
+
--include lib \
|
200
|
+
--include test \
|
201
|
+
--use minitest \
|
202
|
+
--since master \
|
203
|
+
--jobs 4 \
|
204
|
+
"GirFFI*" "GObject*" "GObjectIntrospection*" "GLib*"
|
205
|
+
EOS
|
206
|
+
system command
|
207
|
+
end
|
193
208
|
end
|
194
209
|
|
195
210
|
file "test/lib/Makefile" => "test/lib/configure" do
|
@@ -201,4 +216,3 @@ file "test/lib/configure" => ["test/lib/autogen.sh", "test/lib/configure.ac"] do
|
|
201
216
|
end
|
202
217
|
|
203
218
|
task test: 'test:all'
|
204
|
-
task test: 'test:features'
|
data/test/base_test_helper.rb
CHANGED
@@ -15,29 +15,8 @@ begin
|
|
15
15
|
rescue LoadError
|
16
16
|
end
|
17
17
|
|
18
|
-
require 'minitest/rspec_mocks'
|
19
18
|
require 'minitest/autorun'
|
20
|
-
|
21
|
-
require 'gir_ffi-base'
|
22
|
-
require 'ffi-gobject_introspection'
|
23
|
-
|
24
|
-
GObjectIntrospection::IRepository.prepend_search_path File.join(File.dirname(__FILE__), 'lib')
|
25
|
-
|
26
|
-
module GObjectIntrospection
|
27
|
-
class IRepository
|
28
|
-
def shared_library_with_regress(namespace)
|
29
|
-
case namespace
|
30
|
-
when 'Everything', 'GIMarshallingTests', 'Regress', 'Utility', 'WarnLib'
|
31
|
-
return File.join(File.dirname(__FILE__), 'lib', "lib#{namespace.downcase}.so")
|
32
|
-
else
|
33
|
-
return shared_library_without_regress namespace
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
alias_method :shared_library_without_regress, :shared_library
|
38
|
-
alias_method :shared_library, :shared_library_with_regress
|
39
|
-
end
|
40
|
-
end
|
19
|
+
require 'rspec/mocks/minitest_integration'
|
41
20
|
|
42
21
|
Thread.abort_on_exception = true
|
43
22
|
|
@@ -82,4 +61,41 @@ module BaseTestExtensions
|
|
82
61
|
end
|
83
62
|
|
84
63
|
Minitest::Test.send :include, BaseTestExtensions
|
85
|
-
|
64
|
+
|
65
|
+
# Provide methods needed for integration with mutant
|
66
|
+
module ForMutant
|
67
|
+
# Mark the current test class as covering the given expression.
|
68
|
+
def cover(expression)
|
69
|
+
@expression = expression
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return the currently set covering expression.
|
73
|
+
def covering
|
74
|
+
defined?(@expression) && @expression
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return the cover expression, but raise an exception if it is not defined.
|
78
|
+
# This is the method used by mutant to fetch the coverage information.
|
79
|
+
def cover_expression
|
80
|
+
raise "Cover expression for #{self} is not specified" unless @expression
|
81
|
+
@expression
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
Minitest::Test.send :extend, ForMutant
|
86
|
+
|
87
|
+
def cover_expression_for(cls)
|
88
|
+
full_stack = cls.describe_stack.dup << cls
|
89
|
+
full_stack.reverse_each do |level|
|
90
|
+
return level.covering if level.covering
|
91
|
+
return level.desc.to_s if level.desc.is_a? Module
|
92
|
+
end
|
93
|
+
full_stack.first.desc.to_s
|
94
|
+
end
|
95
|
+
|
96
|
+
# Override describe to automatically set cover information
|
97
|
+
def describe(desc, *additional_desc, &block)
|
98
|
+
super.tap do |cls|
|
99
|
+
cls.cover cover_expression_for(cls) unless cls.covering
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'gir_ffi_test_helper'
|
3
|
+
|
4
|
+
describe GObject::Closure do
|
5
|
+
describe '.new' do
|
6
|
+
it 'updates the ref_count of the created object' do
|
7
|
+
# Tested on a subclass ...
|
8
|
+
c = GObject::RubyClosure.new {}
|
9
|
+
c.ref_count.must_equal 1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#invoke' do
|
14
|
+
it 'invokes the closure' do
|
15
|
+
a = 0
|
16
|
+
c = GObject::RubyClosure.new { a = 2 }
|
17
|
+
c2 = GObject::Closure.wrap(c.to_ptr)
|
18
|
+
c2.invoke nil, []
|
19
|
+
a.must_equal 2
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the closure result' do
|
23
|
+
c = GObject::RubyClosure.new { 3 }
|
24
|
+
c2 = GObject::Closure.wrap(c.to_ptr)
|
25
|
+
result = c2.invoke GObject::Value.for_gtype(GObject::TYPE_INT), []
|
26
|
+
result.must_equal 3
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'passes arguments' do
|
30
|
+
a = 0
|
31
|
+
c = GObject::RubyClosure.new { |val| a = val }
|
32
|
+
c2 = GObject::Closure.wrap(c.to_ptr)
|
33
|
+
c2.invoke nil, [5]
|
34
|
+
a.must_equal 5
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'gir_ffi_test_helper'
|
3
3
|
|
4
|
+
class MainLoopTestException < RuntimeError; end
|
5
|
+
|
4
6
|
describe GLib::MainLoop do
|
5
7
|
describe '#run' do
|
6
8
|
it 'allows other threads to run' do
|
@@ -24,5 +26,27 @@ describe GLib::MainLoop do
|
|
24
26
|
|
25
27
|
a.must_equal ['Before run', 'During run', 'After run']
|
26
28
|
end
|
29
|
+
|
30
|
+
it 'raises and quits on exceptions in callbacks' do
|
31
|
+
main_loop = GLib::MainLoop.new nil, false
|
32
|
+
|
33
|
+
a = 'expected'
|
34
|
+
|
35
|
+
# This timeout shouldn't get called
|
36
|
+
guard = GLib.timeout_add GLib::PRIORITY_DEFAULT, 150 do
|
37
|
+
a = 'unexpected'
|
38
|
+
main_loop.quit
|
39
|
+
end
|
40
|
+
|
41
|
+
GLib.timeout_add GLib::PRIORITY_DEFAULT, 10 do
|
42
|
+
raise MainLoopTestException
|
43
|
+
end
|
44
|
+
|
45
|
+
-> { main_loop.run }.must_raise MainLoopTestException
|
46
|
+
a.must_equal 'expected'
|
47
|
+
|
48
|
+
# Clean up uncalled timeout
|
49
|
+
GLib.source_remove guard
|
50
|
+
end
|
27
51
|
end
|
28
52
|
end
|
@@ -13,11 +13,6 @@ describe GObject::RubyClosure do
|
|
13
13
|
c = GObject::RubyClosure.new {}
|
14
14
|
assert_kind_of GObject::Closure, c
|
15
15
|
end
|
16
|
-
|
17
|
-
it 'updates the ref_count of the created object' do
|
18
|
-
c = GObject::RubyClosure.new {}
|
19
|
-
c.ref_count.must_equal 1
|
20
|
-
end
|
21
16
|
end
|
22
17
|
|
23
18
|
describe '.wrap' do
|
@@ -119,23 +119,19 @@ describe GObject::Object do
|
|
119
119
|
end
|
120
120
|
|
121
121
|
describe 'upon garbage collection' do
|
122
|
-
# FIXME: Test this some other way
|
123
122
|
it 'lowers the reference count' do
|
124
|
-
if
|
123
|
+
if jruby? || rubinius?
|
125
124
|
skip 'cannot be reliably tested on JRuby and Rubinius'
|
126
125
|
end
|
127
|
-
if RUBY_VERSION >= '2.3.0'
|
128
|
-
skip 'cannot be reliably tested on CRuby >= 2.3'
|
129
|
-
end
|
130
126
|
|
131
|
-
|
132
|
-
ptr = object.to_ptr
|
127
|
+
ptr = GObject::Object.new.to_ptr
|
133
128
|
ref_count(ptr).must_equal 1
|
134
129
|
|
135
|
-
# Lose reference to object to allow garbage collection
|
136
|
-
object = nil # rubocop:disable Lint/UselessAssignment
|
137
|
-
|
138
130
|
GC.start
|
131
|
+
# Creating a new object is sometimes needed to trigger enough garbage collection.
|
132
|
+
GObject::Object.new
|
133
|
+
sleep 1
|
134
|
+
|
139
135
|
GC.start
|
140
136
|
GC.start
|
141
137
|
|
@@ -3,16 +3,28 @@ require 'gir_ffi_test_helper'
|
|
3
3
|
|
4
4
|
require 'ffi-gobject'
|
5
5
|
describe GObject::ParamSpec do
|
6
|
+
let(:pspec) do
|
7
|
+
GObject.param_spec_int('foo-bar', 'foo bar',
|
8
|
+
'Foo Bar',
|
9
|
+
1, 3, 2,
|
10
|
+
readable: true, writable: true)
|
11
|
+
end
|
12
|
+
|
6
13
|
describe '#ref' do
|
7
14
|
it 'increases the ref count' do
|
8
|
-
pspec = GObject.param_spec_boolean('foo', 'foo bar',
|
9
|
-
'Boolean Foo Bar',
|
10
|
-
false,
|
11
|
-
readable: true, writable: true)
|
12
|
-
|
13
15
|
old = pspec.ref_count
|
14
16
|
pspec.ref
|
15
17
|
pspec.ref_count.must_equal old + 1
|
16
18
|
end
|
17
19
|
end
|
20
|
+
|
21
|
+
describe '#accessor_name' do
|
22
|
+
it 'returns a safe ruby method name' do
|
23
|
+
pspec.accessor_name.must_equal 'foo_bar'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'cannot be instantiated directly' do
|
28
|
+
proc { GObject::ParamSpec.new }.must_raise NoMethodError
|
29
|
+
end
|
18
30
|
end
|
@@ -256,7 +256,7 @@ describe GObject::Value do
|
|
256
256
|
gv.get_value.must_equal value
|
257
257
|
end
|
258
258
|
|
259
|
-
it 'unwraps
|
259
|
+
it 'unwraps an ulong' do
|
260
260
|
value = FFI.type_size(:long) == 8 ? 0x1234_5678_9012_3456 : 0x1234_5678
|
261
261
|
gv = GObject::Value.for_gtype GObject::TYPE_ULONG
|
262
262
|
gv.set_ulong value
|
@@ -291,6 +291,17 @@ describe GObject::Value do
|
|
291
291
|
result.must_be_kind_of GLib::Array
|
292
292
|
result.reset_typespec(:uint).to_a.must_equal [1, 2, 3]
|
293
293
|
end
|
294
|
+
|
295
|
+
it 'unwraps a Strv' do
|
296
|
+
strv = GLib::Strv.from %w(foo bar)
|
297
|
+
val = GObject::Value.for_gtype GObject::TYPE_STRV
|
298
|
+
val.set_boxed strv
|
299
|
+
|
300
|
+
result = val.get_value
|
301
|
+
|
302
|
+
result.must_be_kind_of GLib::Strv
|
303
|
+
result.to_a.must_equal %w(foo bar)
|
304
|
+
end
|
294
305
|
end
|
295
306
|
|
296
307
|
describe '::from' do
|
@@ -334,12 +345,8 @@ describe GObject::Value do
|
|
334
345
|
end
|
335
346
|
|
336
347
|
describe 'upon garbage collection' do
|
337
|
-
before do
|
338
|
-
GirFFI.setup :GIMarshallingTests
|
339
|
-
end
|
340
|
-
|
341
348
|
it 'restores the underlying GValue to its pristine state' do
|
342
|
-
if
|
349
|
+
if jruby? || rubinius?
|
343
350
|
skip 'cannot be reliably tested on JRuby and Rubinius'
|
344
351
|
end
|
345
352
|
|
@@ -350,6 +357,8 @@ describe GObject::Value do
|
|
350
357
|
value.current_gtype_name.must_equal 'gint'
|
351
358
|
|
352
359
|
GC.start
|
360
|
+
# Creating a new object is sometimes needed to trigger enough garbage collection.
|
361
|
+
GObject::Value.new
|
353
362
|
sleep 1
|
354
363
|
GC.start
|
355
364
|
GC.start
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'introspection_test_helper'
|
3
|
+
|
4
|
+
describe GObjectIntrospection::GObjectTypeInit do
|
5
|
+
describe 'Lib' do
|
6
|
+
it 'represents the gobject-2.0 library' do
|
7
|
+
GObjectIntrospection::GObjectTypeInit::Lib.ffi_libraries.first.name.
|
8
|
+
must_match(/gobject-2\.0/)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'provides the g_type_init function' do
|
12
|
+
GObjectIntrospection::GObjectTypeInit::Lib.must_respond_to :g_type_init
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.type_init' do
|
17
|
+
it 'calls the g_type_init function from the gobject-2.0 library' do
|
18
|
+
allow(GObjectIntrospection::GObjectTypeInit::Lib).to receive(:g_type_init)
|
19
|
+
|
20
|
+
GObjectIntrospection::GObjectTypeInit.type_init
|
21
|
+
|
22
|
+
expect(GObjectIntrospection::GObjectTypeInit::Lib).to have_received(:g_type_init)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -32,7 +32,7 @@ describe GObjectIntrospection::IBaseInfo do
|
|
32
32
|
|
33
33
|
describe 'upon garbage collection' do
|
34
34
|
it 'calls g_base_info_unref' do
|
35
|
-
if
|
35
|
+
if jruby? || rubinius?
|
36
36
|
skip 'cannot be reliably tested on JRuby and Rubinius'
|
37
37
|
end
|
38
38
|
|
@@ -58,4 +58,22 @@ describe GObjectIntrospection::IRepository do
|
|
58
58
|
assert_kind_of GObjectIntrospection::IBaseInfo, gir.info('GObject', 0)
|
59
59
|
end
|
60
60
|
end
|
61
|
+
|
62
|
+
describe '#dependencies' do
|
63
|
+
it 'returns a list of dependencies of the given namespace' do
|
64
|
+
result = gir.dependencies('GObject')
|
65
|
+
result.must_equal ['GLib-2.0']
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'passes its struct pointer to the c function just in case' do
|
69
|
+
ptr = gir.instance_variable_get(:@gobj)
|
70
|
+
allow(GObjectIntrospection::Lib).to receive(:g_irepository_get_dependencies).
|
71
|
+
and_call_original
|
72
|
+
|
73
|
+
gir.dependencies('GObject')
|
74
|
+
|
75
|
+
expect(GObjectIntrospection::Lib).to have_received(:g_irepository_get_dependencies).
|
76
|
+
with(ptr, 'GObject')
|
77
|
+
end
|
78
|
+
end
|
61
79
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'introspection_test_helper'
|
3
|
+
|
4
|
+
describe GObjectIntrospection::IVFuncInfo do
|
5
|
+
let(:vfunc_info) do
|
6
|
+
get_vfunc_introspection_data 'GIMarshallingTests', 'Object', 'method_int8_in'
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:throwing_vfunc_info) do
|
10
|
+
get_vfunc_introspection_data 'GIMarshallingTests', 'Object', 'vfunc_meth_with_err'
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:vfunc_info_with_different_invoker) do
|
14
|
+
get_vfunc_introspection_data 'Regress', 'TestObj', 'matrix'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#throws?' do
|
18
|
+
it 'returns false if there is no error argument' do
|
19
|
+
vfunc_info.wont_be :throws?
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns true if there is and error argument' do
|
23
|
+
throwing_vfunc_info.must_be :throws?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#invoker' do
|
28
|
+
it 'returns nil if no invoker method is present' do
|
29
|
+
throwing_vfunc_info.invoker.must_be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns info for the invoker method if present' do
|
33
|
+
vfunc_info.invoker.name.must_equal 'method_int8_in'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns the correct invoker even if named differently' do
|
37
|
+
vfunc_info_with_different_invoker.invoker.name.must_equal 'do_matrix'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'base_test_helper'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe GObjectIntrospection::Strv do
|
5
5
|
it 'wraps a pointer' do
|
6
|
-
strv =
|
6
|
+
strv = GObjectIntrospection::Strv.new :some_pointer
|
7
7
|
assert_equal :some_pointer, strv.to_ptr
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '::wrap' do
|
11
|
-
it 'takes a pointer and returns a
|
12
|
-
strv =
|
13
|
-
assert_instance_of
|
11
|
+
it 'takes a pointer and returns a GObjectIntrospection::Strv wrapping it' do
|
12
|
+
strv = GObjectIntrospection::Strv.wrap :some_pointer
|
13
|
+
assert_instance_of GObjectIntrospection::Strv, strv
|
14
14
|
assert_equal :some_pointer, strv.to_ptr
|
15
15
|
end
|
16
16
|
end
|
@@ -23,7 +23,7 @@ describe GLib::Strv do
|
|
23
23
|
block = FFI::MemoryPointer.new(:pointer, ptrs.length)
|
24
24
|
block.write_array_of_pointer ptrs
|
25
25
|
|
26
|
-
strv =
|
26
|
+
strv = GObjectIntrospection::Strv.new block
|
27
27
|
arr = []
|
28
28
|
strv.each do |str|
|
29
29
|
arr << str
|
@@ -32,7 +32,7 @@ describe GLib::Strv do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'yields zero times for a Strv wrapping a null pointer' do
|
35
|
-
strv =
|
35
|
+
strv = GObjectIntrospection::Strv.new FFI::Pointer.new(0)
|
36
36
|
strv.each do |_str|
|
37
37
|
flunk
|
38
38
|
end
|
@@ -40,6 +40,6 @@ describe GLib::Strv do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'includes Enumerable' do
|
43
|
-
|
43
|
+
GObjectIntrospection::Strv.must_include Enumerable
|
44
44
|
end
|
45
45
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'gir_ffi_test_helper'
|
3
|
+
|
4
|
+
describe GirFFI::AllocationHelper do
|
5
|
+
describe '.free_after' do
|
6
|
+
before do
|
7
|
+
allow(GirFFI::LibC).to receive(:free)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'frees the passed-in pointer' do
|
11
|
+
ptr = double('pointer', null?: false)
|
12
|
+
GirFFI::AllocationHelper.free_after(ptr) {}
|
13
|
+
expect(GirFFI::LibC).to have_received(:free).with(ptr)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'does not free a passed-in null pointer' do
|
17
|
+
ptr = double('pointer', null?: true)
|
18
|
+
GirFFI::AllocationHelper.free_after(ptr) {}
|
19
|
+
expect(GirFFI::LibC).not_to have_received(:free)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'yields ptr to the block' do
|
23
|
+
ptr = double('pointer', null?: false)
|
24
|
+
foo = nil
|
25
|
+
GirFFI::AllocationHelper.free_after(ptr) { |it| foo = it }
|
26
|
+
foo.must_equal ptr
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns the result of the block' do
|
30
|
+
ptr = double('pointer', null?: false)
|
31
|
+
result = GirFFI::AllocationHelper.free_after(ptr) { 'bar' }
|
32
|
+
result.must_equal 'bar'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -9,20 +9,87 @@ describe GirFFI::ArgHelper do
|
|
9
9
|
GirFFI::ArgHelper.cast_from_pointer(klass, :pointer_value).must_equal :wrapped_value
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
describe 'for :gint8' do
|
13
|
+
it 'handles negative :gint8' do
|
14
|
+
ptr = FFI::Pointer.new(-127)
|
15
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint8, ptr).must_equal(-127)
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
it 'handles positive :gint8' do
|
19
|
+
ptr = FFI::Pointer.new(128)
|
20
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint8, ptr).must_equal(128)
|
21
|
+
end
|
20
22
|
end
|
21
23
|
|
22
24
|
it 'handles :guint32' do
|
23
25
|
ptr = FFI::Pointer.new(0xffffffff)
|
24
26
|
GirFFI::ArgHelper.cast_from_pointer(:guint32, ptr).must_equal(0xffffffff)
|
25
27
|
end
|
28
|
+
|
29
|
+
describe 'for :gint32' do
|
30
|
+
it 'handles positive :gint32' do
|
31
|
+
ptr = FFI::Pointer.new(1)
|
32
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint32, ptr).must_equal(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'handles negative :gint32' do
|
36
|
+
ptr = FFI::Pointer.new(0xffffffff)
|
37
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint32, ptr).must_equal(-1)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'handles largest negative :gint32' do
|
41
|
+
ptr = FFI::Pointer.new(0x80000000)
|
42
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint32, ptr).must_equal(-0x80000000)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'handles largest positive :gint32' do
|
46
|
+
ptr = FFI::Pointer.new(0x7fffffff)
|
47
|
+
GirFFI::ArgHelper.cast_from_pointer(:gint32, ptr).must_equal(0x7fffffff)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'handles :utf8' do
|
52
|
+
ptr = FFI::MemoryPointer.from_string 'foo'
|
53
|
+
GirFFI::ArgHelper.cast_from_pointer(:utf8, ptr).must_equal 'foo'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'handles :filename' do
|
57
|
+
ptr = FFI::MemoryPointer.from_string 'foo'
|
58
|
+
GirFFI::ArgHelper.cast_from_pointer(:filename, ptr).must_equal 'foo'
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'handles GHashTable' do
|
62
|
+
hash = GLib::HashTable.from [:utf8, :gint32], 'foo' => 1, 'bar' => 2
|
63
|
+
ptr = hash.to_ptr
|
64
|
+
result = GirFFI::ArgHelper.cast_from_pointer([:pointer, [:ghash, :utf8, :gint32]], ptr)
|
65
|
+
result.to_hash.must_equal hash.to_hash
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'when passing a broken typespec' do
|
69
|
+
it 'raises on unknown symbol' do
|
70
|
+
ptr = FFI::Pointer.new(0xffffffff)
|
71
|
+
exception = -> { GirFFI::ArgHelper.cast_from_pointer(:foo, ptr) }.must_raise
|
72
|
+
exception.message.must_equal "Don't know how to cast foo"
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'raises on unexpected main type for complex type' do
|
76
|
+
ptr = FFI::Pointer.new(0xffffffff)
|
77
|
+
exception = -> { GirFFI::ArgHelper.cast_from_pointer([:utf8], ptr) }.must_raise
|
78
|
+
exception.message.must_equal "Don't know how to cast [:utf8]"
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'raises on unexpected sub type for complex type' do
|
82
|
+
ptr = FFI::Pointer.new(0xffffffff)
|
83
|
+
exception = -> { GirFFI::ArgHelper.cast_from_pointer([:pointer, :utf8], ptr) }.must_raise
|
84
|
+
exception.message.must_equal "Don't know how to cast [:pointer, :utf8]"
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'raises on unexpected container type for complex type' do
|
88
|
+
ptr = FFI::Pointer.new(0xffffffff)
|
89
|
+
exception = -> { GirFFI::ArgHelper.cast_from_pointer([:pointer, [:gint32]], ptr) }.must_raise
|
90
|
+
exception.message.must_equal "Don't know how to cast [:pointer, [:gint32]]"
|
91
|
+
end
|
92
|
+
end
|
26
93
|
end
|
27
94
|
|
28
95
|
describe '.store' do
|
@@ -41,4 +108,32 @@ describe GirFFI::ArgHelper do
|
|
41
108
|
end
|
42
109
|
end
|
43
110
|
end
|
111
|
+
|
112
|
+
describe '.check_fixed_array_size' do
|
113
|
+
it 'passes if array has the correct size' do
|
114
|
+
GirFFI::ArgHelper.check_fixed_array_size(3, [1, 2, 3], 'foo')
|
115
|
+
pass
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'raises if array does not have the correct size' do
|
119
|
+
result = lambda do
|
120
|
+
GirFFI::ArgHelper.check_fixed_array_size(3, [1, 2], 'foo')
|
121
|
+
end.must_raise ArgumentError
|
122
|
+
result.message.must_equal 'foo should have size 3'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '.check_error' do
|
127
|
+
it 'does nothing if there is no error' do
|
128
|
+
err_ptr = double('err_ptr', read_pointer: nil)
|
129
|
+
GirFFI::ArgHelper.check_error err_ptr
|
130
|
+
pass
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'raises an exception if there is an error' do
|
134
|
+
err = GLib::Error.new
|
135
|
+
err_ptr = double('err_ptr', read_pointer: err.to_ptr)
|
136
|
+
-> { GirFFI::ArgHelper.check_error err_ptr }.must_raise GirFFI::GLibError
|
137
|
+
end
|
138
|
+
end
|
44
139
|
end
|