From d111cf398b430f7f23863e32d2b63d6255fdd3ca Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 31 Jan 2024 23:34:10 +0100 Subject: [PATCH] more tests --- dotdrop/dotdrop.py | 2 +- dotdrop/utils.py | 4 +- tests-ng/uninstall-by-key.sh | 79 ++++++++++++++++++++++++ tests-ng/workers.sh | 73 ++++++++++++++++++++++ tests/test_misc.py | 115 ++++++++++++++++++++++++++++++++++- 5 files changed, 267 insertions(+), 6 deletions(-) create mode 100755 tests-ng/uninstall-by-key.sh create mode 100755 tests-ng/workers.sh diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index ac5d4fc..b09a50a 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -626,7 +626,7 @@ def cmd_uninstall(opts): keys = opts.uninstall_key if keys: - # update only specific keys for this profile + # uninstall only specific keys for this profile dotfiles = [] for key in uniq_list(keys): dotfile = opts.conf.get_dotfile(key) diff --git a/dotdrop/utils.py b/dotdrop/utils.py index 3955ba7..d3d60c8 100644 --- a/dotdrop/utils.py +++ b/dotdrop/utils.py @@ -694,9 +694,7 @@ def pivot_path(path, newdir, striphome=False, logger=None): def dir_empty(path): """return true if directory is empty""" - if not os.path.exists(path): - return True - if not os.path.isdir(path): + if not os.path.exists(path) or not os.path.isdir(path): return True return len(os.listdir(path)) < 1 diff --git a/tests-ng/uninstall-by-key.sh b/tests-ng/uninstall-by-key.sh new file mode 100755 index 0000000..e89adc1 --- /dev/null +++ b/tests-ng/uninstall-by-key.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2024, deadc0de6 +# +# test uninstall by key +# returns 1 in case of error +# + +## start-cookie +set -eu -o errtrace -o pipefail +cur=$(cd "$(dirname "${0}")" && pwd) +ddpath="${cur}/../" +PPATH="{PYTHONPATH:-}" +export PYTHONPATH="${ddpath}:${PPATH}" +altbin="python3 -m dotdrop.dotdrop" +if hash coverage 2>/dev/null; then + mkdir -p coverages/ + altbin="coverage run -p --data-file coverages/coverage --source=dotdrop -m dotdrop.dotdrop" +fi +bin="${DT_BIN:-${altbin}}" +# shellcheck source=tests-ng/helpers +source "${cur}"/helpers +echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)" +## end-cookie + +################################################################ +# this is the test +################################################################ +# dotdrop directory +tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d) +echo "[+] dotdrop dir: ${tmps}" +echo "[+] dotpath dir: ${tmps}/dotfiles" + +# the dotfile to be imported +tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d) + +clear_on_exit "${tmps}" +clear_on_exit "${tmpd}" + +# create the config file +cfg="${tmps}/config.yaml" +create_conf "${cfg}" # sets token + +# single file +echo 'file' > "${tmpd}"/file + +# import +echo "import..." +cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/file + +# install +rm -f "${tmpd}"/file +echo "install..." +cd "${ddpath}" | ${bin} install -f -c "${cfg}" + +# uninstall +echo "uninstall..." +cd "${ddpath}" | ${bin} uninstall -f -c "${cfg}" f_file + +# nothing to uninstall +cat > "${cfg}" << _EOF +config: + backup: false + create: true + dotpath: dotfiles +dotfiles: + f_abc: + dst: ${tmpd}/file + src: file +profiles: + p1: + dotfiles: +_EOF + +echo "uninstall..." +cd "${ddpath}" | ${bin} uninstall -f -c "${cfg}" --profile=p1 + +echo "OK" +exit 0 \ No newline at end of file diff --git a/tests-ng/workers.sh b/tests-ng/workers.sh new file mode 100755 index 0000000..58b8a21 --- /dev/null +++ b/tests-ng/workers.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# author: deadc0de6 (https://github.com/deadc0de6) +# Copyright (c) 2024, deadc0de6 +# +# test workers +# returns 1 in case of error +# + +## start-cookie +set -eu -o errtrace -o pipefail +cur=$(cd "$(dirname "${0}")" && pwd) +ddpath="${cur}/../" +PPATH="{PYTHONPATH:-}" +export PYTHONPATH="${ddpath}:${PPATH}" +altbin="python3 -m dotdrop.dotdrop" +if hash coverage 2>/dev/null; then + mkdir -p coverages/ + altbin="coverage run -p --data-file coverages/coverage --source=dotdrop -m dotdrop.dotdrop" +fi +bin="${DT_BIN:-${altbin}}" +# shellcheck source=tests-ng/helpers +source "${cur}"/helpers +echo -e "$(tput setaf 6)==> RUNNING $(basename "${BASH_SOURCE[0]}") <==$(tput sgr0)" +## end-cookie + +################################################################ +# this is the test +################################################################ + +# dotdrop directory +tmps=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d) +echo "[+] dotdrop dir: ${tmps}" +echo "[+] dotpath dir: ${tmps}/dotfiles" + +# the dotfile to be imported +tmpd=$(mktemp -d --suffix='-dotdrop-tests' || mktemp -d) + +clear_on_exit "${tmps}" +clear_on_exit "${tmpd}" + +# create the config file +cfg="${tmps}/config.yaml" +create_conf "${cfg}" # sets token + +# single file +echo 'unique' > "${tmpd}"/uniquefile + +# import +echo "import..." +cd "${ddpath}" | ${bin} import -f -c "${cfg}" "${tmpd}"/uniquefile + +# install +rm -f "${tmpd}"/uniquefile +echo "install..." +cd "${ddpath}" | ${bin} install -f -c "${cfg}" -w3 + +# compare +echo "new content" > "${tmpd}"/uniquefile +echo "compare..." +set +e +cd "${ddpath}" | ${bin} compare -c "${cfg}" -w3 +set -e + +# update +echo "update..." +cd "${ddpath}" | ${bin} update -f -c "${cfg}" -w3 "${tmpd}"/uniquefile + +# uninstall +echo "uninstall..." +cd "${ddpath}" | ${bin} uninstall -f -c "${cfg}" + +echo "OK" +exit 0 diff --git a/tests/test_misc.py b/tests/test_misc.py index e03db9c..e94867d 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -18,14 +18,20 @@ from dotdrop.profile import Profile from dotdrop.importer import Importer from dotdrop.linktypes import LinkTypes from dotdrop.action import Cmd, Transform +from dotdrop.dotfile import Dotfile +from dotdrop.installer import Installer +from dotdrop.updater import Updater +from dotdrop.uninstaller import Uninstaller from dotdrop.templategen import Templategen from dotdrop.exceptions import UndefinedException, \ UnmetDependency +from dotdrop.dotdrop import apply_install_trans from dotdrop.utils import removepath, samefile, \ content_empty, _match_ignore_pattern, \ - get_module_from_path, dependencies_met + get_module_from_path, dependencies_met, \ + dir_empty from tests.helpers import create_random_file, \ - get_tempdir, clean + get_tempdir, clean, edit_content class TestUtils(unittest.TestCase): @@ -39,6 +45,16 @@ class TestUtils(unittest.TestCase): with self.assertRaises(OSError): removepath(os.path.expanduser('~')) + def test_dirempty(self): + """dir_empty""" + tmpdir = get_tempdir() + self.addCleanup(clean, tmpdir) + + self.assertTrue(dir_empty('/a/b/c/d/e')) + self.assertTrue(dir_empty(tmpdir)) + path1, _ = create_random_file(tmpdir, content='left') + self.assertTrue(dir_empty(path1)) + def test_misc(self): """misc test""" self.assertFalse(samefile('', '')) @@ -98,6 +114,101 @@ class TestUtils(unittest.TestCase): dependencies_met() +class TestDotdropDotdrop(unittest.TestCase): + """test case""" + + def test_apply_install_trans(self): + """ensure transformation fails if destination exists""" + tmpdir = get_tempdir() + self.addCleanup(clean, tmpdir) + + src, _ = create_random_file(tmpdir, content='left') + dst, _ = create_random_file(tmpdir, content='left') + new_src = f'{src}.trans' + edit_content(new_src, 'some_content') + + trans = Transform('somekey', 'echo') + df = Dotfile('key', src, dst) + df.trans_install = trans + self.assertIsNone(apply_install_trans( + tmpdir, + df, + None, + )) + + +class TestUpdater(unittest.TestCase): + """test case""" + + def test_update_path(self): + """coverage for update_path""" + upd = Updater('path', {}, None, 'profile') + self.assertFalse(upd.update_path('/a/b/c/d')) + + +class TestInstaller(unittest.TestCase): + """test case""" + + def test_show_diff_before_write(self): + """coverage for _show_diff_before_write""" + inst = Installer() + + tmpdir = get_tempdir() + self.addCleanup(clean, tmpdir) + + path1, _ = create_random_file(tmpdir, content='left') + path2, _ = create_random_file(tmpdir, content='right') + self.assertIsNotNone(inst._show_diff_before_write( + path1, + path2, + content=b'blah' + )) + + path3, _ = create_random_file(tmpdir, content='left') + path4, _ = create_random_file(tmpdir, content='left') + self.assertEqual(inst._show_diff_before_write( + path3, + path4, + ), '') + + def test_show_diff(self): + """coverage for _print_diff""" + inst = Installer() + self.assertIsNone(inst._print_diff( + "left", + "right", + "diff", + )) + + def test_check_paths(self): + """coverage for _check_paths""" + inst = Installer() + r1, r2, r3, r4 = inst._check_paths(None, None) + self.assertIsNone(r1) + self.assertIsNone(r2) + self.assertFalse(r3) + self.assertIsNotNone(r4) + + +class TestUninstaller(unittest.TestCase): + """test case""" + + def test_uninstall(self): + """coverage for uninstall()""" + uninst = Uninstaller() + r1, r2 = uninst.uninstall(None, None, None) + self.assertTrue(r1) + self.assertIsNone(r2) + + r1, r2 = uninst.uninstall('a/b/c', 'd/e/f', None) + self.assertFalse(r1) + self.assertIsNotNone(r2) + + r1, r2 = uninst._remove_path('a/b/c') + self.assertTrue(r1) + self.assertIsNotNone(r2) + + class TestImporter(unittest.TestCase): """test case"""