-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve StringBasedDateTime and StringBasedTimeDelta (#6)
- Loading branch information
1 parent
e58c91e
commit c0efa3e
Showing
3 changed files
with
204 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from datetime import datetime, timedelta | ||
|
||
import arrow | ||
import pytest | ||
|
||
from implicitdict import StringBasedDateTime | ||
|
||
|
||
ZERO_SKEW = timedelta(microseconds=0) | ||
|
||
|
||
def test_consistency(): | ||
t = datetime.utcnow() | ||
sbdt = StringBasedDateTime(t) | ||
with pytest.raises(TypeError): # can't subtract offset-naive and offset-aware datetimes | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
with pytest.raises(TypeError): # can't compare offset-naive and offset-aware datetimes | ||
assert not (sbdt.datetime > t) | ||
assert abs(sbdt.datetime - arrow.get(t).datetime) <= ZERO_SKEW | ||
|
||
sbdt = StringBasedDateTime(t.isoformat()) | ||
assert abs(sbdt.datetime - arrow.get(t).datetime) <= ZERO_SKEW | ||
|
||
t = arrow.utcnow().datetime | ||
sbdt = StringBasedDateTime(t) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
sbdt = StringBasedDateTime(t.isoformat()) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
t = arrow.now('US/Pacific').datetime | ||
sbdt = StringBasedDateTime(t) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
sbdt = StringBasedDateTime(t.isoformat()) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
t = arrow.now('US/Pacific') | ||
sbdt = StringBasedDateTime(t) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
sbdt = StringBasedDateTime(t.isoformat()) | ||
assert abs(sbdt.datetime - t) <= ZERO_SKEW | ||
|
||
t = arrow.get("1234-01-23T12:34:56.12345678") | ||
sbdt = StringBasedDateTime(t) | ||
assert "12345678" not in sbdt # arrow only stores (after rounding) integer microseconds | ||
|
||
with pytest.raises(ValueError): # unconverted data remains (datetime only parses down to microseconds) | ||
datetime.strptime("1234-01-23T12:34:56.12345678", "%Y-%m-%dT%H:%M:%S.%f") | ||
|
||
|
||
def test_non_mutation(): | ||
"""When a string is provided, expect the string representation to remain the same unless reformatting.""" | ||
|
||
s = "2022-02-01T01:01:00.123456789123456789123456789" | ||
assert StringBasedDateTime(s) == s | ||
sbdt = StringBasedDateTime(s, reformat=True) | ||
assert sbdt != s | ||
assert sbdt.endswith('Z') | ||
|
||
s = "1800-12-01T18:15:00" | ||
assert StringBasedDateTime(s) == s | ||
sbdt = StringBasedDateTime(s, reformat=True) | ||
assert sbdt != s | ||
assert sbdt.endswith('Z') | ||
|
||
s = "2022-06-23T00:00:00+00:00" | ||
assert StringBasedDateTime(s) == s | ||
sbdt = StringBasedDateTime(s, reformat=True) | ||
assert sbdt != s | ||
assert sbdt.endswith('Z') | ||
|
||
|
||
def test_zulu_default(): | ||
"""When a non-string datetime is provided, expect the string representation to use Z as the UTC timezone.""" | ||
|
||
assert StringBasedDateTime(datetime.utcnow()).endswith('Z') | ||
assert StringBasedDateTime(arrow.utcnow().datetime).endswith('Z') | ||
assert StringBasedDateTime(arrow.utcnow()).endswith('Z') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from datetime import timedelta | ||
|
||
import pytest | ||
|
||
from implicitdict import StringBasedTimeDelta | ||
|
||
|
||
def test_behavior_strings(): | ||
s = '1s' | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd == s | ||
assert sbtd.timedelta.total_seconds() == 1 | ||
|
||
sbtd = StringBasedTimeDelta(s, reformat=True) | ||
assert sbtd != s | ||
assert sbtd.timedelta.total_seconds() == 1 | ||
|
||
s = '1.1s' | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd == s | ||
assert sbtd.timedelta.total_seconds() == 1.1 | ||
|
||
sbtd = StringBasedTimeDelta(s, reformat=True) | ||
assert sbtd != s | ||
assert sbtd.timedelta.total_seconds() == 1.1 | ||
|
||
s = '1m' | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd == s | ||
assert sbtd.timedelta.total_seconds() == 60 | ||
|
||
sbtd = StringBasedTimeDelta(s, reformat=True) | ||
assert sbtd != s | ||
assert sbtd.timedelta.total_seconds() == 60 | ||
|
||
s = '5 hours, 34 minutes, 56 seconds' | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd == s | ||
assert sbtd.timedelta.total_seconds() == 5 * 60 * 60 + 34 * 60 + 56 | ||
|
||
sbtd = StringBasedTimeDelta(s, reformat=True) | ||
assert sbtd != s | ||
assert sbtd.timedelta.total_seconds() == 5 * 60 * 60 + 34 * 60 + 56 | ||
|
||
s = '0.1234567s' | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd == s | ||
assert '1234567' not in str(sbtd.timedelta.total_seconds()) # timedelta only stores integer microseconds | ||
|
||
sbtd = StringBasedTimeDelta(s, reformat=True) | ||
assert sbtd != s | ||
|
||
|
||
def test_behavior_seconds(): | ||
for s in (1, 1.1, 0.5, 0.123456): | ||
sbtd = StringBasedTimeDelta(s) | ||
assert sbtd.endswith('s') | ||
assert sbtd.timedelta.total_seconds() == s | ||
|
||
sbtd = StringBasedTimeDelta(0.1234567) | ||
assert '1234567' not in str(sbtd.timedelta.total_seconds()) # timedelta only stores integer microseconds | ||
|
||
|
||
def test_behavior_timedelta(): | ||
deltas = ( | ||
timedelta(seconds=1), | ||
timedelta(seconds=1.1), | ||
timedelta(seconds=0.9), | ||
timedelta(minutes=5), | ||
timedelta(hours=5, minutes=34, seconds=56), | ||
timedelta(hours=5, minutes=34, seconds=56, milliseconds=1234), | ||
) | ||
for dt in deltas: | ||
sbtd = StringBasedTimeDelta(dt) | ||
assert sbtd.timedelta == dt | ||
s = str(sbtd) | ||
with pytest.raises(AttributeError): # 'str' object has no attribute 'timedelta' | ||
assert s.timedelta == dt | ||
sbtd2 = StringBasedTimeDelta(s) | ||
assert sbtd2.timedelta == dt |