def test_003_rejects_invalid_datetime_stings(self) -> None: """Raises ValueError for invalid strings.""" test_cases = ( # Odd strings "", # Empty strings are not valid dateetime strings "Python Discord", # A non-empty string isn't necessarily better # Invalid date values in a valid format "1989-13-01", # We don't have a 13th month "1990-01-32", # January doesn't have 32 days # Valid date values in an invalid format "2345-2-10", # MONTH should have two characters "1788-12-1", # DAY should have two characters "2012/10/02", # `/` is not a valid separator for dates "1999:10:02", # `:` is not a valid separator for dates "2012 10 02", # ` ` is not a valid separator "17-12-2019", # DD-MM-YYYY is not an accepted format "2019-1012", # Combining the normal and truncated format is not allowed "201910-12", # Combining the normal and truncated format is not allowed # The ISO 8601 standard only allows a `T` as the separator "2019-10-01 12:23:34", # According the standard, spaces are not valid separators "1965-02-01t19:09:13", # A lowercase `t` is also not a valid separator "2019-03-25\t08:12:59", # A tab characters is not a valid separator "2019-03-25abc08:12:59", # `abc` is also not a valid separator "2019-03-25P08:12:59", # An `P` isn't either # Incorrect values in the <time> part of the datetime string "2019-10-01T25", # Invalid value (25) for hour "2019-10-01T31:10", # Invalid value (31) for hour "2019-10-01T74:44:28", # Invalid value (74) for hour "2019-10-01T12:61", # Invalid value (61) for minutes "2019-10-01T07:88:12", # Invalid value (88) for hour "2019-10-01T00:01:65", # Invalid value (65) for seconds "2019-13-66T25:62:88", # Invalid values for everything but the year # Incorrect form in the <time> part of the datetime string "1677-09-03T12.31.05", # `.` is not a valid separator for the <time> part "1677-09-03T12-31-05", # `-` is not a valid separator for the <time> part "1677-09-03T12:3105", # Combining the partial and truncated format is not allow "1677-09-03T1231:05", # Combining the partial and truncated format is not allow # Additional test cases that were not published with the qualifier " ", "All the ducks are swimming in the water", "1999-21-09", # Invalid value for the month "2000-12-64", # Invalid value for the day "1887&12&01", # Invalid date separator "1994-04-05K15:15:15", # Invalid part separator "2020-01-01T100:100:100", # Invalid time ) for invalid_datestring in test_cases: with self.subTest(input=invalid_datestring): with self.assertRaises(ValueError): parse_iso8601(invalid_datestring)
def _run_test_cases(self, test_cases: typing.Tuple[TestCase]) -> None: for test_case in test_cases: with self.subTest(**test_case._asdict()): actual_output = parse_iso8601(test_case.input) self.assertIsInstance(actual_output, datetime.datetime) self.assertEqual(test_case.expected_output, actual_output)
def _run_test_cases(self, test_cases: typing.Tuple[TestCase]) -> None: for test_case in test_cases: with self.subTest(**test_case._asdict()): actual_output = parse_iso8601(test_case.input) self.assertIsInstance(actual_output, datetime.datetime) self.assertEqual(test_case.expected_output, actual_output) # The strings for the basic requirements do not contain timezone information self.assertIsNone(actual_output.tzinfo)
def run_benchmark(self) -> None: """Run a benchmark on the `parse_iso8601` function.""" with open("testsuite/benchmark_strings.txt", "r", encoding="utf-8") as datestrings: datestrings = [ datestring.rstrip("\n") for datestring in datestrings ] duration = 0.0 for run in range(1, 101): start = timeit.default_timer() for datestring in datestrings: parse_iso8601(datestring) duration += timeit.default_timer() - start if duration > 5: break cases_tested = run * len(datestrings) self.stream.write(f"Number of strings: {cases_tested}\n") self.stream.write(f"Total time: {duration:.10f}s\n") self.stream.write( f"Average time: {duration/cases_tested:.10f}s\n")
def test_005_accepts_timezones(self) -> None: """Supports timezones.""" test_cases = ( # Truncated TestCase(input="1902-08-02T12:30:24Z", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone.utc)), TestCase(input="2022-12-12T11:10:09Z", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone.utc)), TestCase(input="1902-08-02T12:30:24+01", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=1)))), TestCase(input="2022-12-12T11:10:09+12", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=12)))), TestCase(input="1902-08-02T12:30:24-03", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=-3)))), TestCase(input="2022-12-12T11:10:09-11", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=-11)))), TestCase(input="1902-08-02T12:30:24+01:15", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=1, minutes=15)))), TestCase(input="2022-12-12T11:10:09+12:59", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=12, minutes=59)))), TestCase(input="1902-08-02T12:30:24-03:01", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=-3, minutes=-1)))), TestCase(input="2022-12-12T11:10:09-11:31", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=-11, minutes=-31)))), TestCase(input="19020802T123024+0226", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=2, minutes=26)))), TestCase(input="20221212T111009+1101", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=11, minutes=1)))), TestCase(input="19020802T123024-0509", expected_output=datetime.datetime( year=1902, month=8, day=2, hour=12, minute=30, second=24, tzinfo=datetime.timezone( datetime.timedelta(hours=-5, minutes=-9)))), TestCase(input="20221212T111009-1059", expected_output=datetime.datetime( year=2022, month=12, day=12, hour=11, minute=10, second=9, tzinfo=datetime.timezone( datetime.timedelta(hours=-10, minutes=-59)))), ) for test_case in test_cases: with self.subTest(**test_case._asdict()): actual_output = parse_iso8601(test_case.input) self.assertEqual(test_case.expected_output.utcoffset(), actual_output.utcoffset()) self.assertEqual(test_case.expected_output, actual_output)