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)
Esempio n. 3
0
    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)