Mercurial > hg > configuration
diff tests/unit2.py @ 140:372315b3bb8e
stubbing
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Thu, 06 Nov 2014 07:41:05 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/unit2.py Thu Nov 06 07:41:05 2014 -0800 @@ -0,0 +1,227 @@ +#!/usr/bin/env python + +""" +unit tests for configuration package +""" + +import configuration +import datetime +import json +import os +import sys +import tempfile +import unittest + +from example import ExampleConfiguration # example configuration to test + +# globals +here = os.path.dirname(os.path.abspath(__file__)) + +class ConfigurationUnitTest(unittest.TestCase): + + def test_cli(self): + """test command line interface""" + + example = ExampleConfiguration() + + # parse command line arguments + options, args = example.parse_args(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox']) + + # ensure that the options appropriately get set + self.assertEqual(bool(args), False) # no arguments + self.assertEqual(options.develop, True) + self.assertEqual(options.activeTests, ['ts']) + self.assertEqual(options.browser_path, '/home/jhammel/bin/firefox') + + # ensure that the configuration appropriately gets updated + self.assertEqual(example.config['develop'], True) + self.assertEqual(example.config['activeTests'], ['ts']) + self.assertEqual(example.config['browser_path'], '/home/jhammel/bin/firefox') + + def test_dict(self): + """test dictionary parsing from the "command line" """ + + + # test adding a preference + example = ExampleConfiguration() + options, args = example.parse_args(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox', + '--pref', 'hangmonitor.timeout=0']) + self.assertTrue('hangmonitor.timeout' in options.preferences) + + # test overriding a preference + example = ExampleConfiguration() + options = example.parse_args(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox', + '--pref', 'browser.bookmarks.max_backups=1']) + self.assertTrue(options.preferences['browser.bookmarks.max_backups'] == '1') + + + def test_configuration_providers(self): + """test file-based configuration providers""" + # requires json/simplejson to be installed + + example = ExampleConfiguration() + + # see what providers you got + json_provider = example.configuration_provider('json') + self.assertTrue(isinstance(json_provider, configuration.JSON)) + + # serialize to a temporary file + filename = tempfile.mktemp(suffix='.json') + self.assertEqual(example.filename2format(filename), 'json') + self.assertFalse(os.path.exists(filename)) + config = {'browser_path': '/home/jhammel/bin/firefox', + 'activeTests': ['ts']} + example(config) + config['test_timeout'] = 1200 # default + config['preferences'] = {"browser.bookmarks.max_backups": 0, + "browser.cache.disk.smart_size.enabled": False} + + # ensure they are equal + self.assertEqual(config, example.config) + example.serialize(filename) + self.assertTrue(os.path.exists(filename)) + serialized = json.loads(file(filename).read()) + self.assertEqual(serialized, config) + + # deserialize + deserialized = example.deserialize(filename) + self.assertEqual(deserialized, config) + + # cleanup + if os.path.exists(filename): + os.remove(filename) + + def test_missing_values(self): + """ensure that Configuration raises a missing value exception""" + + example = ExampleConfiguration() + + # monkey-patch the error method from optparse.OptionParser + error_msg = [] + def error(msg): + error_msg.append(msg) + example.error = error + + # trigger it + example.parse_args(args=[]) + self.assertEqual(error_msg, ['Parameter browser_path is required but not present']) + + def test_required(self): + """ensure you have to have required values""" + + example = ExampleConfiguration() + + # ensure you get an exception + missingvalueexception = None + try: + example() + except configuration.MissingValueException, e: + missingvalueexception = e + self.assertTrue(isinstance(e, configuration.MissingValueException)) + + + def test_multiple_configurations(self): + """test having multiple configurations""" + + # simple override + args1 = ['-e', '/opt/bin/firefox'] + + # simple serialized file + json_file = os.path.join(here, 'base.json') + assert os.path.exists(json_file) + json_config = json.loads(file(json_file).read()) + + # parse the json file + example = ExampleConfiguration() + example.parse_args([json_file]) + self.assertEqual(example.config, json_config) + + # parse the json file with overrides + example = ExampleConfiguration() + example.parse_args([json_file] + args1) + config = json_config.copy() + config['browser_path'] = '/opt/bin/firefox' + self.assertEqual(example.config, config) + + # it shouldn't matter in which order the arguments are + example = ExampleConfiguration() + example.parse_args(args1 + [json_file]) + self.assertEqual(example.config, config) + + # Now a tricky case: + # the default value for test_timeout is 1200: + example = ExampleConfiguration() + self.assertEqual(example.options['test_timeout']['default'], 1200) + # The value from base.json is 60: + self.assertEqual(json_config['test_timeout'], 60) + self.assertEqual(config['test_timeout'], 60) + # but we can override it back from the "command line" + example.parse_args(args1 + [json_file, '--test_timeout', '1200']) + config['test_timeout'] = 1200 + self.assertEqual(example.config, config) + + def test_extend(self): + + # default preferences + example = ExampleConfiguration() + default_prefs = {"browser.bookmarks.max_backups": 0, + "browser.cache.disk.smart_size.enabled": False} + example.parse_args(['-a', 'ts', '-e', '/opt/bin/firefox']) + self.assertEqual(example.config['preferences'], default_prefs) + + # now extend them + example = ExampleConfiguration() + default_prefs['network.dns.ipv4OnlyDomains'] = 'localhost' + tf = tempfile.mktemp() + f = file(tf, 'w') + f.write(json.dumps({'preferences': {'network.dns.ipv4OnlyDomains': 'localhost'}})) + f.close() + example.parse_args(['-a', 'ts', '-e', '/opt/bin/firefox', tf]) + self.assertEqual(example.config['preferences'], default_prefs) + os.remove(tf) + + def test_typecast(self): + """casting example""" + + def todate(string): + return datetime.datetime.strptime(string, "%Y%m%d") + + # make an example class + class TypecastExample(configuration.Configuration): + options = {'datestring': {'type': todate}} + example = TypecastExample() + + # parse a date string + example({'datestring': "20120704"}) + + # ensure it works correctly + expected = datetime.datetime(2012, 7, 4, 0, 0) + self.assertEqual(example.config['datestring'], expected) + + + def test_added(self): + """test that we keep track of things added to the configuration""" + + # make an example class + class AddedExample(configuration.Configuration): + options = {'foo': {}, + 'bar': {}} + + # parse it; there should be nothing + instance = AddedExample() + instance() + self.assertEqual(instance.added, set()) + + # parse it; there should be one thing + instance = AddedExample() + instance({'foo': 'foo'}) + self.assertEqual(instance.added, set(['foo'])) + + # parse it; there should be two things + instance = AddedExample() + instance({'foo': 'foo'}, {'foo': 'FOO', 'bar': 'bar'}) + self.assertEqual(instance.added, set(['foo', 'bar'])) + + +if __name__ == '__main__': + unittest.main()