From fe1942f849c2bded41089914543284d598839996 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 4 Aug 2015 14:18:05 +0200 Subject: Add multiplication to duration --- src/isodate/duration.py | 21 ++++++++++++++ src/isodate/tests/test_duration.py | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/isodate/duration.py b/src/isodate/duration.py index 437afe8..8740815 100644 --- a/src/isodate/duration.py +++ b/src/isodate/duration.py @@ -209,6 +209,27 @@ class Duration(object): raise TypeError('unsupported operand type(s) for +: %s and %s' % (other.__class__, self.__class__)) + def __mul__(self, other): + if isinstance(other, int): + newduration = Duration( + years=self.years * other, + months=self.months * other, + seconds=self.tdelta.total_seconds() * other) + return newduration + raise TypeError('unsupported operand type(s) for +: %s and %s' % + (self.__class__, other.__class__)) + + def __rmul__(self, other): + + if isinstance(other, int): + newduration = Duration( + years=self.years * other, + months=self.months * other, + seconds=self.tdelta.total_seconds() * other) + return newduration + raise TypeError('unsupported operand type(s) for +: %s and %s' % + (other.__class__, self.__class__)) + def __sub__(self, other): ''' It is possible to subtract Duration and timedelta objects from Duration diff --git a/src/isodate/tests/test_duration.py b/src/isodate/tests/test_duration.py index 910001e..0b80a54 100644 --- a/src/isodate/tests/test_duration.py +++ b/src/isodate/tests/test_duration.py @@ -231,6 +231,31 @@ DATE_CALC_TEST_CASES = ( # date(2001, 2, 14)), ) +# A list of test cases of multiplications of durations +# are compared against a given expected result. +DATE_MUL_TEST_CASES = ( + (Duration(years=1, months=1), + 3, + Duration(years=3, months=3)), + (Duration(years=1, months=1), + -3, + Duration(years=-3, months=-3)), + (3, + Duration(years=1, months=1), + Duration(years=3, months=3)), + (-3, + Duration(years=1, months=1), + Duration(years=-3, months=-3)), + (5, + Duration(years=2, minutes=40), + Duration(years=10, hours=3, minutes=20)), + (-5, + Duration(years=2, minutes=40), + Duration(years=-10, hours=-3, minutes=-20)), + (7, + Duration(years=1, months=2, weeks=40), + Duration(years=8, months=2, weeks=280))) + class DurationTest(unittest.TestCase): ''' @@ -263,6 +288,16 @@ class DurationTest(unittest.TestCase): 'raise exception') self.assertRaises(TypeError, operator.add, 'raise exception', Duration(years=1, months=1, weeks=5)) + self.assertRaises(TypeError, operator.mul, + Duration(years=1, months=1, weeks=5), + 'raise exception') + self.assertRaises(TypeError, operator.mul, 'raise exception', + Duration(years=1, months=1, weeks=5)) + self.assertRaises(TypeError, operator.mul, + Duration(years=1, months=1, weeks=5), + 3.14) + self.assertRaises(TypeError, operator.mul, 3.14, + Duration(years=1, months=1, weeks=5)) def test_parseerror(self): ''' @@ -515,6 +550,28 @@ def create_datecalctestcase(start, duration, expectation): return unittest.TestLoader().loadTestsFromTestCase(TestDateCalc) +def create_datemultestcase(operand1, operand2, expectation): + """ + Create a TestCase class for a specific test. + + This allows having a separate TestCase for each test tuple from the + DATE_CALC_TEST_CASES list, so that a failed test won't stop other tests. + """ + + class TestDateMul(unittest.TestCase): + ''' + A test case template test addition operators for Duration objects. + ''' + + def test_mul(self): + ''' + Test operator *. + ''' + self.assertEqual(operand1 * operand2, expectation) + + return unittest.TestLoader().loadTestsFromTestCase(TestDateMul) + + def test_suite(): ''' Return a test suite containing all test defined above. @@ -530,6 +587,8 @@ def test_suite(): suite.addTest(create_datetestcase(*testdata)) for testdata in DATE_CALC_TEST_CASES: suite.addTest(create_datecalctestcase(*testdata)) + for testdata in DATE_MUL_TEST_CASES: + suite.addTest(create_datemultestcase(*testdata)) suite.addTest(unittest.TestLoader().loadTestsFromTestCase(DurationTest)) return suite -- cgit v1.2.1