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
@@ -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
|
class Timeval < FFI::Struct
|
10
9
|
layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
|
@@ -21,14 +20,14 @@ describe FFI::Library, "#attach_function" do
|
|
21
20
|
it "correctly returns a value for gettimeofday" do
|
22
21
|
t = Timeval.new
|
23
22
|
time = LibC.gettimeofday(t.pointer, nil)
|
24
|
-
time.
|
23
|
+
expect(time).to be_kind_of(Integer)
|
25
24
|
end
|
26
25
|
|
27
26
|
it "correctly populates a struct for gettimeofday" do
|
28
27
|
t = Timeval.new
|
29
28
|
time = LibC.gettimeofday(t.pointer, nil)
|
30
|
-
t[:tv_sec].
|
31
|
-
t[:tv_usec].
|
29
|
+
expect(t[:tv_sec]).to be_kind_of(Numeric)
|
30
|
+
expect(t[:tv_usec]).to be_kind_of(Numeric)
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
@@ -5,7 +5,6 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
8
|
-
require 'ffi'
|
9
8
|
|
10
9
|
module CTest
|
11
10
|
extend FFI::Library
|
@@ -17,58 +16,58 @@ end
|
|
17
16
|
describe "MemoryPointer" do
|
18
17
|
it "makes a pointer from a string" do
|
19
18
|
m = FFI::MemoryPointer.from_string("FFI is Awesome")
|
20
|
-
m.total.
|
21
|
-
m.type_size.
|
19
|
+
expect(m.total).to eq(15)
|
20
|
+
expect(m.type_size).to eq(1)
|
22
21
|
end
|
23
22
|
|
24
23
|
it "does not make a pointer from non-strings" do
|
25
|
-
expect {FFI::MemoryPointer.from_string(nil)}.to raise_error(TypeError)
|
24
|
+
expect { FFI::MemoryPointer.from_string(nil) }.to raise_error(TypeError)
|
26
25
|
end
|
27
26
|
|
28
27
|
it "makes a pointer from a string with multibyte characters" do
|
29
28
|
m = FFI::MemoryPointer.from_string("ぱんだ")
|
30
|
-
m.total.
|
31
|
-
m.type_size.
|
29
|
+
expect(m.total).to eq(10)
|
30
|
+
expect(m.type_size).to eq(1)
|
32
31
|
end
|
33
32
|
|
34
33
|
it "reads back a string" do
|
35
34
|
m = FFI::MemoryPointer.from_string("FFI is Awesome")
|
36
|
-
m.read_string.
|
35
|
+
expect(m.read_string).to eq("FFI is Awesome")
|
37
36
|
end
|
38
37
|
|
39
38
|
it "makes a pointer for a certain number of bytes" do
|
40
39
|
m = FFI::MemoryPointer.new(8)
|
41
40
|
m.write_array_of_int([1,2])
|
42
|
-
m.read_array_of_int(2).
|
41
|
+
expect(m.read_array_of_int(2)).to eq([1,2])
|
43
42
|
end
|
44
43
|
|
45
44
|
it "allows access to an element of the pointer (as an array)" do
|
46
45
|
m = FFI::MemoryPointer.new(:int, 2)
|
47
46
|
m.write_array_of_int([1,2])
|
48
|
-
m[0].read_int.
|
49
|
-
m[1].read_int.
|
47
|
+
expect(m[0].read_int).to eq(1)
|
48
|
+
expect(m[1].read_int).to eq(2)
|
50
49
|
end
|
51
50
|
|
52
51
|
it "allows writing as an int" do
|
53
52
|
m = FFI::MemoryPointer.new(:int)
|
54
53
|
m.write_int(1)
|
55
|
-
m.read_int.
|
54
|
+
expect(m.read_int).to eq(1)
|
56
55
|
end
|
57
56
|
|
58
57
|
it "allows writing as a long" do
|
59
58
|
m = FFI::MemoryPointer.new(:long)
|
60
59
|
m.write_long(10)
|
61
|
-
m.read_long.
|
60
|
+
expect(m.read_long).to eq(10)
|
62
61
|
end
|
63
62
|
|
64
63
|
it "raises an error if you try putting a long into a pointer of size 1" do
|
65
64
|
m = FFI::MemoryPointer.new(1)
|
66
|
-
|
65
|
+
expect { m.write_long(10) }.to raise_error
|
67
66
|
end
|
68
67
|
|
69
68
|
it "raises an error if you try putting an int into a pointer of size 1" do
|
70
69
|
m = FFI::MemoryPointer.new(1)
|
71
|
-
|
70
|
+
expect { m.write_int(10) }.to raise_error
|
72
71
|
end
|
73
72
|
# it "does not raise IndexError for opaque pointers" do
|
74
73
|
# m = FFI::MemoryPointer.new(8)
|
@@ -81,41 +80,44 @@ describe "MemoryPointer" do
|
|
81
80
|
it "makes a pointer for a certain type" do
|
82
81
|
m = FFI::MemoryPointer.new(:int)
|
83
82
|
m.write_int(10)
|
84
|
-
m.read_int.
|
83
|
+
expect(m.read_int).to eq(10)
|
85
84
|
end
|
86
85
|
|
87
86
|
it "makes a memory pointer for a number of a certain type" do
|
88
87
|
m = FFI::MemoryPointer.new(:int, 2)
|
89
88
|
m.write_array_of_int([1,2])
|
90
|
-
m.read_array_of_int(2).
|
89
|
+
expect(m.read_array_of_int(2)).to eq([1,2])
|
91
90
|
end
|
92
91
|
|
93
92
|
it "makes a pointer for an object responding to #size" do
|
94
93
|
m = FFI::MemoryPointer.new(Struct.new(:size).new(8))
|
95
94
|
m.write_array_of_int([1,2])
|
96
|
-
m.read_array_of_int(2).
|
95
|
+
expect(m.read_array_of_int(2)).to eq([1,2])
|
97
96
|
end
|
98
97
|
|
99
98
|
it "makes a pointer for a number of an object responding to #size" do
|
100
99
|
m = FFI::MemoryPointer.new(Struct.new(:size).new(4), 2)
|
101
100
|
m.write_array_of_int([1,2])
|
102
|
-
m.read_array_of_int(2).
|
101
|
+
expect(m.read_array_of_int(2)).to eq([1,2])
|
103
102
|
end
|
103
|
+
|
104
104
|
it "MemoryPointer#address returns correct value" do
|
105
105
|
m = FFI::MemoryPointer.new(:long_long)
|
106
106
|
magic = 0x12345678
|
107
107
|
m.write_long(magic)
|
108
|
-
m.read_pointer.address.
|
108
|
+
expect(m.read_pointer.address).to eq(magic)
|
109
109
|
end
|
110
|
+
|
110
111
|
it "MemoryPointer#null? returns true for zero value" do
|
111
112
|
m = FFI::MemoryPointer.new(:long_long)
|
112
113
|
m.write_long(0)
|
113
|
-
m.read_pointer.null
|
114
|
+
expect(m.read_pointer.null?).to be true
|
114
115
|
end
|
116
|
+
|
115
117
|
it "MemoryPointer#null? returns false for non-zero value" do
|
116
118
|
m = FFI::MemoryPointer.new(:long_long)
|
117
119
|
m.write_long(0x12345678)
|
118
|
-
m.read_pointer.null
|
120
|
+
expect(m.read_pointer.null?).to be false
|
119
121
|
end
|
120
122
|
|
121
123
|
it "initialize with block should execute block" do
|
@@ -123,6 +125,6 @@ describe "MemoryPointer" do
|
|
123
125
|
FFI::MemoryPointer.new(:pointer) do |ptr|
|
124
126
|
block_executed = true
|
125
127
|
end
|
126
|
-
block_executed.
|
128
|
+
expect(block_executed).to be true
|
127
129
|
end
|
128
130
|
end
|
data/spec/ffi/rbx/spec_helper.rb
CHANGED
data/spec/ffi/rbx/struct_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
|
class Timeval < FFI::Struct
|
10
9
|
layout :tv_sec, :ulong, 0, :tv_usec, :ulong, 4
|
@@ -14,6 +13,6 @@ describe FFI::Struct do
|
|
14
13
|
it "allows setting fields" do
|
15
14
|
t = Timeval.new
|
16
15
|
t[:tv_sec] = 12
|
17
|
-
t[:tv_sec].
|
16
|
+
expect(t[:tv_sec]).to eq(12)
|
18
17
|
end
|
19
18
|
end
|
data/spec/ffi/spec_helper.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require 'rbconfig'
|
7
|
+
require 'fileutils'
|
7
8
|
require 'ffi'
|
8
9
|
|
9
10
|
CPU = case RbConfig::CONFIG['host_cpu'].downcase
|
@@ -53,17 +54,19 @@ def compile_library(path, lib)
|
|
53
54
|
dir = File.expand_path(path, File.dirname(__FILE__))
|
54
55
|
lib = "#{dir}/#{lib}"
|
55
56
|
if !File.exists?(lib)
|
56
|
-
ldshared = RbConfig::CONFIG["LDSHARED"]
|
57
|
+
ldshared = RbConfig::CONFIG["LDSHARED"] || "clang -dynamic -bundle"
|
57
58
|
libs = RbConfig::CONFIG["LIBS"]
|
58
|
-
dldflags = RbConfig::CONFIG["DLDFLAGS"]
|
59
|
+
dldflags = RbConfig::CONFIG["DLDFLAGS"] || "-Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress"
|
59
60
|
|
60
61
|
puts Dir.pwd, dir, File.dirname(__FILE__)
|
61
62
|
|
63
|
+
output = nil
|
62
64
|
FileUtils.cd(dir) do
|
63
65
|
output = system(*%{#{system('which gmake >/dev/null') && 'gmake' || 'make'} CPU=#{CPU} OS=#{OS} }.tap{|x| puts x.inspect})
|
64
66
|
end
|
65
67
|
|
66
68
|
if $?.exitstatus != 0
|
69
|
+
puts "ERROR:\n#{output}"
|
67
70
|
raise "Unable to compile \"#{lib}\""
|
68
71
|
end
|
69
72
|
end
|
data/spec/ffi/string_spec.rb
CHANGED
@@ -4,8 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
7
|
-
require 'ffi'
|
8
|
-
|
9
7
|
describe "String tests" do
|
10
8
|
include FFI
|
11
9
|
module StrLibTest
|
@@ -16,40 +14,46 @@ describe "String tests" do
|
|
16
14
|
attach_function :string_dummy, [ :string ], :void
|
17
15
|
attach_function :string_null, [ ], :string
|
18
16
|
end
|
17
|
+
|
19
18
|
it "MemoryPointer#get_string returns a tainted string" do
|
20
19
|
mp = FFI::MemoryPointer.new 1024
|
21
20
|
mp.put_string(0, "test\0")
|
22
21
|
str = mp.get_string(0)
|
23
|
-
str.tainted
|
22
|
+
expect(str.tainted?).to be true
|
24
23
|
end
|
24
|
+
|
25
25
|
it "String returned by a method is tainted" do
|
26
26
|
mp = FFI::MemoryPointer.new :pointer
|
27
27
|
sp = FFI::MemoryPointer.new 1024
|
28
28
|
sp.put_string(0, "test")
|
29
29
|
mp.put_pointer(0, sp)
|
30
30
|
str = StrLibTest.ptr_ret_pointer(mp, 0)
|
31
|
-
str.
|
32
|
-
str.
|
31
|
+
expect(str).to eq("test")
|
32
|
+
expect(str).to be_tainted
|
33
33
|
end
|
34
|
+
|
34
35
|
it "Poison null byte raises error" do
|
35
36
|
s = "123\0abc"
|
36
|
-
|
37
|
+
expect { StrLibTest.string_equals(s, s) }.to raise_error
|
37
38
|
end
|
39
|
+
|
38
40
|
it "Tainted String parameter should throw a SecurityError" do
|
39
41
|
$SAFE = 1
|
40
42
|
str = "test"
|
41
43
|
str.taint
|
42
44
|
begin
|
43
|
-
LibTest.string_equals(str, str).
|
45
|
+
expect(LibTest.string_equals(str, str)).to be false
|
44
46
|
rescue SecurityError
|
45
47
|
end
|
46
48
|
end if false
|
47
49
|
it "casts nil as NULL pointer" do
|
48
|
-
StrLibTest.string_dummy(nil).
|
50
|
+
expect(StrLibTest.string_dummy(nil)).to be_nil
|
49
51
|
end
|
52
|
+
|
50
53
|
it "return nil for NULL char*" do
|
51
|
-
StrLibTest.string_null.
|
54
|
+
expect(StrLibTest.string_null).to be_nil
|
52
55
|
end
|
56
|
+
|
53
57
|
it "reads an array of strings until encountering a NULL pointer" do
|
54
58
|
strings = ["foo", "bar", "baz", "testing", "ffi"]
|
55
59
|
ptrary = FFI::MemoryPointer.new(:pointer, 6)
|
@@ -60,8 +64,9 @@ describe "String tests" do
|
|
60
64
|
end
|
61
65
|
ary.insert(3, nil)
|
62
66
|
ptrary.write_array_of_pointer(ary)
|
63
|
-
ptrary.get_array_of_string(0).
|
67
|
+
expect(ptrary.get_array_of_string(0)).to eq(["foo", "bar", "baz"])
|
64
68
|
end
|
69
|
+
|
65
70
|
it "reads an array of strings of the size specified, substituting nil when a pointer is NULL" do
|
66
71
|
strings = ["foo", "bar", "baz", "testing", "ffi"]
|
67
72
|
ptrary = FFI::MemoryPointer.new(:pointer, 6)
|
@@ -72,8 +77,9 @@ describe "String tests" do
|
|
72
77
|
end
|
73
78
|
ary.insert(2, nil)
|
74
79
|
ptrary.write_array_of_pointer(ary)
|
75
|
-
ptrary.get_array_of_string(0, 4).
|
80
|
+
expect(ptrary.get_array_of_string(0, 4)).to eq(["foo", "bar", nil, "baz"])
|
76
81
|
end
|
82
|
+
|
77
83
|
it "reads an array of strings, taking a memory offset parameter" do
|
78
84
|
strings = ["foo", "bar", "baz", "testing", "ffi"]
|
79
85
|
ptrary = FFI::MemoryPointer.new(:pointer, 5)
|
@@ -83,8 +89,9 @@ describe "String tests" do
|
|
83
89
|
a << f
|
84
90
|
end
|
85
91
|
ptrary.write_array_of_pointer(ary)
|
86
|
-
ptrary.get_array_of_string(2 * FFI.type_size(:pointer), 3).
|
92
|
+
expect(ptrary.get_array_of_string(2 * FFI.type_size(:pointer), 3)).to eq(["baz", "testing", "ffi"])
|
87
93
|
end
|
94
|
+
|
88
95
|
it "raises an IndexError when trying to read an array of strings out of bounds" do
|
89
96
|
strings = ["foo", "bar", "baz", "testing", "ffi"]
|
90
97
|
ptrary = FFI::MemoryPointer.new(:pointer, 5)
|
@@ -94,8 +101,9 @@ describe "String tests" do
|
|
94
101
|
a << f
|
95
102
|
end
|
96
103
|
ptrary.write_array_of_pointer(ary)
|
97
|
-
|
104
|
+
expect { ptrary.get_array_of_string(0, 6) }.to raise_error
|
98
105
|
end
|
106
|
+
|
99
107
|
it "raises an IndexError when trying to read an array of strings using a negative offset" do
|
100
108
|
strings = ["foo", "bar", "baz", "testing", "ffi"]
|
101
109
|
ptrary = FFI::MemoryPointer.new(:pointer, 5)
|
@@ -105,6 +113,6 @@ describe "String tests" do
|
|
105
113
|
a << f
|
106
114
|
end
|
107
115
|
ptrary.write_array_of_pointer(ary)
|
108
|
-
|
116
|
+
expect { ptrary.get_array_of_string(-1) }.to raise_error
|
109
117
|
end
|
110
118
|
end
|
data/spec/ffi/strptr_spec.rb
CHANGED
@@ -4,12 +4,11 @@
|
|
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 "functions returning :strptr" do
|
10
9
|
|
11
10
|
it "can attach function with :strptr return type" do
|
12
|
-
|
11
|
+
expect do
|
13
12
|
Module.new do
|
14
13
|
extend FFI::Library
|
15
14
|
ffi_lib FFI::Library::LIBC
|
@@ -19,7 +18,7 @@ describe "functions returning :strptr" do
|
|
19
18
|
attach_function :_strdup, [ :string ], :strptr
|
20
19
|
end
|
21
20
|
end
|
22
|
-
end.
|
21
|
+
end.not_to raise_error
|
23
22
|
end
|
24
23
|
|
25
24
|
module StrPtr
|
@@ -35,17 +34,17 @@ describe "functions returning :strptr" do
|
|
35
34
|
|
36
35
|
it "should return [ String, Pointer ]" do
|
37
36
|
result = StrPtr.strdup("test")
|
38
|
-
result[0].is_a?(String).
|
39
|
-
result[1].is_a?(FFI::Pointer).
|
37
|
+
expect(result[0].is_a?(String)).to be true
|
38
|
+
expect(result[1].is_a?(FFI::Pointer)).to be true
|
40
39
|
end
|
41
40
|
|
42
41
|
it "should return the correct value" do
|
43
42
|
result = StrPtr.strdup("test")
|
44
|
-
result[0].
|
43
|
+
expect(result[0]).to eq("test")
|
45
44
|
end
|
46
45
|
|
47
46
|
it "should return non-NULL pointer" do
|
48
47
|
result = StrPtr.strdup("test")
|
49
|
-
result[1].
|
48
|
+
expect(result[1]).not_to be_null
|
50
49
|
end
|
51
50
|
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 FFI::Struct, ' by_ref' do
|
10
9
|
before :all do
|
@@ -22,15 +21,15 @@ describe FFI::Struct, ' by_ref' do
|
|
22
21
|
|
23
22
|
it "should accept instances of exact struct class" do
|
24
23
|
s = @struct_class.new
|
25
|
-
@api.struct_test(s).
|
24
|
+
expect(@api.struct_test(s)).to eq(s.pointer)
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should accept nil" do
|
29
|
-
@api.struct_test(nil).
|
28
|
+
expect(@api.struct_test(nil)).to be_null
|
30
29
|
end
|
31
30
|
|
32
31
|
it "should reject other types" do
|
33
|
-
|
32
|
+
expect { expect(@api.struct_test('test')).to be_nil }.to raise_error(TypeError)
|
34
33
|
end
|
35
34
|
|
36
35
|
it "should reject instances of other struct classes" do
|
@@ -38,7 +37,7 @@ describe FFI::Struct, ' by_ref' do
|
|
38
37
|
layout :a, :pointer
|
39
38
|
end
|
40
39
|
|
41
|
-
|
40
|
+
expect { @api.struct_test(other_class.new) }.to raise_error(TypeError)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
@@ -4,11 +4,10 @@
|
|
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::Struct, ' with inline callback functions' do
|
10
9
|
it 'should be able to define inline callback field' do
|
11
|
-
module CallbackMember1
|
10
|
+
expect(module CallbackMember1
|
12
11
|
extend FFI::Library
|
13
12
|
ffi_lib TestLibrary::PATH
|
14
13
|
DUMMY_CB = callback :dummy_cb, [ :int ], :int
|
@@ -20,8 +19,9 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
20
19
|
end
|
21
20
|
attach_function :struct_call_add_cb, [TestStruct, :int, :int], :int
|
22
21
|
attach_function :struct_call_sub_cb, [TestStruct, :int, :int], :int
|
23
|
-
end.
|
22
|
+
end).to be_an_instance_of FFI::Function
|
24
23
|
end
|
24
|
+
|
25
25
|
it 'should take methods as callbacks' do
|
26
26
|
module CallbackMember2
|
27
27
|
extend FFI::Library
|
@@ -43,7 +43,7 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
43
43
|
ts = CallbackMember2::TestStruct.new
|
44
44
|
ts[:add] = StructCallbacks.method(:add)
|
45
45
|
|
46
|
-
CallbackMember2.struct_call_add_cb(ts, 1, 2).
|
46
|
+
expect(CallbackMember2.struct_call_add_cb(ts, 1, 2)).to eq(3)
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'should return callable object from []' do
|
@@ -63,8 +63,7 @@ describe FFI::Struct, ' with inline callback functions' do
|
|
63
63
|
add = Proc.new { |a,b| a+b}
|
64
64
|
s[:add] = add
|
65
65
|
fn = s[:add]
|
66
|
-
fn.respond_to?(:call).
|
67
|
-
fn.call(1, 2).
|
66
|
+
expect(fn.respond_to?(:call)).to be true
|
67
|
+
expect(fn.call(1, 2)).to eq(3)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|