import ctypes
import reference_project as r
import unittest
import sys
r.init_lib("../../../../target/debug/interoptopus_reference_project.dll")
def limits(c_int_type):
signed = c_int_type(-1).value < c_int_type(0).value
bit_size = ctypes.sizeof(c_int_type) * 8
signed_limit = 2 ** (bit_size - 1)
return (-signed_limit, signed_limit - 1) if signed else (0, 2 * signed_limit - 1)
i8_min = limits(ctypes.c_int8)[0]
i16_min = limits(ctypes.c_int16)[0]
i32_min = limits(ctypes.c_int32)[0]
i64_min = limits(ctypes.c_int64)[0]
i8_max = limits(ctypes.c_int8)[1]
i16_max = limits(ctypes.c_int16)[1]
i32_max = limits(ctypes.c_int32)[1]
i64_max = limits(ctypes.c_int64)[1]
u8_max = limits(ctypes.c_uint8)[1]
u16_max = limits(ctypes.c_uint16)[1]
u32_max = limits(ctypes.c_uint32)[1]
u64_max = limits(ctypes.c_uint64)[1]
class TestFunctions(unittest.TestCase):
def test_primitives(self):
r.primitive_void()
r.primitive_void2()
self.assertEqual(True, r.primitive_bool(False))
self.assertEqual(0, r.primitive_u8(u8_max))
self.assertEqual(0, r.primitive_u16(u16_max))
self.assertEqual(0, r.primitive_u32(u32_max))
self.assertEqual(0, r.primitive_u64(u64_max))
self.assertEqual(-i8_max, r.primitive_i8(i8_max))
self.assertEqual(-i16_max, r.primitive_i16(i16_max))
self.assertEqual(-i32_max, r.primitive_i32(i32_max))
self.assertEqual(-i64_max, r.primitive_i64(i64_max))
def test_ptr(self):
ptr = (ctypes.c_int64 * 100)(100, 2, 3)
ptr_ptr = ctypes.POINTER(ctypes.POINTER(ctypes.c_int64))()
r.ptr_ptr(ptr_ptr)
self.assertEqual(ctypes.cast(ptr, ctypes.c_void_p).value, ctypes.cast(r.ptr(ptr), ctypes.c_void_p).value)
self.assertEqual(ctypes.cast(ptr_ptr, ctypes.c_void_p).value,
ctypes.cast(r.ptr_ptr(ptr_ptr), ctypes.c_void_p).value)
self.assertEqual(True, r.ref_option(ptr))
self.assertEqual(True, r.ref_mut_option(ptr))
self.assertEqual(ctypes.cast(ptr, ctypes.c_void_p).value, ctypes.cast(r.ptr_mut(ptr), ctypes.c_void_p).value)
self.assertEqual(-100, ptr[0])
def test_tuple(self):
tupled = r.Tupled(x0=100)
self.assertEqual(200, r.tupled(tupled).x0)
def test_complex(self):
vec = r.Vec3f32()
foreign = r.SomeForeignType()
r.complex_args_1(vec, None)
self.assertEqual(None, r.complex_args_2(foreign))
def test_callback(self):
def my_callback(param):
return param * 3
self.assertEqual(9, r.callback(my_callback, 3))
def test_generic(self):
uint32 = (ctypes.c_uint32 * 10)(123)
genericu32 = r.Genericu32(uint32)
phantom = r.Phantomu8()
self.assertEqual(123, r.generic_1a(genericu32, phantom))
def test_documented(self):
documented = r.StructDocumented()
self.assertEqual(r.EnumDocumented.A, r.documented(documented))
def test_ambiguous(self):
vec1 = r.Vec1(x=10.0)
vec2 = r.Vec2(x=10.0, z=11.0)
for i in range(1000):
self.assertEqual(10.0, r.ambiguous_1(vec1).x)
self.assertEqual(11.0, r.ambiguous_2(vec2).z)
self.assertEqual(True, r.ambiguous_3(vec1, vec2))
def test_namespaces(self):
vec = r.Vec(x=10)
self.assertEqual(10.0, r.namespaced_type(vec).x)
def test_panics(self):
worked = False
try:
r.panics()
worked = True
except:
pass
self.assertFalse(worked)
def test_slice_from_ctypes_array(self):
array = (ctypes.c_uint32 * 10)()
returned_length = r.pattern_ffi_slice_1(array)
self.assertEqual(len(array), returned_length)
slice = r.Sliceu32(data=ctypes.cast(array, ctypes.POINTER(ctypes.c_uint32)), len=len(array))
returned_length = r.pattern_ffi_slice_1(slice)
self.assertEqual(len(slice), returned_length)
def test_slice_from_ctypes_array_callback(self):
array = (ctypes.c_uint8 * 10)()
def callback(x):
self.assertEqual(1, x[0])
self.assertEqual(0, x[1])
r.pattern_ffi_slice_3(array, callback)
class TestPatterns(unittest.TestCase):
def test_services(self):
service = r.SimpleService.new_with(123)
slice = service.return_slice_mut()
self.assertEqual(10, service.method_value(10))
self.assertEqual(123, slice[0])
def test_service_new_string(self):
service = r.SimpleService.new_with_string(b"abc")
def test_ascii_pointer(self):
self.assertEqual(3, r.pattern_ascii_pointer_1(b"111"))
self.assertEqual(b'', r.pattern_ascii_pointer_2())
def test_c_char(self):
self.assertEqual(b'X', r.pattern_ffi_cchar(b'X'))
def test_slice_callback(self):
def callback(x):
self.assertEqual(9, x[-1])
self.assertEqual(9, x.last())
self.assertEqual(9, x.bytearray()[-1])
try:
i = x[10]
self.assertFalse(True, "Index out of error should throw exception")
except IndexError:
pass
return 0
r.pattern_ffi_slice_delegate(callback)
if __name__ == '__main__':
unittest.main()
sys.exit(0)