Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 4 additions & 42 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,57 +40,19 @@ jobs:
run: ./scripts/checkstyle.py
- name: Shellcheck
run: shellcheck --severity=error bin/* ./*.sh
- name: Lint and format Python with Ruff
uses: astral-sh/ruff-action@v3

typo:
runs-on: ubuntu-latest
steps:
- name: Check out code.
uses: actions/checkout@v7
- name: Install poetry
run: pip install poetry
- name: Set up Python
uses: actions/setup-python@v6
with:
cache: 'poetry'
cache-dependency-path: "tests/pyproject.toml"
python-version-file: "tests/pyproject.toml"
- name: Install dependencies
run: |
cd tests || exit
poetry install --only dev
- name: Install codespell
run: python3 -m pip install codespell==2.4
- name: spell check
run: |
cd tests
git grep --cached -l '' .. | \
git grep --cached -l '' . | \
grep -v -e 'History\.md' -e 'AUTHORS' -e 'man/.*\.1' -e 'man/.*\.html' | \
xargs poetry run codespell --ignore-words=../.github/.ignore_words

test-pytest:
name: 'Test with Pytest'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Install poetry
run: pip install poetry
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: 'poetry'
cache-dependency-path: "tests/pyproject.toml"
python-version-file: "tests/pyproject.toml"
- name: Install Python Dependencies
run: |
cd tests || exit
poetry install --only test
- name: Test with Pytest
run: |
cd tests
poetry run pytest
xargs codespell --ignore-words=.github/.ignore_words

test-bats:
name: 'Test with Bats'
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,6 @@ docclean:
rm -f man/*.html

test:
pytest
bats ./tests

.PHONY: default docs check install uninstall clean docclean test
7 changes: 6 additions & 1 deletion scripts/checkstyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,12 @@ def main():
lintfile(p, rules, options)
else:
for file in Path.cwd().glob('**/*'):
if '.git' in str(file.absolute()):
skip = False
for name in ('.git', 'vendor', '__pycache__'):
if name in str(file.absolute()):
skip = True
break
if skip:
continue

if file.is_file():
Expand Down
50 changes: 2 additions & 48 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Testing

Originally, the tests were written in pytest. However, tests are in the process of being converted to Bats so coverage can be calculated.
Tests are written in Bats so coverage can be calculated for shell commands.

## Bats Testing

Expand All @@ -10,7 +10,7 @@ We require a somewhat recent version of Bats. Version v1.8.1 is tested in CI. On
bats ./tests
```

We highly recommend adding tests for new features and fixes.
We highly recommend adding Bats tests for new features and fixes.

### Code Coverage

Expand All @@ -21,49 +21,3 @@ bashcov -- bats ./tests
```

By default, the report will be generated in `./coverage/index.html`.

## Python Testing

The test part depends on:

* python >= 3.11
* poetry >= 1.8.0
* pytest >= 8.1.2
* gitpython >= 3.1.43

So the versions are higher than above is recommended.

### How to run the tests

1. Install `poetry`
2. Install the dependencies via `poetry install`
3. Run `poetry run pytest`

It is done or go without `poetry`,

1. Install python >= 3.11
2. Install pytest >= 8.1.2
3. Install gitpython >= 3.1.43
4. Install testpath >= 0.6.0
5. Run `pytest`

The second way maybe blocked the some missing dependencies at someday, so the first one is recommended.

### What and how to create a unit test

One command has a unit test, because one `git-*` command is just do one thing, so we can eat a piece of `git-*` command in one time.

For example,

1. The `git-alias` should have a test suite, so create `test_git_alias.py` in the directory `test`
2. Create a test class `TestGitAlias` in the `test_git_alias.py`
3. Create a test case `test_init`, and some test fixtures can be used, `temp_repo`, `named_temp_repo` etc.
* `temp_repo` is module scoped fixture which create a temporary directory and available in the test suite `test_git_alias.py`.
* `named_temp_repo` is just same as `temp_repo` except the custom directory renaming.
4. Loop the third step until the 100% coverage of the function of the `git-alias`

### References

* [poetry](https://github.com/python-poetry/poetry)
* [pytest](https://github.com/pytest-dev/pytest/)
* [git python](https://github.com/gitpython-developers/GitPython)
45 changes: 0 additions & 45 deletions tests/conftest.py

This file was deleted.

30 changes: 27 additions & 3 deletions tests/git-archive-file.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ source "$BATS_TEST_DIRNAME/test_util.sh"

setup_file() {
test_util.setup_file
test_util.install_command archive-file
}

setup() {
Expand Down Expand Up @@ -37,7 +38,7 @@ setup() {
}

@test "archive file on any not tags branch with default branch" {
skip "Not working as expected"
git config git-extras.default-branch main

run git archive-file
assert_success
Expand All @@ -58,9 +59,32 @@ setup() {
}

@test "archive file on dirname has backslash" {
skip
local repo_dir="$BATS_TEST_TMPDIR/backslash\\dir"
mkdir "$repo_dir"
cd "$repo_dir"

test_util.git_init
printf '%s\n' 'data' > tmpfile
git add .
git commit -m 'test: add data'
git checkout -b default

run git archive-file
assert_success

local describe_output=
describe_output=$(git describe --always --long)
assert_file_exists "backslash-dir.$describe_output.default.zip"
}

@test "archive file on tag name has slash" {
skip
git tag --delete 0.1.0
git tag 0.1.0/slash -m 'bump: 0.1.0'

run git archive-file
assert_success

local describe_output=
describe_output=$(git describe --always --long)
assert_file_exists "${PWD##*/}.${describe_output//\//-}.zip"
}
114 changes: 114 additions & 0 deletions tests/git-browse-ci.bats
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ get_ci_uri() {
fi
}

mock_uname() {
local output=$1
local mock_bin="$BATS_TEST_TMPDIR/bin"

mkdir -p "$mock_bin"
printf '#!/usr/bin/env bash\nprintf "%%s\\n" "%s"\n' "$output" > "$mock_bin/uname"
chmod +x "$mock_bin/uname"
PATH="$mock_bin:$PATH"
}

@test "works with mac and github" {
get_ci_uri 'github'
local expected_url=$REPLY
Expand Down Expand Up @@ -96,6 +106,110 @@ get_ci_uri() {
assert_success
}

@test "works with WSL and github" {
get_ci_uri 'github'
local expected_url=$REPLY
mock_uname microsoft

git remote add upstream https://github.com/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_line "powershell.exe -NoProfile start $expected_url"
assert_success
}

@test "works with WSL and gitlab" {
get_ci_uri 'gitlab'
local expected_url=$REPLY
mock_uname microsoft

git remote add upstream https://gitlab.com/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_line "powershell.exe -NoProfile start $expected_url"
assert_success
}

@test "works with WSL and bitbucket" {
get_ci_uri 'bitbucket'
local expected_url=$REPLY
mock_uname microsoft

git remote add upstream https://bitbucket.org/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_line "powershell.exe -NoProfile start $expected_url"
assert_success
}

@test "works with linux without Microsoft kernel and github" {
get_ci_uri 'github'
local expected_url=$REPLY
mock_uname no-micro-soft

git remote add upstream https://github.com/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "works with linux without Microsoft kernel and gitlab" {
get_ci_uri 'gitlab'
local expected_url=$REPLY
mock_uname no-micro-soft

git remote add upstream https://gitlab.com/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "works with linux without Microsoft kernel and bitbucket" {
get_ci_uri 'bitbucket'
local expected_url=$REPLY
mock_uname no-micro-soft

git remote add upstream https://bitbucket.org/tj/git-extras
OSTYPE=linux run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "falls back to xdg-open on an unknown OS with github" {
get_ci_uri 'github'
local expected_url=$REPLY

git remote add upstream https://github.com/tj/git-extras
OSTYPE=unique-system run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "falls back to xdg-open on an unknown OS with gitlab" {
get_ci_uri 'gitlab'
local expected_url=$REPLY

git remote add upstream https://gitlab.com/tj/git-extras
OSTYPE=unique-system run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "falls back to xdg-open on an unknown OS with bitbucket" {
get_ci_uri 'bitbucket'
local expected_url=$REPLY

git remote add upstream https://bitbucket.org/tj/git-extras
OSTYPE=unique-system run git browse-ci upstream
assert_output "xdg-open $expected_url"
assert_success
}

@test "opens an empty URL for an unknown site" {
git remote add upstream https://unknown-site.com/tj/git-extras.git

OSTYPE=unique-system run git browse-ci upstream
assert_output "xdg-open "
assert_success
}

@test "works with linux and gitlab" {
get_ci_uri 'gitlab'
local expected_url=$REPLY
Expand Down
Loading
Loading