ffi 1.9.5 → 1.9.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +13 -6
- data/ext/ffi_c/extconf.rb +2 -2
- data/lib/ffi.rb +2 -0
- data/lib/ffi/version.rb +1 -1
- data/spec/ffi/async_callback_spec.rb +4 -5
- data/spec/ffi/bool_spec.rb +9 -8
- data/spec/ffi/buffer_spec.rb +64 -37
- data/spec/ffi/callback_spec.rb +195 -116
- data/spec/ffi/custom_param_type.rb +1 -1
- data/spec/ffi/custom_type_spec.rb +5 -6
- data/spec/ffi/dup_spec.rb +6 -8
- data/spec/ffi/enum_spec.rb +135 -129
- data/spec/ffi/errno_spec.rb +2 -2
- data/spec/ffi/ffi_spec.rb +4 -6
- data/spec/ffi/fixtures/EnumTest.o +0 -0
- data/spec/ffi/function_spec.rb +22 -11
- data/spec/ffi/io_spec.rb +0 -1
- data/spec/ffi/library_spec.rb +71 -36
- data/spec/ffi/long_double.rb +3 -4
- data/spec/ffi/managed_struct_spec.rb +14 -4
- data/spec/ffi/memorypointer_spec.rb +7 -1
- data/spec/ffi/number_spec.rb +43 -34
- data/spec/ffi/platform_spec.rb +76 -59
- data/spec/ffi/pointer_spec.rb +35 -31
- data/spec/ffi/rbx/attach_function_spec.rb +3 -4
- data/spec/ffi/rbx/memory_pointer_spec.rb +24 -22
- data/spec/ffi/rbx/spec_helper.rb +0 -1
- data/spec/ffi/rbx/struct_spec.rb +1 -2
- data/spec/ffi/spec_helper.rb +5 -2
- data/spec/ffi/string_spec.rb +22 -14
- data/spec/ffi/strptr_spec.rb +6 -7
- data/spec/ffi/struct_by_ref_spec.rb +4 -5
- data/spec/ffi/struct_callback_spec.rb +6 -7
- data/spec/ffi/struct_initialize_spec.rb +2 -3
- data/spec/ffi/struct_packed_spec.rb +12 -14
- data/spec/ffi/struct_spec.rb +203 -129
- data/spec/ffi/typedef_spec.rb +11 -10
- data/spec/ffi/union_spec.rb +8 -7
- data/spec/ffi/variadic_spec.rb +13 -10
- metadata +2 -2
data/spec/ffi/ffi_spec.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe "FFI" do
|
10
9
|
|
@@ -12,19 +11,18 @@ describe "FFI" do
|
|
12
11
|
|
13
12
|
let(:prefix) { FFI::Platform::LIBPREFIX }
|
14
13
|
let(:suffix) { FFI::Platform::LIBSUFFIX }
|
15
|
-
|
14
|
+
|
16
15
|
it "should add platform library extension if not present" do
|
17
|
-
FFI.map_library_name("#{prefix}dummy").
|
16
|
+
expect(FFI.map_library_name("#{prefix}dummy")).to eq("#{prefix}dummy.#{suffix}")
|
18
17
|
end
|
19
18
|
|
20
19
|
it "should add platform library extension even if lib suffix is present in name" do
|
21
|
-
FFI.map_library_name("#{prefix}dummy_with_#{suffix}").
|
20
|
+
expect(FFI.map_library_name("#{prefix}dummy_with_#{suffix}")).to eq("#{prefix}dummy_with_#{suffix}.#{suffix}")
|
22
21
|
end
|
23
22
|
|
24
23
|
it "should return Platform::LIBC when called with 'c'" do
|
25
|
-
FFI.map_library_name('c').
|
24
|
+
expect(FFI.map_library_name('c')).to eq(FFI::Library::LIBC)
|
26
25
|
end
|
27
26
|
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
Binary file
|
data/spec/ffi/function_spec.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe FFI::Function do
|
10
9
|
module LibTest
|
@@ -16,33 +15,41 @@ describe FFI::Function do
|
|
16
15
|
@libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
|
17
16
|
FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
|
18
17
|
end
|
18
|
+
|
19
19
|
it 'is initialized with a signature and a block' do
|
20
20
|
fn = FFI::Function.new(:int, []) { 5 }
|
21
21
|
expect(fn.call).to eql 5
|
22
22
|
end
|
23
|
+
|
23
24
|
it 'raises an error when passing a wrong signature' do
|
24
|
-
|
25
|
+
expect { FFI::Function.new([], :int).new { } }.to raise_error TypeError
|
25
26
|
end
|
27
|
+
|
26
28
|
it 'returns a native pointer' do
|
27
29
|
expect(FFI::Function.new(:int, []) { }).to be_a_kind_of FFI::Pointer
|
28
30
|
end
|
31
|
+
|
29
32
|
it 'can be used as callback from C passing to it a block' do
|
30
33
|
function_add = FFI::Function.new(:int, [:int, :int]) { |a, b| a + b }
|
31
|
-
LibTest.testFunctionAdd(10, 10, function_add).
|
34
|
+
expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
|
32
35
|
end
|
36
|
+
|
33
37
|
it 'can be used as callback from C passing to it a Proc object' do
|
34
38
|
function_add = FFI::Function.new(:int, [:int, :int], Proc.new { |a, b| a + b })
|
35
|
-
LibTest.testFunctionAdd(10, 10, function_add).
|
39
|
+
expect(LibTest.testFunctionAdd(10, 10, function_add)).to eq(20)
|
36
40
|
end
|
41
|
+
|
37
42
|
it 'can be used to wrap an existing function pointer' do
|
38
|
-
FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd')).call(10, 10).
|
43
|
+
expect(FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd')).call(10, 10)).to eq(20)
|
39
44
|
end
|
45
|
+
|
40
46
|
it 'can be attached to a module' do
|
41
47
|
module Foo; end
|
42
48
|
fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
|
43
49
|
fp.attach(Foo, 'add')
|
44
|
-
Foo.add(10, 10).
|
50
|
+
expect(Foo.add(10, 10)).to eq(20)
|
45
51
|
end
|
52
|
+
|
46
53
|
it 'can be used to extend an object' do
|
47
54
|
fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
|
48
55
|
foo = Object.new
|
@@ -52,27 +59,31 @@ describe FFI::Function do
|
|
52
59
|
end
|
53
60
|
end
|
54
61
|
fp.attach(foo.singleton_class, 'add')
|
55
|
-
foo.add(10, 10).
|
62
|
+
expect(foo.add(10, 10)).to eq(20)
|
56
63
|
end
|
64
|
+
|
57
65
|
it 'can wrap a blocking function' do
|
58
66
|
fp = FFI::Function.new(:void, [ :int ], @libtest.find_function('testBlocking'), :blocking => true)
|
59
67
|
time = Time.now
|
60
68
|
threads = []
|
61
69
|
threads << Thread.new { fp.call(2) }
|
62
|
-
threads << Thread.new(time) { (Time.now - time).
|
70
|
+
threads << Thread.new(time) { expect(Time.now - time).to be < 1 }
|
63
71
|
threads.each { |t| t.join }
|
64
72
|
end
|
73
|
+
|
65
74
|
it 'autorelease flag is set to true by default' do
|
66
75
|
fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
|
67
|
-
fp.autorelease
|
76
|
+
expect(fp.autorelease?).to be true
|
68
77
|
end
|
78
|
+
|
69
79
|
it 'can explicity free itself' do
|
70
80
|
fp = FFI::Function.new(:int, []) { }
|
71
81
|
fp.free
|
72
|
-
|
82
|
+
expect { fp.free }.to raise_error RuntimeError
|
73
83
|
end
|
84
|
+
|
74
85
|
it 'can\'t explicity free itself if not previously allocated' do
|
75
86
|
fp = FFI::Function.new(:int, [:int, :int], @libtest.find_function('testAdd'))
|
76
|
-
|
87
|
+
expect { fp.free }.to raise_error RuntimeError
|
77
88
|
end
|
78
89
|
end
|
data/spec/ffi/io_spec.rb
CHANGED
data/spec/ffi/library_spec.rb
CHANGED
@@ -4,15 +4,30 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe "Library" do
|
9
|
+
describe ".enum_value" do
|
10
|
+
m = Module.new do
|
11
|
+
extend FFI::Library
|
12
|
+
enum :something, [:one, :two]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return a value for a valid key" do
|
16
|
+
expect(m.enum_value(:one)).to eq(0)
|
17
|
+
expect(m.enum_value(:two)).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return nil for an invalid key" do
|
21
|
+
expect(m.enum_value(:three)).to be nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
10
25
|
describe "#ffi_convention" do
|
11
26
|
it "defaults to :default" do
|
12
27
|
m = Module.new do
|
13
28
|
extend FFI::Library
|
14
29
|
end
|
15
|
-
m.ffi_convention.
|
30
|
+
expect(m.ffi_convention).to eq(:default)
|
16
31
|
end
|
17
32
|
|
18
33
|
it "should be settable" do
|
@@ -20,9 +35,9 @@ describe "Library" do
|
|
20
35
|
extend FFI::Library
|
21
36
|
end
|
22
37
|
|
23
|
-
m.ffi_convention.
|
38
|
+
expect(m.ffi_convention).to eq(:default)
|
24
39
|
m.ffi_convention :stdcall
|
25
|
-
m.ffi_convention.
|
40
|
+
expect(m.ffi_convention).to eq(:stdcall)
|
26
41
|
end
|
27
42
|
end
|
28
43
|
|
@@ -51,76 +66,83 @@ describe "Library" do
|
|
51
66
|
|
52
67
|
describe "ffi_lib" do
|
53
68
|
it "empty name list should raise error" do
|
54
|
-
|
69
|
+
expect {
|
55
70
|
Module.new do |m|
|
56
71
|
m.extend FFI::Library
|
57
72
|
ffi_lib
|
58
73
|
end
|
59
|
-
}.
|
74
|
+
}.to raise_error(LoadError)
|
60
75
|
end
|
61
76
|
|
62
77
|
end
|
78
|
+
|
63
79
|
unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
|
64
80
|
it "attach_function with no library specified" do
|
65
|
-
|
81
|
+
expect {
|
66
82
|
Module.new do |m|
|
67
83
|
m.extend FFI::Library
|
68
84
|
attach_function :getpid, [ ], :uint
|
69
85
|
end
|
70
|
-
}.
|
86
|
+
}.to raise_error
|
71
87
|
end
|
88
|
+
|
72
89
|
it "attach_function :getpid from this process" do
|
73
|
-
|
74
|
-
Module.new do |m|
|
90
|
+
expect {
|
91
|
+
expect(Module.new do |m|
|
75
92
|
m.extend FFI::Library
|
76
93
|
ffi_lib FFI::Library::CURRENT_PROCESS
|
77
94
|
attach_function :getpid, [ ], :uint
|
78
|
-
end.getpid.
|
79
|
-
}.
|
95
|
+
end.getpid).to eq(Process.pid)
|
96
|
+
}.not_to raise_error
|
80
97
|
end
|
98
|
+
|
81
99
|
it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
|
82
|
-
|
83
|
-
Module.new do |m|
|
100
|
+
expect {
|
101
|
+
expect(Module.new do |m|
|
84
102
|
m.extend FFI::Library
|
85
103
|
ffi_lib [ 'c', 'libc.so.6' ]
|
86
104
|
attach_function :getpid, [ ], :uint
|
87
|
-
end.getpid.
|
88
|
-
}.
|
105
|
+
end.getpid).to eq(Process.pid)
|
106
|
+
}.not_to raise_error
|
89
107
|
end
|
108
|
+
|
90
109
|
it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
|
91
|
-
|
92
|
-
Module.new do |m|
|
110
|
+
expect {
|
111
|
+
expect(Module.new do |m|
|
93
112
|
m.extend FFI::Library
|
94
113
|
ffi_lib [ 'libc.so.6', 'c' ]
|
95
114
|
attach_function :getpid, [ ], :uint
|
96
|
-
end.getpid.
|
97
|
-
}.
|
115
|
+
end.getpid).to eq(Process.pid)
|
116
|
+
}.not_to raise_error
|
98
117
|
end
|
118
|
+
|
99
119
|
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
|
100
|
-
|
101
|
-
Module.new do |m|
|
120
|
+
expect {
|
121
|
+
expect(Module.new do |m|
|
102
122
|
m.extend FFI::Library
|
103
123
|
ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
|
104
124
|
attach_function :getpid, [ ], :uint
|
105
|
-
end.getpid.
|
106
|
-
}.
|
125
|
+
end.getpid).to eq(Process.pid)
|
126
|
+
}.not_to raise_error
|
107
127
|
end
|
128
|
+
|
108
129
|
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
|
109
|
-
|
110
|
-
Module.new do |m|
|
130
|
+
expect {
|
131
|
+
expect(Module.new do |m|
|
111
132
|
m.extend FFI::Library
|
112
133
|
ffi_lib 'libfubar.so.0xdeadbeef'
|
113
134
|
attach_function :getpid, [ ], :uint
|
114
|
-
end.getpid.
|
115
|
-
}.
|
135
|
+
end.getpid).to eq(Process.pid)
|
136
|
+
}.to raise_error(LoadError)
|
116
137
|
end
|
138
|
+
|
117
139
|
it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
|
118
|
-
Module.new do |m|
|
140
|
+
mod = Module.new do |m|
|
119
141
|
m.extend FFI::Library
|
120
142
|
ffi_lib File.expand_path(TestLibrary::PATH)
|
121
143
|
attach_function :bool_return_true, [ ], :bool
|
122
|
-
m.bool_return_true.should == true
|
123
144
|
end
|
145
|
+
expect(mod.bool_return_true).to be true
|
124
146
|
end
|
125
147
|
end
|
126
148
|
|
@@ -133,60 +155,71 @@ describe "Library" do
|
|
133
155
|
attach_function :set, "gvar_#{name}_set", [ type ], :void
|
134
156
|
end
|
135
157
|
end
|
158
|
+
|
136
159
|
def gvar_test(name, type, val)
|
137
160
|
lib = gvar_lib(name, type)
|
138
161
|
lib.set(val)
|
139
|
-
lib.gvar.
|
162
|
+
expect(lib.gvar).to eq(val)
|
140
163
|
lib.set(0)
|
141
164
|
lib.gvar = val
|
142
|
-
lib.get.
|
165
|
+
expect(lib.get).to eq(val)
|
143
166
|
end
|
167
|
+
|
144
168
|
[ 0, 127, -128, -1 ].each do |i|
|
145
169
|
it ":char variable" do
|
146
170
|
gvar_test("s8", :char, i)
|
147
171
|
end
|
148
172
|
end
|
173
|
+
|
149
174
|
[ 0, 0x7f, 0x80, 0xff ].each do |i|
|
150
175
|
it ":uchar variable" do
|
151
176
|
gvar_test("u8", :uchar, i)
|
152
177
|
end
|
153
178
|
end
|
179
|
+
|
154
180
|
[ 0, 0x7fff, -0x8000, -1 ].each do |i|
|
155
181
|
it ":short variable" do
|
156
182
|
gvar_test("s16", :short, i)
|
157
183
|
end
|
158
184
|
end
|
185
|
+
|
159
186
|
[ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
|
160
187
|
it ":ushort variable" do
|
161
188
|
gvar_test("u16", :ushort, i)
|
162
189
|
end
|
163
190
|
end
|
191
|
+
|
164
192
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
165
193
|
it ":int variable" do
|
166
194
|
gvar_test("s32", :int, i)
|
167
195
|
end
|
168
196
|
end
|
197
|
+
|
169
198
|
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
170
199
|
it ":uint variable" do
|
171
200
|
gvar_test("u32", :uint, i)
|
172
201
|
end
|
173
202
|
end
|
203
|
+
|
174
204
|
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
|
175
205
|
it ":long_long variable" do
|
176
206
|
gvar_test("s64", :long_long, i)
|
177
207
|
end
|
178
208
|
end
|
209
|
+
|
179
210
|
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
180
211
|
it ":ulong_long variable" do
|
181
212
|
gvar_test("u64", :ulong_long, i)
|
182
213
|
end
|
183
214
|
end
|
215
|
+
|
184
216
|
if FFI::Platform::LONG_SIZE == 32
|
185
217
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
186
218
|
it ":long variable" do
|
187
219
|
gvar_test("long", :long, i)
|
188
220
|
end
|
189
221
|
end
|
222
|
+
|
190
223
|
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
|
191
224
|
it ":ulong variable" do
|
192
225
|
gvar_test("ulong", :ulong, i)
|
@@ -198,20 +231,22 @@ describe "Library" do
|
|
198
231
|
gvar_test("long", :long, i)
|
199
232
|
end
|
200
233
|
end
|
234
|
+
|
201
235
|
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
|
202
236
|
it ":ulong variable" do
|
203
237
|
gvar_test("ulong", :ulong, i)
|
204
238
|
end
|
205
239
|
end
|
206
240
|
end
|
241
|
+
|
207
242
|
it "Pointer variable" do
|
208
243
|
lib = gvar_lib("pointer", :pointer)
|
209
244
|
val = FFI::MemoryPointer.new :long
|
210
245
|
lib.set(val)
|
211
|
-
lib.gvar.
|
246
|
+
expect(lib.gvar).to eq(val)
|
212
247
|
lib.set(nil)
|
213
248
|
lib.gvar = val
|
214
|
-
lib.get.
|
249
|
+
expect(lib.get).to eq(val)
|
215
250
|
end
|
216
251
|
|
217
252
|
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
|
@@ -231,11 +266,11 @@ describe "Library" do
|
|
231
266
|
val = GlobalStruct.new
|
232
267
|
val[:data] = i
|
233
268
|
lib.set(val)
|
234
|
-
lib.gvar[:data].
|
269
|
+
expect(lib.gvar[:data]).to eq(i)
|
235
270
|
val[:data] = 0
|
236
271
|
lib.gvar[:data] = i
|
237
272
|
val = GlobalStruct.new(lib.get)
|
238
|
-
val[:data].
|
273
|
+
expect(val[:data]).to eq(i)
|
239
274
|
end
|
240
275
|
end
|
241
276
|
end
|
data/spec/ffi/long_double.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
require 'bigdecimal'
|
9
8
|
|
10
9
|
describe ":long_double arguments and return values" do
|
@@ -16,16 +15,16 @@ describe ":long_double arguments and return values" do
|
|
16
15
|
end
|
17
16
|
|
18
17
|
it "returns first parameter" do
|
19
|
-
LibTest.ret_f128(0.1).
|
18
|
+
expect(LibTest.ret_f128(0.1)).to be_within(0.01).of(0.1)
|
20
19
|
end
|
21
20
|
|
22
21
|
it "returns first parameter with high precision" do
|
23
22
|
ld = BigDecimal.new("1.234567890123456789")
|
24
23
|
tolerance = BigDecimal.new("0.0000000000000000001")
|
25
|
-
LibTest.ret_f128(ld).
|
24
|
+
expect(LibTest.ret_f128(ld)).to be_within(tolerance).of(ld)
|
26
25
|
end
|
27
26
|
|
28
27
|
it "add two long double numbers" do
|
29
|
-
LibTest.add_f128(0.1, 0.2).
|
28
|
+
expect(LibTest.add_f128(0.1, 0.2)).to be_within(0.01).of(0.3)
|
30
29
|
end
|
31
30
|
end
|
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
7
|
|
9
8
|
describe "Managed Struct" do
|
10
9
|
include FFI
|
@@ -13,9 +12,10 @@ describe "Managed Struct" do
|
|
13
12
|
ffi_lib TestLibrary::PATH
|
14
13
|
attach_function :ptr_from_address, [ FFI::Platform::ADDRESS_SIZE == 32 ? :uint : :ulong_long ], :pointer
|
15
14
|
end
|
15
|
+
|
16
16
|
it "should raise an error if release() is not defined" do
|
17
17
|
class NoRelease < FFI::ManagedStruct ; layout :i, :int; end
|
18
|
-
|
18
|
+
expect { NoRelease.new(ManagedStructTestLib.ptr_from_address(0x12345678)) }.to raise_error(NoMethodError)
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should be the right class" do
|
@@ -25,7 +25,17 @@ describe "Managed Struct" do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
WhatClassAmI.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class.
|
28
|
+
expect(WhatClassAmI.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(WhatClassAmI)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should build with self reference" do
|
32
|
+
class ClassWithSelfRef < FFI::ManagedStruct
|
33
|
+
layout :data, self.ptr
|
34
|
+
def self.release
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(ClassWithSelfRef.new(ManagedStructTestLib.ptr_from_address(0x12345678)).class).to eq(ClassWithSelfRef)
|
29
39
|
end
|
30
40
|
|
31
41
|
it "should release memory properly" do
|
@@ -48,7 +58,7 @@ describe "Managed Struct" do
|
|
48
58
|
loop_count = 30
|
49
59
|
wiggle_room = 5
|
50
60
|
|
51
|
-
PleaseReleaseMe.
|
61
|
+
expect(PleaseReleaseMe).to receive(:release).at_least(loop_count-wiggle_room).times
|
52
62
|
loop_count.times do
|
53
63
|
PleaseReleaseMe.new(ManagedStructTestLib.ptr_from_address(0x12345678))
|
54
64
|
end
|