summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Cooper <ahnolds@gmail.com>2015-12-23 18:46:46 -0500
committerAlec Cooper <ahnolds@gmail.com>2015-12-23 19:04:27 -0500
commit2f8a7b822d1a78c421dd4398d4f5ef21ab69ff0c (patch)
tree7d7f748a6d027dfbdabc1f4dc563b4490dc178a9
parentba01182ec4806667f4b220b88cc7e25da08d834d (diff)
downloadswig-2f8a7b822d1a78c421dd4398d4f5ef21ab69ff0c.tar.gz
Adding unit tests for Python primitive type conversions
Adding unit tests for operator overloading to determine which overload was chosen Allow TypeError when testing overloads since it is generated instead of NotImplementedError when swig is run with -O or -fastdispatch
-rw-r--r--Examples/test-suite/primitive_types.i1
-rw-r--r--Examples/test-suite/python/primitive_types_runme.py137
2 files changed, 138 insertions, 0 deletions
diff --git a/Examples/test-suite/primitive_types.i b/Examples/test-suite/primitive_types.i
index 82a673536..29b44ec8c 100644
--- a/Examples/test-suite/primitive_types.i
+++ b/Examples/test-suite/primitive_types.i
@@ -365,6 +365,7 @@ macro(size_t, pfx, sizet)
%define ovr_decl(type, pfx, name)
virtual int pfx##_##val(type x) { return 1; }
virtual int pfx##_##ref(const type& x) { return 1; }
+ virtual const char* pfx##_##str(type x) { return "name"; }
%enddef
diff --git a/Examples/test-suite/python/primitive_types_runme.py b/Examples/test-suite/python/primitive_types_runme.py
index 2e7ed7db7..2f8b2d99c 100644
--- a/Examples/test-suite/python/primitive_types_runme.py
+++ b/Examples/test-suite/python/primitive_types_runme.py
@@ -1,3 +1,5 @@
+import ctypes
+import sys
from primitive_types import *
var_init()
@@ -436,3 +438,138 @@ if s != "hello":
v = SetPos(1, 3)
if v != 4:
raise RuntimeError, "bad int typemap"
+
+#
+# Check the bounds for converting various types
+#
+
+# Get the minimum and maximum values that fit in signed char, short, int, long, and long long
+overchar = 2 ** 7
+while ctypes.c_byte(overchar).value > 0:
+ overchar *= 2
+minchar = -overchar
+maxchar = overchar - 1
+maxuchar = 2 * maxchar + 1
+overshort = overchar
+while ctypes.c_short(overshort).value > 0:
+ overshort *= 2
+minshort = -overshort
+maxshort = overshort - 1
+maxushort = 2 * maxshort + 1
+overint = overshort
+while ctypes.c_int(overint).value > 0:
+ overint *= 2
+minint = -overint
+maxint = overint - 1
+maxuint = 2 * maxint + 1
+overlong = overint
+while ctypes.c_long(overlong).value > 0:
+ overlong *= 2
+minlong = -overlong
+maxlong = overlong - 1
+maxulong = 2 * maxlong + 1
+overllong = overlong
+while ctypes.c_longlong(overllong).value > 0:
+ overllong *= 2
+minllong = -overllong
+maxllong = overllong - 1
+maxullong = 2 * maxllong + 1
+
+# Make sure Python 2's sys.maxint is the same as the maxlong we calculated
+if sys.version_info[0] <= 2 and maxlong != sys.maxint:
+ raise RuntimeError, "sys.maxint is not the maximum value of a signed long"
+
+def checkType(t, e, val, delta):
+ """t = Test object, e = type name (e.g. ulong), val = max or min allowed value, delta = +1 for max, -1 for min"""
+ error = 0
+ # Set the extreme valid value for var_*
+ setattr(t, 'var_' + e, val)
+ # Make sure it was set properly and works properly in the val_* and ref_* methods
+ if getattr(t, 'var_' + e) != val or getattr(t, 'val_' + e)(val) != val or getattr(t, 'ref_' + e)(val) != val:
+ error = 1
+ # Make sure setting a more extreme value fails without changing the value
+ try:
+ a = getattr(t, 'var_' + e)
+ setattr(t, 'var_' + e, val + delta)
+ error = 1
+ except OverflowError:
+ if a != getattr(t, 'var_' + e):
+ error = 1
+ # Make sure the val_* and ref_* methods fail with a more extreme value
+ try:
+ getattr(t, 'val_' + e)(val + delta)
+ error = 1
+ except OverflowError:
+ pass
+ try:
+ getattr(t, 'ref_' + e)(val + delta)
+ error = 1
+ except OverflowError:
+ pass
+ if error:
+ raise RuntimeError, "bad " + e + " typemap"
+
+def checkFull(t, e, maxval, minval):
+ """Check the maximum and minimum bounds for the type given by e"""
+ checkType(t, e, maxval, 1)
+ checkType(t, e, minval, -1)
+
+checkFull(t, 'llong', maxllong, minllong)
+checkFull(t, 'long', maxlong, minlong)
+checkFull(t, 'int', maxint, minint)
+checkFull(t, 'short', maxshort, minshort)
+checkFull(t, 'schar', maxchar, minchar)
+checkFull(t, 'ullong', maxullong, 0)
+checkFull(t, 'ulong', maxulong, 0)
+checkFull(t, 'uint', maxuint, 0)
+checkFull(t, 'ushort', maxushort, 0)
+checkFull(t, 'uchar', maxuchar, 0)
+
+def checkOverload(t, name, val, delta, prevval, limit):
+ """
+ Check that overloading works
+ t = Test object
+ name = type name (e.g. ulong)
+ val = max or min allowed value
+ delta = +1 for max, -1 for min
+ prevval = corresponding value for one smaller type
+ limit = most extreme value for any type
+ """
+ # If val == prevval, then the smaller typemap will win
+ if val != prevval:
+ # Make sure the most extreme value of this type gives the name of this type
+ if t.ovr_str(val) != name:
+ raise RuntimeError, "bad " + name + " typemap"
+ # Make sure a more extreme value doesn't give the name of this type
+ try:
+ if t.ovr_str(val + delta) == name:
+ raise RuntimeError, "bad " + name + " typemap"
+ if val == limit:
+ # Should raise NotImplementedError here since this is the largest integral type
+ raise RuntimeError, "bad " + name + " typemap"
+ except NotImplementedError:
+ # NotImplementedError is expected only if this is the most extreme type
+ if val != limit:
+ raise RuntimeError, "bad " + name + " typemap"
+ except TypeError:
+ # TypeError is raised instead if swig is run with -O or -fastdispatch
+ if val != limit:
+ raise RuntimeError, "bad " + name + " typemap"
+
+# Check that overloading works: uchar > schar > ushort > short > uint > int > ulong > long > ullong > llong
+checkOverload(t, 'uchar', maxuchar, +1, 0, maxullong)
+checkOverload(t, 'ushort', maxushort, +1, maxuchar, maxullong)
+checkOverload(t, 'uint', maxuint, +1, maxushort, maxullong)
+checkOverload(t, 'ulong', maxulong, +1, maxuint, maxullong)
+checkOverload(t, 'ullong', maxullong, +1, maxulong, maxullong)
+checkOverload(t, 'schar', minchar, -1, 0, minllong)
+checkOverload(t, 'short', minshort, -1, minchar, minllong)
+checkOverload(t, 'int', minint, -1, minshort, minllong)
+checkOverload(t, 'long', minlong, -1, minint, minllong)
+checkOverload(t, 'llong', minllong, -1, minlong, minllong)
+
+# Make sure that large ints can be converted to doubles properly
+if val_double(sys.maxint + 1) != float(sys.maxint + 1):
+ raise RuntimeError, "bad double typemap"
+if val_double(-sys.maxint - 2) != float(-sys.maxint - 2):
+ raise RuntimeError, "bad double typemap"