diff options
Diffstat (limited to 'Lib/test/test_datetime.py')
| -rw-r--r-- | Lib/test/test_datetime.py | 200 |
1 files changed, 134 insertions, 66 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 40eb3ab..735582f 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -3,7 +3,6 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ -import os import sys import pickle import cPickle @@ -128,7 +127,7 @@ class TestTZInfo(unittest.TestCase): # Base clase for testing a particular aspect of timedelta, time, date and # datetime comparisons. -class HarmlessMixedComparison(unittest.TestCase): +class HarmlessMixedComparison: # Test that __eq__ and __ne__ don't complain for mixed-type comparisons. # Subclasses must define 'theclass', and theclass(1, 1, 1) must be a @@ -167,7 +166,7 @@ class HarmlessMixedComparison(unittest.TestCase): ############################################################################# # timedelta tests -class TestTimeDelta(HarmlessMixedComparison): +class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): theclass = timedelta @@ -254,7 +253,7 @@ class TestTimeDelta(HarmlessMixedComparison): self.assertRaises(TypeError, lambda: a // x) self.assertRaises(TypeError, lambda: x // a) - # Divison of int by timedelta doesn't make sense. + # Division of int by timedelta doesn't make sense. # Division by zero doesn't make sense. for zero in 0, 0L: self.assertRaises(TypeError, lambda: zero // a) @@ -514,7 +513,7 @@ class TestDateOnly(unittest.TestCase): class SubclassDate(date): sub_var = 1 -class TestDate(HarmlessMixedComparison): +class TestDate(HarmlessMixedComparison, unittest.TestCase): # Tests here should pass for both dates and datetimes, except for a # few tests that TestDateTime overrides. @@ -710,15 +709,16 @@ class TestDate(HarmlessMixedComparison): def test_overflow(self): tiny = self.theclass.resolution - dt = self.theclass.min + tiny - dt -= tiny # no problem - self.assertRaises(OverflowError, dt.__sub__, tiny) - self.assertRaises(OverflowError, dt.__add__, -tiny) + for delta in [tiny, timedelta(1), timedelta(2)]: + dt = self.theclass.min + delta + dt -= delta # no problem + self.assertRaises(OverflowError, dt.__sub__, delta) + self.assertRaises(OverflowError, dt.__add__, -delta) - dt = self.theclass.max - tiny - dt += tiny # no problem - self.assertRaises(OverflowError, dt.__add__, tiny) - self.assertRaises(OverflowError, dt.__sub__, -tiny) + dt = self.theclass.max - delta + dt += delta # no problem + self.assertRaises(OverflowError, dt.__add__, delta) + self.assertRaises(OverflowError, dt.__sub__, -delta) def test_fromtimestamp(self): import time @@ -851,9 +851,56 @@ class TestDate(HarmlessMixedComparison): self.assertRaises(TypeError, t.strftime, "one", "two") # too many args self.assertRaises(TypeError, t.strftime, 42) # arg wrong type + # test that unicode input is allowed (issue 2782) + self.assertEqual(t.strftime(u"%m"), "03") + # A naive object replaces %z and %Z w/ empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + #make sure that invalid format specifiers are handled correctly + #self.assertRaises(ValueError, t.strftime, "%e") + #self.assertRaises(ValueError, t.strftime, "%") + #self.assertRaises(ValueError, t.strftime, "%#") + + #oh well, some systems just ignore those invalid ones. + #at least, excercise them to make sure that no crashes + #are generated + for f in ["%e", "%", "%#"]: + try: + t.strftime(f) + except ValueError: + pass + + #check that this standard extension works + t.strftime("%f") + + + def test_format(self): + dt = self.theclass(2007, 9, 10) + self.assertEqual(dt.__format__(''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10) + self.assertEqual(b.__format__(''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_resolution_info(self): self.assert_(isinstance(self.theclass.min, self.theclass)) self.assert_(isinstance(self.theclass.max, self.theclass)) @@ -957,6 +1004,7 @@ class TestDate(HarmlessMixedComparison): # compare-by-address (which never says "equal" for distinct # objects). return 0 + __hash__ = None # Silence Py3k warning # This still errors, because date and datetime comparison raise # TypeError instead of NotImplemented when they don't know what to @@ -989,7 +1037,7 @@ class TestDate(HarmlessMixedComparison): self.failUnless(self.theclass.min) self.failUnless(self.theclass.max) - def test_srftime_out_of_range(self): + def test_strftime_out_of_range(self): # For nasty technical reasons, we can't handle years before 1900. cls = self.theclass self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900") @@ -1126,6 +1174,7 @@ class TestDateTime(TestDate): self.assertEqual(t.isoformat(), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat('T'), "0002-03-02T04:05:01.000123") self.assertEqual(t.isoformat(' '), "0002-03-02 04:05:01.000123") + self.assertEqual(t.isoformat('\x00'), "0002-03-02\x0004:05:01.000123") # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 04:05:01.000123") @@ -1136,6 +1185,32 @@ class TestDateTime(TestDate): # str is ISO format with the separator forced to a blank. self.assertEqual(str(t), "0002-03-02 00:00:00") + def test_format(self): + dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(dt.__format__(''), str(dt)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(2007, 9, 10, 4, 5, 1, 123) + self.assertEqual(b.__format__(''), str(dt)) + + for fmt in ["m:%m d:%d y:%y", + "m:%m d:%d y:%y H:%H M:%M S:%S", + "%z %Z", + ]: + self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_more_ctime(self): # Test fields that TestDate doesn't touch. import time @@ -1428,7 +1503,7 @@ class TestDateTime(TestDate): def test_negative_float_fromtimestamp(self): # Windows doesn't accept negative timestamps - if os.name == "nt": + if sys.platform == "win32": return # The result is tz-dependent; at least test that this doesn't # fail (like it did before bug 1646728 was fixed). @@ -1436,7 +1511,7 @@ class TestDateTime(TestDate): def test_negative_float_utcfromtimestamp(self): # Windows doesn't accept negative timestamps - if os.name == "nt": + if sys.platform == "win32": return d = self.theclass.utcfromtimestamp(-1.05) self.assertEquals(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) @@ -1456,11 +1531,12 @@ class TestDateTime(TestDate): self.failUnless(abs(from_timestamp - from_now) <= tolerance) def test_strptime(self): - import time + import _strptime - string = '2004-12-01 13:02:47' - format = '%Y-%m-%d %H:%M:%S' - expected = self.theclass(*(time.strptime(string, format)[0:6])) + string = '2004-12-01 13:02:47.197' + format = '%Y-%m-%d %H:%M:%S.%f' + result, frac = _strptime._strptime(string, format) + expected = self.theclass(*(result[0:6]+(frac,))) got = self.theclass.strptime(string, format) self.assertEqual(expected, got) @@ -1488,9 +1564,9 @@ class TestDateTime(TestDate): def test_more_strftime(self): # This tests fields beyond those tested by the TestDate.test_strftime. - t = self.theclass(2004, 12, 31, 6, 22, 33) - self.assertEqual(t.strftime("%m %d %y %S %M %H %j"), - "12 31 04 33 22 06 366") + t = self.theclass(2004, 12, 31, 6, 22, 33, 47) + self.assertEqual(t.strftime("%m %d %y %f %S %M %H %j"), + "12 31 04 000047 33 22 06 366") def test_extract(self): dt = self.theclass(2002, 3, 4, 18, 45, 3, 1234) @@ -1596,7 +1672,7 @@ class TestDateTime(TestDate): class SubclassTime(time): sub_var = 1 -class TestTime(HarmlessMixedComparison): +class TestTime(HarmlessMixedComparison, unittest.TestCase): theclass = time @@ -1756,12 +1832,41 @@ class TestTime(HarmlessMixedComparison): self.assertEqual(t.isoformat(), "00:00:00.100000") self.assertEqual(t.isoformat(), str(t)) + def test_1653736(self): + # verify it doesn't accept extra keyword arguments + t = self.theclass(second=1) + self.assertRaises(TypeError, t.isoformat, foo=3) + def test_strftime(self): t = self.theclass(1, 2, 3, 4) - self.assertEqual(t.strftime('%H %M %S'), "01 02 03") + self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") # A naive object replaces %z and %Z with empty strings. self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + def test_format(self): + t = self.theclass(1, 2, 3, 4) + self.assertEqual(t.__format__(''), str(t)) + + # check that a derived class's __str__() gets called + class A(self.theclass): + def __str__(self): + return 'A' + a = A(1, 2, 3, 4) + self.assertEqual(a.__format__(''), 'A') + + # check that a derived class's strftime gets called + class B(self.theclass): + def strftime(self, format_spec): + return 'B' + b = B(1, 2, 3, 4) + self.assertEqual(b.__format__(''), str(t)) + + for fmt in ['%H %M %S', + ]: + self.assertEqual(t.__format__(fmt), t.strftime(fmt)) + self.assertEqual(a.__format__(fmt), t.strftime(fmt)) + self.assertEqual(b.__format__(fmt), 'B') + def test_str(self): self.assertEqual(str(self.theclass(1, 2, 3, 4)), "01:02:03.000004") self.assertEqual(str(self.theclass(10, 2, 3, 4000)), "10:02:03.004000") @@ -1874,7 +1979,7 @@ class TestTime(HarmlessMixedComparison): # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) # must be legit (which is true for time and datetime). -class TZInfoBase(unittest.TestCase): +class TZInfoBase: def test_argument_passing(self): cls = self.theclass @@ -2034,7 +2139,7 @@ class TZInfoBase(unittest.TestCase): # Testing time objects with a non-None tzinfo. -class TestTimeTZ(TestTime, TZInfoBase): +class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): theclass = time def test_empty(self): @@ -2282,7 +2387,7 @@ class TestTimeTZ(TestTime, TZInfoBase): # Testing datetime objects with a non-None tzinfo. -class TestDateTimeTZ(TestDateTime, TZInfoBase): +class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): theclass = datetime def test_trivial(self): @@ -3243,45 +3348,8 @@ class Oddballs(unittest.TestCase): self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) -def test_suite(): - allsuites = [unittest.makeSuite(klass, 'test') - for klass in (TestModule, - TestTZInfo, - TestTimeDelta, - TestDateOnly, - TestDate, - TestDateTime, - TestTime, - TestTimeTZ, - TestDateTimeTZ, - TestTimezoneConversions, - Oddballs, - ) - ] - return unittest.TestSuite(allsuites) - def test_main(): - import gc - import sys - - thesuite = test_suite() - lastrc = None - while True: - test_support.run_suite(thesuite) - if 1: # change to 0, under a debug build, for some leak detection - break - gc.collect() - if gc.garbage: - raise SystemError("gc.garbage not empty after test run: %r" % - gc.garbage) - if hasattr(sys, 'gettotalrefcount'): - thisrc = sys.gettotalrefcount() - print >> sys.stderr, '*' * 10, 'total refs:', thisrc, - if lastrc: - print >> sys.stderr, 'delta:', thisrc - lastrc - else: - print >> sys.stderr - lastrc = thisrc + test_support.run_unittest(__name__) if __name__ == "__main__": test_main() |
