summaryrefslogtreecommitdiff
path: root/test/fiddle/test_import.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/fiddle/test_import.rb')
-rw-r--r--test/fiddle/test_import.rb499
1 files changed, 0 insertions, 499 deletions
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb
deleted file mode 100644
index a6a3b66655..0000000000
--- a/test/fiddle/test_import.rb
+++ /dev/null
@@ -1,499 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: true
-begin
- require_relative 'helper'
- require 'fiddle/import'
-rescue LoadError
-end
-
-module Fiddle
- module LIBC
- extend Importer
- dlload LIBC_SO, LIBM_SO
-
- typealias 'string', 'char*'
- typealias 'FILE*', 'void*'
-
- extern "void *strcpy(char*, char*)"
- extern "int isdigit(int)"
- extern "double atof(string)"
- extern "unsigned long strtoul(char*, char **, int)"
- extern "int qsort(void*, unsigned long, unsigned long, void*)"
- extern "int fprintf(FILE*, char*)" rescue nil
- extern "int gettimeofday(timeval*, timezone*)" rescue nil
-
- Timeval = struct [
- "long tv_sec",
- "long tv_usec",
- ]
- Timezone = struct [
- "int tz_minuteswest",
- "int tz_dsttime",
- ]
- MyStruct = struct [
- "short num[5]",
- "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'
- ]
- }
- ]
- end
-
- class TestImport < TestCase
- def test_ensure_call_dlload
- err = assert_raise(RuntimeError) do
- Class.new do
- extend Importer
- extern "void *strcpy(char*, char*)"
- end
- end
- assert_match(/call dlload before/, err.message)
- end
-
- def test_struct_memory_access()
- # check memory operations performed directly on struct
- 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]
- end
- end
-
- def test_struct_ptr_array_subscript_multiarg()
- # check memory operations performed on struct#to_ptr
- Fiddle::Importer.struct([ 'int x' ]).malloc(Fiddle::RUBY_FREE) do |struct|
- ptr = struct.to_ptr
-
- struct.x = 0x02020202
- assert_equal("\x02".b * Fiddle::SIZEOF_INT, ptr[0, Fiddle::SIZEOF_INT])
-
- ptr[0, Fiddle::SIZEOF_INT] = "\x01".b * Fiddle::SIZEOF_INT
- assert_equal 0x01010101, struct.x
- end
- end
-
- def test_malloc()
- 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)
- end
- end
- end
-
- def test_sizeof()
- assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
- assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
- LIBC::MyStruct.malloc(Fiddle::RUBY_FREE) do |my_struct|
- assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(my_struct))
- 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
- type = $&
- const_type_name = $1
- size = Fiddle.const_get("SIZEOF_#{const_type_name}")
- if const_type_name == "CONST_STRING"
- name = "const_string"
- type_name = "const char*"
- else
- name = $1.sub(/P\z/,"*").gsub(/_(?!T\z)/, " ").downcase
- type_name = name
- end
- type_name = "unsigned #{$1}" if type_name =~ /\Au(long|short|char|int|long long)\z/
-
- define_method("test_sizeof_#{name}") do
- assert_equal(size, Fiddle::Importer.sizeof(type_name), type)
- end
- end
-
- # Assert that the unsigned constants are equal to the "negative" signed ones
- # for backwards compatibility
- def test_unsigned_equals_negative_signed
- Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(U.*)/) do |unsigned|
- assert_equal(-Fiddle.const_get(unsigned.to_s.sub(/U/, '')),
- Fiddle.const_get(unsigned))
- end
- end
-
- def test_type_constants
- Fiddle::Types.constants.each do |const|
- assert_equal Fiddle::Types.const_get(const), Fiddle.const_get("TYPE_#{const}")
- end
- end
-
- def test_unsigned_result()
- d = (2 ** 31) + 1
-
- r = LIBC.strtoul(d.to_s, nil, 0)
- assert_equal(d, r)
- end
-
- def test_io()
- if ffi_backend?
- omit("BUILD_RUBY_PLATFORM doesn't exist in FFI backend")
- end
-
- if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM ) || !defined?(LIBC.fprintf)
- return
- end
- io_in,io_out = IO.pipe()
- LIBC.fprintf(io_out, "hello")
- io_out.flush()
- io_out.close()
- str = io_in.read()
- io_in.close()
- assert_equal("hello", str)
- end
-
- def test_value()
- i = LIBC.value('int', 2)
- assert_equal(2, i.value)
-
- d = LIBC.value('double', 2.0)
- assert_equal(2.0, d.value)
-
- ary = LIBC.value('int[3]', [0,1,2])
- assert_equal([0,1,2], ary.value)
- end
-
- def test_struct_array_assignment()
- 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
- assert_equal 1024, instance.stages[0]
- assert_equal 10, instance.stages[1]
- assert_equal 100, instance.stages[2]
- assert_equal [1024, 10, 100].pack(Fiddle::PackInfo::PACK_MAP[-Fiddle::TYPE_INT] * 3),
- instance.to_ptr[0, 3 * Fiddle::SIZEOF_INT]
- assert_raise(IndexError) { instance.stages[-1] = 5 }
- assert_raise(IndexError) { instance.stages[3] = 5 }
- 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([{ keyboard: 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] = nil
- 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()
- 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,"\xFF".ord], s.buff)
- end
- end
-
- def test_gettimeofday()
- if( defined?(LIBC.gettimeofday) )
- LIBC::Timeval.malloc(Fiddle::RUBY_FREE) do |timeval|
- LIBC::Timezone.malloc(Fiddle::RUBY_FREE) do |timezone|
- LIBC.gettimeofday(timeval, timezone)
- end
- cur = Time.now()
- assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
- end
- end
- end
-
- def test_strcpy()
- if RUBY_ENGINE == "jruby"
- omit("Function that returns string doesn't work with JRuby")
- end
-
- buff = +"000"
- str = LIBC.strcpy(buff, "123")
- assert_equal("123", buff)
- assert_equal("123", str.to_s)
- end
-
- def test_isdigit
- r1 = LIBC.isdigit(?1.ord)
- r2 = LIBC.isdigit(?2.ord)
- rr = LIBC.isdigit(?r.ord)
- assert_operator(r1, :>, 0)
- assert_operator(r2, :>, 0)
- assert_equal(0, rr)
- end
-
- def test_atof
- r = LIBC.atof("12.34")
- assert_includes(12.00..13.00, r)
- end
- end
-end if defined?(Fiddle)