From 4bada8b864e445b6eebe1a341e30cad94dbcaf84 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Thu, 6 May 2010 06:59:24 +0000 Subject: * 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 --- test/fiddle/helper.rb | 71 ++++++++++++++++++++++++++++++++++++++++++++ test/fiddle/test_closure.rb | 49 ++++++++++++++++++++++++++++++ test/fiddle/test_fiddle.rb | 19 ++++++++++++ test/fiddle/test_function.rb | 66 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 test/fiddle/helper.rb create mode 100644 test/fiddle/test_closure.rb create mode 100644 test/fiddle/test_fiddle.rb create mode 100644 test/fiddle/test_function.rb (limited to 'test') 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} ") + 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 -- cgit v1.2.3