Skip to content

Commit

Permalink
Enable branch coverage (cookiecutter#1542)
Browse files Browse the repository at this point in the history
* Add test cases for untested branches

* Add branches coverage

Branch coverage helps to find out untested branches.

Closes: cookiecutter#1541
  • Loading branch information
simobasso authored Jun 15, 2021
1 parent b1f6427 commit d6037b7
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cookiecutter/vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def clone(repo_url, checkout=None, clone_to_dir='.', no_input=False):
if repo_type == 'git':
repo_name = repo_name.split(':')[-1].rsplit('.git')[0]
repo_dir = os.path.normpath(os.path.join(clone_to_dir, repo_name))
elif repo_type == 'hg':
if repo_type == 'hg':
repo_dir = os.path.normpath(os.path.join(clone_to_dir, repo_name))
logger.debug('repo_dir is {0}'.format(repo_dir))

Expand Down
10 changes: 10 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ def test_work_in(tmp_path):
assert cwd == Path.cwd()


def test_work_in_without_path():
"""Folder is not changed if no path provided."""
cwd = Path.cwd()

with utils.work_in():
assert cwd == Path.cwd()

assert cwd == Path.cwd()


def test_prompt_should_ask_and_rm_repo_dir(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user agrees to delete/reclone the \
repo, the repo should be deleted."""
Expand Down
22 changes: 22 additions & 0 deletions tests/vcs/test_clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,28 @@ def test_clone_should_abort_if_user_does_not_want_to_reclone(mocker, clone_dir):
assert not mock_subprocess.called


def test_clone_should_silent_exit_if_ok_to_reuse(mocker, tmpdir):
"""In `clone()`, if user doesn't want to reclone, Cookiecutter should exit \
without cloning anything."""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mocker.patch(
'cookiecutter.vcs.prompt_and_delete', return_value=False, autospec=True
)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output', autospec=True,
)

clone_to_dir = tmpdir.mkdir('clone')

# Create repo_dir to trigger prompt_and_delete
clone_to_dir.mkdir('cookiecutter-pytest-plugin')

repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'

vcs.clone(repo_url, clone_to_dir=str(clone_to_dir))
assert not mock_subprocess.called


@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
Expand Down
56 changes: 56 additions & 0 deletions tests/zipfile/test_unzip.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import tempfile

import pytest
import shutil

from cookiecutter import zipfile
from cookiecutter.exceptions import InvalidZipRepository
Expand All @@ -16,6 +17,16 @@ def mock_download():
chunk = zf.read(1024)


def mock_download_with_empty_chunks():
"""Fake download function."""
yield
with open('tests/files/fake-repo-tmpl.zip', 'rb') as zf:
chunk = zf.read(1024)
while chunk:
yield chunk
chunk = zf.read(1024)


def test_unzip_local_file(mocker, clone_dir):
"""Local file reference can be unzipped."""
mock_prompt_and_delete = mocker.patch(
Expand Down Expand Up @@ -170,6 +181,29 @@ def test_unzip_url(mocker, clone_dir):
assert not mock_prompt_and_delete.called


def test_unzip_url_with_empty_chunks(mocker, clone_dir):
"""In `unzip()` empty chunk must be ignored."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)

request = mocker.MagicMock()
request.iter_content.return_value = mock_download_with_empty_chunks()

mocker.patch(
'cookiecutter.zipfile.requests.get', return_value=request, autospec=True,
)

output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)

assert output_dir.startswith(tempfile.gettempdir())
assert not mock_prompt_and_delete.called


def test_unzip_url_existing_cache(mocker, clone_dir):
"""Url should be downloaded and unzipped, old zip file will be removed."""
mock_prompt_and_delete = mocker.patch(
Expand Down Expand Up @@ -240,3 +274,25 @@ def test_unzip_should_abort_if_no_redownload(mocker, clone_dir):
zipfile.unzip(zipfile_url, is_url=True, clone_to_dir=str(clone_dir))

assert not mock_requests_get.called


def test_unzip_is_ok_to_reuse(mocker, clone_dir):
"""Already downloaded zip should not be downloaded again."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=False, autospec=True
)

request = mocker.MagicMock()

existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
shutil.copy('tests/files/fake-repo-tmpl.zip', existing_zip)

output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)

assert output_dir.startswith(tempfile.gettempdir())
assert mock_prompt_and_delete.call_count == 1
assert request.iter_content.call_count == 0
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ passenv =
HOME
commands =
pip install -e .
pytest --cov=cookiecutter --cov-report=term --cov-fail-under=100 {posargs:tests}
pytest --cov=cookiecutter --cov-report=term --cov-fail-under=100 --cov-branch {posargs:tests}
cov-report: coverage html
cov-report: coverage xml
deps = -rtest_requirements.txt
Expand Down

0 comments on commit d6037b7

Please sign in to comment.