diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0257c9..1dc305a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,9 +65,9 @@ jobs: grep -v -e 'History\.md' -e 'AUTHORS' -e 'man/.*\.1' -e 'man/.*\.html' | \ xargs poetry run codespell --ignore-words=../.github/.ignore_words - test: + test-pytest: + name: 'Test with Pytest' runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 with: @@ -85,13 +85,23 @@ jobs: run: | cd tests || exit poetry install --only test - - name: Setup Bats - id: setup-bats - uses: bats-core/bats-action@3.0.0 - name: Test with Pytest run: | cd tests poetry run pytest + + test-bats: + name: 'Test with Bats' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Setup Bats + id: setup-bats + uses: bats-core/bats-action@3.0.0 + with: + bats-version: 'v1.8.1' - name: Test with Bats env: BATS_LIB_PATH: ${{ steps.setup-bats.outputs.lib-path }} diff --git a/.gitignore b/.gitignore index a230a78..294ece4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .venv/ __pycache__/ +coverage/ diff --git a/tests/README.md b/tests/README.md index 7c60a07..836021d 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,7 +1,28 @@ -# Test for git-extras -The git-extras has its own testcases now, and the more is on the way! So let's introduce it. +# Testing -We choose python to help us to reach to other shore cause **python is life saver**. +Originally, the tests were written in pytest. However, tests are in the process of being converted to Bats so coverage can be calculated. + +## Bats Testing + +We require a somewhat recent version of Bats. Version v1.8.1 is tested in CI. Once it is installed, the tests can be executed like so: + +```sh +bats ./tests +``` + +We highly recommend adding tests for new features and fixes. + +### Code Coverage + +Coverage can be calculated with [bashcov](https://github.com/infertux/bashcov) like so: + +```sh +bashcov -- bats ./tests +``` + +By default, the report will be generated in `./coverage/index.html`. + +## Python Testing The test part depends on: @@ -12,7 +33,8 @@ The test part depends on: So the versions are higher than above is recommended. -# How to run the tests +### How to run the tests + 1. Install `poetry` 2. Install the dependencies via `poetry install` 3. Run `poetry run pytest` @@ -27,7 +49,8 @@ It is done or go without `poetry`, 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 +### 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, @@ -39,7 +62,8 @@ For example, * `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 +### References + * [poetry](https://github.com/python-poetry/poetry) * [pytest](https://github.com/pytest-dev/pytest/) * [git python](https://github.com/gitpython-developers/GitPython) diff --git a/tests/bin/open b/tests/bin/open new file mode 100755 index 0000000..2be3eaf --- /dev/null +++ b/tests/bin/open @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +printf '%s\n' "open $*" diff --git a/tests/bin/powershell.exe b/tests/bin/powershell.exe new file mode 100755 index 0000000..aee36a1 --- /dev/null +++ b/tests/bin/powershell.exe @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +printf '%s\n' "powershell.exe $*" diff --git a/tests/bin/start b/tests/bin/start new file mode 100755 index 0000000..89eeebd --- /dev/null +++ b/tests/bin/start @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +printf '%s\n' "start $*" diff --git a/tests/bin/xdg-open b/tests/bin/xdg-open new file mode 100755 index 0000000..951b999 --- /dev/null +++ b/tests/bin/xdg-open @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +printf '%s\n' "xdg-open $*" diff --git a/tests/git-abort.bats b/tests/git-abort.bats index 94f9f8d..73e8302 100644 --- a/tests/git-abort.bats +++ b/tests/git-abort.bats @@ -9,7 +9,7 @@ setup_file() { setup() { test_util.cd_test - git init + test_util.git_init git commit --allow-empty -m "Initial commit" git branch A git branch B @@ -24,7 +24,7 @@ setup() { git status } -@test "cherry pick" { +@test "works with cherry pick" { run git cherry-pick A assert_failure @@ -41,7 +41,7 @@ setup() { assert_success } -@test "merge" { +@test "works with merge" { run git merge A assert_failure @@ -58,7 +58,7 @@ setup() { assert_success } -@test "rebase" { +@test "works with rebase" { run git rebase A assert_failure @@ -75,7 +75,7 @@ setup() { assert_success } -@test "revert" { +@test "works with revert" { run git revert A assert_failure diff --git a/tests/git-alias.bats b/tests/git-alias.bats index fa210a7..bb15410 100644 --- a/tests/git-alias.bats +++ b/tests/git-alias.bats @@ -9,7 +9,7 @@ setup_file() { setup() { test_util.cd_test - git init + test_util.git_init git config --global alias.globalalias status git config --global alias.x status git config --local alias.localalias status diff --git a/tests/git-archive-file.bats b/tests/git-archive-file.bats index 76cffd6..b7f1849 100644 --- a/tests/git-archive-file.bats +++ b/tests/git-archive-file.bats @@ -9,7 +9,7 @@ setup_file() { setup() { test_util.cd_test - git init + test_util.git_init printf '%s\n' 'data' > tmpfile git add . git commit -m 'test: add data' diff --git a/tests/git-authors.bats b/tests/git-authors.bats index 203a882..2fafffa 100644 --- a/tests/git-authors.bats +++ b/tests/git-authors.bats @@ -10,17 +10,22 @@ setup_file() { setup() { test_util.cd_test - git init - GIT_CONFIG_VALUE_0='test@example.com' - GIT_CONFIG_VALUE_1='test' + test_util.git_init + + git config user.name 'test' + git config user.email 'test@example.com' printf '%s\n' 'A' > tmpfile git add . git commit -m 'test: add data A' - GIT_CONFIG_VALUE_0='testagain@example.com' - GIT_CONFIG_VALUE_1='testagain' + + git config user.name 'testagain' + git config user.email 'testagain@example.com' printf '%s\n' 'B' > tmpfile git add . git commit -m 'test: add data B' + + # git config unset user.name + # git config unset user.email } @test "output authors has email without any parameter" { diff --git a/tests/git-browse-ci.bats b/tests/git-browse-ci.bats new file mode 100644 index 0000000..fee89fc --- /dev/null +++ b/tests/git-browse-ci.bats @@ -0,0 +1,117 @@ +# shellcheck shell=bash + +source "$BATS_TEST_DIRNAME/test_util.sh" + +setup_file() { + test_util.setup_file + + PATH="$BATS_TEST_DIRNAME/bin:$PATH" +} + +setup() { + test_util.cd_test + + test_util.git_init +} + +get_ci_uri() { + local mode=$1 + + if [ "$mode" = 'github' ]; then + REPLY="https://github.com/tj/git-extras/actions" + elif [ "$mode" = 'gitlab' ]; then + REPLY="https://gitlab.com/tj/git-extras/-/pipelines" + elif [ "$mode" = 'bitbucket' ]; then + REPLY="https://bitbucket.org/tj/git-extras/addon/pipelines/home" + fi +} + +@test "works with mac and github" { + get_ci_uri 'github' + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=darwin run git browse-ci upstream + assert_output "open $expected_url" + assert_success +} + +@test "works with mac and gitlab" { + get_ci_uri 'gitlab' + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=darwin run git browse-ci upstream + assert_output "open $expected_url" + assert_success +} + +@test "works with mac and bitbucket" { + get_ci_uri 'bitbucket' + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=darwin run git browse-ci upstream + assert_output "open $expected_url" + assert_success +} + +@test "works with windows and github" { + get_ci_uri 'github' + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=msys run git browse-ci upstream + assert_output "start $expected_url" + assert_success +} + +@test "works with windows and gitlab" { + get_ci_uri 'gitlab' + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=msys run git browse-ci upstream + assert_output "start $expected_url" + assert_success +} + +@test "works with windows and bitbucket" { + get_ci_uri 'bitbucket' + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=msys run git browse-ci upstream + assert_output "start $expected_url" + assert_success +} + +@test "works with linux and github" { + get_ci_uri 'github' + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=linux-gnu run git browse-ci upstream + assert_output "xdg-open $expected_url" + assert_success +} + +@test "works with linux and gitlab" { + get_ci_uri 'gitlab' + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=linux-gnu run git browse-ci upstream + assert_output "xdg-open $expected_url" + assert_success +} + +@test "works with linux and bitbucket" { + get_ci_uri 'bitbucket' + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=linux-gnu run git browse-ci upstream + assert_output "xdg-open $expected_url" + assert_success +} diff --git a/tests/git-browse.bats b/tests/git-browse.bats new file mode 100644 index 0000000..190ef00 --- /dev/null +++ b/tests/git-browse.bats @@ -0,0 +1,123 @@ +# shellcheck shell=bash + +source "$BATS_TEST_DIRNAME/test_util.sh" + +setup_file() { + test_util.setup_file + + PATH="$BATS_TEST_DIRNAME/bin:$PATH" +} + +setup() { + test_util.cd_test + + test_util.git_init + touch ./browse_this + git add ./browse_this + git commit -m 'Add test file' +} + +get_file_uri() { + local mode=$1 + local filename=$2 + + local commit_hash= + commit_hash=$(git rev-parse HEAD) + if [ "$mode" = 'github' ]; then + REPLY="https://github.com/tj/git-extras/blob/$commit_hash/${filename}" + elif [ "$mode" = 'gitlab' ]; then + REPLY="https://gitlab.com/tj/git-extras/-/blob/${commit_hash}/${filename}" + elif [ "$mode" = 'bitbucket' ]; then + REPLY="https://bitbucket.org/tj/git-extras/src/${commit_hash}/${filename}" + fi +} + +@test "works with mac and github" { + get_file_uri github ./browse_this + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=darwin run git browse upstream ./browse_this + assert_output "open $expected_url" + assert_success +} + +@test "works with mac and gitlab" { + get_file_uri gitlab ./browse_this + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=darwin run git browse upstream ./browse_this + assert_output "open $expected_url" + assert_success +} + +@test "works with mac and bitbucket" { + get_file_uri bitbucket ./browse_this + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=darwin run git browse upstream ./browse_this + assert_output "open $expected_url" + assert_success +} + +@test "works with windows and github" { + get_file_uri github ./browse_this + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=msys run git browse upstream ./browse_this + assert_output "start $expected_url" + assert_success +} + +@test "works with windows and gitlab" { + get_file_uri gitlab ./browse_this + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=msys run git browse upstream ./browse_this + assert_output "start $expected_url" + assert_success +} + +@test "works with windows and bitbucket" { + get_file_uri bitbucket ./browse_this + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=msys run git browse upstream ./browse_this + assert_output "start $expected_url" + assert_success +} + +@test "works with linux and github" { + get_file_uri github ./browse_this + local expected_url=$REPLY + + git remote add upstream https://github.com/tj/git-extras + OSTYPE=linux-gnu run git browse upstream ./browse_this + assert_output "xdg-open $expected_url" + assert_success +} + +@test "works with linux and gitlab" { + get_file_uri gitlab ./browse_this + local expected_url=$REPLY + + git remote add upstream https://gitlab.com/tj/git-extras + OSTYPE=linux-gnu run git browse upstream ./browse_this + assert_output "xdg-open $expected_url" + assert_success +} + +@test "works with linux and bitbucket" { + get_file_uri bitbucket ./browse_this + local expected_url=$REPLY + + git remote add upstream https://bitbucket.org/tj/git-extras + OSTYPE=linux-gnu run git browse upstream ./browse_this + assert_output "xdg-open $expected_url" + assert_success +} diff --git a/tests/git-continue.bats b/tests/git-continue.bats new file mode 100755 index 0000000..da916a8 --- /dev/null +++ b/tests/git-continue.bats @@ -0,0 +1,92 @@ +#!/usr/bin/env bats + +source "$BATS_TEST_DIRNAME/test_util.sh" + +setup_file() { + test_util.setup_file +} + +setup() { + test_util.cd_test + + test_util.git_init + git commit -m 'Initial commit' --allow-empty + + git switch -c A main + printf '%s\n' 'a' >> ./tmp_file + git add ./tmp_file + git commit -m 'A' + + git switch -c B main + printf '%s\n' 'b' >> ./tmp_file + git add ./tmp_file + git commit -m 'B' +} + +@test "works with cherry pick" { + run git cherry-pick A + assert_failure + + run git status + assert_line -p 'Unmerged paths:' + assert_success + + git add . + GIT_EDITOR=cat run git continue + assert_success + + run git status + assert_line -p 'nothing to commit, working tree clean' + assert_success +} + +@test "works with merge" { + run git merge A + assert_failure + + run git status + assert_line -p 'Unmerged paths:' + assert_success + + git add . + GIT_EDITOR=cat run git continue + assert_success + + run git status + assert_line -p 'nothing to commit, working tree clean' + assert_success +} + +@test "works with rebase" { + run git rebase A + assert_failure + + run git status + assert_line -p 'Unmerged paths:' + assert_success + + git add . + GIT_EDITOR=cat run git continue + assert_success + + run git status + assert_line -p 'nothing to commit, working tree clean' + assert_success +} + +@test "works with revert" { + run git revert A + assert_failure + + run git status + assert_line -p 'Unmerged paths:' + assert_success + + git add . + GIT_EDITOR=cat run git continue + assert_failure # TODO: Git seems to do nothing and error out? + + run git status + assert_line -p 'nothing to commit, working tree clean' + assert_success +} diff --git a/tests/test_util.sh b/tests/test_util.sh index 73ca915..4c85773 100644 --- a/tests/test_util.sh +++ b/tests/test_util.sh @@ -7,14 +7,6 @@ test_util.setup_file() { export GIT_CONFIG_NOSYSTEM=1 export GIT_CONFIG_GLOBAL="$PWD/git_config" - export GIT_CONFIG_COUNT=3 - export GIT_CONFIG_KEY_0="user.email" - export GIT_CONFIG_VALUE_0="name@example.com" - export GIT_CONFIG_KEY_1="user.name" - export GIT_CONFIG_VALUE_1="Name" - # This removes default warning about default "master" branch on some Git versions. - export GIT_CONFIG_KEY_2="init.defaultBranch" - export GIT_CONFIG_VALUE_2="main" # Append to path so that we can access all commands included from git-extras # TODO: This currently breaks with commands that are included in "not_needed_git_repo" etc. @@ -24,3 +16,9 @@ test_util.setup_file() { test_util.cd_test() { cd "$BATS_TEST_TMPDIR" } + +test_util.git_init() { + git init --initial-branch main + git config user.name 'Name' + git config user.email 'name@example.com' +}