Add ConfigParser and tests.
authorRadek Brich <radek.brich@devl.cz>
Sat, 06 Apr 2013 00:07:17 +0200
changeset 3 cc27136cdead
parent 2 d3ffa15f5886
child 4 fdaa7dc9035e
Add ConfigParser and tests.
pycolib/configparser.py
run_tests.py
tests/__init__.py
tests/data/test_badargs.conf
tests/data/test_ok.conf
tests/test_configparser.py
tests/test_prettysize.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pycolib/configparser.py	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,52 @@
+# simple config file reader using Python's syntax and parser
+
+
+class ConfigParserError(Exception):
+    pass
+
+
+class ConfigParser:
+    def __init__(self):
+        self.args = {}       # config file arguments
+        self.registered_args = {}
+
+    def add_argument(self, name, type_=str, default=None):
+        """Register argument name, type and default value."""
+        self.registered_args[name] = {'type':type_, 'default':default}
+        self.args[name] = default
+
+    def load(self, fname):
+        """Load config file and check loaded values."""
+        self.parse(fname)
+        self.check()
+
+    def parse(self, fname):
+        """Parse config file. Does not check values."""
+        with open(fname) as f:
+            exec(f.read(), self.args)
+
+    def check(self):
+        """Check loaded argument values against registered types."""
+        for key in self.args.keys():
+            if key == '__builtins__':
+                continue
+            if key in self.registered_args:
+                # arg registered, check type
+                type_ = self.registered_args[key]['type']
+                if not isinstance(self.args[key], type_) and not self.args[key] is None:
+                    raise ConfigParserError("Bad value of config parameter '%s': type is %s but should be %s"
+                        % (key, type(self.args[key]), type_))
+            else:
+                raise ConfigParserError("Unknown config parameter '%s'." % key)
+
+    def __getattr__(self, name):
+        """Attribute access for config parameters.
+
+        cfg.my_param <===> cfg.args['myparam']
+
+        """
+        if name in self.args:
+            return self.args[name]
+        else:
+            raise AttributeError()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/run_tests.py	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import unittest
+
+loader = unittest.TestLoader()
+tests = loader.discover('tests')
+runner = unittest.runner.TextTestRunner()
+runner.run(tests)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/data/test_badargs.conf	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,3 @@
+arg_str = 1
+arg_int = '2'
+arg_unknown = 3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/data/test_ok.conf	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,2 @@
+arg_str = '1'
+arg_int = 2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_configparser.py	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+
+from pycolib.configparser import ConfigParser, ConfigParserError
+
+import unittest
+import os.path
+
+
+class TestConfigParser(unittest.TestCase):
+
+    def setUp(self):
+        self.config = ConfigParser()
+        self.config.add_argument('arg_str')
+        self.config.add_argument('arg_int', int, 1)
+        script_path = os.path.dirname(os.path.realpath(__file__))
+        self.data_path = os.path.join(script_path, 'data')
+
+    def test_add_argument(self):
+        name = 'argname'
+        self.config.add_argument(name, int, 1)
+        self.assertEqual(self.config.registered_args[name]['type'], int)
+        self.assertEqual(self.config.registered_args[name]['default'], 1)
+        self.assertEqual(self.config.args[name], 1)
+
+    def test_load_badname(self):
+        self.assertRaises(IOError, self.config.load, 'bad/file_name')
+
+    def test_load_badargs(self):
+        fname = os.path.join(self.data_path, 'test_badargs.conf')
+        self.assertRaises(ConfigParserError, self.config.load, fname)
+
+    def test_load_ok(self):
+        fname = os.path.join(self.data_path, 'test_ok.conf')
+        self.config.load(fname)
+        self.assertEqual(self.config.arg_str, '1')
+        self.assertEqual(self.config.arg_int, 2)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_prettysize.py	Sat Apr 06 00:07:17 2013 +0200
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+
+from pycolib import prettysize
+
+import unittest
+
+
+class TestPrettySize(unittest.TestCase):
+
+    def test_prettysize(self):
+        psize = prettysize.prettysize_short
+        expected = (
+            (0, '0'),
+            (1000, '1000'),
+            (1024, '1K'),
+            (1050, '1.03K'),
+            (2050, '2K'),
+            (333333, '325.52K'),
+            (1048576, '1M'),
+            (1050000, '1M'),
+            (5555555, '5.3M'),
+            (1073741824, '1G'),
+            )
+        for value, result in expected:
+            self.assertEqual(psize(value), result)
+
+
+if __name__ == '__main__':
+    unittest.main()