Improve coverage of utils.py

Also fix bugs this discovers. Fix #15.
stix2.1
clenk 2017-05-22 11:11:42 -04:00
parent 41f2ceb8e5
commit b4dfa07a20
2 changed files with 28 additions and 6 deletions

View File

@ -15,11 +15,33 @@ eastern = pytz.timezone('US/Eastern')
(amsterdam.localize(dt.datetime(2017, 1, 1)), '2016-12-31T23:00:00Z'), (amsterdam.localize(dt.datetime(2017, 1, 1)), '2016-12-31T23:00:00Z'),
(eastern.localize(dt.datetime(2017, 1, 1, 12, 34, 56)), '2017-01-01T17:34:56Z'), (eastern.localize(dt.datetime(2017, 1, 1, 12, 34, 56)), '2017-01-01T17:34:56Z'),
(eastern.localize(dt.datetime(2017, 7, 1)), '2017-07-01T04:00:00Z'), (eastern.localize(dt.datetime(2017, 7, 1)), '2017-07-01T04:00:00Z'),
(dt.datetime(2017, 7, 1), '2017-07-01T00:00:00Z'),
(dt.datetime(2017, 7, 1, 0, 0, 0, 1), '2017-07-01T00:00:00.000001Z'),
]) ])
def test_timestamp_formatting(dttm, timestamp): def test_timestamp_formatting(dttm, timestamp):
assert stix2.utils.format_datetime(dttm) == timestamp assert stix2.utils.format_datetime(dttm) == timestamp
@pytest.mark.parametrize('timestamp, dttm', [
(dt.datetime(2017, 1, 1, 0, tzinfo=pytz.utc), dt.datetime(2017, 1, 1, 0, 0, 0, tzinfo=pytz.utc)),
(dt.date(2017, 1, 1), dt.datetime(2017, 1, 1, 0, 0, 0, tzinfo=pytz.utc)),
('2017-01-01T00:00:00Z', dt.datetime(2017, 1, 1, 0, 0, 0, tzinfo=pytz.utc)),
('2017-01-01T02:00:00+2:00', dt.datetime(2017, 1, 1, 0, 0, 0, tzinfo=pytz.utc)),
('2017-01-01T00:00:00', dt.datetime(2017, 1, 1, 0, 0, 0, tzinfo=pytz.utc)),
])
def test_parse_datetime(timestamp, dttm):
assert stix2.utils.parse_into_datetime(timestamp) == dttm
@pytest.mark.parametrize('ts', [
'foobar',
1,
])
def test_parse_datetime_invalid(ts):
with pytest.raises(ValueError):
stix2.utils.parse_into_datetime('foobar')
@pytest.mark.parametrize('data', [ @pytest.mark.parametrize('data', [
{"a": 1}, {"a": 1},
'{"a": 1}', '{"a": 1}',

View File

@ -23,11 +23,11 @@ def format_datetime(dttm):
# 4. Add subsecond value if non-zero # 4. Add subsecond value if non-zero
# 5. Add "Z" # 5. Add "Z"
try: if dttm.tzinfo is None or dttm.tzinfo.utcoffset(dttm) is None:
zoned = dttm.astimezone(pytz.utc)
except ValueError:
# dttm is timezone-naive; assume UTC # dttm is timezone-naive; assume UTC
pytz.utc.localize(dttm) zoned = pytz.utc.localize(dttm)
else:
zoned = dttm.astimezone(pytz.utc)
ts = zoned.strftime("%Y-%m-%dT%H:%M:%S") ts = zoned.strftime("%Y-%m-%dT%H:%M:%S")
if zoned.microsecond > 0: if zoned.microsecond > 0:
ms = zoned.strftime("%f") ms = zoned.strftime("%f")
@ -41,12 +41,12 @@ def parse_into_datetime(value):
return value return value
else: else:
# Add a time component # Add a time component
return dt.datetime.combine(value, dt.time(), tzinfo=pytz.utc) return dt.datetime.combine(value, dt.time(0, 0, tzinfo=pytz.utc))
# value isn't a date or datetime object so assume it's a string # value isn't a date or datetime object so assume it's a string
try: try:
parsed = parser.parse(value) parsed = parser.parse(value)
except TypeError: except (TypeError, ValueError):
# Unknown format # Unknown format
raise ValueError("must be a datetime object, date object, or " raise ValueError("must be a datetime object, date object, or "
"timestamp string in a recognizable format.") "timestamp string in a recognizable format.")