summaryrefslogtreecommitdiff
path: root/testing/test_function.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2012-05-21 09:52:53 +0200
committerArmin Rigo <arigo@tunes.org>2012-05-21 09:52:53 +0200
commitc518795ac5694a028ef297190c93e5257e81a683 (patch)
treeabbb21cac7014c0bde104e23a6a6a8d8fcef3a97 /testing/test_function.py
parent6906d3bdc94d1d2182195566e578744db5a7f94d (diff)
downloadcffi-c518795ac5694a028ef297190c93e5257e81a683.tar.gz
Rename this test file.
Diffstat (limited to 'testing/test_function.py')
-rw-r--r--testing/test_function.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/testing/test_function.py b/testing/test_function.py
new file mode 100644
index 0000000..120e590
--- /dev/null
+++ b/testing/test_function.py
@@ -0,0 +1,134 @@
+import py
+from ffi import FFI
+import math, os, cStringIO
+
+
+class FdWriteCapture(object):
+ """xxx limited to capture at most 512 bytes of output, according
+ to the Posix manual."""
+
+ def __init__(self, capture_fd=1): # stdout, by default
+ self.capture_fd = capture_fd
+
+ def __enter__(self):
+ self.read_fd, self.write_fd = os.pipe()
+ self.copy_fd = os.dup(self.capture_fd)
+ os.dup2(self.write_fd, self.capture_fd)
+ return self
+
+ def __exit__(self, *args):
+ os.dup2(self.copy_fd, self.capture_fd)
+ os.close(self.copy_fd)
+ os.close(self.write_fd)
+ self._value = os.read(self.read_fd, 512)
+ os.close(self.read_fd)
+
+ def getvalue(self):
+ return self._value
+
+
+def test_sin():
+ ffi = FFI()
+ ffi.cdef("""
+ double sin(double x);
+ """)
+ m = ffi.load("m")
+ x = m.sin(1.23)
+ assert x == math.sin(1.23)
+
+def test_sinf():
+ ffi = FFI()
+ ffi.cdef("""
+ float sinf(float x);
+ """)
+ m = ffi.load("m")
+ x = m.sinf(1.23)
+ assert type(x) is float
+ assert x != math.sin(1.23) # rounding effects
+ assert abs(x - math.sin(1.23)) < 1E-6
+
+def test_puts():
+ ffi = FFI()
+ ffi.cdef("""
+ int puts(const char *);
+ int fflush(void *);
+ """)
+ ffi.C.puts # fetch before capturing, for easier debugging
+ with FdWriteCapture() as fd:
+ ffi.C.puts("hello")
+ ffi.C.puts(" world")
+ ffi.C.fflush(None)
+ res = fd.getvalue()
+ assert res == 'hello\n world\n'
+
+def test_fputs():
+ py.test.skip("in-progress")
+ ffi = FFI()
+ ffi.cdef("""
+ int fputs(const char *, void *);
+ void *stdout, *stderr;
+ """)
+ with FdWriteCapture(2) as fd:
+ ffi.C.fputs("hello from stderr", ffi.C.stderr)
+ ffi.C.fflush(ffi.C.stderr)
+ res = fd.getvalue()
+ assert res == 'hello from stderr\n'
+
+def test_vararg():
+ ffi = FFI()
+ ffi.cdef("""
+ int printf(const char *format, ...);
+ int fflush(void *);
+ """)
+ with FdWriteCapture() as fd:
+ ffi.C.printf("hello\n")
+ ffi.C.printf("hello, %s!\n", ffi.new("const char *", "world"))
+ ffi.C.printf("hello int %d long %ld long long %lld\n",
+ ffi.new("int", 42),
+ ffi.new("long", 84),
+ ffi.new("long long", 168))
+ ffi.C.fflush(None)
+ res = fd.getvalue()
+ assert res == ("hello\n"
+ "hello, world!\n"
+ "hello int 42 long 84 long long 168\n")
+
+def test_must_specify_type_of_vararg():
+ ffi = FFI()
+ ffi.cdef("""
+ int printf(const char *format, ...);
+ """)
+ e = py.test.raises(TypeError, ffi.C.printf, "hello %d\n", 42)
+ assert str(e.value) == 'argument 2 needs to be a cdata'
+
+def test_function_has_a_c_type():
+ ffi = FFI()
+ ffi.cdef("""
+ int puts(const char *);
+ """)
+ fptr = ffi.C.puts
+ assert type(fptr) == ffi.typeof("int(*)(const char*)")
+
+def test_function_pointer():
+ py.test.skip("in-progress")
+ ffi = FFI()
+ ffi.cdef("""
+ int puts(const char *);
+ int fflush(void *);
+ """)
+ f = ffi.new("int(*)(const char *txt)", ffi.C.puts)
+ assert f == ffi.new("int(*)(const char *)", ffi.C.puts)
+ with FdWriteCapture() as fd:
+ f("hello")
+ ffi.C.fflush(None)
+ res = fd.getvalue()
+ assert res == 'hello\n'
+
+def test_passing_array():
+ ffi = FFI()
+ ffi.cdef("""
+ int strlen(char[]);
+ """)
+ p = ffi.new("char[]", "hello")
+ res = ffi.C.strlen(p)
+ assert res == 5