diff options
| -rw-r--r-- | lesana/types.py | 98 | ||||
| -rw-r--r-- | tests/test_types.py | 88 | 
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() | 
