Mercurial > hgrepos > Python > libs > ConfigMix
view tests/test.py @ 755:04c5a3a36499
WS
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 30 Nov 2023 21:11:47 +0100 |
| parents | c431160e3c48 |
| children | cabd1046d95f |
line wrap: on
line source
# -*- coding: utf-8 -*- import unittest import platform import io import os import sys from _test_context import TESTDATADIR import configmix import configmix.ini import configmix.yaml import configmix.json import configmix.py import configmix.toml import configmix.config from configmix.compat import u, PY2 class T01Basic(unittest.TestCase): """Check with low-level internal interfaces""" def __check_types(self, cfg): self.assertEqual(u("the value"), cfg.get("key1")) self.assertTrue(isinstance(cfg.get("key1"), type(u('')))) self.assertEqual(2, cfg.get("key2")) self.assertEqual(5.7, cfg.get("key3")) self.assertTrue(isinstance(cfg.get("key1"), type(u('')))) self.assertTrue(cfg.get("key4")) self.assertTrue(isinstance(cfg.get("key4"), bool)) self.assertFalse(cfg.get("key5")) self.assertTrue(isinstance(cfg.get("key5"), bool)) self.assertEqual(255, cfg.get("key6")) self.assertEqual(u("Umlaute: ÄÖÜäöüß"), cfg.get("key7")) def __check_comment(self, cfg): # Check comments: low level comments are *not* filtered self.assertEqual(u("Comment 1"), cfg.get("__comment1")) self.assertEqual(u("Comment no 2"), cfg.get("__comment2")) def __check_no_comment(self, cfg): def _c(name): def _f(): cfg[u(name)] return _f # Variables with leading underscores are *not* imported by default self.assertRaises(KeyError, _c("__comment1")) self.assertRaises(KeyError, _c("__comment2")) def __check_tree(self, cfg): self.assertEqual(u("in the root namespace"), cfg.get("key1")) self.assertEqual(u("in the root namespace -- too"), cfg.get("key2")) self.assertEqual(32, cfg["tree1"]["key3"]) self.assertEqual(u("get this as `tree1.tree2.key4'"), cfg["tree1"]["tree2"]["key4"]) self.assertTrue(cfg["tree1"]["tree2"]["key5"]) def test01_ini_types(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) self.__check_types(cfg) self.__check_comment(cfg) def test01_toml_types(self): cfg = configmix.toml.load(os.path.join(TESTDATADIR, "conf1.toml")) self.__check_types(cfg) self.__check_comment(cfg) def test02_py_types(self): cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf1.py")) self.__check_types(cfg) self.__check_no_comment(cfg) def test03_yaml_types(self): with io.open(os.path.join(TESTDATADIR, "conf1.yml"), "rt", encoding="utf-8") as f: cfg = configmix.yaml.safe_load(f) if configmix.yaml.OrderedDict: self.assertTrue(isinstance(cfg, configmix.yaml.OrderedDict)) self.__check_types(cfg) self.__check_comment(cfg) def test04_json_types(self): cfg = configmix.json.load(os.path.join(TESTDATADIR, "conf1.json")) self.assertTrue(isinstance(cfg, configmix.json.DictImpl)) self.__check_types(cfg) self.__check_comment(cfg) def test05_py_export_all(self): # When __all__ is given only it's keys are exported cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf2.py")) self.assertEqual(u("the next value"), cfg.get("key1")) self.assertTrue(isinstance(cfg.get("key1"), type(u('')))) self.assertTrue(cfg.get("key2") is None) def test06_py_hide_private(self): # When no __all__ is given all symbols with leading "_" are hidden cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf3.py")) self.assertEqual(u("the next value "), cfg.get("key1")) self.assertTrue(isinstance(cfg.get("key1"), type(u('')))) self.assertTrue(cfg.get("_key2") is None) def test07_ini_tree(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf10.ini")) self.__check_tree(cfg) def test08_py_tree(self): cfg = configmix.py.load(os.path.join(TESTDATADIR, "conf10.py")) self.__check_tree(cfg) def test09_yaml_tree(self): with io.open(os.path.join(TESTDATADIR, "conf10.yml"), "rt", encoding="utf-8") as f: cfg = configmix.yaml.safe_load(f) self.__check_tree(cfg) def test10_json_tree(self): cfg = configmix.json.load(os.path.join(TESTDATADIR, "conf10.json")) self.__check_tree(cfg) def test11_toml_tree(self): cfg = configmix.toml.load(os.path.join(TESTDATADIR, "conf10.toml")) self.__check_tree(cfg) def test12_yaml_no_duplicate_keys(self): import yaml.constructor as yc with io.open(os.path.join(TESTDATADIR, "duplicate-keys.yml"), "rt", encoding="utf-8") as f: cfg = configmix.yaml.safe_load(f) with io.open(os.path.join(TESTDATADIR, "duplicate-keys.yml"), "rt", encoding="utf-8") as f: self.assertRaises(yc.ConstructorError, configmix.yaml.safe_load, f, strict=True) def test13_yaml_no_duplicate_keys_2(self): import yaml.constructor as yc with io.open(os.path.join(TESTDATADIR, "duplicate-keys-2.yml"), "rt", encoding="utf-8") as f: cfg = configmix.yaml.safe_load(f) with io.open(os.path.join(TESTDATADIR, "duplicate-keys-2.yml"), "rt", encoding="utf-8") as f: self.assertRaises(yc.ConstructorError, configmix.yaml.safe_load, f, strict=True) class _T02MixinLoadAndMerge: def test01_load(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertEqual(u("the_database_user"), cfg.getvar_s("db.user.name")) self.assertEqual(u("the-database-password"), cfg.getvar_s("db.user.pwd")) tmpdir = cfg.getvar_s("tmpdir") if os.name == 'nt': self.assertFalse(u('/') in tmpdir) self.assertEqual( os.path.normpath( os.path.abspath( os.path.join(os.getcwd(), "tmp"))), tmpdir) self.assertEqual(u("anotherhost"), cfg.getvar_s("db.locinfo.ro.hostname")) self.assertEqual(u("localhost"), cfg.getvar_s("db.locinfo.rw.hostname")) self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port")) url = cfg.getvar_s("db.engines.ro.url") self.assertEqual( u("postgresql+psycopg2://the_database_user:the-database-password@anotherhost:5432/my_database_catalog"), url) self.assertEqual(u("not a list any more"), cfg.getvar_s("test.List")) self.assertEqual(list(range(0, 3)), cfg.getvar_s("test.Str")) def test02_load_with_ini(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) self.assertEqual(u("the_database_user_2"), cfg.getvar_s("db.user.name")) self.assertEqual(u("the-database-password-2"), cfg.getvar_s("db.user.pwd")) tmpdir = cfg.getvar_s("tmpdir") self.assertEqual(u(os.getcwd()) + u("/tmp\\2"), tmpdir) self.assertEqual(u("3rd-host"), cfg.getvar_s("db.locinfo.ro.hostname")) self.assertEqual(u("localhost"), cfg.getvar_s("db.locinfo.rw.hostname")) self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port")) url = cfg.getvar_s("db.engines.ro.url") self.assertEqual( u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"), url) def test02b_load_with_ini(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) self.assertEqual(u("3rd-host3rd-host"), cfg.getvar_s("db.locinfo.ro.hostname2")) def test02_load_with_json(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), # .ini replaced with an equivalent .json os.path.join(TESTDATADIR, "conf23.json")) self.assertEqual(u("the_database_user_2"), cfg.getvar_s("db.user.name")) self.assertEqual(u("the-database-password-2"), cfg.getvar_s("db.user.pwd")) tmpdir = cfg.getvar_s("tmpdir") self.assertEqual(u(os.getcwd()) + u("/tmp\\3"), tmpdir) self.assertEqual(u("3rd-host"), cfg.getvar_s("db.locinfo.ro.hostname")) self.assertEqual(u("localhost"), cfg.getvar_s("db.locinfo.rw.hostname")) self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port")) url = cfg.getvar_s("db.engines.ro.url") self.assertEqual( u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"), url) def test02_load_with_toml(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), # .ini replaced with an equivalent .toml os.path.join(TESTDATADIR, "conf24.toml")) self.assertEqual(u("the_database_user_2"), cfg.getvar_s("db.user.name")) self.assertEqual(u("the-database-password-2"), cfg.getvar_s("db.user.pwd")) tmpdir = cfg.getvar_s("tmpdir") self.assertEqual(u(os.getcwd()) + u("/tmp\\4"), tmpdir) self.assertEqual(u("3rd-host"), cfg.getvar_s("db.locinfo.ro.hostname")) self.assertEqual(u("localhost"), cfg.getvar_s("db.locinfo.rw.hostname")) self.assertEqual(5432, cfg.getvar_s("db.locinfo.ro.port")) url = cfg.getvar_s("db.engines.ro.url") self.assertEqual( u("postgresql+psycopg2://the_database_user_2:the-database-password-2@3rd-host:5432/my_database_catalog"), url) def test03_namespace(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) self.assertEqual(u(os.getcwd()), cfg.getvar("OS:cwd")) self.assertEqual(u(platform.python_version()), cfg.getvar_s("PY:version")) self.assertEqual(u(sys.executable), cfg.getvar_s("SYS:executable")) self.assertEqual(u(sys.prefix), cfg.getvar_s("SYS:prefix")) self.assertEqual(u(sys.platform), cfg.getvar_s("SYS:platform")) if hasattr(sys, "base_prefix"): self.assertEqual(u(sys.base_prefix), cfg.getvar_s("SYS:base_prefix")) else: self.assertRaises(KeyError, cfg.getvar_s, "SYS:base_prefix") def test03_namespace_l(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) self.assertEqual(u(os.getcwd()), cfg.getvarl("cwd", namespace="OS")) self.assertEqual(u(platform.python_version()), cfg.getvarl_s("version", namespace="PY")) self.assertEqual(u(sys.prefix), cfg.getvarl_s("prefix", namespace="SYS")) def test04_no_filter(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) def _look(): return cfg.getvar("OS:cwd|upper") self.assertRaises(KeyError, _look) def test04_no_filter_l(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini")) def _look(): return cfg.getvarl("cwd|upper", namespace="OS") self.assertRaises(KeyError, _look) def test05_comments(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) def _c(name): def _f(): cfg.getvar_s(name) return _f # Variables with leading underscores are *not* imported by default self.assertEqual(0o0027, int(cfg.getvar_s("process.umask"), 0)) self.assertRaises(KeyError, _c("process.__doc1")) self.assertRaises(KeyError, _c("db.__comment1")) self.assertRaises(KeyError, _c("db.user.__doc2")) def test05_comments_l(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) def _c(*names): def _f(): cfg.getvarl_s(*names) return _f # Variables with leading underscores are *not* imported by default self.assertEqual(0o0027, int(cfg.getvarl_s("process", "umask"), 0)) self.assertRaises(KeyError, _c("process", "__doc1")) self.assertRaises(KeyError, _c("db", "__comment1")) self.assertRaises(KeyError, _c("db", "user", "__doc2")) def test06_check_all_comments(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) def _check(d): for k, v in d.items(): self.assertFalse(configmix._is_comment(k)) if isinstance(v, dict): _check(v) _check(cfg) def test07_deletions(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml"), os.path.join(TESTDATADIR, "delete-in-dict.yml")) # automatic clean-up self.assertRaises(KeyError, cfg.getvar_s, "not-deleted") # explicit deletion self.assertRaises(KeyError, cfg.getvar_s, "to-be-deleted") self.assertRaises(KeyError, cfg.getvar_s, "db.user.name") self.assertEqual("the-database-password-2", cfg.getvar_s("db.user.pwd")) self.assertRaises(KeyError, cfg.getvar_s, "test.Str") self.assertEqual("not a list any more", cfg.getvar_s("test.List")) self.assertEqual("the last value", cfg.getvar_s("to-be-deleted-but-reassigned")) def test07_deletions_l(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml"), os.path.join(TESTDATADIR, "delete-in-dict.yml")) # automatic clean-up self.assertRaises(KeyError, cfg.getvarl_s, "not-deleted") # explicit deletion self.assertRaises(KeyError, cfg.getvarl_s, "to-be-deleted") self.assertRaises(KeyError, cfg.getvarl_s, "db" "user.name") self.assertEqual("the-database-password-2", cfg.getvarl_s("db", "user", "pwd")) self.assertRaises(KeyError, cfg.getvarl_s, "test", "Str") self.assertEqual("not a list any more", cfg.getvarl_s("test", "List")) self.assertEqual("the last value", cfg.getvarl_s("to-be-deleted-but-reassigned")) def test08_None_filter_single(self): cfg = self._load() x = cfg.interpolate_variables("{{non-existing|None}}") self.assertIsNone(x) def test09_None_filter_embedded(self): cfg = self._load() x = cfg.interpolate_variables("A{{non-existing|None}}Z") self.assertEqual("AZ", x) def test10_Empty_filtersingle(self): cfg = self._load() x = cfg.interpolate_variables("{{non-existing|Empty}}") self.assertEqual("", x) def test11_None_filter_pass_through(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) x = cfg.interpolate_variables("{{intl.cache.items|None}}") self.assertEqual(10, x) def test12_Empty_filter_pass_through(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) x = cfg.interpolate_variables("{{intl.cache.items|Empty}}") self.assertEqual(10, x) x = cfg.interpolate_variables("{{intl.cache.items|Empty}}") self.assertEqual(10, x) def test12a_Empty_filter_pass_through_without_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) cfg.disable_cache() x = cfg.interpolate_variables("{{intl.cache.items|Empty}}") self.assertEqual(10, x) x = cfg.interpolate_variables("{{intl.cache.items|Empty}}") self.assertEqual(10, x) def test13_keyerror(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises(KeyError, cfg.getvar_s, "non.existing.key") self.assertRaises(KeyError, cfg.getvar_s, "non.existing.key") def test13a_keyerror_without_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) cfg.disable_cache() self.assertRaises(KeyError, cfg.getvar_s, "non.existing.key") self.assertRaises(KeyError, cfg.getvar_s, "non.existing.key") def test14_getvar_with_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual("999", cfg.getvar("non.existing.key", default="999")) def test14_getvar_with_original_default(self): # The default must be the original and not a copy dflt = {"foo": "bar"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvar("non.existing.key", default=dflt) is dflt) def test15_getvar_s_with_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual("999", cfg.getvar_s("non.existing.key", default="999")) self.assertEqual("999", cfg.getvar_s("non.existing.key", default="999")) def test15a_getvar_s_with_default_without_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) cfg.disable_cache() self.assertEqual("999", cfg.getvar_s("non.existing.key", default="999")) self.assertEqual("999", cfg.getvar_s("non.existing.key", default="999")) def test15_getvar_s_with_original_default(self): # The default must be the original and not a copy dflt = {"foo2": "bar2"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvar_s("non.existing.key", default=dflt) is dflt) def test15_getvar_s_substituting_error_with_original_default(self): # The default must be the original and not a copy dflt = {"foo22": "bar22"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) # exists ... cfg.getvar(u"intl.localedir") # ... but cannot interpolated self.assertTrue(cfg.getvar_s(u"intl.localedir", default=dflt) is dflt) def test15b_getvarl_with_original_default(self): # The default must be the original and not a copy dflt = {"foo2": "bar2"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvarl(u"non", u"existing", u"key", default=dflt) is dflt) def test15c_getvarl_s_with_original_default(self): # The default must be the original and not a copy dflt = {"foo3": "bar3"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvarl_s(u"non", u"existing", u"key4", default=dflt) is dflt) def test15d_getvarl_s_substituting_error_with_original_default(self): dflt = {"foo4": "bar4"} cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) # key exists ... cfg.getvarl(u"intl", u"localedir") # ... but cannot interpolated self.assertTrue(cfg.getvarl_s(u"intl", u"localedir", default=dflt) is dflt) def test16_getintvar_s_with_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual(9999, cfg.getintvar_s("non.existing.key", default=9999)) def test17_getintvar_s_with_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertFalse(cfg.getboolvar_s("non.existing.key", default=u('false'))) def test18_getfirstvar_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises( KeyError, cfg.getfirstvar, "db.non.existing.key", "db.non.existing.key2") def test19_getfirstvar_nonexisting_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertIsNone(cfg.getfirstvar("db.non.existing.key", "db.non.existing.key2", "intl.non.existing", default=None)) def test20_getfirstvar_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual("test-configmix", cfg.getfirstvar("intl.domain")) self.assertEqual("test-configmix", cfg.getfirstvar("intl.domain", "intl.fallback")) self.assertEqual("de", cfg.getfirstvar("intl.fallback", "intl.domain", default=None)) self.assertEqual("de", cfg.getfirstvar("intl.non.existing", "intl.fallback", default=None)) def test20a_getfirstvar_existing_without_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) cfg.disable_cache() self.assertEqual("test-configmix", cfg.getfirstvar("intl.domain")) self.assertEqual("test-configmix", cfg.getfirstvar("intl.domain", "intl.fallback")) self.assertEqual("de", cfg.getfirstvar("intl.fallback", "intl.domain", default=None)) self.assertEqual("de", cfg.getfirstvar("intl.non.existing", "intl.fallback", default=None)) def test21_getfirstvar_s_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvar_s("intl.non.existing", "intl.localedir")) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvar_s("intl.localedir", "intl.non.existing")) def test22_getfirstvar_s_non_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertIsNone( cfg.getfirstvar_s("intl.non.existing", "intl.non.existing2", default=None)) self.assertRaises( KeyError, cfg.getfirstvar_s, "intl.non.existing", "intl.non.existing2") def test22a_getfirstvar_s_non_existing_without_cache(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) cfg.disable_cache() self.assertIsNone( cfg.getfirstvar_s("intl.non.existing", "intl.non.existing2", default=None)) self.assertRaises( KeyError, cfg.getfirstvar_s, "intl.non.existing", "intl.non.existing2") def test23_getfirstintvar_s_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertIsNone(cfg.getfirstintvar_s("db.non.existing.key", "db.non.existing.key2", "intl.non.existing", default=None)) self.assertRaises( KeyError, cfg.getfirstintvar_s, "db.non.existing.key", "db.non.exksting.key2", "intl.non.existing") def test23_getfirstintvar_s_nonexisting_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual(20, cfg.getfirstintvar_s("db.non.existing.key", "db.non.existing.key2", "intl.non.existing", default=u("20"))) self.assertEqual(30, cfg.getfirstintvar_s("db.non.existing.key", "db.non.existing.key2", "intl.non.existing", default=30)) self.assertRaises( KeyError, cfg.getfirstintvar_s, "db.non.existing.key", "db.non.exksting.key2", "intl.non.existing") def test24_getfirstintvar_s_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual(10, cfg.getfirstintvar_s("db.non.existing.key", "intl.cache.items", "db.non.existing.key2", default=u("20"))) def test25_getfirstboolvar_s_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertFalse( cfg.getfirstboolvar_s("db.non.existing.key", "db.non.existing.key2", "db.engines.rw.no-echo", default=u("false"))) self.assertTrue( cfg.getfirstboolvar_s("db.non.existing.key", "db.non.existing.key2", "db.engines.rw.no-echo", default=True)) self.assertRaises( KeyError, cfg.getfirstboolvar_s, "db.non.existing.key", "db.non.exksting.key2", "b.engines.rw.no-echo") def test26_getfirstboolvar_s_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertFalse( cfg.getfirstboolvar_s("db.non.existing.key", "db.engines.rw.echo", "db.non.existing.key2", default=u("true"))) def test27_getfirstvarl_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises( KeyError, cfg.getfirstvarl, *[["db", "non", "existing", "key"], ("db", "non", "existing", "key2")]) def test27b_getfirstvarl_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises( KeyError, cfg.getfirstvarl, *[{"namespace": None, "path": ["db", "non", "existing", "key"]}, {"namespace": None, "path": ["db", "non", "existing", "key2"]}]) def test28_getfirstvarl_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertIsNone(cfg.getfirstvarl( *[["db", "non", "existing", "key"], ("db", "non", "existing", "key2")], default=None)) def test28b_getfirstvarl_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertIsNone(cfg.getfirstvarl( *[{"namespace": None, "path": ["db", "non", "existing", "key"]}, {"namespace": None, "path": ("db", "non", "existing", "key2")}], default=None)) def test29_getfirstvarl_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( "test-configmix", cfg.getfirstvarl(*(("intl", "domain"),))) self.assertEqual( "test-configmix", cfg.getfirstvarl(*(("intl", "domain"), ("intl", "fallback")))) self.assertEqual( "de", cfg.getfirstvarl(*[["intl", "fallback"], ["intl", "domain"]], default=None)) self.assertEqual( "de", cfg.getfirstvarl(*[["intl", "non", "existing"], ["intl", "fallback"]], default=None)) def test29b_getfirstvarl_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( "test-configmix", cfg.getfirstvarl(*({"namespace": None, "path": ("intl", "domain")},))) self.assertEqual( "test-configmix", cfg.getfirstvarl(*({"namespace": None, "path": ("intl", "domain")}, {"namespace": None, "path": ("intl", "fallback")}))) self.assertEqual( "de", cfg.getfirstvarl(*[{"namespace": None, "path": ["intl", "fallback"]}, {"namespace": None, "path": ["intl", "domain"]}], default=None)) self.assertEqual( "de", cfg.getfirstvarl(*[{"namespace": None, "path": ["intl", "non", "existing"]}, {"namespace": None, "path": ["intl", "fallback"]}], default=None)) def test30_getfirstvarl_s_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvarl_s(*[["intl", "non", "existing"], ["intl", "localedir"]])) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvarl_s(*[["intl", "localedir"], ["intl", "non", "existing"]])) def test30b_getfirstvarl_s_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvarl_s(*[{"namespace": None, "path": ["intl", "non", "existing"]}, {"namespace": None, "path": ["intl", "localedir"]}])) self.assertEqual( os.getcwd()+"/locale", cfg.getfirstvarl_s(*[{"namespace": None, "path": ["intl", "localedir"]}, {"namespace": None, "path": ["intl", "non", "existing"]}])) def test31_getfirstvar_s_non_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertIsNone( cfg.getfirstvarl_s( *[["intl", "non", "existing"], ["intl", "non", "existing2"]], default=None)) self.assertRaises( KeyError, cfg.getfirstvarl_s, ["intl" ,"non", "existing"], ["intl", "non", "existing2"]) def test31b_getfirstvar_s_non_existing(self): cfg = self._load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml")) self.assertIsNone( cfg.getfirstvarl_s( *[{"namespace": None, "path": ["intl", "non", "existing"]}, {"namespace": None, "path": ["intl", "non", "existing2"]}], default=None)) self.assertRaises( KeyError, cfg.getfirstvarl_s, {"namespace": None, "path": ["intl" ,"non", "existing"]}, {"namespace": None, "path": ["intl", "non", "existing2"]}) def test32_getfirstintvarl_s_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertIsNone(cfg.getfirstintvarl_s( *(("db", "non", "existing", "key"), ("db", "non", "existing", "key2"), ("intl", "non", "existing")), default=None)) self.assertRaises( KeyError, cfg.getfirstintvarl_s, ("db", "non", "existing", "key"), ("db", "non", "exksting", "key2"), ("intl", "non", "existing")) def test33_getfirstintvarl_s_nonexisting(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( 20, cfg.getfirstintvarl_s( *(("db", "non", "existing", ".key"), ("db", "non", "existing", "key2"), ("intl", "non", "existing")), default=u("20"))) self.assertEqual( 30, cfg.getfirstintvarl_s( *(("db", "non", "existing", "key"), ("db", "non", "existing", "key2"), ("intl", "non", "existing")), default=30)) self.assertRaises( KeyError, cfg.getfirstintvarl_s, ("db", "non", "existing", "key"), ("db", "non", "exksting", "key2"), ("intl", "non", "existing")) def test34_getfirstintvarl_s_existing(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( 10, cfg.getfirstintvarl_s( *(("db", "non", "existing", "key"), ("intl", "cache", "items"), ("db", "non", "existing", "key2")), default=u("20"))) def test35_keysl(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( set([u"domain", u"localedir", u"fallback", u"cache",]), set(cfg.getkeysl(u"intl"))) def test36_keys(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( set([u"name", u"pwd"]), set(cfg.getkeys(u"db.user"))) def test37_get_root_object(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvarl() is cfg) def test38_get_root_object(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvar(u"") is cfg) def test39_get_root_keys(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertEqual( set([u"key1", u"key2", u"tree1"]), set(cfg.getkeys(u""))) def test39b_get_root_keys(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertEqual( set([u"key1", u"key2", u"tree1"]), set(cfg.getkeysl())) def test40_contains_with_string(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertTrue(u"tree1" in cfg) self.assertFalse(u"non-existing-tree1" in cfg) def test41_contains_with_path(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertTrue((u"tree1", u"tree2") in cfg) self.assertFalse((u"tree1", u"non-existing-tree2") in cfg) def test43_get_with_string(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertEqual( u"in the root namespace", cfg.get(u"key1")) self.assertTrue( cfg.get(u"key1-not", default=None) is None) def test43_get_with_path(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) self.assertEqual( 0x20, cfg.get((u"tree1", u"key3"))) self.assertEqual( 0x1, cfg.get((u"no", u"key"), default=0x1)) def test44_iterator(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) s = [] for k in cfg: s.append(k) s.sort() self.assertEqual([u"key1", u"key2", u"tree1"], s) def test45_clear_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.py")) cfg.clear_cache() def test46_reenable_cache(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertTrue(cfg.getvarl() is cfg) cfg.disable_cache() self.assertTrue(cfg.getvarl() is cfg) cfg.clear_cache() self.assertTrue(cfg.getvarl() is cfg) cfg.enable_cache() self.assertTrue(cfg.getvarl() is cfg) def test47_indexed_access_to_lists(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) for i in range(4): self.assertEqual( i, cfg.getvarl_s(u"test", u"List", i)) def test48_indexed_access_to_lists(self): cfg = self._load(os.path.join(TESTDATADIR, "conf20.yml")) for i in range(4): self.assertEqual( i, cfg.getvar_s(u"test.List.~%d~" % (i, ))) def test49_index_access_to_lists_with_subdicts(self): cfg = self._load(os.path.join(TESTDATADIR, "index-access-for-jails.yml")) for idx in range(len(cfg.getvarl(u"the-list"))): self.assertEqual( idx, cfg.getvarl_s(u"the-list", idx, u"entry")) def test50_index_access_to_lists_with_subdicts(self): cfg = self._load(os.path.join(TESTDATADIR, "index-access-for-jails.yml")) for idx in range(len(cfg.getvarl(u"the-list"))): self.assertEqual( idx, cfg.getvar_s(u"the-list.~%d~.entry" % (idx, ))) def test51_neg_index_access_to_lists_with_subdicts(self): cfg = self._load(os.path.join(TESTDATADIR, "index-access-for-jails.yml")) self.assertEqual( 2, cfg.getvarl_s(u"the-list", -1, u"entry")) def test52_neg_index_access_to_lists_with_subdicts(self): cfg = self._load(os.path.join(TESTDATADIR, "index-access-for-jails.yml")) self.assertEqual( 2, cfg.getvar_s(u"the-list.~%d~.entry" % (-1, ))) def test53_expand_an_indexed_substitution(self): cfg = self._load(os.path.join(TESTDATADIR, "index-access-for-jails.yml")) self.assertEqual(1, cfg.getvar_s(u"expand-me")) self.assertEqual(2, cfg.getvar_s(u"expand-me-2")) def test54_list_merge_replaces_by_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10.yml")) self.assertEqual([u"val1", u"val2", u"in the root namespace"], cfg.getvarl_s(u"tree1", u"tree2", u"key8")) def test55_list_merge_extend(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10.yml"), merge_lists="extend") self.assertEqual([u"val1", u"val2", u"in the root namespace", u"val1", u"val2", u"in the root namespace"], cfg.getvarl_s(u"tree1", u"tree2", u"key8")) def test56_list_merge_wrong_param(self): try: self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10.yml"), merge_lists="__unknown-merge-strategy__") except ValueError: pass else: self.fail("Should have thrown a `ValueError' exception") def test57_list_merge_extend(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10_list_extend.yml"), merge_lists="extend") self.assertEqual([u"val1", u"val2", u"in the root namespace", u"val4", u"val5", u"val6"], cfg.getvarl_s(u"tree1", u"tree2", u"key8")) def test58_list_merge_prepend(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10_list_extend.yml"), merge_lists="prepend") self.assertEqual([u"val4", u"val5", u"val6", u"val1", u"val2", u"in the root namespace",], cfg.getvarl_s(u"tree1", u"tree2", u"key8")) def test59_list_merge_default(self): cfg = self._load(os.path.join(TESTDATADIR, "conf10.toml"), os.path.join(TESTDATADIR, "conf10_list_extend.yml")) self.assertEqual([u"val4", u"val5", u"val6",], cfg.getvarl_s(u"tree1", u"tree2", u"key8")) class T02LoadAndMerge(_T02MixinLoadAndMerge, unittest.TestCase): def setUp(self): self._load = configmix.load def test0100_identity(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) cfg2 = configmix.merge(cfg, None) self.assertEqual(id(cfg), id(cfg2)) def test0101_identity(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) cfg2 = configmix.merge(cfg, {}) self.assertEqual(id(cfg), id(cfg2)) class T03SafeLoadAndMerge(_T02MixinLoadAndMerge, unittest.TestCase): def setUp(self): self._load = configmix.safe_load def test0100_deepcopy(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) cfg2 = configmix.safe_merge(cfg, None) self.assertNotEqual(id(cfg), id(cfg2)) def test0101_deepcopy(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) cfg2 = configmix.safe_merge(cfg, {}) self.assertNotEqual(id(cfg), id(cfg2)) class T04CustomExtension(unittest.TestCase): def setUp(self): self._reset() def tearDown(self): self._reset() def _reset(self): configmix.clear_assoc() for pat, fmode in configmix.DEFAULT_ASSOC: configmix.set_assoc(pat, fmode) def test01_additional(self): configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml")) cfg = configmix.load( os.path.join(TESTDATADIR, "conf1.ini"), os.path.join(TESTDATADIR, "conf30.conf")) self.assertEqual(u("Umlaute: ÄÖÜäöüß"), cfg.getvar_s("key7")) self.assertEqual(u("new value"), cfg.getvar_s("key-new")) def test02_only_style_wrong_style(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml")) def _ld(): return configmix.load(os.path.join(TESTDATADIR, "conf1.ini"), os.path.join(TESTDATADIR, "conf30.conf")) self.assertRaises(ValueError, _ld) def test02_ignore_one_style(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml")) configmix.set_assoc("*", "-*-ignore-*-", append=True) cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"), os.path.join(TESTDATADIR, "conf30.conf")) self.assertEqual(u("new value"), cfg.getvar_s("key-new")) self.assertRaises(KeyError, cfg.getvar_s, "key1") def test02_ignore_all(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml")) # This inserts at index 0 effectively ignoring all configuration files! configmix.set_assoc("*", "-*-ignore-*-") cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini"), os.path.join(TESTDATADIR, "conf30.conf")) self.assertRaises(KeyError, cfg.getvar_s, "key-new") self.assertRaises(KeyError, cfg.getvar_s, "key1") def test03_only_style_corrrect_style(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.get_default_assoc("*.yml")) cfg = configmix.load(os.path.join(TESTDATADIR, "conf30.conf")) self.assertEqual(u("new value"), cfg.getvar_s("key-new")) def _g(): return cfg.getvar_s("key7") self.assertRaises(KeyError, _g) def test04_determine_mode(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.try_determine_filemode) cfg = configmix.load(os.path.join(TESTDATADIR, "conf30.conf")) self.assertEqual(u("new value"), cfg.getvar_s("key-new")) self.assertRaises(KeyError, cfg.getvar_s, "key7") def test05_try_determine_mode_none(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.try_determine_filemode) def _ld(): return configmix.load(os.path.join(TESTDATADIR, "no-mode.conf")) self.assertRaises(ValueError, _ld) def test06_try_determine_mode_unknown(self): configmix.clear_assoc() configmix.set_assoc("*.conf", configmix.try_determine_filemode) def _ld(): return configmix.load(os.path.join(TESTDATADIR, "unknown-mode.conf")) self.assertRaises(KeyError, _ld) class T05SubstituteExpand(unittest.TestCase): def setUp(self): self._reset() def tearDown(self): self._reset() def _reset(self): configmix.clear_assoc() for pat, fmode in configmix.DEFAULT_ASSOC: configmix.set_assoc(pat, fmode) def test01_expand_int_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual(2, cfg.getvar_s("key100")) def test01_expand_int_ini_l(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual(2, cfg.getvarl_s("key100")) def test02_expand_int_indirect_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual(2, cfg.getvar_s("key102")) def test02_expand_int_indirect_ini_l(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual(2, cfg.getvarl_s("key102")) def test03_expand_int2str_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual("the 2 value", cfg.getvar_s("key101")) def test03_expand_int2str_ini_l(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual("the 2 value", cfg.getvarl_s("key101")) def test04_expand_intint2str_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual("22", cfg.getvar_s("key103")) def test04_expand_intint2str_ini_l(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual("22", cfg.getvarl_s("key103")) def test05_expand_falsy_values(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual( u"AFalseB0C", cfg.getvar_s("test-falsy-values.v")) class T06References(unittest.TestCase): def setUp(self): self._reset() self._cfg = configmix.load( os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml"), os.path.join(TESTDATADIR, "reference-style.yml")) def tearDown(self): self._reset() def _reset(self): configmix.clear_assoc() for pat, fmode in configmix.DEFAULT_ASSOC: configmix.set_assoc(pat, fmode) def test01_reference_without_expansions(self): self.assertTrue(isinstance(self._cfg.getvar("wsgi.profiler"), dict)) self.assertTrue(isinstance( self._cfg.getvar("wsgi.profiler.params"), dict)) self.assertEqual("werkzeug", self._cfg.getvar("wsgi.profiler.params.type")) self.assertTrue(self._cfg.getvar("wsgi.profiler.params.params.evalex")) self.assertEqual(self._cfg.getvar("wsgi.debugger"), self._cfg.getvar("wsgi.profiler.params")) def test01_reference_without_expansions_l(self): self.assertTrue(isinstance(self._cfg.getvarl("wsgi", "profiler"), dict)) self.assertTrue(isinstance( self._cfg.getvarl("wsgi", "profiler", "params"), dict)) self.assertEqual( "werkzeug", self._cfg.getvarl("wsgi", "profiler", "params", "type")) self.assertTrue(self._cfg.getvarl( "wsgi", "profiler", "params", "params", "evalex")) self.assertEqual(self._cfg.getvarl("wsgi", "debugger"), self._cfg.getvarl("wsgi", "profiler", "params")) def test02_reference__with_expansions(self): self.assertTrue(isinstance(self._cfg.getvar_s("wsgi.profiler"), dict)) self.assertTrue(isinstance( self._cfg.getvar_s("wsgi.profiler.params"), dict)) self.assertTrue( self._cfg.getvar_s("wsgi.profiler.params.params.evalex")) self.assertEqual("werkzeug", self._cfg.getvar_s("wsgi.profiler.params.type")) def test02_reference__with_expansions_l(self): self.assertTrue(isinstance( self._cfg.getvarl_s("wsgi", "profiler"), dict)) self.assertTrue(isinstance( self._cfg.getvarl_s("wsgi", "profiler", "params"), dict)) self.assertTrue( self._cfg.getvarl_s("wsgi", "profiler", "params", "params", "evalex")) self.assertEqual( "werkzeug", self._cfg.getvarl_s("wsgi", "profiler", "params", "type")) def test03_direct_attribute_access_to_expanded_references(self): self.assertEqual( u"werkzeug", self._cfg.wsgi.profiler.params.type) def test03b_dict_like_access_expands_references(self): self.assertEqual( u"werkzeug", self._cfg[(u"wsgi", u"profiler", u"params", u"type")]) def test03c_dict_like_access_with_single_string_key(self): self.assertTrue( u"profiler" in self._cfg[u"wsgi"]) def test04_indirect_recursive_references(self): self.assertEqual( "werkzeug", self._cfg.getvar_s("testref.here.params.type")) self.assertTrue( self._cfg.getvar_s("testref.here.params.params.evalex")) def test04_indirect_recursive_references_l(self): self.assertEqual( "werkzeug", self._cfg.getvarl_s("testref", "here", "params", "type")) self.assertTrue( self._cfg.getvarl_s("testref", "here", "params", "params", "evalex")) def test05_recursive_expansion(self): c = self._cfg.getvar_s("testref") self.assertTrue(c["here"]["params"]["params"]["evalex"]) def test05_recursive_expansion_l(self): c = self._cfg.getvarl_s("testref") self.assertTrue(c["here"]["params"]["params"]["evalex"]) def test06_no_recursive_expansion_in_getvar_parents(self): v = self._cfg.getvar("wsgi.profiler") self.assertEqual( "{{ref:#wsgi.debugger}}", v["params"]) def test06_no_recursive_expansion_in_getvar_parents_l(self): v = self._cfg.getvarl("wsgi", "profiler") self.assertEqual( "{{ref:#wsgi.debugger}}", v["params"]) def test07_explicit_reference_expansion(self): v = self._cfg.getvar("wsgi.profiler") self.assertTrue(isinstance(self._cfg.expand_if_reference(v["params"]), dict)) def test07_explicit_reference_expansion_l(self): v = self._cfg.getvarl("wsgi", "profiler") self.assertTrue(isinstance(self._cfg.expand_if_reference(v["params"]), dict)) def test08_explicit_indirect_expansion_through_value(self): v = self._cfg.getvar_s("expand-ref-value.key0") self.assertTrue(isinstance(v, bool)) self.assertTrue(v) # but not that .getvar does not **not** v2 = self._cfg.getvar("expand-ref-value.key0") self.assertEqual("{{testref.here.params.params.evalex}}", v2) def test08_explicit_indirect_expansion_through_value_l(self): v = self._cfg.getvarl_s("expand-ref-value", "key0") self.assertTrue(isinstance(v, bool)) self.assertTrue(v) # but not that .getvar does not **not** v2 = self._cfg.getvarl("expand-ref-value", "key0") self.assertEqual("{{testref.here.params.params.evalex}}", v2) class T07Quoting(unittest.TestCase): def setUp(self): self._reset() self._cfg = configmix.load(os.path.join(TESTDATADIR, "quoting.yml")) def tearDown(self): self._reset() def _reset(self): configmix.clear_assoc() for pat, fmode in configmix.DEFAULT_ASSOC: configmix.set_assoc(pat, fmode) def test_getvar(self): self.assertEqual( "value", self._cfg.getvar("%x23%x3a%x7c%x25%x2e.%x2e.%x3a.%x25.%x7c./.%x23")) self.assertEqual( "value", self._cfg.getvar( "%u0023%u003a%u007c%u0025%u002e.%u002e.%u003a.%u0025.%u007c./.%u0023")) self.assertEqual( "value", self._cfg.getvar( "%U00000023%U0000003a%U0000007c%U00000025%U0000002e.%U0000002e.%U0000003a.%U00000025.%U0000007c./.%U00000023")) def test_getvar_s(self): self.assertEqual( "value", self._cfg.getvar_s("%x23%x3a%x7c%x25%x2e.%x2e.%x3a.%x25.%x7c./.%x23")) self.assertEqual( "value", self._cfg.getvar_s( "%u0023%u003a%u007c%u0025%u002e.%u002e.%u003a.%u0025.%u007c./.%u0023")) self.assertEqual( "value", self._cfg.getvar_s( "%U00000023%U0000003a%U0000007c%U00000025%U0000002e.%U0000002e.%U0000003a.%U00000025.%U0000007c./.%U00000023")) def test_getvarl(self): self.assertEqual( "value", self._cfg.getvarl("#:|%.", ".", ":", "%", "|", "/", "#")) def test_getvarl_s(self): self.assertEqual( "value", self._cfg.getvarl_s("#:|%.", ".", ":", "%", "|", "/", "#")) def test_interpolation1(self): self.assertEqual( "value", self._cfg.getvarl_s("events", "qc-2021.1-5G-summit", "xname")) def test_interpolation2(self): self.assertEqual( "value", self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xname")) def test_reference1(self): self.assertTrue( isinstance( self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xref"), dict)) def test_reference2(self): self.assertEqual( "value", self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xref.%x23")) def test_namespace_quoting(self): v1 = self._cfg.getvar("PY:version") v2 = self._cfg.getvar("P%x59:version") v3 = self._cfg.getvar("%U00000050Y:version") v4 = self._cfg.getvar("%x50%u0059:version") v5 = self._cfg.getvarl_s("events", "qc-2021.1-5G-summit", "xver") v6 = self._cfg.getvar_s("events.qc-2021%x2e1-5G-summit.xver") self.assertEqual(v1, v2) self.assertEqual(v1, v3) self.assertEqual(v1, v4) self.assertEqual(v1, v5) self.assertEqual(v1, v6) def test_direct_ref_namespace_quoting(self): v = self._cfg.getvar_s("re%x66:#%x23%u003a%x7c%U00000025%x2e.%x2e.%x3a.%x25.%x7c./.%x23") self.assertEqual("value", v) class T08Jailed(unittest.TestCase): def setUp(self): pass def tearDown(self): self._reset() def _reset(self): configmix.clear_assoc() for pat, fmode in configmix.DEFAULT_ASSOC: configmix.set_assoc(pat, fmode) def test_root(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"tree1") self.assertTrue(jcfg.getvarl(u"tree2", u"key5")) self.assertTrue(jcfg.getvarl_s(u"tree2", u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl(u"tree2", u"key4")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl_s(u"tree2", u"key4")) self.assertTrue(jcfg.getvar(u"tree2.key5")) self.assertTrue(jcfg.getvar_s(u"tree2.key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar(u"tree2.key4")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar_s(u"tree2.key4")) def test_root2(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"tree1.tree2") self.assertTrue(jcfg.getvarl(u"key5")) self.assertTrue(jcfg.getvarl_s(u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl(u"key4")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl_s(u"key4")) self.assertTrue(jcfg.getvar(u"key5")) self.assertTrue(jcfg.getvar_s(u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar(u"key4")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar_s(u"key4")) def test_root_non_existing_raises(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) self.assertRaises(KeyError, cfg.jailed, root=u"tree-non-existing") self.assertRaises( KeyError, cfg.jailed, rootpath=(u"non", u"existing", u"tree")) def test_rootpath(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=[u"tree1"]) self.assertTrue(jcfg.getvarl(u"tree2", u"key5")) self.assertTrue(jcfg.getvarl_s(u"tree2", u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl_s(u"tree2", u"key4")) self.assertTrue(jcfg.getvar(u"tree2.key5")) self.assertTrue(jcfg.getvar_s(u"tree2.key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar_s(u"tree2.key4")) def test_rootpath_non_existing_raises(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) self.assertRaises( KeyError, cfg.jailed, rootpath=[u"tree-non-existing"]) def test_root_empty(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"") self.assertFalse(jcfg._path) self.assertFalse(jcfg._pathstr) self.assertTrue(jcfg._path is not None) self.assertTrue(jcfg._pathstr is not None) self.assertTrue(jcfg.getvarl(u"tree1", u"tree2", u"key5")) self.assertTrue(jcfg.getvarl_s(u"tree1", u"tree2", u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl_s(u"tree1", u"tree2", u"key4")) self.assertTrue(jcfg.getvar(u"tree1.tree2.key5")) self.assertTrue(jcfg.getvar_s(u"tree1.tree2.key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar_s(u"tree1.tree2.key4")) def test_rootpath_empty(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=tuple()) self.assertFalse(jcfg._path) self.assertFalse(jcfg._pathstr) self.assertTrue(jcfg._path is not None) self.assertTrue(jcfg._pathstr is not None) self.assertTrue(jcfg.getvarl(u"tree1", u"tree2", u"key5")) self.assertTrue(jcfg.getvarl_s(u"tree1", u"tree2", u"key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvarl_s(u"tree1", u"tree2", u"key4")) self.assertTrue(jcfg.getvar(u"tree1.tree2.key5")) self.assertTrue(jcfg.getvar_s(u"tree1.tree2.key5")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getvar_s(u"tree1.tree2.key4")) def test_rootpath_getfirstvar_nonexisting(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertIsNone(jcfg.getfirstvarl( *[(u"a", u"b"), (u"tree2", u"no-key")], default=None)) self.assertIsNone(jcfg.getfirstvarl_s( *[(u"a", u"b"), (u"tree2", u"no-key")], default=None)) self.assertIsNone(jcfg.getfirstvar( u"a.b", u"tree2.no-key", default=None)) self.assertIsNone(jcfg.getfirstvar_s( u"a.b", u"tree2.no-key", default=None)) def test_rootpath_getfirstvar_raising(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertRaises( KeyError, jcfg.getfirstvarl, (u"a", u"b"), (u"tree2", u"no-key")) self.assertRaises( KeyError, jcfg.getfirstvarl_s, (u"a", u"b"), (u"tree2", u"no-key")) self.assertRaises( KeyError, jcfg.getfirstvar, u"a.b", u"tree2.no-key") self.assertRaises( KeyError, jcfg.getfirstvar_s, u"a.b", u"tree2.no-key") def test_rootpath_getfirstvar_existing(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getfirstvarl( *[(u"a", u"b"), (u"tree2", u"key4")])) self.assertEqual( 0x20, jcfg.getfirstvarl_s( *[(u"a", u"b"), (u"key3", ), (u"tree2", u"key4")])) self.assertEqual( 0x20, jcfg.getfirstvar( u"key1", u"key3")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg.getfirstvar_s( u"a.b", u"tree2.key4", u"tree2.key5")) def test_root_getfirstvar_nonexisting(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"tree1") self.assertIsNone(jcfg.getfirstvarl( *[(u"a", u"b"), (u"tree2", u"no-key")], default=None)) self.assertIsNone(jcfg.getfirstvarl_s( *[(u"a", u"b"), (u"tree2", u"no-key")], default=None)) self.assertIsNone(jcfg.getfirstvarl_s( *[(u"a", u"b"), (u"tree2", u"no-key")], default=None)) self.assertIsNone(jcfg.getfirstvar_s( u"a.b", u"tree2.no-key", default=None)) def test_root_getfirstvar_raising(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"tree1") self.assertRaises( KeyError, jcfg.getfirstvarl, (u"a", u"b"), (u"tree2", u"no-key")) self.assertRaises( KeyError, jcfg.getfirstvarl_s, (u"a", u"b"), (u"tree2", u"no-key")) self.assertRaises( KeyError, jcfg.getfirstvar, u"a.b", u"tree2.no-key") self.assertRaises( KeyError, jcfg.getfirstvar_s, u"a.b", u"tree2.no-key") def test_base_rebind(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) self.assertFalse(cfg.is_jail) jcfg = cfg.jailed(rootpath=[]) self.assertTrue(jcfg.is_jail) self.assertTrue(jcfg.base is cfg) self.assertRaises( KeyError, jcfg.getvarl, u"tree1", u"tree2", u"no-key") self.assertEqual( 0x20, jcfg.getvar(u"tree1.key3")) self.assertEqual( u"in the root namespace", jcfg.getvar("key1")) cfg2 = configmix.load(os.path.join(TESTDATADIR, "conf2.py")) self.assertFalse(cfg2.is_jail) jcfg.rebind(cfg2) self.assertTrue(jcfg.base is cfg2) self.assertRaises( KeyError, jcfg.getvar, u"tree1.key3") self.assertEqual( u"the next value", jcfg.getvar("key1")) def test_rebind_no_nesting(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) self.assertFalse(cfg.is_jail) jcfg1 = cfg.jailed(rootpath=[]) self.assertTrue(jcfg1.is_jail) jcfg2 = cfg.jailed(rootpath=[u"tree1"]) self.assertTrue(jcfg2.is_jail) self.assertRaises( TypeError, jcfg1.rebind, jcfg2) # base is not because rebind() failed self.assertTrue(cfg is jcfg1.base) def test_getbool(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2")) self.assertFalse(jcfg.getboolvar_s(u"key6")) self.assertEqual(u"off", jcfg.getvarl_s(u"key6")) self.assertTrue(jcfg.getvar_s(u"key6")) def test_subjail_from_rootpath_empty(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=tuple()) sjcfg = jcfg.jailed(rootpath=(u"tree1",)) self.assertTrue(sjcfg._path) self.assertTrue(sjcfg._pathstr) self.assertEqual(0x20, sjcfg.getintvar_s(u"key3")) self.assertTrue(sjcfg.base is cfg) def test_subjail_from_root_empty(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"") sjcfg = jcfg.jailed(root=u"tree1") self.assertTrue(sjcfg._path) self.assertTrue(sjcfg._pathstr) self.assertEqual(0x20, sjcfg.getintvar_s(u"key3")) self.assertTrue(sjcfg.base is cfg) def test_getkeys(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(root=u"tree1") self.assertEqual( set([u"key4", u"key5", u"key6", u"key7", u"key8", u"key9"]), set(jcfg.getkeysl(u"tree2"))) self.assertEqual( set([u"key4", u"key5", u"key6", u"key7", u"key8", u"key9"]), set(jcfg.getkeys(u"tree2"))) self.assertEqual( set([u"key3", u"tree2"]), set(jcfg.getkeysl())) def test_getkeys_all_empty_paths(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=tuple()) self.assertEqual( set([u"key1", u"key2", u"tree1"]), set(jcfg.getkeysl())) self.assertEqual( set([u"key1", u"key2", u"tree1"]), set(jcfg.getkeys(u""))) def test_repr_empty_rootpath(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=tuple()) self.assertEqual( r"_JailedConfiguration(rootpath=())", repr(jcfg)) def test_repr_non_empty_rootpath(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2")) if PY2: self.assertEqual( r"_JailedConfiguration(rootpath=(u'tree1', u'tree2'))", repr(jcfg)) else: self.assertEqual( r"_JailedConfiguration(rootpath=('tree1', 'tree2'))", repr(jcfg)) def test_dict_level_access_with_single_key(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2")) self.assertEqual( u"off", jcfg[u"key6"]) try: jcfg[u"key3"] except KeyError: pass else: self.fail("KeyError expected") def test_dict_level_access_with_path(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2")) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg[(u"key4",)]) self.assertEqual( u"get this as `tree1.tree2.key4'", jcfg[[u"key4"]]) try: jcfg[(u"key3",)] except KeyError: pass else: self.fail("KeyError expected") try: jcfg[[u"key3"]] except KeyError: pass else: self.fail("KeyError expected") def test_contains_with_string(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertTrue(u"key3" in jcfg) self.assertFalse(u"key3-not" in jcfg) def test_contains_with_path(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertTrue((u"key3",) in jcfg) self.assertFalse((u"key3-not",) in jcfg) self.assertTrue((u"tree2", u"key5") in jcfg) self.assertFalse((u"tree2", u"no-key") in jcfg) self.assertTrue([u"tree2", u"key5"] in jcfg) self.assertFalse([u"tree2", u"no-key"] in jcfg) def test_get_with_string(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertEqual( 0x20, jcfg.get(u"key3")) self.assertEqual( 0x2, jcfg.get(u"no-key3", default=0x2)) def test_get_with_path(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertEqual( 0x20, jcfg.get((u"key3",))) self.assertEqual( 0x3, jcfg.get((u"no-key",), default=0x3)) self.assertEqual( u"off", jcfg.get((u"tree2", u"key6"))) self.assertEqual( u"the default", jcfg.get((u"no", u"key"), default=u"the default")) self.assertTrue( jcfg.get((u"no", u"key")) is None) self.assertEqual( u"off", jcfg.get([u"tree2", u"key6"])) self.assertEqual( u"the default", jcfg.get([u"no", u"key"], default=u"the default")) self.assertTrue( jcfg.get([u"no", u"key"]) is None) def test_attribute_access(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) self.assertEqual(0x20, jcfg.key3) self.assertEqual(u"off", jcfg.tree2.key6) def test_attribute_access_interpolates(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) self.assertEqual( [u"val1", u"val2", u"in the root namespace"], cfg.tree1.tree2.key8) def test_attribute_access_non_existing(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) try: jcfg.non_existing except AttributeError: pass else: self.fail("AttributeError expected") try: jcfg.tree2.non_existing except AttributeError: pass else: self.fail("AttributeError expected") def test_iteration_dict(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1",)) s = [] for k in jcfg: s.append(k) s.sort() self.assertEqual([u"key3", u"tree2"], s) def test_iteration_list(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2", u"key8")) s = [] for k in jcfg: s.append(k) s.sort() self.assertEqual([u"in the root namespace", u"val1", u"val2"], s) def test_boolean_context_list_false(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2", u"key7")) self.assertFalse(jcfg) self.assertEqual(0, len(jcfg)) def test_boolean_context_list_true(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2", u"key8")) self.assertTrue(jcfg) self.assertEqual(3, len(jcfg)) def test_boolean_context_dict_false(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2", u"key9")) self.assertFalse(jcfg) self.assertEqual(0, len(jcfg)) def test_boolean_context_dict_true(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2")) self.assertTrue(jcfg) self.assertEqual(6, len(jcfg)) def test_list_by_index(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py")) jcfg = cfg.jailed(rootpath=(u"tree1", u"tree2", u"key8")) self.assertEqual(u"val1", jcfg[0]) self.assertEqual(u"val2", jcfg[1]) self.assertEqual(u"in the root namespace", jcfg[2]) def test_index_jail_access(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) for idx in range(len(cfg.getvarl(u"the-list"))): jcfg = cfg.jailed(rootpath=(u"the-list", idx)) self.assertEqual(1, len(jcfg)) self.assertEqual(idx, jcfg.getvarl_s(u"entry")) self.assertEqual((u"the-list", idx), jcfg._path) self.assertEqual(u"the-list.~%d~." % (idx, ), jcfg._pathstr) def test_index_subjail_access(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) jcfg = cfg.jailed(rootpath=(u"the-list",)) for idx in range(len(jcfg)): jcfg2 = jcfg.jailed(rootpath=(idx,)) self.assertEqual(1, len(jcfg2)) self.assertEqual(idx, jcfg2.getvarl_s(u"entry")) self.assertEqual((u"the-list", idx), jcfg2._path) self.assertEqual(u"the-list.~%d~." % (idx, ), jcfg2._pathstr) def test_direct_iter_jailed(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) testidx = -1 for jcfg2 in cfg.iter_jailed(rootpath=(u"the-list", )): testidx += 1 self.assertEqual(1, len(jcfg2)) self.assertEqual(testidx, jcfg2.getvarl_s(u"entry")) self.assertEqual((u"the-list", testidx), jcfg2._path) self.assertEqual(u"the-list.~%d~." % (testidx, ), jcfg2._pathstr) def test_iter_jailed(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) jcfg = cfg.jailed(rootpath=(u"the-list",)) testidx = -1 for jcfg2 in jcfg.iter_jailed(): testidx += 1 self.assertEqual(1, len(jcfg2)) self.assertEqual(testidx, jcfg2.getvarl_s(u"entry")) self.assertEqual((u"the-list", testidx), jcfg2._path) self.assertEqual(u"the-list.~%d~." % (testidx, ), jcfg2._pathstr) def test_negative_index_jail_access(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) jcfg = cfg.jailed(rootpath=(u"the-list", -1)) self.assertEqual(2, jcfg.getvarl_s("entry")) self.assertEqual((u"the-list", -1), jcfg._path) self.assertEqual(u"the-list.~-1~.", jcfg._pathstr) def test_index_jail_access_with_strpath(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) for idx in range(len(cfg.getvarl(u"the-list"))): jcfg = cfg.jailed(root=u"the-list.~%d~" % (idx, )) self.assertEqual(1, len(jcfg)) self.assertEqual(idx, jcfg.getvarl_s(u"entry")) self.assertEqual((u"the-list", idx), jcfg._path) self.assertEqual(u"the-list.~%d~." % (idx, ), jcfg._pathstr) def test_index_subjail_access_with_strpath(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml")) jcfg = cfg.jailed(root=u"the-list") for idx in range(len(jcfg)): jcfg2 = jcfg.jailed(root=u"~%d~" % (idx, )) self.assertEqual(1, len(jcfg2)) self.assertEqual(idx, jcfg2.getvarl_s(u"entry")) self.assertEqual((u"the-list", idx), jcfg2._path) self.assertEqual(u"the-list.~%d~." % (idx, ), jcfg2._pathstr) def test_referenced_root(self): cfg = configmix.load(os.path.join( TESTDATADIR, "jail-root-ref.yml")) jcfg = cfg.jailed(rootpath=("the-root", "ref1")) print(repr(jcfg.getvarl_s())) self.assertEqual("v3", jcfg.getvarl_s("ks")) def test_referenced_root_2(self): cfg = configmix.load(os.path.join( TESTDATADIR, "jail-root-ref.yml")) jcfg = cfg.jailed(rootpath=("the-root", "ref1")) print(repr(jcfg.getvarl_s())) self.assertEqual("v3", jcfg.getvarl_s("ks")) self.assertEqual("v1", jcfg.getvarl_s("k1")) def test_referenced_root_in_subjail(self): cfg = configmix.load(os.path.join( TESTDATADIR, "jail-root-ref.yml")) jcfg = cfg.jailed(rootpath=("the-root", "ref2")) jcfg2 = jcfg.jailed(rootpath=("sub-tree1",)) self.assertEqual("v6", jcfg2.getvarl_s("k6")) self.assertEqual("v3", jcfg2.getvarl_s("ks")) def test_jails_and_refs_tree(self): cfg = configmix.load(os.path.join( TESTDATADIR, "jail-root-ref.yml")) for flavour in ("access", "job"): tokcfg = cfg.jailed(rootpath=("realworld", "token", flavour)) self.assertEqual(-2, tokcfg.getintvar_s("nbf")) for idx, keysetcfg in enumerate( tokcfg.jailed(rootpath=("sign",)).iter_jailed()): self.assertEqual("key-%d" % (idx+1,), keysetcfg.getvarl_s("name")) self.assertEqual("something%d" % (idx+1,), keysetcfg.getvarl_s("type")) self.assertIsNone(keysetcfg.getvarl_s("data")) class _TParserMixin: def test_quote_and_unquote_empty(self): e = self.quote(u"") self.assertEqual(u"", e) self.assertEqual(u"", self.unquote(e)) def test_quoting_and_unquoting_are_inverse(self): for c in u"""%.:#|"'{}[]~""": qc = self.quote(c) self.assertTrue(qc.startswith(u"%x") and len(qc) == 4) self.assertEqual(c, self.unquote(qc)) def test_quoting_and_unquoting_are_inverse_all(self): c = u"""%.:#|"'{}[]~""" qc = self.quote(c) self.assertEqual(len(c)*4, len(qc)) self.assertEqual(c, self.unquote(qc)) def test_quoting_and_unquoting_are_identical(self): # other characters for c in configmix.config._QUOTE_SAFE: qc = self.quote(c) self.assertEqual(c, qc) self.assertEqual(c, self.unquote(qc)) def test_quoting_and_unquoting_are_identical_all(self): # other characters qc = self.quote(configmix.config._QUOTE_SAFE) self.assertEqual(configmix.config._QUOTE_SAFE, qc) self.assertEqual(configmix.config._QUOTE_SAFE, self.unquote(qc)) def test_quote_index_to_tilde(self): self.assertEqual(u"~4~", self.quote(4)) def test_unquote_index_with_tilde(self): self.assertEqual(4, self.unquote(u"~4~")) def test_unquote_empty_tilde(self): self.assertEqual(u"~~", self.unquote(u"~~")) def test_unquote_invalid_number_tilde(self): self.assertEqual(u"~0x4~", self.unquote(u"~0x4~")) def test_unquote_invalid_number_tilde_2(self): self.assertEqual(u"~\U00019001~", self.unquote(u"~%U00019001~")) def test_quote_unquote_indexes(self): for idx in range(0, 10000): self.assertEqual(idx, self.unquote(self.quote(idx))) def test_quote_unquote_negative_index(self): for idx in (-1, -2, -3): self.assertEqual(idx, self.unquote(self.quote(idx))) def test_index_overflow_border(self): self.assertEqual(32759, self.unquote(u"~32759~")) self.assertEqual(u"~32760~", self.unquote(u"~32760~")) def test_unquote_unimax(self): self.assertEqual(u"\U00019001", self.unquote(u"%U00019001")) self.assertEqual(u"X\U00019AF1Z", self.unquote(u"X%U00019aF1Z")) def test_unquote_base_plane(self): self.assertEqual(u"\uFFFF", self.unquote(u"%uffff")) self.assertEqual(u"X\uFFFFZ", self.unquote(u"X%uffffZ")) def test_unquote_latin(self): self.assertEqual(u"\xFF", self.unquote(u"%xff")) self.assertEqual(u"X\xFFZ", self.unquote(u"X%xffZ")) def test_unquote_zero(self): self.assertEqual(u"\x00", self.unquote(u"%x00")) self.assertEqual(u"X\x00Z", self.unquote(u"X%x00Z")) def test_unquote_adjacent_x(self): self.assertEqual(u"\x00\x01\xA0\xB0\xFF", self.unquote(u"%x00%x01%xA0%xB0%xFF")) def test_unquote_adjacent_u(self): self.assertEqual(u"\u0000\u0001\u00A0\uABCD\uFEFE", self.unquote(u"%u0000%u0001%u00A0%uabCD%ufeFE")) def test_unquote_adjacent_U(self): self.assertEqual( u"\U00000000\U00000001\U000000A0\U0001ABCD\U0001FEFE", self.unquote(u"%U00000000%U00000001%U000000A0%U0001abCD%U0001feFE")) def test_invalid_hex_digits(self): self.assertRaises( ValueError, self.unquote, u"%xgG") self.assertRaises( ValueError, self.unquote, u"%ugGGG") self.assertRaises( ValueError, self.unquote, u"%UgGGGgGGG") def test_invalid_too_short(self): self.assertRaises( ValueError, self.unquote, u"%x0") self.assertRaises( ValueError, self.unquote, u"%u000") self.assertRaises( ValueError, self.unquote, u"%U0000000") def test_invalid_too_short_no_sigil(self): self.assertRaises( ValueError, self.unquote, u"%") def test_empty_pathstr(self): # an empty path string returns an empty path tuple self.assertEqual(tuple(), self.pathstr2path(u"")) def test_split(self): p = self.pathstr2path(u"abc.def.hik.jkl") self.assertEqual((u"abc", u"def", u"hik", u"jkl"), p) def test_split_all_empty_parts(self): p = self.pathstr2path(u"....") self.assertEqual((u"", u"", u"", u"", u""), p) def test_split_all_empty_tail(self): p = self.pathstr2path(u"1.2.") self.assertEqual((u"1", u"2", u""), p) def test_split_unquote(self): p = self.pathstr2path(u"a%x2Eb.c%u002Ed.e%U0000002Ef") self.assertEqual((u"a.b", u"c.d", u"e.f"), p) def test_split_unquote_with_index(self): p = self.pathstr2path(u"a%x2Eb.~555~.c%u002Ed.e%U0000002Ef.~6~") self.assertEqual((u"a.b", 555, u"c.d", u"e.f", 6), p) def test_split_ns_empty(self): self.assertEqual((None, u""), self.split_ns(u"")) def test_split_ns_empty_parts(self): self.assertEqual((u"", u""), self.split_ns(u":")) def test_split_ns_no_ns(self): self.assertEqual((None, u"the-varname"), self.split_ns(u"the-varname")) def test_split_ns_non_quoted(self): self.assertEqual( (u"the-ns", "the-rest:with:colons|filter1|filter2"), self.split_ns(u"the-ns:the-rest:with:colons|filter1|filter2")) def test_split_ns_quoting(self): self.assertEqual((u":", u"%x3a"), self.split_ns(u"%x3a:%x3a")) def test_split_filters_empty(self): self.assertEqual((u"", []), self.split_filters(u"", 1)) def test_split_filters_varname_only_no_stripping(self): self.assertEqual((u" varname ", []), self.split_filters(u" varname ", 1)) def test_split_filters_single_no_stripping(self): self.assertEqual((u" the-varname ", []), self.split_filters(u" the-varname | ", 1)) def test_split_filters_one(self): self.assertEqual((u"the-varname", [u"None"]), self.split_filters(u"the-varname|None", 1)) def test_split_filters_many(self): self.assertEqual((u"the-varname", [u"Empty", u"None"]), self.split_filters(u"the-varname|Empty|None", 1)) def test_split_filters_many_alt(self): self.assertEqual((u"the-varname", [u"Empty", u"None"]), self.split_filters(u"the-varname|Empty,None", 1)) def test_split_filters_many_alt_preferred(self): # "," is preferred self.assertEqual((u"the-varname", [u"Empty|", u"None"]), self.split_filters(u"the-varname|Empty|,None", 1)) def test_None_filter_single(self): cfg = configmix.load() x = getattr(cfg, self.interpolate_meth)(u"{{non-existing|None}}") self.assertIsNone(x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"{{non-existing|None}}") self.assertIsNone(y) def test_None_filter_embedded(self): cfg = configmix.load() x = getattr(cfg, self.interpolate_meth)(u"A{{non-existing|None}}Z") self.assertEqual(u"AZ", x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"A{{non-existing|None}}Z") self.assertEqual(u"AZ", y) def test_Empty_filtersingle(self): cfg = configmix.load() x = getattr(cfg, self.interpolate_meth)(u"{{non-existing|Empty}}") self.assertEqual("", x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"{{non-existing|Empty}}") self.assertEqual("", y) def test_None_filter_pass_through(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) x = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|None}}") self.assertEqual(10, x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|None}}") self.assertEqual(10, y) def test_Empty_filter_pass_through(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) x = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|Empty}}") self.assertEqual(10, x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|Empty}}") self.assertEqual(10, y) def test_Empty_filter_no_pass_through_2(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf20.yml"), os.path.join(TESTDATADIR, "conf21.yml"), os.path.join(TESTDATADIR, "conf22.ini"), os.path.join(TESTDATADIR, "conf23.json"), os.path.join(TESTDATADIR, "conf24.toml")) x = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|Empty}}{{intl.cache.items}}") self.assertEqual(u"1010", x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"{{intl.cache.items|Empty}}{{intl.cache.items}}") self.assertEqual(u"1010", y) def test_interpolate_wrong_syntax(self): cfg = configmix.load() x1 = getattr(cfg, self.interpolate_meth)(u"{{the-variable}") self.assertEqual(u"{{the-variable}", x1) x2 = getattr(cfg, self.interpolate_meth)(u"A{{the-variable}Z") self.assertEqual(u"A{{the-variable}Z", x2) x3 = getattr(cfg, self.interpolate_meth)(u"A{{1{{2{{3}Z") self.assertEqual(u"A{{1{{2{{3}Z", x3) # caching should have no effect y1 = getattr(cfg, self.interpolate_meth)(u"{{the-variable}") self.assertEqual(u"{{the-variable}", y1) y2 = getattr(cfg, self.interpolate_meth)(u"A{{the-variable}Z") self.assertEqual(u"A{{the-variable}Z", y2) y3 = getattr(cfg, self.interpolate_meth)(u"A{{1{{2{{3}Z") self.assertEqual(u"A{{1{{2{{3}Z", y3) def test_interpolate_empty_str(self): cfg = configmix.load() x = getattr(cfg, self.interpolate_meth)(u"") self.assertEqual(u"", x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"") self.assertEqual(u"", y) def test_interpolate_no_interpolation(self): cfg = configmix.load() x = getattr(cfg, self.interpolate_meth)(u"no-interpolation-here") self.assertEqual(u"no-interpolation-here", x) # caching should have no effect y = getattr(cfg, self.interpolate_meth)(u"no-interpolation-here") self.assertEqual(u"no-interpolation-here", y) def test_single_load_removes_DEL_VALUE(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises( KeyError, cfg.getvar, u("not-deleted")) def test_single_safeload_removes_DEL_VALUE(self): cfg = configmix.safe_load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertRaises( KeyError, cfg.getvar, u("not-deleted")) def test_never_expanding_lone_DEL_VALUE(self): cfg = { u("key1"): u("{{::DEL::}}"), u("subkey2"): { u("key3"): u("{{::DEL::}}") } } cfg = configmix.config.Configuration(cfg) print(repr(cfg)) self.assertEqual(u("{{::DEL::}}"), cfg.getvar_s(u("key1"))) self.assertEqual(u("{{::DEL::}}"), cfg.getvar_s(u("subkey2.key3"))) def test_merge_does_never_expand(self): cfg1 = configmix.load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual(u("{{appdir}}/locale"), cfg1.getvar(u("intl.localedir"))) self.assertRaises( KeyError, cfg1.getvar_s, u("intl.localedir")) cfg2 = { u("process"): u("{{::DEL::}}"), u("intl"): { u("localedir"): u("{{appdir}}/other-locale"), u("cache"): u("{{::DEL::}}") } } cfg = configmix.merge(configmix.config.Configuration(cfg2), cfg1) self.assertEqual( u("{{appdir}}/other-locale"), cfg.getvar(u("intl.localedir"))) self.assertRaises( KeyError, cfg.getvar, u("process")) self.assertRaises( KeyError, cfg.getvar, u("intl.cache")) def test_safemerge_does_never_expand(self): cfg1 = configmix.safe_load(os.path.join(TESTDATADIR, "conf20.yml")) self.assertEqual(u("{{appdir}}/locale"), cfg1.getvar(u("intl.localedir"))) self.assertRaises( KeyError, cfg1.getvar_s, u("intl.localedir")) cfg2 = { u("process"): u("{{::DEL::}}"), u("intl"): { u("localedir"): u("{{appdir}}/other-locale"), u("cache"): u("{{::DEL::}}") } } cfg = configmix.safe_merge(configmix.config.Configuration(cfg2), cfg1) self.assertEqual( u("{{appdir}}/other-locale"), cfg.getvar(u("intl.localedir"))) self.assertRaises( KeyError, cfg.getvar, u("process")) self.assertRaises( KeyError, cfg.getvar, u("intl.cache")) def test_nested_filter_wrong_syntax(self): cfg = configmix.load() try: y = getattr(cfg, self.interpolate_meth)(u"{{|{{not-existing}}|None}}") except ValueError: pass else: self.fail("`ValueError' should have been raised") def test_nested_filter_None(self): cfg = configmix.load() y = getattr(cfg, self.interpolate_meth)(u"{{|{{not-existing}}|None|}}") self.assertTrue(y is None) def test_nested_filter_empty(self): cfg = configmix.load() y = getattr(cfg, self.interpolate_meth)(u"{{|{{not-existing}}|Empty|}}") self.assertEqual(u(""), y) def test_nested_nested_filter_empty(self): cfg = configmix.load() y = getattr(cfg, self.interpolate_meth)(u"{{|pre-{{not-existing|Empty}}-post|upper|}}") self.assertEqual(u("PRE--POST"), y) def test_nested_filter_upper(self): cfg1 = { u("key-1"): u("Value for key-1") } cfg = cfg = configmix.config.Configuration(cfg1) y = getattr(cfg, self.interpolate_meth)(u"{{|pre_{{key-1}}_post|upper|}}") self.assertEqual(u("PRE_VALUE FOR KEY-1_POST"), y) def test_nested_filter_normpath(self): p1 = u(os.path.join("a", "b", "c")) cfg1 = { u("path1"): p1, u("path2"): u("{{|{{path1}}/../d|normpath|}}") } cfg = cfg = configmix.config.Configuration(cfg1) np = cfg.getvarl_s(u("path2")) self.assertEqual( os.path.normpath(u(os.path.join("a", "b", "d"))), np) def test_nested_filter_normpath_posixpath(self): p1 = u(os.path.join("a", "b", "c")) cfg1 = { u("path1"): p1, u("path2"): u("{{|{{path1}}/../d|normpath,posixpath|}}") } cfg = cfg = configmix.config.Configuration(cfg1) np = cfg.getvarl_s(u("path2")) self.assertEqual( u("a/b/d"), np) def test_nested_filter_normpath_posixpath_2(self): p1 = u(os.path.join("a", "b", "C", "d")) cfg1 = { u("path1"): p1, u("path2"): u("{{|{{path1}}/../e|normpath,posixpath|}}") } cfg = cfg = configmix.config.Configuration(cfg1) np = cfg.getvarl_s(u("path2")) self.assertEqual( u("a/b/C/e"), np) def test_nested_filter_normpath_posixpath_upper(self): p1 = u(os.path.join("a", "b", "C", "d")) cfg1 = { u("path1"): p1, u("path2"): u("{{|{{path1}}/../e|normpath,posixpath,upper|}}") } cfg = cfg = configmix.config.Configuration(cfg1) np = cfg.getvarl_s(u("path2")) self.assertEqual( u("A/B/C/E"), np) class T09Parser(_TParserMixin, unittest.TestCase): def setUp(self): self.unquote = configmix.config.py_unquote self.quote = configmix.config.py_quote self.pathstr2path = configmix.config.py_pathstr2path self.split_ns = configmix.config._py_split_ns self.split_filters = configmix.config._py_split_filters self.interpolate_meth = "py_interpolate_variables" def test_split_ns_wrong_type(self): self.assertRaises( AttributeError, # no .partition self.split_ns, 1) def test_quote_wrong_type(self): self.assertRaises( AttributeError, # no .lstrip self.quote, 1.0) def test_unquote_wrong_type(self): self.assertRaises( TypeError, # argument of type "int" is not iterable self.unquote, 1) if configmix.config.fast_unquote is not None: class T10FastParser(_TParserMixin, unittest.TestCase): def setUp(self): self.unquote = configmix.config.fast_unquote self.quote = configmix.config.fast_quote self.pathstr2path = configmix.config.fast_pathstr2path self.split_ns = configmix.config._fast_split_ns self.split_filters = configmix.config._fast_split_filters self.interpolate_meth = "fast_interpolate_variables" def test_split_ns_wrong_type(self): self.assertRaises( TypeError, self.split_ns, b":") def test_quote_wrong_type(self): self.assertRaises( TypeError, self.quote, b":") def test_unquote_wrong_type(self): self.assertRaises( TypeError, self.unquote, b":") if __name__ == "__main__": unittest.main()
