1require_relative 'test_base'
2require_relative '../ruby/envutil'
3require 'dl/callback'
4require 'dl/func'
5
6module DL
7  class TestCallback < TestBase
8    include DL
9
10    def test_remove_callback_failed
11      assert_equal(false, remove_callback(0, TYPE_VOIDP))
12    end
13
14    def test_remove_callback
15      addr = set_callback(TYPE_VOIDP, 1) do |str|
16        str
17      end
18      assert remove_callback(addr, TYPE_VOIDP), 'callback removed'
19    end
20
21    def test_callback_return_value
22      addr = set_callback(TYPE_VOIDP, 1) do |str|
23        str
24      end
25      func = CFunc.new(addr, TYPE_VOIDP, 'test')
26      f = Function.new(func, [TYPE_VOIDP])
27      ptr = CPtr['blah']
28      assert_equal ptr.to_i, f.call(ptr).to_i
29    end
30
31    def test_callback_return_arbitrary
32      foo = 'foo'
33      addr = set_callback(TYPE_VOIDP, 1) do |ptr|
34        CPtr[foo].to_i
35      end
36      func = CFunc.new(addr, TYPE_VOIDP, 'test')
37      f = Function.new(func, [TYPE_VOIDP])
38
39      ptr = CPtr['foo']
40      assert_equal 'foo', f.call(ptr).to_s
41    end
42
43    def test_callback_with_string
44      called_with = nil
45      addr = set_callback(TYPE_VOID, 1) do |str|
46        called_with = dlunwrap(str)
47      end
48      func = CFunc.new(addr, TYPE_VOID, 'test')
49      f = Function.new(func, [TYPE_VOIDP])
50
51      # Don't remove local variable arg.
52      # This necessary to protect objects from GC.
53      arg = 'foo'
54      f.call(dlwrap(arg))
55      assert_equal arg, called_with
56    end
57
58    def test_call_callback
59      called = false
60
61      addr = set_callback(TYPE_VOID, 1) do |foo|
62        called = true
63      end
64
65      func = CFunc.new(addr, TYPE_VOID, 'test')
66      f = Function.new(func, [TYPE_VOIDP])
67      f.call(nil)
68
69      assert called, 'function should be called'
70    end
71  end
72end
73