diff options
Diffstat (limited to 'test/fiddle/test_import.rb')
-rw-r--r-- | test/fiddle/test_import.rb | 324 |
1 files changed, 284 insertions, 40 deletions
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb index 4afd8e5562..afa8df9e00 100644 --- a/test/fiddle/test_import.rb +++ b/test/fiddle/test_import.rb @@ -36,6 +36,29 @@ module Fiddle "char c", "unsigned char buff[7]", ] + StructNestedStruct = struct [ + { + "vertices[2]" => { + position: ["float x", "float y", "float z"], + texcoord: ["float u", "float v"] + }, + object: ["int id", "void *user_data"], + }, + "int id" + ] + UnionNestedStruct = union [ + { + keyboard: [ + 'unsigned int state', + 'char key' + ], + mouse: [ + 'unsigned int button', + 'unsigned short x', + 'unsigned short y' + ] + } + ] CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2| f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID) @@ -56,22 +79,18 @@ module Fiddle def test_struct_memory_access() # check memory operations performed directly on struct - my_struct = Fiddle::Importer.struct(['int id']).malloc - begin + Fiddle::Importer.struct(['int id']).malloc(Fiddle::RUBY_FREE) do |my_struct| my_struct[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT assert_equal 0x01010101, my_struct.id my_struct.id = 0 assert_equal "\x00".b * Fiddle::SIZEOF_INT, my_struct[0, Fiddle::SIZEOF_INT] - ensure - Fiddle.free my_struct.to_ptr end end def test_struct_ptr_array_subscript_multiarg() # check memory operations performed on struct#to_ptr - struct = Fiddle::Importer.struct([ 'int x' ]).malloc - begin + Fiddle::Importer.struct([ 'int x' ]).malloc(Fiddle::RUBY_FREE) do |struct| ptr = struct.to_ptr struct.x = 0x02020202 @@ -79,35 +98,25 @@ module Fiddle ptr[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT assert_equal 0x01010101, struct.x - ensure - Fiddle.free struct.to_ptr end end def test_malloc() - s1 = LIBC::Timeval.malloc() - begin - s2 = LIBC::Timeval.malloc() - begin + LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s1| + LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |s2| refute_equal(s1.to_ptr.to_i, s2.to_ptr.to_i) - ensure - Fiddle.free s2.to_ptr end - ensure - Fiddle.free s1.to_ptr end end def test_sizeof() assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*")) assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct)) - my_struct = LIBC::MyStruct.malloc() - begin + LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |my_struct| assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(my_struct)) - ensure - Fiddle.free my_struct.to_ptr end assert_equal(SIZEOF_LONG_LONG, LIBC.sizeof("long long")) if defined?(SIZEOF_LONG_LONG) + assert_equal(LIBC::StructNestedStruct.size(), LIBC.sizeof(LIBC::StructNestedStruct)) end Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(.*)/) do @@ -158,8 +167,7 @@ module Fiddle end def test_struct_array_assignment() - instance = Fiddle::Importer.struct(["unsigned int stages[3]"]).malloc - begin + Fiddle::Importer.struct(["unsigned int stages[3]"]).malloc(Fiddle::RUBY_FREE) do |instance| instance.stages[0] = 1024 instance.stages[1] = 10 instance.stages[2] = 100 @@ -170,39 +178,279 @@ module Fiddle instance.to_ptr[0, 3 * Fiddle::SIZEOF_INT] assert_raise(IndexError) { instance.stages[-1] = 5 } assert_raise(IndexError) { instance.stages[3] = 5 } - ensure - Fiddle.free instance.to_ptr + end + end + + def test_nested_struct_reusing_other_structs() + position_struct = Fiddle::Importer.struct(['float x', 'float y', 'float z']) + texcoord_struct = Fiddle::Importer.struct(['float u', 'float v']) + vertex_struct = Fiddle::Importer.struct(position: position_struct, texcoord: texcoord_struct) + mesh_struct = Fiddle::Importer.struct([ + { + "vertices[2]" => vertex_struct, + object: [ + "int id", + "void *user_data", + ], + }, + "int id", + ]) + assert_equal LIBC::StructNestedStruct.size, mesh_struct.size + + + keyboard_event_struct = Fiddle::Importer.struct(['unsigned int state', 'char key']) + mouse_event_struct = Fiddle::Importer.struct(['unsigned int button', 'unsigned short x', 'unsigned short y']) + event_union = Fiddle::Importer.union([{ keboard: keyboard_event_struct, mouse: mouse_event_struct}]) + assert_equal LIBC::UnionNestedStruct.size, event_union.size + end + + def test_nested_struct_alignment_is_not_its_size() + inner = Fiddle::Importer.struct(['int x', 'int y', 'int z', 'int w']) + outer = Fiddle::Importer.struct(['char a', { 'nested' => inner }, 'char b']) + outer.malloc(Fiddle::RUBY_FREE) do |instance| + offset = instance.to_ptr.instance_variable_get(:"@offset") + assert_equal Fiddle::SIZEOF_INT * 5, offset.last + assert_equal Fiddle::SIZEOF_INT * 6, outer.size + assert_equal instance.to_ptr.size, outer.size + end + end + + def test_struct_nested_struct_members() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + Fiddle::Pointer.malloc(24, Fiddle::RUBY_FREE) do |user_data| + s.vertices[0].position.x = 1 + s.vertices[0].position.y = 2 + s.vertices[0].position.z = 3 + s.vertices[0].texcoord.u = 4 + s.vertices[0].texcoord.v = 5 + s.vertices[1].position.x = 6 + s.vertices[1].position.y = 7 + s.vertices[1].position.z = 8 + s.vertices[1].texcoord.u = 9 + s.vertices[1].texcoord.v = 10 + s.object.id = 100 + s.object.user_data = user_data + s.id = 101 + assert_equal({ + "vertices" => [ + { + "position" => { + "x" => 1, + "y" => 2, + "z" => 3, + }, + "texcoord" => { + "u" => 4, + "v" => 5, + }, + }, + { + "position" => { + "x" => 6, + "y" => 7, + "z" => 8, + }, + "texcoord" => { + "u" => 9, + "v" => 10, + }, + }, + ], + "object" => { + "id" => 100, + "user_data" => user_data, + }, + "id" => 101, + }, + s.to_h) + end + end + end + + def test_union_nested_struct_members() + LIBC::UnionNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + s.keyboard.state = 100 + s.keyboard.key = 101 + assert_equal(100, s.mouse.button) + refute_equal( 0, s.mouse.x) + end + end + + def test_struct_nested_struct_replace_array_element() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + s.vertices[0].position.x = 5 + + vertex_struct = Fiddle::Importer.struct [{ + position: ["float x", "float y", "float z"], + texcoord: ["float u", "float v"] + }] + vertex_struct.malloc(Fiddle::RUBY_FREE) do |vertex| + vertex.position.x = 100 + s.vertices[0] = vertex + + # make sure element was copied by value, but things like memory address + # should not be changed + assert_equal(100, s.vertices[0].position.x) + refute_equal(vertex.object_id, s.vertices[0].object_id) + refute_equal(vertex.to_ptr, s.vertices[0].to_ptr) + end + end + end + + def test_struct_nested_struct_replace_array_element_nil() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + s.vertices[0].position.x = 5 + s.vertices[0] = nil + assert_equal({ + "position" => { + "x" => 0.0, + "y" => 0.0, + "z" => 0.0, + }, + "texcoord" => { + "u" => 0.0, + "v" => 0.0, + }, + }, + s.vertices[0].to_h) + end + end + + def test_struct_nested_struct_replace_array_element_hash() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + s.vertices[0] = { + position: { + x: 10, + y: 100, + } + } + assert_equal({ + "position" => { + "x" => 10.0, + "y" => 100.0, + "z" => 0.0, + }, + "texcoord" => { + "u" => 0.0, + "v" => 0.0, + }, + }, + s.vertices[0].to_h) + end + end + + def test_struct_nested_struct_replace_entire_array() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + vertex_struct = Fiddle::Importer.struct [{ + position: ["float x", "float y", "float z"], + texcoord: ["float u", "float v"] + }] + + vertex_struct.malloc(Fiddle::RUBY_FREE) do |same0| + vertex_struct.malloc(Fiddle::RUBY_FREE) do |same1| + same = [same0, same1] + same[0].position.x = 1; same[1].position.x = 6 + same[0].position.y = 2; same[1].position.y = 7 + same[0].position.z = 3; same[1].position.z = 8 + same[0].texcoord.u = 4; same[1].texcoord.u = 9 + same[0].texcoord.v = 5; same[1].texcoord.v = 10 + s.vertices = same + assert_equal([ + { + "position" => { + "x" => 1.0, + "y" => 2.0, + "z" => 3.0, + }, + "texcoord" => { + "u" => 4.0, + "v" => 5.0, + }, + }, + { + "position" => { + "x" => 6.0, + "y" => 7.0, + "z" => 8.0, + }, + "texcoord" => { + "u" => 9.0, + "v" => 10.0, + }, + } + ], + s.vertices.collect(&:to_h)) + end + end + end + end + + def test_struct_nested_struct_replace_entire_array_with_different_struct() + LIBC::StructNestedStruct.malloc(Fiddle::RUBY_FREE) do |s| + different_struct_same_size = Fiddle::Importer.struct [{ + a: ['float i', 'float j', 'float k'], + b: ['float l', 'float m'] + }] + + different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different0| + different_struct_same_size.malloc(Fiddle::RUBY_FREE) do |different1| + different = [different0, different1] + different[0].a.i = 11; different[1].a.i = 16 + different[0].a.j = 12; different[1].a.j = 17 + different[0].a.k = 13; different[1].a.k = 18 + different[0].b.l = 14; different[1].b.l = 19 + different[0].b.m = 15; different[1].b.m = 20 + s.vertices[0][0, s.vertices[0].class.size] = different[0].to_ptr + s.vertices[1][0, s.vertices[1].class.size] = different[1].to_ptr + assert_equal([ + { + "position" => { + "x" => 11.0, + "y" => 12.0, + "z" => 13.0, + }, + "texcoord" => { + "u" => 14.0, + "v" => 15.0, + }, + }, + { + "position" => { + "x" => 16.0, + "y" => 17.0, + "z" => 18.0, + }, + "texcoord" => { + "u" => 19.0, + "v" => 20.0, + }, + } + ], + s.vertices.collect(&:to_h)) + end + end end end def test_struct() - s = LIBC::MyStruct.malloc() - begin + LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |s| s.num = [0,1,2,3,4] s.c = ?a.ord s.buff = "012345\377" assert_equal([0,1,2,3,4], s.num) assert_equal(?a.ord, s.c) assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff) - ensure - Fiddle.free s.to_ptr end end def test_gettimeofday() if( defined?(LIBC.gettimeofday) ) - timeval = LIBC::Timeval.malloc() - begin - timezone = LIBC::Timezone.malloc() - begin + LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |timeval| + LIBC::Timezone.malloc(Fiddle::RUBY_FREE) do |timezone| LIBC.gettimeofday(timeval, timezone) - ensure - Fiddle.free timezone.to_ptr end cur = Time.now() assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i) - ensure - Fiddle.free timeval.to_ptr end end end @@ -227,9 +475,5 @@ module Fiddle r = LIBC.atof("12.34") assert_includes(12.00..13.00, r) end - - def test_no_message_with_debug - assert_in_out_err(%w[--debug --disable=gems -rfiddle/import], 'p Fiddle::Importer', ['Fiddle::Importer']) - end end end if defined?(Fiddle) |