1+ import datetime
2+ import random
3+ import string
4+ import sys
15from unittest import TestCase
26
3- from icloudpd .string_helpers import truncate_middle
7+ import pytest
8+
9+ from icloudpd .string_helpers import parse_timestamp_or_timedelta , truncate_middle
410
511
612class TruncateMiddleTestCase (TestCase ):
@@ -17,3 +23,78 @@ def test_truncate_middle(self) -> None:
1723 assert truncate_middle ("test_filename.jpg" , 0 ) == ""
1824 with self .assertRaises (ValueError ):
1925 truncate_middle ("test_filename.jpg" , - 1 )
26+
27+
28+ class ParseTimestampeOrTimeDeltaTestCase (TestCase ):
29+ def test_totality (self ) -> None :
30+ characters = string .ascii_letters + string .digits
31+ for _case in range (500 ):
32+ target_length = random .randint (0 , 100 )
33+ target_string = "" .join (random .choice (characters ) for i in range (target_length ))
34+ _result = parse_timestamp_or_timedelta (target_string )
35+ # not throwing is okay
36+
37+ def test_naive (self ) -> None :
38+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.000600" ) == datetime .datetime (
39+ 2025 , 1 , 2 , 3 , 4 , 5 , 600
40+ )
41+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.006" ) == datetime .datetime (
42+ 2025 , 1 , 2 , 3 , 4 , 5 , 6000
43+ )
44+ assert parse_timestamp_or_timedelta ("2025-01-02" ) == datetime .datetime (
45+ 2025 , 1 , 2 , 0 , 0 , 0 , 0
46+ )
47+
48+ @pytest .mark .skipif (
49+ sys .version_info < (3 , 11 ), reason = "Requires Python 3.11 or higher for full parsing support"
50+ )
51+ def test_naive_311plus (self ) -> None :
52+ # short
53+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.0006" ) == datetime .datetime (
54+ 2025 , 1 , 2 , 3 , 4 , 5 , 600
55+ )
56+
57+ def test_aware (self ) -> None :
58+ assert parse_timestamp_or_timedelta (
59+ "2025-01-02T03:04:05.000600+08:00"
60+ ) == datetime .datetime (
61+ 2025 , 1 , 2 , 3 , 4 , 5 , 600 , datetime .timezone (datetime .timedelta (hours = 8 ))
62+ )
63+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.006+08:00" ) == datetime .datetime (
64+ 2025 , 1 , 2 , 3 , 4 , 5 , 6000 , datetime .timezone (datetime .timedelta (hours = 8 ))
65+ )
66+
67+ @pytest .mark .skipif (
68+ sys .version_info < (3 , 11 ), reason = "Requires Python 3.11 or higher for full parsing support"
69+ )
70+ def test_aware_311plus (self ) -> None :
71+ # short
72+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.0006Z" ) == datetime .datetime (
73+ 2025 , 1 , 2 , 3 , 4 , 5 , 600 , datetime .timezone .utc
74+ )
75+ assert parse_timestamp_or_timedelta ("2025-01-02T03:04:05.0006+08:00" ) == datetime .datetime (
76+ 2025 , 1 , 2 , 3 , 4 , 5 , 600 , datetime .timezone (datetime .timedelta (hours = 8 ))
77+ )
78+
79+ def test_timestamp_invalid (self ) -> None :
80+ assert parse_timestamp_or_timedelta ("2025-01" ) is None
81+ assert parse_timestamp_or_timedelta ("" ) is None
82+
83+ def test_delta_totality (self ) -> None :
84+ digits = string .digits
85+ characters = ["d" , "D" ]
86+ for _case in range (500 ):
87+ target_length = random .randint (1 , 5 )
88+ target_string = "" .join (
89+ random .choice (digits ) for i in range (target_length )
90+ ) + random .choice (characters )
91+ result = parse_timestamp_or_timedelta (target_string )
92+ assert isinstance (result , datetime .timedelta )
93+
94+ def test_delta (self ) -> None :
95+ assert parse_timestamp_or_timedelta ("1d" ) == datetime .timedelta (days = 1 )
96+ assert parse_timestamp_or_timedelta ("0d" ) == datetime .timedelta (days = 0 )
97+
98+ def test_delta_invalid (self ) -> None :
99+ assert parse_timestamp_or_timedelta ("-1d" ) is None
100+ assert parse_timestamp_or_timedelta ("" ) is None
0 commit comments