Mercurial > hgrepos > Python > libs > ConfigMix
view tests/test.py @ 276:af371f9c016d
Allow deletion of key-value pairs when merging is done.
When encountering the "{{::DEL::}}" special value the corresponding key-value
pair is deleted.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 03 Oct 2020 17:11:41 +0200 |
| parents | 2a8dcab2de8c |
| children | 6a044778371a |
line wrap: on
line source
# -*- coding: utf-8 -*- import sys import os import unittest import platform import io sys.path.insert( 0, os.path.abspath( os.path.normpath(os.path.join(os.path.dirname(__file__), "..")))) import configmix import configmix.ini import configmix.yaml import configmix.json import configmix.py import configmix.toml from configmix.compat import u TESTDATADIR = os.path.join( os.path.abspath(os.path.dirname(__file__)), "data") 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) 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 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")) 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 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 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")) class T02LoadAndMerge(_T02MixinLoadAndMerge, unittest.TestCase): def setUp(self): self._load = configmix.load def test08_identity(self): cfg = configmix.ini.load(os.path.join(TESTDATADIR, "conf1.ini")) cfg2 = configmix.merge(cfg, None) self.assertEqual(id(cfg), id(cfg2)) def test09_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 test08_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 test09_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 test02_expand_int_indirect_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual(2, cfg.getvar_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 test04_expand_intint2str_ini(self): cfg = configmix.load(os.path.join(TESTDATADIR, "conf1.ini")) self.assertEqual("22", cfg.getvar_s("key103")) if __name__ == "__main__": unittest.main()
