aboutsummaryrefslogtreecommitdiffstats
path: root/test/fiddle
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-06 06:59:24 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-05-06 06:59:24 +0000
commit4bada8b864e445b6eebe1a341e30cad94dbcaf84 (patch)
treebb7e4ed991aa16eda953d536265c6f9e5dc03a5d /test/fiddle
parentca3c007f058f17b2f0bf3c5ccc6701f3f6d49ca5 (diff)
downloadruby-4bada8b864e445b6eebe1a341e30cad94dbcaf84.tar.gz
* ext/fiddle/*: Adding fiddle library to wrap libffi
* test/fiddle/*: testing fiddle extension * ext/dl/lib/dl.rb: Requiring fiddle if it is available * ext/dl/lib/dl/callback.rb: using Fiddle if it is available * ext/dl/lib/dl/func.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27640 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/fiddle')
-rw-r--r--test/fiddle/helper.rb71
-rw-r--r--test/fiddle/test_closure.rb49
-rw-r--r--test/fiddle/test_fiddle.rb19
-rw-r--r--test/fiddle/test_function.rb66
4 files changed, 205 insertions, 0 deletions
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
new file mode 100644
index 0000000000..6f9c5651b8
--- /dev/null
+++ b/test/fiddle/helper.rb
@@ -0,0 +1,71 @@
+require 'minitest/autorun'
+require 'dl'
+require 'fiddle'
+
+# FIXME: this is stolen from DL and needs to be refactored.
+require_relative '../ruby/envutil'
+
+libc_so = libm_so = nil
+
+case RUBY_PLATFORM
+when /cygwin/
+ libc_so = "cygwin1.dll"
+ libm_so = "cygwin1.dll"
+when /x86_64-linux/
+ libc_so = "/lib64/libc.so.6"
+ libm_so = "/lib64/libm.so.6"
+when /linux/
+ libdir = '/lib'
+ case [0].pack('L!').size
+ when 4
+ # 32-bit ruby
+ libdir = '/lib32' if File.directory? '/lib32'
+ when 8
+ # 64-bit ruby
+ libdir = '/lib64' if File.directory? '/lib64'
+ end
+ libc_so = File.join(libdir, "libc.so.6")
+ libm_so = File.join(libdir, "libm.so.6")
+when /mingw/, /mswin/
+ require "rbconfig"
+ libc_so = libm_so = RbConfig::CONFIG["RUBY_SO_NAME"].split(/-/, 2)[0] + ".dll"
+when /darwin/
+ libc_so = "/usr/lib/libc.dylib"
+ libm_so = "/usr/lib/libm.dylib"
+when /kfreebsd/
+ libc_so = "/lib/libc.so.0.1"
+ libm_so = "/lib/libm.so.1"
+when /bsd|dragonfly/
+ libc_so = "/usr/lib/libc.so"
+ libm_so = "/usr/lib/libm.so"
+else
+ libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
+ libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
+ if( !(libc_so && libm_so) )
+ $stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
+ end
+end
+
+libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
+libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
+
+if !libc_so || !libm_so
+ ruby = EnvUtil.rubybin
+ ldd = `ldd #{ruby}`
+ #puts ldd
+ libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
+ libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
+ #p [libc_so, libm_so]
+end
+
+Fiddle::LIBC_SO = libc_so
+Fiddle::LIBM_SO = libm_so
+
+module Fiddle
+ class TestCase < MiniTest::Unit::TestCase
+ def setup
+ @libc = DL.dlopen(LIBC_SO)
+ @libm = DL.dlopen(LIBM_SO)
+ end
+ end
+end
diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb
new file mode 100644
index 0000000000..ae343460f2
--- /dev/null
+++ b/test/fiddle/test_closure.rb
@@ -0,0 +1,49 @@
+require_relative 'helper'
+
+module Fiddle
+ class TestClosure < Fiddle::TestCase
+ def test_argument_errors
+ assert_raises(TypeError) do
+ Closure.new(TYPE_INT, TYPE_INT)
+ end
+
+ assert_raises(TypeError) do
+ Closure.new('foo', [TYPE_INT])
+ end
+
+ assert_raises(TypeError) do
+ Closure.new(TYPE_INT, ['meow!'])
+ end
+ end
+
+ def test_call
+ closure = Class.new(Closure) {
+ def call
+ 10
+ end
+ }.new(TYPE_INT, [])
+
+ func = Function.new(closure, [], TYPE_INT)
+ assert_equal 10, func.call
+ end
+
+ def test_returner
+ closure = Class.new(Closure) {
+ def call thing
+ thing
+ end
+ }.new(TYPE_INT, [TYPE_INT])
+
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+ assert_equal 10, func.call(10)
+ end
+
+ def test_block_caller
+ cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
+ one
+ end
+ func = Function.new(cb, [TYPE_INT], TYPE_INT)
+ assert_equal 11, func.call(11)
+ end
+ end
+end
diff --git a/test/fiddle/test_fiddle.rb b/test/fiddle/test_fiddle.rb
new file mode 100644
index 0000000000..fa19aaff07
--- /dev/null
+++ b/test/fiddle/test_fiddle.rb
@@ -0,0 +1,19 @@
+require_relative 'helper'
+
+class TestFiddle < Fiddle::TestCase
+ def test_constants_match
+ [
+ :TYPE_VOID,
+ :TYPE_VOIDP,
+ :TYPE_CHAR,
+ :TYPE_SHORT,
+ :TYPE_INT,
+ :TYPE_LONG,
+ :TYPE_LONG_LONG,
+ :TYPE_FLOAT,
+ :TYPE_DOUBLE,
+ ].each do |name|
+ assert_equal(DL.const_get(name), Fiddle.const_get(name))
+ end
+ end
+end
diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb
new file mode 100644
index 0000000000..50b214a9e0
--- /dev/null
+++ b/test/fiddle/test_function.rb
@@ -0,0 +1,66 @@
+require_relative 'helper'
+
+module Fiddle
+ class TestFunction < Fiddle::TestCase
+ def setup
+ super
+ Fiddle.last_error = nil
+ end
+
+ def test_default_abi
+ func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
+ assert_equal Function::DEFAULT, func.abi
+ end
+
+ def test_argument_errors
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], TYPE_DOUBLE, TYPE_DOUBLE)
+ end
+
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], ['foo'], TYPE_DOUBLE)
+ end
+
+ assert_raises(TypeError) do
+ Function.new(@libm['sin'], [TYPE_DOUBLE], 'foo')
+ end
+ end
+
+ def test_call
+ func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
+ assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001
+ end
+
+ def test_argument_count
+ closure = Class.new(Closure) {
+ def call one
+ 10 + one
+ end
+ }.new(TYPE_INT, [TYPE_INT])
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+
+ assert_raises(ArgumentError) do
+ func.call(1,2,3)
+ end
+ assert_raises(ArgumentError) do
+ func.call
+ end
+ end
+
+ def test_last_error
+ func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
+
+ assert_nil Fiddle.last_error
+ str = func.call("000", "123")
+ refute_nil Fiddle.last_error
+ end
+
+ def test_strcpy
+ f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
+ buff = "000"
+ str = f.call(buff, "123")
+ assert_equal("123", buff)
+ assert_equal("123", str.to_s)
+ end
+ end
+end