import datetime from unittest import TestCase from ..converters import Iso8601Serializer class Iso8601SerializerTestCase(TestCase): def _gen_dates(self, start_date, end_date, step=1): date = start_date while date <= end_date: text = '%04d-%02d-%02d' % (date.year, date.month, date.day) yield date, text date += datetime.timedelta(step) def _gen_times(self, step_hours=1, step_minutes=1, step_seconds=1): for hour in range(0, 13, step_hours): for minute in range(0, 60, step_minutes): for second in range(0, 60, step_seconds): text = '%02d:%02d:%02d' % (hour, minute, second) time = datetime.time(hour, minute, second) yield (time, text) def _gen_datetimes(self, start_date, end_date, step_days=47, step_hours=1, step_minutes=13, step_seconds=17): for date, date_text in self._gen_dates(start_date, end_date, step_days): for time, time_text in self._gen_times(step_hours, step_minutes, step_seconds): text = '{}T{}'.format(date_text, time_text) obj = datetime.datetime.combine(date, time) yield (obj, text) def test_init_without_arg(self): with self.assertRaises(TypeError) as cm: _ = Iso8601Serializer() self.assertEqual(str(cm.exception), 'Iso8601Serializer.__init__()' ' missing 1 required positional argument: \'value\'') def test_init_with_date(self): date_obj = datetime.date(1976, 2, 1) serializer = Iso8601Serializer(date_obj) self.assertEqual(str(serializer), 'ISO8601:1976-02-01') def test_init_with_datetime(self): datetime_obj = datetime.datetime(1976, 2, 1, 12, 34, 56) serializer = Iso8601Serializer(datetime_obj) self.assertEqual(str(serializer), 'ISO8601:1976-02-01T12:34:56') def test_init_with_time(self): time_obj = datetime.time(12, 34, 56) serializer = Iso8601Serializer(time_obj) self.assertEqual(str(serializer), 'ISO8601:12:34:56') def test_init_with_valid_text(self): text = 'ISO8601:1976-02-01' serializer = Iso8601Serializer(text) self.assertEqual(str(serializer), text) def test_init_with_invalid_format(self): text = 'ISO8601:02.01.1976' with self.assertRaises(ValueError) as cm: _ = Iso8601Serializer(text) self.assertEqual(str(cm.exception), 'Format not recognized \'02.01.1976\'') def test_init_with_invalid_string(self): text = '1976-02-01' with self.assertRaisesRegex(ValueError, 'String must begin with \'ISO8601:\''): _ = Iso8601Serializer(text) def test_serialize_valid(self): test_data = [] # Check date objects # Populate test data with all days between 1970 and 2070 test_data += self._gen_dates(datetime.date(1970, 1, 1), datetime.date(2070, 12, 31)) # Check time objects test_data += self._gen_times() # Check datetime objects test_data += self._gen_datetimes(datetime.date(1999, 1, 1), datetime.date(2035, 12, 31)) for obj, text in test_data: expected = 'ISO8601:{}'.format(text) serialized = Iso8601Serializer.serialize(obj) self.assertEqual(serialized, expected) def test_serialize_invalid(self): invalid_values = ( None, True, False, 'ISO8601:1976-02-01', ) for value in invalid_values: emsg = ('Expected datetime.datetime, datetime.date or datetime.time,' ' not {}'.format(value.__class__.__name__)) with self.assertRaisesRegex(ValueError, emsg): Iso8601Serializer.serialize(value) serialized = Iso8601Serializer.serialize(value, ignore_unsupported_input=True) self.assertEqual(serialized, value) def test_deserialize_valid(self): test_data = [] # Check '--
' format test_data += self._gen_dates(datetime.date(1970, 1, 1), datetime.date(2070, 12, 31)) # Check '::' format test_data += self._gen_times() # Check '--
T::' format test_data += self._gen_datetimes(datetime.date(1999, 1, 1), datetime.date(2035, 12, 31)) for obj, text in test_data: text = 'ISO8601:{}'.format(text) deserialized = Iso8601Serializer.deserialize(text) self.assertIsInstance(deserialized, obj.__class__) self.assertEqual(deserialized, obj) def test_deserialize_with_valid_offset(self): test_data = ( ('1976-02-01T12:34:56+02', '1976-02-01 10:34:56+00:00'), ('1976-02-01T12:34:56+10:04', '1976-02-01 02:30:56+00:00'), ('1976-02-01T12:34:56-02', '1976-02-01 14:34:56+00:00'), ('1976-02-01T12:34:56-12:14', '1976-02-02 00:48:56+00:00'), ) for input_text, dt_str in test_data: text = 'ISO8601:{}'.format(input_text) deserialized = Iso8601Serializer.deserialize(text) self.assertEqual(str(deserialized), dt_str) def test_deserialize_with_invalid_offset(self): invalid_data = ( '1976-02-01T12:34:56+2', '1976-02-01T12:34:56+02:02:02', '1976-02-01T12:34:56+-02', '1976-02-01T12:34:56=02', '1976-02-01T12:34:56+CEST', ) for input_text in invalid_data: text = 'ISO8601:{}'.format(input_text) with self.assertRaisesRegex(ValueError, 'Format not recognized \'.*\''): Iso8601Serializer.deserialize(text) def test_deserialize_invalid(self): invalid_data = ( (None, TypeError, 'Expected string type, not NoneType'), (True, TypeError, 'Expected string type, not bool'), (False, TypeError, 'Expected string type, not bool'), ('1976-02-01', ValueError, 'String must begin with \'ISO8601:\''), ('ISO8601:02.01.1976', ValueError, 'Format not recognized \'02.01.1976\''), ) for value, expected_exception, expected_msg in invalid_data: with self.assertRaisesRegex(expected_exception, expected_msg): Iso8601Serializer.deserialize(value) serialized = Iso8601Serializer.deserialize(value, ignore_unsupported_input=True) self.assertEqual(serialized, value)