1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
# frozen_string_literal: true
begin
require_relative 'helper'
require 'fiddle/struct'
rescue LoadError
end
module Fiddle
class TestCStructEntity < TestCase
def test_class_size
types = [TYPE_DOUBLE, TYPE_CHAR]
size = CStructEntity.size types
alignments = types.map { |type| PackInfo::ALIGN_MAP[type] }
expected = PackInfo.align 0, alignments[0]
expected += PackInfo::SIZE_MAP[TYPE_DOUBLE]
expected = PackInfo.align expected, alignments[1]
expected += PackInfo::SIZE_MAP[TYPE_CHAR]
expected = PackInfo.align expected, alignments.max
assert_equal expected, size
end
def test_class_size_with_count
size = CStructEntity.size([[TYPE_DOUBLE, 2], [TYPE_CHAR, 20]])
types = [TYPE_DOUBLE, TYPE_CHAR]
alignments = types.map { |type| PackInfo::ALIGN_MAP[type] }
expected = PackInfo.align 0, alignments[0]
expected += PackInfo::SIZE_MAP[TYPE_DOUBLE] * 2
expected = PackInfo.align expected, alignments[1]
expected += PackInfo::SIZE_MAP[TYPE_CHAR] * 20
expected = PackInfo.align expected, alignments.max
assert_equal expected, size
end
def test_set_ctypes
CStructEntity.malloc([TYPE_INT, TYPE_LONG], Fiddle::RUBY_FREE) do |struct|
struct.assign_names %w[int long]
# this test is roundabout because the stored ctypes are not accessible
struct['long'] = 1
struct['int'] = 2
assert_equal 1, struct['long']
assert_equal 2, struct['int']
end
end
def test_aref_pointer_array
CStructEntity.malloc([[TYPE_VOIDP, 2]], Fiddle::RUBY_FREE) do |team|
team.assign_names(["names"])
Fiddle::Pointer.malloc(6, Fiddle::RUBY_FREE) do |alice|
alice[0, 6] = "Alice\0"
Fiddle::Pointer.malloc(4, Fiddle::RUBY_FREE) do |bob|
bob[0, 4] = "Bob\0"
team["names"] = [alice, bob]
assert_equal(["Alice", "Bob"], team["names"].map(&:to_s))
end
end
end
end
def test_aref_pointer
CStructEntity.malloc([TYPE_VOIDP], Fiddle::RUBY_FREE) do |user|
user.assign_names(["name"])
Fiddle::Pointer.malloc(6, Fiddle::RUBY_FREE) do |alice|
alice[0, 6] = "Alice\0"
user["name"] = alice
assert_equal("Alice", user["name"].to_s)
end
end
end
def test_new_double_free
types = [TYPE_INT]
Pointer.malloc(CStructEntity.size(types), Fiddle::RUBY_FREE) do |pointer|
assert_raise ArgumentError do
CStructEntity.new(pointer, types, Fiddle::RUBY_FREE)
end
end
end
def test_malloc_block
escaped_struct = nil
returned = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
assert_equal Fiddle::SIZEOF_INT, struct.size
assert_equal Fiddle::RUBY_FREE, struct.free.to_i
escaped_struct = struct
:returned
end
assert_equal :returned, returned
assert escaped_struct.freed?
end
def test_malloc_block_no_free
assert_raise ArgumentError do
CStructEntity.malloc([TYPE_INT]) { |struct| }
end
end
def test_free
struct = CStructEntity.malloc([TYPE_INT])
begin
assert_nil struct.free
ensure
Fiddle.free struct
end
end
def test_free_with_func
struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
refute struct.freed?
struct.call_free
assert struct.freed?
struct.call_free # you can safely run it again
assert struct.freed?
GC.start # you can safely run the GC routine
assert struct.freed?
end
def test_free_with_no_func
struct = CStructEntity.malloc([TYPE_INT])
refute struct.freed?
struct.call_free
refute struct.freed?
struct.call_free # you can safely run it again
refute struct.freed?
end
def test_freed?
struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
refute struct.freed?
struct.call_free
assert struct.freed?
end
def test_null?
struct = CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE)
refute struct.null?
end
def test_size
CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
assert_equal Fiddle::SIZEOF_INT, struct.size
end
end
def test_size=
CStructEntity.malloc([TYPE_INT], Fiddle::RUBY_FREE) do |struct|
assert_raise NoMethodError do
struct.size = 1
end
end
end
end
end if defined?(Fiddle)
|