changeset 24:39f2611db9be

rename a bunch of things and begin to work on the sanity of validation
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 26 Mar 2012 15:46:25 -0700
parents 73e72a764c3a
children b39e550402ea
files configuration/config.py tests/unit.py
diffstat 2 files changed, 44 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/configuration/config.py	Mon Mar 26 15:14:26 2012 -0700
+++ b/configuration/config.py	Mon Mar 26 15:46:25 2012 -0700
@@ -20,7 +20,7 @@
 except ImportError:
     yaml = None
 
-__all__ = ['Configuration', 'configuration_providers']
+__all__ = ['Configuration', 'configuration_providers', 'types']
 
 configuration_providers = []
 if json:
@@ -108,6 +108,7 @@
          float: float_cli,
          list:  list_cli,
          None:  base_cli} # default
+__all__ += [i.__name__ for i in types.values()]
 
 class Configuration(object):
     options = {}
@@ -121,22 +122,45 @@
         # TODO: allow options to be a list of 2-tuples
         return self.options.items()
 
-    def check(self, config):
-        """check validity of configuration"""
+    ### methods for validating configuration
 
-        # TODO: ensure options in configuration are in self.options
-        unknown_options = []
+    def check(self, config):
+        """
+        check validity of configuration to be added
+        """
+        # TODO: should probably deepcopy config
+
+        # ensure options in configuration are in self.options
+        unknown_options = [i for i in config if i in self.options]
+        if unknown_options:
+            # TODO: more specific error type
+            raise Exception("Unknown options: %s" % ', '.join(unknown_options))
 
         # TODO: ensure options are of the right type (if specified)
+        for key, value in config.items():
+            _type = self.options[key].get('type')
+            if _type is not None:
+                config[key] = _type(value)
+
+        return config
+
+    def validate(self):
+        """validate resultant configuration"""
+        # TODO: configuration should be locked after this is called
+
+    ### methods for adding configuration
 
     def __call__(self, *args):
         """add items to configuration and check it"""
+        for config in args:
+            self.add(config)
+        self.valdate() # validate total configuration
+        # TODO: configuration should be locked after this is called
 
-    def add(self, config):
+    def add(self, config, check=True):
         """update configuration: not undoable"""
 
-        self.check(config)
-
+        self.check(config) # check config to be added
         self.config.update(config)
         # TODO: option to extend; augment lists/dicts
 
@@ -176,13 +200,20 @@
         self.optparse_options(parser)
         return parser
 
-    def parse(self, args=sys.argv[1:], parser=None):
+    def parse(self, args=sys.argv[1:], parser=None, configuration_provider_option=None):
         """parse configuration including command line options"""
 
         # parse arguments
         if parser is None:
-            parser = self.parser()
+            parser = self.parser(configuration_provider_option=configuration_provider_option)
         options, args = parser.parse_args(args)
 
+        # get CLI configuration options
+        cli_config = dict([(key, value) for key, value in options.__dict__.items()
+                           if key in self.options])
+
+        # generate configuration
+        self(cli_config)
+
         # return parsed arguments
         return options, args
--- a/tests/unit.py	Mon Mar 26 15:14:26 2012 -0700
+++ b/tests/unit.py	Mon Mar 26 15:46:25 2012 -0700
@@ -13,15 +13,16 @@
 # globals
 here = os.path.dirname(os.path.abspath(__file__))
 
-class configurationUnitTest(unittest.TestCase):
+class ConfigurationUnitTest(unittest.TestCase):
 
-    def test_configuration(self):
+    def test_cli(self):
         example = ExampleConfiguration()
 
         # parse command line arguments
         options, args = example.parse(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox'])
         self.assertEqual(bool(args), False) # no arguments
         self.assertEqual(options.develop, True)
+        self.assertEqual(options.activeTests, 'ts')
 
 if __name__ == '__main__':
     unittest.main()