diff --git a/yokadi/tests/basepathstestcase.py b/yokadi/tests/basepathstestcase.py index aaefc61c..ef2b4d95 100644 --- a/yokadi/tests/basepathstestcase.py +++ b/yokadi/tests/basepathstestcase.py @@ -7,37 +7,22 @@ import os import shutil import tempfile -import unittest from pathlib import Path from yokadi.core import basepaths +from yokadi.tests.yokaditestcase import YokadiTestCase -def saveEnv(): - return dict(os.environ) - - -def restoreEnv(env): - # Do not use `os.environ = env`: this would replace the special os.environ - # object with a plain dict. We must update the *existing* object. - os.environ.clear() - os.environ.update(env) - - -class BasePathsUnixTestCase(unittest.TestCase): +class BasePathsUnixTestCase(YokadiTestCase): def setUp(self): + YokadiTestCase.setUp(self) self._oldWindows = basepaths._WINDOWS basepaths._WINDOWS = False - self._oldEnv = saveEnv() - self.testHomeDir = tempfile.mkdtemp(prefix="yokadi-basepaths-testcase") - os.environ["HOME"] = self.testHomeDir - def tearDown(self): - shutil.rmtree(self.testHomeDir) - restoreEnv(self._oldEnv) basepaths._WINDOWS = self._oldWindows + YokadiTestCase.tearDown(self) def testMigrateOldDb(self): oldDb = Path(self.testHomeDir) / '.yokadi.db' @@ -102,10 +87,10 @@ def testDbEnvVar(self): self.assertEqual(basepaths.getDbPath(), path) -class BasePathsWindowsTestCase(unittest.TestCase): +class BasePathsWindowsTestCase(YokadiTestCase): def setUp(self): + YokadiTestCase.setUp(self) self._oldWindows = basepaths._WINDOWS - self._oldEnv = saveEnv() basepaths._WINDOWS = True self.testAppDataDir = tempfile.mkdtemp(prefix="yokadi-basepaths-testcase") os.environ["APPDATA"] = self.testAppDataDir @@ -113,7 +98,7 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.testAppDataDir) basepaths._WINDOWS = self._oldWindows - restoreEnv(self._oldEnv) + YokadiTestCase.tearDown(self) def testGetCacheDir(self): expected = os.path.join(self.testAppDataDir, "yokadi", "cache") diff --git a/yokadi/tests/testutils.py b/yokadi/tests/testutils.py index 7c1c8be4..d1785a18 100644 --- a/yokadi/tests/testutils.py +++ b/yokadi/tests/testutils.py @@ -5,6 +5,8 @@ @license: GPL v3 or later """ +import os + def multiLinesAssertEqual(test, str1, str2): lst1 = str1.splitlines() @@ -27,4 +29,32 @@ def addTaskList(self, sectionName, taskList): def end(self): pass + + +class EnvironSaver(object): + """ + This class saves and restore the environment. + + Can be used manually or as a context manager. + """ + def __init__(self): + self.save() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.restore() + return False + + def save(self): + self.oldEnv = dict(os.environ) + + def restore(self): + # Do not use `os.environ = env`: this would replace the special os.environ + # object with a plain dict. We must update the *existing* object. + os.environ.clear() + os.environ.update(self.oldEnv) + + # vi: ts=4 sw=4 et diff --git a/yokadi/tests/yokaditestcase.py b/yokadi/tests/yokaditestcase.py new file mode 100644 index 00000000..fae49ba6 --- /dev/null +++ b/yokadi/tests/yokaditestcase.py @@ -0,0 +1,30 @@ +""" +Yokadi base class for test cases +@author: Aurélien Gâteau +@license: GPL v3 or later +""" +import os +import shutil +import tempfile +import unittest + +from yokadi.tests.testutils import EnvironSaver + + +class YokadiTestCase(unittest.TestCase): + """ + A TestCase which takes care of isolating the test from the user home dir + and environment. + """ + def setUp(self): + self.__envSaver = EnvironSaver() + self.testHomeDir = tempfile.mkdtemp(prefix="yokadi-basepaths-testcase") + os.environ["HOME"] = self.testHomeDir + os.environ["XDG_DATA_HOME"] = "" + os.environ["XDG_CACHE_HOME"] = "" + os.environ["YOKADI_DB"] = "" + os.environ["YOKADI_HISTORY"] = "" + + def tearDown(self): + shutil.rmtree(self.testHomeDir) + self.__envSaver.restore()