summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHernan Grecco <hernan.grecco@gmail.com>2014-06-10 23:18:42 -0300
committerHernan Grecco <hernan.grecco@gmail.com>2014-06-11 01:55:22 -0300
commitafbac103c66710fbd2cb123d0bd418850b9548ca (patch)
tree5c631593a1255685a34691f36132580cf633d0d0
parent4d338c1fbc812d46d4fe472bc4e3124a046ea210 (diff)
downloadpint-afbac103c66710fbd2cb123d0bd418850b9548ca.tar.gz
Improved testing
- added docs to ufunc testing helper funcs - changed ufunc testing helper funcs to rely on base testing classes for Quantity comparison - fixed a few tests - Changed test asanyarray bug from skip to expectedFailure
-rw-r--r--pint/testsuite/test_numpy.py39
-rw-r--r--pint/testsuite/test_umath.py123
2 files changed, 113 insertions, 49 deletions
diff --git a/pint/testsuite/test_numpy.py b/pint/testsuite/test_numpy.py
index 3b753d4..a8dc3c5 100644
--- a/pint/testsuite/test_numpy.py
+++ b/pint/testsuite/test_numpy.py
@@ -4,6 +4,7 @@ from __future__ import division, unicode_literals, print_function, absolute_impo
from pint.compat import np, unittest
from pint.testsuite import QuantityTestCase, helpers
+from pint.testsuite.test_umath import TestUFuncs
@helpers.requires_numpy()
@@ -189,9 +190,11 @@ class TestNumpyMethods(QuantityTestCase):
q[0] = 1*self.ureg.m
self.assertQuantityEqual(q, [[1,1],[3,4]]*self.ureg.m)
- q[0] = (1,2)*self.ureg.m
- self.assertQuantityEqual(q, self.q)
+ q = self.q.copy()
+ q.__setitem__(Ellipsis, 1*self.ureg.m)
+ self.assertQuantityEqual(q, [[1,1],[1,1]]*self.ureg.m)
+ q = self.q.copy()
q[:] = 1*self.ureg.m
self.assertQuantityEqual(q, [[1,1],[1,1]]*self.ureg.m)
@@ -239,23 +242,25 @@ class TestNumpyMethods(QuantityTestCase):
self.assertQuantityEqual(u == 1, u.magnitude == 1)
-from pint.testsuite.test_umath import TestUFuncs
-@unittest.skip
-class TestNumpyNotSupported(TestUFuncs):
+@unittest.expectedFailure
+class TestNumpyNeedsSubclassing(TestUFuncs):
FORCE_NDARRAY = True
+ @property
+ def q(self):
+ return [1. ,2., 3., 4.] * self.ureg.J
def test_unwrap(self):
"""unwrap depends on diff
"""
- self.assertEqual(np.unwrap([0,3*np.pi]*self.ureg.radians), [0,np.pi])
- self.assertEqual(np.unwrap([0,540]*self.ureg.deg), [0,180]*self.ureg.deg)
+ self.assertQuantityEqual(np.unwrap([0,3*np.pi]*self.ureg.radians), [0,np.pi])
+ self.assertQuantityEqual(np.unwrap([0,540]*self.ureg.deg), [0,180]*self.ureg.deg)
def test_trapz(self):
"""Units are erased by asanyarray, Quantity does not inherit from NDArray
"""
- self.assertEqual(np.trapz(self.q, dx = 1*self.ureg.m), 7.5 * self.ureg.J*self.ureg.m)
+ self.assertQuantityEqual(np.trapz(self.q, dx=1*self.ureg.m), 7.5 * self.ureg.J*self.ureg.m)
def test_diff(self):
"""Units are erased by asanyarray, Quantity does not inherit from NDArray
@@ -265,13 +270,13 @@ class TestNumpyNotSupported(TestUFuncs):
def test_ediff1d(self):
"""Units are erased by asanyarray, Quantity does not inherit from NDArray
"""
- self.assertEqual(np.ediff1d(self.q, 1), [1, 1, 1] * self.ureg.J)
+ self.assertQuantityEqual(np.ediff1d(self.q, 1 * self.ureg.J), [1, 1, 1] * self.ureg.J)
def test_fix(self):
"""Units are erased by asanyarray, Quantity does not inherit from NDArray
"""
- self.assertEqual(np.fix(3.14 * self.ureg.m), 3.0 * self.ureg.m)
- self.assertEqual(np.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m)
+ self.assertQuantityEqual(np.fix(3.14 * self.ureg.m), 3.0 * self.ureg.m)
+ self.assertQuantityEqual(np.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m)
self.assertQuantityEqual(
np.fix([2.1, 2.9, -2.1, -2.9] * self.ureg.m),
[2., 2., -2., -2.] * self.ureg.m
@@ -281,15 +286,15 @@ class TestNumpyNotSupported(TestUFuncs):
"""shape is a property not a function
"""
l = np.gradient([[1,1],[3,4]] * self.ureg.J, 1 * self.ureg.m)
- self.assertEqual(l[0], [[2., 3.], [2., 3.]] * self.ureg.J / self.ureg.m)
- self.assertEqual(l[1], [[0., 0.], [1., 1.]] * self.ureg.J / self.ureg.m)
+ self.assertQuantityEqual(l[0], [[2., 3.], [2., 3.]] * self.ureg.J / self.ureg.m)
+ self.assertQuantityEqual(l[1], [[0., 0.], [1., 1.]] * self.ureg.J / self.ureg.m)
def test_cross(self):
"""Units are erased by asarray, Quantity does not inherit from NDArray
"""
- a = [3,-3, 1] * self.ureg.kPa
- b = [4, 9, 2] * self.ureg.m**2
- self.assertQuantityEqual(np.cross(a,b), [-15,-2,39]*self.ureg.kPa*self.ureg.m**2)
+ a = [[3,-3, 1]] * self.ureg.kPa
+ b = [[4, 9, 2]] * self.ureg.m**2
+ self.assertQuantityEqual(np.cross(a, b), [-15, -2, 39] * self.ureg.kPa * self.ureg.m**2)
def test_power(self):
"""This is not supported as different elements might end up with different units
@@ -311,7 +316,7 @@ class TestNumpyNotSupported(TestUFuncs):
2)
-@unittest.skip
+@unittest.expectedFailure
class TestBitTwiddlingUfuncs(TestUFuncs):
"""Universal functions (ufuncs) > Bittwiddling functions
diff --git a/pint/testsuite/test_umath.py b/pint/testsuite/test_umath.py
index 9586af5..cfbba86 100644
--- a/pint/testsuite/test_umath.py
+++ b/pint/testsuite/test_umath.py
@@ -52,17 +52,29 @@ class TestUFuncs(QuantityTestCase):
except Exception as e:
self.assertFalse(True, msg='{0} not raised but {1}\n{2}'.format(ExcType, e, msg))
- def _testn(self, func, ok_with, raise_with=(), results=None):
- self._test1(func, ok_with, raise_with, output_units=None, results=results)
-
def _test1(self, func, ok_with, raise_with=(), output_units='same', results=None, rtol=1e-6):
+ """Test function that takes a single argument and returns Quantity.
+
+ :param func: function callable.
+ :param ok_with: iterables of values that work fine.
+ :param raise_with: iterables of values that raise exceptions.
+ :param output_units: units to be used when building results.
+ 'same': ok_with[n].units (default).
+ is float: ok_with[n].units ** output_units.
+ None: no output units, the result should be an ndarray.
+ Other value will be parsed as unit.
+ :param results: iterable of results.
+ If None, the result will be obtained by applying
+ func to each ok_with value
+ :param rtol: relative tolerance.
+ """
if results is None:
results = [None, ] * len(ok_with)
for x1, res in zip(ok_with, results):
err_msg = 'At {0} with {1}'.format(func.__name__, x1)
if output_units == 'same':
ou = x1.units
- elif isinstance(output_units, int):
+ elif isinstance(output_units, (int, float)):
ou = x1.units ** output_units
else:
ou = output_units
@@ -70,20 +82,45 @@ class TestUFuncs(QuantityTestCase):
qm = func(x1)
if res is None:
res = func(x1.magnitude)
- if ou:
+ if ou is not None:
res = self.Q_(res, ou)
- if isinstance(res, self.Q_):
- self.assertIsInstance(qm, self.Q_, msg=err_msg + ' {0!r} is not Quantity'.format(qm))
- qm = qm.magnitude
- res = res.magnitude
- np.testing.assert_allclose(qm, res, rtol=rtol, err_msg=err_msg)
+
+ self.assertQuantityAlmostEqual(qm, res, rtol=rtol, msg=err_msg)
for x1 in raise_with:
self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1),
ValueError, func, x1)
+ def _testn(self, func, ok_with, raise_with=(), results=None):
+ """Test function that takes a single argument and returns and ndarray (not a Quantity)
+
+ :param func: function callable.
+ :param ok_with: iterables of values that work fine.
+ :param raise_with: iterables of values that raise exceptions.
+ :param results: iterable of results.
+ If None, the result will be obtained by applying
+ func to each ok_with value
+ """
+ self._test1(func, ok_with, raise_with, output_units=None, results=results)
+
def _test1_2o(self, func, ok_with, raise_with=(), output_units=('same', 'same'),
results=None, rtol=1e-6):
+ """Test functions that takes a single argument and return two Quantities.
+
+ :param func: function callable.
+ :param ok_with: iterables of values that work fine.
+ :param raise_with: iterables of values that raise exceptions.
+ :param output_units: tuple of units to be used when building the result tuple.
+ 'same': ok_with[n].units (default).
+ is float: ok_with[n].units ** output_units.
+ None: no output units, the result should be an ndarray.
+ Other value will be parsed as unit.
+ :param results: iterable of results.
+ If None, the result will be obtained by applying
+ func to each ok_with value
+ :param rtol: relative tolerance.
+ """
+
if results is None:
results = [None, ] * len(ok_with)
for x1, res in zip(ok_with, results):
@@ -95,26 +132,35 @@ class TestUFuncs(QuantityTestCase):
for ndx, (qm, re, ou) in enumerate(zip(qms, res, output_units)):
if ou == 'same':
ou = x1.units
- elif isinstance(ou, int):
+ elif isinstance(ou, (int, float)):
ou = x1.units ** ou
if ou is not None:
re = self.Q_(re, ou)
- if isinstance(re, self.Q_):
- self.assertIsInstance(qm, self.Q_, msg=err_msg)
- qm = qm.magnitude
- re = re.magnitude
- np.testing.assert_allclose(qm, re, rtol=rtol, err_msg=err_msg)
+ self.assertQuantityAlmostEqual(qm, re, rtol=rtol, msg=err_msg)
for x1 in raise_with:
self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1),
ValueError, func, x1)
- def _testn2(self, func, x1, ok_with, raise_with=()):
- self._test2(func, x1, ok_with, raise_with, output_units=None)
-
def _test2(self, func, x1, ok_with, raise_with=(), output_units='same', rtol=1e-6, convert2=True):
+ """Test function that takes two arguments and return a Quantity.
+
+ :param func: function callable.
+ :param x1: first argument of func.
+ :param ok_with: iterables of values that work fine.
+ :param raise_with: iterables of values that raise exceptions.
+ :param output_units: units to be used when building results.
+ 'same': x1.units (default).
+ 'prod': x1.units * ok_with[n].units
+ 'div': x1.units / ok_with[n].units
+ 'second': x1.units * ok_with[n]
+ None: no output units, the result should be an ndarray.
+ Other value will be parsed as unit.
+ :param rtol: relative tolerance.
+ :param convert2: if the ok_with[n] should be converted to x1.units.
+ """
for x2 in ok_with:
err_msg = 'At {0} with {1} and {2}'.format(func.__name__, x1, x2)
if output_units == 'same':
@@ -136,18 +182,25 @@ class TestUFuncs(QuantityTestCase):
m2 = getattr(x2, 'magnitude', x2)
res = func(x1.magnitude, m2)
- if ou:
+ if ou is not None:
res = self.Q_(res, ou)
- if isinstance(res, self.Q_):
- self.assertIsInstance(qm, self.Q_, msg=err_msg)
- qm = qm.magnitude
- res = res.magnitude
- np.testing.assert_allclose(qm, res, rtol=rtol, err_msg=err_msg)
+
+ self.assertQuantityAlmostEqual(qm, res, rtol=rtol, msg=err_msg)
for x2 in raise_with:
self.assertRaisesMsg('At {0} with {1} and {2}'.format(func.__name__, x1, x2),
ValueError, func, x1, x2)
+ def _testn2(self, func, x1, ok_with, raise_with=()):
+ """Test function that takes two arguments and return a ndarray.
+
+ :param func: function callable.
+ :param x1: first argument of func.
+ :param ok_with: iterables of values that work fine.
+ :param raise_with: iterables of values that raise exceptions.
+ """
+ self._test2(func, x1, ok_with, raise_with, output_units=None)
+
@helpers.requires_numpy()
class TestMathUfuncs(TestUFuncs):
@@ -248,7 +301,7 @@ class TestMathUfuncs(TestUFuncs):
self.q1,
(self.q2, self.qs, self.qless),
(),
- 'div', convert2=False)
+ 'same', convert2=False)
def test_mod(self):
self._test2(np.mod,
@@ -322,7 +375,7 @@ class TestMathUfuncs(TestUFuncs):
self._test1(np.sqrt,
(self.q2, self.qs, self.qless, self.qi),
(),
- 'same')
+ 0.5)
def test_square(self):
self._test1(np.square,
@@ -334,7 +387,7 @@ class TestMathUfuncs(TestUFuncs):
self._test1(np.reciprocal,
(self.q2, self.qs, self.qless, self.qi),
(),
- 2)
+ -1)
@helpers.requires_numpy()
@@ -469,10 +522,16 @@ class TestTrigUfuncs(TestUFuncs):
), (self.ureg.m, ), 'radians')
def test_rad2deg(self):
- self._test1(np.rad2deg, (np.arange(0, pi/2, pi/4) * self.ureg.dimensionless,
- np.arange(0, pi/2, pi/4) * self.ureg.radian,
- np.arange(0, pi/2, pi/4) * self.ureg.mm / self.ureg.m
- ), (self.ureg.m, ), 'degree', results=(None, None, np.rad2deg(np.arange(0, pi/2, pi/4)*0.001)))
+ self._test1(np.rad2deg,
+ (np.arange(0, pi/2, pi/4) * self.ureg.dimensionless,
+ np.arange(0, pi/2, pi/4) * self.ureg.radian,
+ np.arange(0, pi/2, pi/4) * self.ureg.mm / self.ureg.m,
+ ),
+ (self.ureg.m, ), 'degree',
+ results=(None,
+ None,
+ np.rad2deg(np.arange(0, pi/2, pi/4)*0.001) * self.ureg.degree,
+ ))