diff options
-rw-r--r-- | lesana/types.py | 40 | ||||
-rw-r--r-- | tests/test_types.py | 110 |
2 files changed, 148 insertions, 2 deletions
diff --git a/lesana/types.py b/lesana/types.py index 500f21e..7f182ea 100644 --- a/lesana/types.py +++ b/lesana/types.py @@ -27,6 +27,16 @@ class LesanaType: def empty(self): raise NotImplementedError + def update(self, value): + """ + Return an updated value, as appropriate for the field. + + Default is to return the value itself, but types can use their + configuration to e.g. increment a numerical value or return the + current date(time). + """ + return value + def _to_index_text(self, value): """ Prepare a value for indexing. @@ -212,11 +222,24 @@ class LesanaDatetime(LesanaType): ) def empty(self): - if self.field.get('auto', False) == 'creation': + if self.field.get('auto', False) in ('creation', 'update'): return datetime.datetime.now(datetime.timezone.utc) return None + def update(self, value): + """ + Return an updated value. + + If the field settings ``auto`` is ``update`` return the current + datetime, otherwise the old value. + + """ + if self.field.get('auto', False) == 'update': + return datetime.datetime.now(datetime.timezone.utc) + + return value + class LesanaDate(LesanaType): """ @@ -239,11 +262,24 @@ class LesanaDate(LesanaType): ) def empty(self): - if self.field.get('auto', False) == 'creation': + if self.field.get('auto', False) in ('creation', 'update'): return datetime.date.today() return None + def update(self, value): + """ + Return an updated value. + + If the field settings ``auto`` is ``update`` return the current + date, otherwise the old value. + + """ + if self.field.get('auto', False) == 'update': + return datetime.date.today() + + return value + class LesanaBoolean(LesanaType): """ diff --git a/tests/test_types.py b/tests/test_types.py index 9663288..260167c 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -42,6 +42,9 @@ class testTypes(unittest.TestCase): s = checker.load(None) self.assertEqual(s, None) + v = checker.update("Hello World!") + self.assertEqual(v, "Hello World!") + def test_text(self): checker = types.LesanaText(self._get_field_def('text'), {}) @@ -54,6 +57,9 @@ class testTypes(unittest.TestCase): s = checker.load(None) self.assertEqual(s, None) + v = checker.update("Hello World!") + self.assertEqual(v, "Hello World!") + def test_int(self): checker = types.LesanaInt(self._get_field_def('integer'), {}) @@ -73,6 +79,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(10) + self.assertEqual(v, 10) + def test_float(self): checker = types.LesanaFloat(self._get_field_def('float'), {}) @@ -95,6 +104,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(10.5) + self.assertEqual(v, 10.5) + def test_decimal(self): checker = types.LesanaDecimal(self._get_field_def('decimal'), {}) @@ -117,6 +129,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(decimal.Decimal("10.5")) + self.assertEqual(v, decimal.Decimal("10.5")) + def test_timestamp(self): checker = types.LesanaTimestamp(self._get_field_def('timestamp'), {}) @@ -147,6 +162,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(today) + self.assertEqual(v, today) + def test_datetime(self): checker = types.LesanaDatetime(self._get_field_def('datetime'), {}) @@ -176,6 +194,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(now) + self.assertEqual(v, now) + def test_datetime_auto(self): field_def = self._get_field_def('datetime') field_def['auto'] = 'creation' @@ -193,6 +214,42 @@ class testTypes(unittest.TestCase): v = checker.empty() self.assertEqual(v, None) + # auto=update fields should also be filled at creation time + field_def['auto'] = 'update' + checker = types.LesanaDatetime(field_def, {}) + v = checker.empty() + self.assertIsInstance(v, datetime.datetime) + self.assertEqual(v.tzinfo, datetime.timezone.utc) + self.assertEqual(v.year, now.year) + + def test_datetime_auto_update(self): + field_def = self._get_field_def('datetime') + field_def['auto'] = 'update' + checker = types.LesanaDatetime(field_def, {}) + + now = datetime.datetime.now() + past = datetime.datetime(2016, 12, 10, 21, 2) + # we pass a date in the past + v = checker.update(past) + self.assertIsInstance(v, datetime.datetime) + self.assertEqual(v.tzinfo, datetime.timezone.utc) + # and we want to get a date in the present + self.assertEqual(v.year, now.year) + + # with auto=False we want our old date instead + field_def['auto'] = False + checker = types.LesanaDatetime(field_def, {}) + + v = checker.update(past) + self.assertEqual(v, past) + + # and the same should happen with auto=creation + field_def['auto'] = 'creation' + checker = types.LesanaDatetime(field_def, {}) + + v = checker.update(past) + self.assertEqual(v, past) + def test_date(self): checker = types.LesanaDate(self._get_field_def('date'), {}) @@ -222,6 +279,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(today) + self.assertEqual(v, today) + def test_date_auto(self): field_def = self._get_field_def('date') field_def['auto'] = 'creation' @@ -238,6 +298,41 @@ class testTypes(unittest.TestCase): v = checker.empty() self.assertEqual(v, None) + # auto=update fields should also be filled at creation time + field_def['auto'] = 'update' + checker = types.LesanaDate(field_def, {}) + + v = checker.empty() + self.assertIsInstance(v, datetime.date) + self.assertEqual(v, today) + + def test_date_auto_update(self): + field_def = self._get_field_def('date') + field_def['auto'] = 'update' + checker = types.LesanaDate(field_def, {}) + + today = datetime.date.today() + past = datetime.date(2016, 12, 10) + # we pass a date in the past + v = checker.update(past) + self.assertIsInstance(v, datetime.date) + # and we want to get a date in the present + self.assertEqual(v, today) + + # with auto=False we want our old date instead + field_def['auto'] = False + checker = types.LesanaDate(field_def, {}) + + v = checker.update(past) + self.assertEqual(v, past) + + # and the same should happen with auto=creation + field_def['auto'] = 'creation' + checker = types.LesanaDate(field_def, {}) + + v = checker.update(past) + self.assertEqual(v, past) + def test_boolean(self): checker = types.LesanaBoolean(self._get_field_def('boolean'), {}) @@ -254,6 +349,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(True) + self.assertEqual(v, True) + def test_file(self): checker = types.LesanaFile(self._get_field_def('file'), {}) @@ -268,6 +366,9 @@ class testTypes(unittest.TestCase): # TODO: check for invalid file paths + v = checker.update("relative/path/to/file") + self.assertEqual(v, "relative/path/to/file") + def test_url(self): checker = types.LesanaURL(self._get_field_def('url'), {}) @@ -282,6 +383,9 @@ class testTypes(unittest.TestCase): # TODO: check for invalid URLs + v = checker.update("http://example.org") + self.assertEqual(v, "http://example.org") + def test_yaml(self): checker = types.LesanaYAML(self._get_field_def('yaml'), {}) @@ -298,6 +402,9 @@ class testTypes(unittest.TestCase): v = checker.load(None) self.assertEqual(v, None) + v = checker.update(some_data) + self.assertEqual(v, some_data) + def test_list(self): field_def = self._get_field_def('yaml') # we use one type that is easy to check for correct validation @@ -318,6 +425,9 @@ class testTypes(unittest.TestCase): with self.assertRaises(types.LesanaValueError): checker.load(d) + v = checker.update(some_data) + self.assertEqual(v, some_data) + def test_list_unknown_subtype(self): field_def = self._get_field_def('yaml') # we use one type that is easy to check for correct validation |