From 50229dd85bc7fd3bb5592a75f1b3f1aca6a87fc0 Mon Sep 17 00:00:00 2001 From: Fabio Todaro Date: Wed, 21 Apr 2021 00:52:58 +0200 Subject: [PATCH 1/3] Clean tests --- cookiecutter/utils.py | 2 +- tests/test_cli.py | 5 ----- tests/test_utils.py | 29 +++++++++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cookiecutter/utils.py b/cookiecutter/utils.py index 5935a249c..19b727a52 100644 --- a/cookiecutter/utils.py +++ b/cookiecutter/utils.py @@ -16,7 +16,7 @@ def force_delete(func, path, exc_info): """Error handler for `shutil.rmtree()` equivalent to `rm -rf`. Usage: `shutil.rmtree(path, onerror=force_delete)` - From stackoverflow.com/questions/1889597 + From https://docs.python.org/3/library/shutil.html#rmtree-example """ os.chmod(path, stat.S_IWRITE) func(path) diff --git a/tests/test_cli.py b/tests/test_cli.py index a2d8accee..4a1e11471 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2,7 +2,6 @@ import json import os -import sys import pytest from click.testing import CliRunner @@ -365,10 +364,6 @@ def test_default_user_config(mocker, cli_runner): ) -@pytest.mark.skipif( - sys.version_info[0] == 3 and sys.version_info[1] == 6 and sys.version_info[2] == 1, - reason="Outdated pypy3 version on Travis CI/CD with wrong OrderedDict syntax.", -) def test_echo_undefined_variable_error(tmpdir, cli_runner): """Cli invocation return error if variable undefined in template.""" output_dir = str(tmpdir.mkdir('output')) diff --git a/tests/test_utils.py b/tests/test_utils.py index ef0003f25..5b089ae4a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -14,10 +14,23 @@ def make_readonly(path): Path.chmod(path, mode & ~stat.S_IWRITE) -@pytest.mark.skipif( - sys.version_info[0] == 3 and sys.version_info[1] == 6 and sys.version_info[2] == 1, - reason="Outdated pypy3 version on Travis CI/CD", -) +def test_force_delete(mocker, tmp_path): + """Verify `utils.force_delete` makes files writable.""" + ro_file = Path(tmp_path, 'bar') + + with open(ro_file, "w") as f: + f.write("Test data") + make_readonly(ro_file) + + rmtree = mocker.Mock() + utils.force_delete(rmtree, ro_file, sys.exc_info()) + + assert (ro_file.stat().st_mode & stat.S_IWRITE) == stat.S_IWRITE + rmtree.assert_called_once_with(ro_file) + + utils.rmtree(tmp_path) + + def test_rmtree(tmp_path): """Verify `utils.rmtree` remove files marked as read-only.""" with open(Path(tmp_path, 'bar'), "w") as f: @@ -29,10 +42,6 @@ def test_rmtree(tmp_path): assert not Path(tmp_path).exists() -@pytest.mark.skipif( - sys.version_info[0] == 3 and sys.version_info[1] == 6 and sys.version_info[2] == 1, - reason="Outdated pypy3 version on Travis CI/CD", -) def test_make_sure_path_exists(tmp_path): """Verify correct True/False response from `utils.make_sure_path_exists`. @@ -68,10 +77,6 @@ def raiser(*args, **kwargs): assert not utils.make_sure_path_exists(uncreatable_directory) -@pytest.mark.skipif( - sys.version_info[0] == 3 and sys.version_info[1] == 6 and sys.version_info[2] == 1, - reason="Outdated pypy3 version on Travis CI/CD", -) def test_work_in(tmp_path): """Verify returning to original folder after `utils.work_in` use.""" cwd = Path.cwd() From 5713b5b26ff0f5b262d35f6ad5c050857e8c0504 Mon Sep 17 00:00:00 2001 From: Fabio Todaro Date: Thu, 22 Apr 2021 17:52:02 +0200 Subject: [PATCH 2/3] Add 100% coverage on Windows tests --- tests/test_hooks.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_hooks.py b/tests/test_hooks.py index bd374ad07..4e17f68e5 100644 --- a/tests/test_hooks.py +++ b/tests/test_hooks.py @@ -1,5 +1,6 @@ """Tests for `cookiecutter.hooks` module.""" import os +import errno import stat import sys import textwrap @@ -144,6 +145,31 @@ def test_run_script(self): hooks.run_script(os.path.join(self.hooks_path, self.post_hook)) assert os.path.isfile('shell_post.txt') + def test_run_failing_script(self, mocker): + """Test correct exception raise if run_script fails.""" + + err = OSError() + + prompt = mocker.patch('subprocess.Popen') + prompt.side_effect = err + + with pytest.raises(exceptions.FailedHookException) as excinfo: + hooks.run_script(os.path.join(self.hooks_path, self.post_hook)) + assert 'Hook script failed (error: {})'.format(err) in str(excinfo.value) + + def test_run_failing_script_enoexec(self, mocker): + """Test correct exception raise if run_script fails.""" + + err = OSError() + err.errno = errno.ENOEXEC + + prompt = mocker.patch('subprocess.Popen') + prompt.side_effect = err + + with pytest.raises(exceptions.FailedHookException) as excinfo: + hooks.run_script(os.path.join(self.hooks_path, self.post_hook)) + assert 'Hook script failed, might be an empty file or missing a shebang' in str(excinfo.value) + def test_run_script_cwd(self): """Change directory before running hook.""" hooks.run_script(os.path.join(self.hooks_path, self.post_hook), 'tests') From ff0186f69e6dcf8f32f66dd42afa49187d10509f Mon Sep 17 00:00:00 2001 From: Fabio Todaro Date: Thu, 22 Apr 2021 17:54:08 +0200 Subject: [PATCH 3/3] Add fail under 100% coverage --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9179c8da5..0d888f608 100644 --- a/tox.ini +++ b/tox.ini @@ -19,7 +19,7 @@ passenv = HOME commands = pip install -e . - pytest --cov=cookiecutter --cov-report=term {posargs:tests} + pytest --cov=cookiecutter --cov-report=term --cov-fail-under=100 {posargs:tests} cov-report: coverage html cov-report: coverage xml deps = -rtest_requirements.txt