import unittest import config class BasicTests(unittest.TestCase): """Tests of features the test template depends on.""" def tearDown(self): config.clear_all() def test_setValue(self): config.set_value("a.b", "123") self.assertEquals(str(config.values['a']['b']), "123") def test_setValues(self): config.set_values({'a.b': '123', 'a.c': '456'}) self.assertEquals(str(config.values['a']['b']), "123") self.assertEquals(str(config.values['a']['c']), "456") def test_absentValue(self): try: str(config.values['a']['b']) self.fail("Call succeeded") except config.ConfigValueUndefinedException: return def test_clearAll(self): config.set_value("a.b", "123") self.assertEquals(str(config.values['a']['b']), "123") config.clear_all() try: str(config.values['a']['b']) self.fail("Call succeeded") except config.ConfigValueUndefinedException: return class TestTemplate(unittest.TestCase): """A basic template that most of the tests are based on. To disable all tests except for those that are needed for testing the template itself, modify this to inherit from object instead of unittest.TestCase.""" init_values = {} def setUp(self): config.set_values(self.init_values) def tearDown(self): config.clear_all() class SetValueTest(TestTemplate): "Tests setting a single value." def testBody(self): config.set_value("a.b", "123") self.assertEquals(str(config.values['a']['b']), "123") class DottedValuesAccessTest(TestTemplate): "Tests accessing via dot syntax." init_values = {'a.b': '123'} def testBody(self): self.assertEquals(str(config.values.a.b), "123") class DeepDottedAccessTest(TestTemplate): "Tests accessing a deep value via dotted syntax." init_values = {'a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t': '123'} def testBody(self): self.assertEquals( str(config.values.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t), '123') class LongKeyComponentsTest(TestTemplate): "Tests a moderately long key component name." init_values = {'my_module_installed': '123', 'my_module.some_long_section.some_long_item': '456'} def testBody(self): self.assertEquals(str(config.my_module_installed), '123') self.assertEquals( str(config.my_module.some_long_section.some_long_item), '456') class TopLevelAccessTest(TestTemplate): "Tests accessing a top-level item via values." init_values = {'a': '123'} def testBody(self): self.assertEquals(str(config.values.a), '123') class MultipleTopLevelValuesTest(TestTemplate): "Test where there are multiple top-level values." init_values = {'a.b': '123', 'b.b': '456'} def testBody(self): self.assertEquals(str(config.values.a.b), '123') self.assertEquals(str(config.values.b.b), '456') class AccessParentValueTest(TestTemplate): "Tests accessing a parent node as a value." init_values = {'a.b': '123', 'a.b.c': '456'} def testBody(self): self.assertEquals(str(config.values.a.b), '123') self.assertEquals(str(config.values.a.b.c), '456') class AccessBranchedValuesTest(TestTemplate): "Tests accessing a complex tree of values." init_values = {'a.b': '123', 'a.b.c1': '456', 'a.b.c2': '789'} def testBody(self): self.assertEquals(str(config.values.a.b), '123') self.assertEquals(str(config.values.a.b.c1), '456') self.assertEquals(str(config.values.a.b.c2), '789') class AccessEmptyNodeAsStrTest(TestTemplate): "Tests accessing the value of a node with subvalues but no value." init_values = {'a.b.c': '123'} def testBody(self): try: str(config.values.a.b) self.fail("returned a non-existant value") except config.ConfigValueUndefinedException: return class TopLevelTest(TestTemplate): "Tests dotted access directly off of config" init_values = {'a.b': '123'} def testBody(self): self.assertEquals(str(config.a.b), '123') _original_set_values_function = config.set_values class TopLevelInvalidTest(TestTemplate): "Tests using a top level name not valid for direct access." init_values = {'set_values.a.b': '123'} def testBody(self): self.assertEquals(config.set_values, _original_set_values_function) self.assertEquals(str(config.values.set_values.a.b), '123') class DottedStringAccessTest(TestTemplate): "Tests using a dotted string for access." init_values = {'a.b.c': '123'} def testBody(self): self.assertEquals(str(config.values['a.b.c']), '123') self.assertEquals(str(config.values.a['b.c']), '123') self.assertEquals(str(config.values['a.b'].c), '123') class AccessAsStringTest(TestTemplate): "Tests simply using a node as a string." init_values = {'a.b': '123'} def testBody(self): self.assertEquals(config.a.b, '123') self.assert_(isinstance(config.a.b, str)) self.assertNotEqual(type(config.a.b), type('123')) class AccessIntermediateNodeAsStringTest(TestTemplate): "Tests that an intermediate node is a string also." init_values = {'a.b': '123', 'a.b.c': '456'} def testBody(self): self.assertEquals(config.a.b, '123') self.assert_(isinstance(config.a.b, str)) self.assertEquals(config.a.b.c, '456') self.assert_(isinstance(config.a.b.c, str)) class AccessTopNodeAsStringTest(TestTemplate): "Tests that a top-level node can be accessed as a string." init_values = {'a': '123'} def testBody(self): self.assertEquals(config.a, '123') self.assert_(isinstance(config.a, str)) class OverloadGetitemToBeStrAndNode(TestTemplate): """Tests the situation when a node has a value and also has child nodes... this requires that __getitem__ accept integers (to index the str) or strings (to find subnodes).""" init_values = {'a.b': '123', 'a.b.c': '456'} def testBody(self): self.assertEquals(config.a.b[1], '2') self.assertEquals(config.a.b['c'], '456') try: config.a.b[None] self.fail("Expected exception not raised.") except TypeError, err: # err must be BOTH a TypeError and a ConfigException self.assert_(isinstance(err, config.ConfigException)) except: self.fail("Wrong exception raised.") class OverloadGetitemToBeUnicodendNode(TestTemplate): """Tests the situation when a node has a value and also has child nodes... this requires that __getitem__ accept integers (to index the str) or strings (to find subnodes).""" init_values = {'a.b': u'123', 'a.b.c': u'456'} def testBody(self): self.assertEquals(config.a.b[1], u'2') self.assertEquals(config.a.b['c'], u'456') try: config.a.b[None] self.fail("Expected exception not raised.") except TypeError, err: # err must be BOTH a TypeError and a ConfigException self.assert_(isinstance(err, config.ConfigException)) except: self.fail("Wrong exception raised.") class KeyIsUnicodeTest(TestTemplate): "Tests unicode key." init_values = {u'a.\u01a9.c': '123'} def testBody(self): self.assertEquals(str(config.a[u'\u01a9'].c), '123') class ValueIsUnicodeTest(TestTemplate): "Tests unicode value." init_values = {u'a.b': u'\01a9'} def testBody(self): self.assertEquals(unicode(config.a.b), u'\01a9') class DirectlyUsingUnicodeTest(TestTemplate): "Tests using a unicode value without converting it." init_values = {u'a.b': u'\u01a9'} def testBody(self): self.assertEquals(config.a.b, u'\u01a9') self.assert_(isinstance(config.a.b, unicode)) class AsciiAsStrOrUnicodeTest(TestTemplate): "Tests that pure ascii values can be converted to unicode or ascii." init_values = {'a.b': '123', u'a.c': u'456'} def testBody(self): self.assertEquals(unicode(config.a.b), u'123') self.assertEquals(str(config.a.c), '456') class ErrorConvertingUnicodeToStrTest(TestTemplate): "Tests that non-ascii unicode values cannot be converted to str." init_values = {u'a.b': u'\u01a9'} def testBody(self): self.assertRaises(UnicodeEncodeError, str, config.a.b) class ErrorConvertingStrToUnicodeTest(TestTemplate): "Tests that non-ascii str values cannot be converted to unicode." init_values = {'a.b': '\x8f'} def testBody(self): self.assertRaises(UnicodeDecodeError, unicode, config.a.b) class ExceptionForInvalidValueTest(TestTemplate): "Tests that an exception is thrown for non-str/non-unicode values." def testBody(self): obj = object() # exception should be a TypeError and should ALSO be a ConfigException self.assertRaises(TypeError, config.set_value, 'a.b', obj) self.assertRaises(config.ConfigException, config.set_value, 'a.b', obj) class SubclassesOfStrAreValidValuesTest(TestTemplate): "Tests that subclasses of str are valid values." def testBody(self): class SomeStrSubclass(str): pass value = SomeStrSubclass('123') config.set_value('a.b', value) result = str(config.a.b) self.assertEquals(value, result) self.assert_(isinstance(value, SomeStrSubclass)) class SubclassesOfUnicodeAreValidValuesTest(TestTemplate): "Tests that subclasses of unicode are valid values." def testBody(self): class SomeUnicodeSubclass(unicode): pass value = SomeUnicodeSubclass('123') config.set_value('a.b', value) result = unicode(config.a.b) self.assertEquals(value, result) self.assert_(isinstance(value, SomeUnicodeSubclass)) class SubconfigTest(TestTemplate): "Tests subconfig." init_values = {'a.b.c': '111', 'a.b.d': '222', 'a.b.e.f': '333', 'a.b.e.g': '444', 'a.b.e.g.h': '555'} def testBody(self): self.assertEquals(set(config.a.b.subconfig()), set(['c', 'd', 'e'])) self.assertEquals(set(config.a.b.subconfig(deep=True)), set(['c', 'd', 'e.f', 'e.g', 'e.g.h'])) class GetTest(TestTemplate): "Tests config.get() without a default." init_values = {'a.b': '123'} def testBody(self): self.assertEquals(config.get('a.b'), '123') self.assertRaises(config.ConfigValueUndefinedException, config.get, 'x') self.assertRaises(config.ConfigValueUndefinedException, config.get, 'a.b.c') class GetDefaultTest(TestTemplate): "Tests config.get() with a default." init_values = {'a.b': '123'} def testBody(self): self.assertEquals(config.get('a.b', '456'), '123') self.assertEquals(config.get('x', '456'), '456') self.assertEquals(config.get('a.b.c', '456'), '456') class GetDefaultNeedNotBeAStringTest(TestTemplate): "Tests config.get() with a default value which is NOT a basestring" init_values = {'a.b': '123'} def testBody(self): obj = object() self.assertEquals(config.get('a.b', obj), '123') self.assertEquals(config.get('x', obj), obj) self.assertEquals(config.get('a.b.c', obj), obj) class EmptyStringsTest(TestTemplate): "Tests the use of empty strings at various places in the key." init_values = {'': '123', 'a.': '456', 'a..b': '789'} def testBody(self): self.assertEquals(config.values[''], '123') self.assertEquals(config.values.a[''], '456') self.assertEquals(config.values['a.'], '456') self.assertEquals(config.values.a[''].b, '789') self.assertEquals(config.values['a..b'], '789') class IterateEmptyNodeTest(TestTemplate): "Ensures the error is helpful when iterating an empty node." init_values = {'a.b': '123'} def testBody(self): self.assertRaises(config.ConfigKeyMustBeStringException, list, config.a); # Ensure it is a KeyError and a ConfigException self.assertRaises(KeyError, list, config.a) self.assertRaises(config.ConfigException, list, config.a) if __name__ == '__main__': unittest.main()