diff options
| author | Armin Rigo <arigo@tunes.org> | 2012-05-21 09:52:53 +0200 |
|---|---|---|
| committer | Armin Rigo <arigo@tunes.org> | 2012-05-21 09:52:53 +0200 |
| commit | c518795ac5694a028ef297190c93e5257e81a683 (patch) | |
| tree | abbb21cac7014c0bde104e23a6a6a8d8fcef3a97 /testing/test_function.py | |
| parent | 6906d3bdc94d1d2182195566e578744db5a7f94d (diff) | |
| download | cffi-c518795ac5694a028ef297190c93e5257e81a683.tar.gz | |
Rename this test file.
Diffstat (limited to 'testing/test_function.py')
| -rw-r--r-- | testing/test_function.py | 134 |
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 |
