1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
import ntpath
import os
import platform
import posixpath
import shutil
import tempfile
import unittest
from typing import ClassVar
import confuse
import confuse.yaml_util
DEFAULT = (platform.system, os.environ, os.path)
SYSTEMS = {
"Linux": ({"HOME": "/home/test", "XDG_CONFIG_HOME": "~/xdgconfig"}, posixpath),
"Darwin": ({"HOME": "/Users/test"}, posixpath),
"Windows": (
{
"APPDATA": "~\\winconfig",
"HOME": "C:\\Users\\test",
"USERPROFILE": "C:\\Users\\test",
},
ntpath,
),
}
def _touch(path):
open(path, "a").close()
class FakeHome(unittest.TestCase):
def setUp(self):
super().setUp()
self.home = tempfile.mkdtemp()
os.environ["HOME"] = self.home
os.environ["USERPROFILE"] = self.home
def tearDown(self):
super().tearDown()
shutil.rmtree(self.home)
class FakeSystem(unittest.TestCase):
SYS_NAME: ClassVar[str]
def setUp(self):
super().setUp()
self.os_path = os.path
os.environ = {} # type: ignore[assignment]
environ, os.path = SYSTEMS[self.SYS_NAME]
os.environ.update(environ)
platform.system = lambda: self.SYS_NAME
def tearDown(self):
super().tearDown()
platform.system, os.environ, os.path = DEFAULT
class LinuxTestCases(FakeSystem):
SYS_NAME = "Linux"
def test_both_xdg_and_fallback_dirs(self):
assert confuse.config_dirs() == [
"/home/test/.config",
"/home/test/xdgconfig",
"/etc/xdg",
"/etc",
]
def test_fallback_only(self):
del os.environ["XDG_CONFIG_HOME"]
assert confuse.config_dirs() == ["/home/test/.config", "/etc/xdg", "/etc"]
def test_xdg_matching_fallback_not_duplicated(self):
os.environ["XDG_CONFIG_HOME"] = "~/.config"
assert confuse.config_dirs() == ["/home/test/.config", "/etc/xdg", "/etc"]
def test_xdg_config_dirs(self):
os.environ["XDG_CONFIG_DIRS"] = "/usr/local/etc/xdg:/etc/xdg"
assert confuse.config_dirs() == [
"/home/test/.config",
"/home/test/xdgconfig",
"/usr/local/etc/xdg",
"/etc/xdg",
"/etc",
]
class OSXTestCases(FakeSystem):
SYS_NAME = "Darwin"
def test_mac_dirs(self):
assert confuse.config_dirs() == [
"/Users/test/.config",
"/Users/test/Library/Application Support",
"/etc/xdg",
"/etc",
]
def test_xdg_config_dirs(self):
os.environ["XDG_CONFIG_DIRS"] = "/usr/local/etc/xdg:/etc/xdg"
assert confuse.config_dirs() == [
"/Users/test/.config",
"/Users/test/Library/Application Support",
"/usr/local/etc/xdg",
"/etc/xdg",
"/etc",
]
class WindowsTestCases(FakeSystem):
SYS_NAME = "Windows"
def test_dir_from_environ(self):
assert confuse.config_dirs() == [
"C:\\Users\\test\\AppData\\Roaming",
"C:\\Users\\test\\winconfig",
]
def test_fallback_dir(self):
del os.environ["APPDATA"]
assert confuse.config_dirs() == ["C:\\Users\\test\\AppData\\Roaming"]
class ConfigFilenamesTest(unittest.TestCase):
def setUp(self):
self._old = os.path.isfile, confuse.yaml_util.load_yaml
os.path.isfile = lambda x: True # type: ignore[assignment]
confuse.yaml_util.load_yaml = lambda *args, **kwargs: {}
def tearDown(self):
os.path.isfile, confuse.yaml_util.load_yaml = self._old
def test_no_sources_when_files_missing(self):
config = confuse.Configuration("myapp", read=False)
filenames = [s.filename for s in config.sources]
assert filenames == []
def test_search_package(self):
config = confuse.Configuration("myapp", __name__, read=False)
config._add_default_source()
for source in config.sources:
if source.default:
default_source = source
break
else:
self.fail("no default source")
assert default_source.filename == os.path.join(
os.path.dirname(__file__), "config_default.yaml"
)
assert source.default
class EnvVarTest(FakeHome):
def setUp(self):
super().setUp()
self.config = confuse.Configuration("myapp", read=False)
os.environ["MYAPPDIR"] = self.home # use the tmp home as a config dir
def test_env_var_name(self):
assert self.config._env_var == "MYAPPDIR"
def test_env_var_dir_has_first_priority(self):
assert self.config.config_dir() == self.home
def test_env_var_missing(self):
del os.environ["MYAPPDIR"]
assert self.config.config_dir() != self.home
@unittest.skipUnless(platform.system() == "Linux", "Linux-specific tests")
class PrimaryConfigDirTest(FakeHome, FakeSystem):
SYS_NAME = "Linux" # conversion from posix to nt is easy
def setUp(self):
super().setUp()
self.config = confuse.Configuration("test", read=False)
def test_create_dir_if_none_exists(self):
path = os.path.join(self.home, ".config", "test")
assert not os.path.exists(path)
assert self.config.config_dir() == path
assert os.path.isdir(path)
def test_return_existing_dir(self):
path = os.path.join(self.home, "xdgconfig", "test")
os.makedirs(path)
_touch(os.path.join(path, confuse.CONFIG_FILENAME))
assert self.config.config_dir() == path
def test_do_not_create_dir_if_lower_priority_exists(self):
path1 = os.path.join(self.home, "xdgconfig", "test")
path2 = os.path.join(self.home, ".config", "test")
os.makedirs(path2)
_touch(os.path.join(path2, confuse.CONFIG_FILENAME))
assert not os.path.exists(path1)
assert os.path.exists(path2)
assert self.config.config_dir() == path2
assert not os.path.isdir(path1)
assert os.path.isdir(path2)
|