Skip to content

Commit

Permalink
Add: Improve test coverage for plugin git API #295
Browse files Browse the repository at this point in the history
Merge pull request #295 from greenbone/improve-test-coverage
  • Loading branch information
bjoernricks committed May 5, 2022
2 parents 91ca8d3 + 2921436 commit 1a611da
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 12 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
- 3.7
- 3.8
- 3.9
- "3.10"
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -33,14 +34,15 @@ jobs:
- 3.7
- 3.8
- 3.9
- "3.10"
steps:
- uses: actions/checkout@v2
- name: Install poetry and dependencies
uses: greenbone/actions/poetry@v1
with:
version: ${{ matrix.python-version }}
- name: Run unit tests
run: poetry run python -m unittest
run: poetry run python -m unittest -v

codecov:
name: Upload coverage to codecov.io
Expand All @@ -51,4 +53,4 @@ jobs:
- name: Calculate and upload coverage to codecov.io
uses: greenbone/actions/coverage-python@v1
with:
version: 3.8
version: 3.9
16 changes: 8 additions & 8 deletions autohooks/api/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from pathlib import Path
from tempfile import NamedTemporaryFile
from types import TracebackType
from typing import Any, Generator, List, Optional, Type, Union
from typing import Any, Iterable, Iterator, List, Optional, Type, Union

from autohooks.utils import GitError, exec_git, get_project_root_path

Expand Down Expand Up @@ -83,7 +83,7 @@ def absolute_path(self) -> Path:
return self.path.resolve()


def _parse_status(output: str) -> Generator[str, None, None]:
def _parse_status(output: str) -> Iterator[str]:
output = output.rstrip("\0")
if not output:
return
Expand Down Expand Up @@ -129,7 +129,7 @@ def is_partially_staged_status(status: StatusEntry) -> bool:
)


def get_status(files: List[Union[Path, str]] = None) -> List[StatusEntry]:
def get_status(files: Iterable[Union[Path, str]] = None) -> List[StatusEntry]:
"""execute get status
Arguments:
Expand All @@ -156,7 +156,7 @@ def get_status(files: List[Union[Path, str]] = None) -> List[StatusEntry]:


def get_staged_status(
files: List[Union[Path, str]] = None
files: Iterable[Union[Path, str]] = None
) -> List[StatusEntry]:
"""get a list of StatusEntries containing only staged files
Expand All @@ -171,7 +171,7 @@ def get_staged_status(
return [s for s in status if is_staged_status(s)]


def stage_files_from_status_list(status_list: List[StatusEntry]) -> None:
def stage_files_from_status_list(status_list: Iterable[StatusEntry]) -> None:
"""Add the passed files to staged
Arguments:
Expand All @@ -181,7 +181,7 @@ def stage_files_from_status_list(status_list: List[StatusEntry]) -> None:
exec_git("add", *filenames)


def get_diff(files: List[StatusEntry] = None) -> str:
def get_diff(files: Iterable[StatusEntry] = None) -> str:
"""Get the diff of the passed files
Arguments:
Expand All @@ -207,7 +207,7 @@ def _read_tree(ref_or_hashid: str) -> None:
exec_git("read-tree", ref_or_hashid)


def _checkout_from_index(status_list: List[StatusEntry]) -> None:
def _checkout_from_index(status_list: Iterable[StatusEntry]) -> None:
filenames = [str(s.path) for s in status_list]
exec_git("checkout-index", "-f", "--", *filenames)

Expand Down Expand Up @@ -252,7 +252,7 @@ def _apply_diff(patch: bytes) -> None:


class stash_unstaged_changes: # pylint: disable=invalid-name
def __init__(self, status_list: List[StatusEntry]) -> None:
def __init__(self, status_list: Iterable[StatusEntry]) -> None:
self.partially_staged = [
s for s in status_list if is_partially_staged_status(s)
]
Expand Down
6 changes: 4 additions & 2 deletions autohooks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ def exec_git(*args: str, ignore_errors: bool = False) -> str:
try:
cmd_args = ["git"]
cmd_args.extend(args)
output = subprocess.check_output(cmd_args)
return output.decode()
process = subprocess.run(
cmd_args, check=True, capture_output=True, text=True
)
return process.stdout
except subprocess.CalledProcessError as e:
if ignore_errors:
return ""
Expand Down
66 changes: 66 additions & 0 deletions tests/api/git/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright (C) 2022 Greenbone Networks GmbH
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import os
import tempfile
import unittest
from contextlib import contextmanager
from pathlib import Path
from typing import Generator

from autohooks.utils import exec_git


@contextmanager
def temdir() -> Generator[Path, None, None]:
tempdir = tempfile.TemporaryDirectory()
yield Path(tempdir.name)
tempdir.cleanup()


@contextmanager
def tempgitdir() -> Generator[Path, None, None]:
cwd = Path.cwd()
tempdir = tempfile.TemporaryDirectory()
temppath = Path(tempdir.name)
os.chdir(str(temppath))
exec_git("init", "-b", "main")
exec_git("config", "--local", "user.email", "max.mustermann@example.com")
exec_git("config", "--local", "user.name", "Max Mustermann")
yield temppath
tempdir.cleanup()
os.chdir(str(cwd))


def git_add(*paths: Path) -> None:
exec_git("add", *paths)


def git_rm(*paths: Path) -> None:
exec_git("rm", *paths)


def git_mv(from_path: Path, to_path: Path) -> None:
exec_git("mv", from_path, to_path)


def git_commit(message: str = "Foo Bar"):
exec_git("commit", "--no-gpg-sign", "-m", message)


class GitTestCase(unittest.TestCase):
pass
66 changes: 66 additions & 0 deletions tests/api/git/test_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright (C) 2022 Greenbone Networks GmbH
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from autohooks.api.git import StatusEntry, get_diff
from tests.api.git import GitTestCase, git_add, git_commit, tempgitdir


class DiffTestCase(GitTestCase):
def test_get_diff_from_status(self):
with tempgitdir() as tmpdir:
test_file = tmpdir / "foo.txt"
test_file.write_text(
"Lorem\nipsum\ndolor\nsit\namet", encoding="utf8"
)

git_add(test_file)
git_commit()

test_file.write_text("ipsum\ndolor\nsit\namet", encoding="utf8")
status = StatusEntry("M foo.txt", tmpdir)
diff = get_diff((status,))

expected_diff = """--- a/foo.txt
+++ b/foo.txt
@@ -1,4 +1,3 @@
-Lorem
ipsum
dolor
sit"""
self.assertIn(expected_diff, diff)

def test_get_diff(self):
with tempgitdir() as tmpdir:
test_file = tmpdir / "foo.txt"
test_file.write_text(
"Lorem\nipsum\ndolor\nsit\namet", encoding="utf8"
)

git_add(test_file)
git_commit()

test_file.write_text("ipsum\ndolor\nsit\namet", encoding="utf8")
diff = get_diff()

expected_diff = """--- a/foo.txt
+++ b/foo.txt
@@ -1,4 +1,3 @@
-Lorem
ipsum
dolor
sit"""
self.assertIn(expected_diff, diff)
Loading

0 comments on commit 1a611da

Please sign in to comment.