aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElena ``of Valhalla'' Grandi <valhalla@trueelena.org>2020-09-30 17:10:49 +0200
committerElena ``of Valhalla'' Grandi <valhalla@trueelena.org>2020-09-30 17:10:49 +0200
commit06eeed552b34fb5f60401c1536db3f2cbf868a89 (patch)
tree14ae8045b0b9f1c35aacfa1ac4575ca260c9f356
parent0385fdd64368d65e86b296ed94e57176c5a08fec (diff)
Start defining type classes
-rw-r--r--lesana/types.py98
-rw-r--r--tests/test_types.py88
2 files changed, 186 insertions, 0 deletions
diff --git a/lesana/types.py b/lesana/types.py
new file mode 100644
index 0000000..e093c9f
--- /dev/null
+++ b/lesana/types.py
@@ -0,0 +1,98 @@
+"""
+Type checkers for lesana fields.
+
+Warning: this part of the code is still in flux and it may change
+significantly in a future release.
+"""
+import decimal
+
+
+class LesanaType:
+ """
+ Base class for lesana field types.
+ """
+ def load(self, data):
+ raise NotImplementedError
+
+ def empty(self):
+ raise NotImplementedError
+
+
+class LesanaString(LesanaType):
+ """
+ A string of unicode text
+ """
+ name = 'string'
+
+ def load(self, data):
+ return str(data)
+
+ def empty(self):
+ return ""
+
+
+class LesanaText(LesanaString):
+ """
+ A longer block of unicode text
+ """
+ name = 'text'
+
+
+class LesanaInt(LesanaType):
+ """
+ An integer number
+ """
+ name = "integer"
+
+ def load(self, data):
+ try:
+ return int(data)
+ except ValueError:
+ raise LesanaValueError(
+ "Invalid value for integer field: {}".format(data)
+ )
+
+ def empty(self):
+ return 0
+
+
+class LesanaFloat(LesanaType):
+ """
+ A floating point number
+ """
+ name = "float"
+
+ def load(self, data):
+ try:
+ return float(data)
+ except ValueError:
+ raise LesanaValueError(
+ "Invalid value for float field: {}".format(data)
+ )
+
+ def empty(self):
+ return 0.0
+
+
+class LesanaDecimal(LesanaType):
+ """
+ A floating point number
+ """
+ name = "float"
+
+ def load(self, data):
+ try:
+ return decimal.Decimal(data)
+ except decimal.InvalidOperation:
+ raise LesanaValueError(
+ "Invalid value for float field: {}".format(data)
+ )
+
+ def empty(self):
+ return decimal.Decimal(0)
+
+
+class LesanaValueError(ValueError):
+ """
+ Raised in case of validation errors.
+ """
diff --git a/tests/test_types.py b/tests/test_types.py
new file mode 100644
index 0000000..907be20
--- /dev/null
+++ b/tests/test_types.py
@@ -0,0 +1,88 @@
+import decimal
+import unittest
+
+from lesana import types
+
+
+class testTypes(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_string(self):
+ checker = types.LesanaString()
+
+ s = checker.empty()
+ self.assertEqual(s, "")
+
+ s = checker.load("Hello World!")
+ self.assertEqual(s, "Hello World!")
+
+ def test_text(self):
+ checker = types.LesanaText()
+
+ s = checker.empty()
+ self.assertEqual(s, "")
+
+ s = checker.load("Hello World!")
+ self.assertEqual(s, "Hello World!")
+
+ def test_int(self):
+ checker = types.LesanaInt()
+
+ v = checker.empty()
+ self.assertEqual(v, 0)
+
+ v = checker.load("10")
+ self.assertEqual(v, 10)
+
+ v = checker.load(10.5)
+ self.assertEqual(v, 10)
+
+ for d in ("ten", "10.5"):
+ with self.assertRaises(types.LesanaValueError):
+ checker.load(d)
+
+ def test_float(self):
+ checker = types.LesanaFloat()
+
+ v = checker.empty()
+ self.assertEqual(v, 0.0)
+
+ v = checker.load("10")
+ self.assertEqual(v, 10)
+
+ v = checker.load(10.5)
+ self.assertEqual(v, 10.5)
+
+ v = checker.load("10.5")
+ self.assertEqual(v, 10.5)
+
+ for d in ("ten"):
+ with self.assertRaises(types.LesanaValueError):
+ checker.load(d)
+
+ def test_decimal(self):
+ checker = types.LesanaDecimal()
+
+ v = checker.empty()
+ self.assertEqual(v, decimal.Decimal(0))
+
+ v = checker.load("10")
+ self.assertEqual(v, decimal.Decimal(10))
+
+ v = checker.load(10.5)
+ self.assertEqual(v, decimal.Decimal(10.5))
+
+ v = checker.load("10.5")
+ self.assertEqual(v, decimal.Decimal(10.5))
+
+ for d in ("ten"):
+ with self.assertRaises(types.LesanaValueError):
+ checker.load(d)
+
+
+if __name__ == '__main__':
+ unittest.main()