mirror of
https://github.com/tj/git-extras.git
synced 2026-09-10 07:26:17 -04:00
port python tests to bats
Signed-off-by: spacewander <spacewanderlzx@gmail.com>
This commit is contained in:
parent
fd2e03cf55
commit
e76884aa7b
46
.github/workflows/ci.yml
vendored
46
.github/workflows/ci.yml
vendored
|
|
@ -40,57 +40,19 @@ jobs:
|
||||||
run: ./scripts/checkstyle.py
|
run: ./scripts/checkstyle.py
|
||||||
- name: Shellcheck
|
- name: Shellcheck
|
||||||
run: shellcheck --severity=error bin/* ./*.sh
|
run: shellcheck --severity=error bin/* ./*.sh
|
||||||
- name: Lint and format Python with Ruff
|
|
||||||
uses: astral-sh/ruff-action@v3
|
|
||||||
|
|
||||||
typo:
|
typo:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code.
|
- name: Check out code.
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v7
|
||||||
- name: Install poetry
|
- name: Install codespell
|
||||||
run: pip install poetry
|
run: python3 -m pip install codespell==2.4
|
||||||
- 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: spell check
|
- name: spell check
|
||||||
run: |
|
run: |
|
||||||
cd tests
|
git grep --cached -l '' . | \
|
||||||
git grep --cached -l '' .. | \
|
|
||||||
grep -v -e 'History\.md' -e 'AUTHORS' -e 'man/.*\.1' -e 'man/.*\.html' | \
|
grep -v -e 'History\.md' -e 'AUTHORS' -e 'man/.*\.1' -e 'man/.*\.html' | \
|
||||||
xargs poetry run codespell --ignore-words=../.github/.ignore_words
|
xargs 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
|
|
||||||
|
|
||||||
test-bats:
|
test-bats:
|
||||||
name: 'Test with Bats'
|
name: 'Test with Bats'
|
||||||
|
|
|
||||||
2
Makefile
2
Makefile
|
|
@ -141,6 +141,6 @@ docclean:
|
||||||
rm -f man/*.html
|
rm -f man/*.html
|
||||||
|
|
||||||
test:
|
test:
|
||||||
pytest
|
bats ./tests
|
||||||
|
|
||||||
.PHONY: default docs check install uninstall clean docclean test
|
.PHONY: default docs check install uninstall clean docclean test
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,12 @@ def main():
|
||||||
lintfile(p, rules, options)
|
lintfile(p, rules, options)
|
||||||
else:
|
else:
|
||||||
for file in Path.cwd().glob('**/*'):
|
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
|
continue
|
||||||
|
|
||||||
if file.is_file():
|
if file.is_file():
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Testing
|
# 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
|
## Bats Testing
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ We require a somewhat recent version of Bats. Version v1.8.1 is tested in CI. On
|
||||||
bats ./tests
|
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
|
### Code Coverage
|
||||||
|
|
||||||
|
|
@ -21,49 +21,3 @@ bashcov -- bats ./tests
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, the report will be generated in `./coverage/index.html`.
|
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)
|
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# Sharing fixtures
|
|
||||||
# Ref: https://docs.pytest.org/en/6.2.x/fixture.html#scope-sharing-fixtures-across-classes-modules-packages-or-session
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from helper import TempRepository
|
|
||||||
|
|
||||||
|
|
||||||
def create_repo(dirname=None):
|
|
||||||
repo = TempRepository(dirname)
|
|
||||||
repo.create_tmp_file() # tmp_file_a
|
|
||||||
repo.create_tmp_file() # tmp_file_b
|
|
||||||
repo.switch_cwd_under_repo()
|
|
||||||
return repo
|
|
||||||
|
|
||||||
|
|
||||||
def init_repo_git_status(repo):
|
|
||||||
git = repo.get_repo_git()
|
|
||||||
git.add(".")
|
|
||||||
git.config("--local", "user.name", "test")
|
|
||||||
git.config("--local", "user.email", "test@git-extras.com")
|
|
||||||
git.commit("-m", "chore: initial commit")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def temp_repo():
|
|
||||||
repo = create_repo()
|
|
||||||
init_repo_git_status(repo)
|
|
||||||
return repo
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def named_temp_repo(request):
|
|
||||||
dirname = request.param
|
|
||||||
repo = create_repo(dirname)
|
|
||||||
init_repo_git_status(repo)
|
|
||||||
yield repo
|
|
||||||
repo.teardown()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
|
||||||
def temp_repo_clean():
|
|
||||||
"""Create a temporary repository that is reset for each function call."""
|
|
||||||
repo = create_repo()
|
|
||||||
init_repo_git_status(repo)
|
|
||||||
return repo
|
|
||||||
|
|
@ -4,6 +4,7 @@ source "$BATS_TEST_DIRNAME/test_util.sh"
|
||||||
|
|
||||||
setup_file() {
|
setup_file() {
|
||||||
test_util.setup_file
|
test_util.setup_file
|
||||||
|
test_util.install_command archive-file
|
||||||
}
|
}
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
|
|
@ -37,7 +38,7 @@ setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "archive file on any not tags branch with default branch" {
|
@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
|
run git archive-file
|
||||||
assert_success
|
assert_success
|
||||||
|
|
@ -58,9 +59,32 @@ setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "archive file on dirname has backslash" {
|
@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" {
|
@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"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,16 @@ get_ci_uri() {
|
||||||
fi
|
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" {
|
@test "works with mac and github" {
|
||||||
get_ci_uri 'github'
|
get_ci_uri 'github'
|
||||||
local expected_url=$REPLY
|
local expected_url=$REPLY
|
||||||
|
|
@ -96,6 +106,110 @@ get_ci_uri() {
|
||||||
assert_success
|
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" {
|
@test "works with linux and gitlab" {
|
||||||
get_ci_uri 'gitlab'
|
get_ci_uri 'gitlab'
|
||||||
local expected_url=$REPLY
|
local expected_url=$REPLY
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,16 @@ get_file_uri() {
|
||||||
fi
|
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" {
|
@test "works with mac and github" {
|
||||||
get_file_uri github ./browse_this
|
get_file_uri github ./browse_this
|
||||||
local expected_url=$REPLY
|
local expected_url=$REPLY
|
||||||
|
|
@ -102,6 +112,148 @@ get_file_uri() {
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "works with WSL and github" {
|
||||||
|
get_file_uri github ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname microsoft
|
||||||
|
|
||||||
|
git remote add upstream https://github.com/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_line "powershell.exe -NoProfile start $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "works with WSL and gitlab" {
|
||||||
|
get_file_uri gitlab ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname microsoft
|
||||||
|
|
||||||
|
git remote add upstream https://gitlab.com/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_line "powershell.exe -NoProfile start $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "works with WSL and bitbucket" {
|
||||||
|
get_file_uri bitbucket ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname microsoft
|
||||||
|
|
||||||
|
git remote add upstream https://bitbucket.org/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_line "powershell.exe -NoProfile start $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "works with linux without Microsoft kernel and github" {
|
||||||
|
get_file_uri github ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname no-micro-soft
|
||||||
|
|
||||||
|
git remote add upstream https://github.com/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "works with linux without Microsoft kernel and gitlab" {
|
||||||
|
get_file_uri gitlab ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname no-micro-soft
|
||||||
|
|
||||||
|
git remote add upstream https://gitlab.com/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "works with linux without Microsoft kernel and bitbucket" {
|
||||||
|
get_file_uri bitbucket ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
mock_uname no-micro-soft
|
||||||
|
|
||||||
|
git remote add upstream https://bitbucket.org/tj/git-extras
|
||||||
|
OSTYPE=linux run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "falls back to xdg-open on an unknown OS with github" {
|
||||||
|
get_file_uri github ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
|
||||||
|
git remote add upstream https://github.com/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "falls back to xdg-open on an unknown OS with gitlab" {
|
||||||
|
get_file_uri gitlab ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
|
||||||
|
git remote add upstream https://gitlab.com/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "falls back to xdg-open on an unknown OS with bitbucket" {
|
||||||
|
get_file_uri bitbucket ./browse_this
|
||||||
|
local expected_url=$REPLY
|
||||||
|
|
||||||
|
git remote add upstream https://bitbucket.org/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "adds github line numbers" {
|
||||||
|
get_file_uri github ./browse_this
|
||||||
|
local expected_url="$REPLY#L10-L20"
|
||||||
|
|
||||||
|
git remote add upstream https://github.com/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this 10 20
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "adds gitlab line numbers" {
|
||||||
|
get_file_uri gitlab ./browse_this
|
||||||
|
local expected_url="$REPLY#L10-20"
|
||||||
|
|
||||||
|
git remote add upstream https://gitlab.com/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this 10 20
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "adds bitbucket line numbers" {
|
||||||
|
get_file_uri bitbucket ./browse_this
|
||||||
|
local expected_url="$REPLY#lines-10:20"
|
||||||
|
|
||||||
|
git remote add upstream https://bitbucket.org/tj/git-extras
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this 10 20
|
||||||
|
assert_output "xdg-open $expected_url"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "opens an unknown site repository" {
|
||||||
|
git remote add upstream https://unknown-site.com/tj/git-extras.git
|
||||||
|
|
||||||
|
OSTYPE=unique-system run git browse upstream
|
||||||
|
assert_output "xdg-open https://unknown-site.com/tj/git-extras"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "does not add file or line information for an unknown site" {
|
||||||
|
git remote add upstream https://unknown-site.com/tj/git-extras.git
|
||||||
|
|
||||||
|
OSTYPE=unique-system run git browse upstream ./browse_this 10 20
|
||||||
|
assert_output "xdg-open https://unknown-site.com/tj/git-extras"
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
@test "works with linux and gitlab" {
|
@test "works with linux and gitlab" {
|
||||||
get_file_uri gitlab ./browse_this
|
get_file_uri gitlab ./browse_this
|
||||||
local expected_url=$REPLY
|
local expected_url=$REPLY
|
||||||
|
|
|
||||||
130
tests/helper.py
130
tests/helper.py
|
|
@ -1,130 +0,0 @@
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import shutil
|
|
||||||
import tempfile
|
|
||||||
from git import Repo, GitCommandError
|
|
||||||
|
|
||||||
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
GIT_EXTRAS_BIN = os.path.abspath(os.path.join(CURRENT_DIR, "..", "bin"))
|
|
||||||
GIT_EXTRAS_HELPER = os.path.abspath(os.path.join(CURRENT_DIR, "..", "helper"))
|
|
||||||
|
|
||||||
GITHUB_ORIGIN = "https://github.com/tj/git-extras.git"
|
|
||||||
GITLAB_ORIGIN = "https://gitlab.com/tj/git-extras.git"
|
|
||||||
BITBUCKET_ORIGIN = "https://bitbucket.org/tj/git-extras.git"
|
|
||||||
|
|
||||||
|
|
||||||
class TempRepository:
|
|
||||||
def __init__(self, repo_work_dir=None):
|
|
||||||
self._system_tmpdir = tempfile.gettempdir()
|
|
||||||
if repo_work_dir is None:
|
|
||||||
repo_work_dir = tempfile.mkdtemp()
|
|
||||||
else:
|
|
||||||
repo_work_dir = os.path.join(self._system_tmpdir, repo_work_dir)
|
|
||||||
self._cwd = repo_work_dir
|
|
||||||
self._tempdirname = self._cwd[len(self._system_tmpdir) + 1 :]
|
|
||||||
self._git_repo = Repo.init(repo_work_dir, b="default")
|
|
||||||
self._files = []
|
|
||||||
self.change_origin_to_github()
|
|
||||||
|
|
||||||
def switch_cwd_under_repo(self):
|
|
||||||
os.chdir(self._cwd)
|
|
||||||
print(f"The current work directory has switched to {self._cwd}")
|
|
||||||
|
|
||||||
def get_cwd(self):
|
|
||||||
return self._cwd
|
|
||||||
|
|
||||||
def get_repo_dirname(self):
|
|
||||||
return self._tempdirname
|
|
||||||
|
|
||||||
def get_repo_git(self):
|
|
||||||
return self._git_repo.git
|
|
||||||
|
|
||||||
def get_file(self, index):
|
|
||||||
return self._files[index]
|
|
||||||
|
|
||||||
def get_filename(self, index):
|
|
||||||
file = self._files[index]
|
|
||||||
return file[1:]
|
|
||||||
|
|
||||||
def get_files(self):
|
|
||||||
return self._files
|
|
||||||
|
|
||||||
def create_tmp_dir(self):
|
|
||||||
tmp_dir = tempfile.mkdtemp()
|
|
||||||
return tmp_dir
|
|
||||||
|
|
||||||
def create_tmp_file(self, temp_dir=None):
|
|
||||||
if temp_dir is None:
|
|
||||||
temp_dir = self._cwd
|
|
||||||
|
|
||||||
tmp_file = tempfile.mkstemp(dir=temp_dir)
|
|
||||||
self._files.append(tmp_file[1])
|
|
||||||
return tmp_file
|
|
||||||
|
|
||||||
def remove_tmp_file(self, file_path):
|
|
||||||
os.remove(file_path)
|
|
||||||
print(f"File {file_path} has been removed")
|
|
||||||
|
|
||||||
def writefile(self, temp_file, data):
|
|
||||||
if data is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
with open(temp_file, "w", encoding="utf-8") as f:
|
|
||||||
f.write(data)
|
|
||||||
|
|
||||||
def teardown(self):
|
|
||||||
shutil.rmtree(self._cwd, ignore_errors=True)
|
|
||||||
print(f"The temp directory {self._cwd} has been removed")
|
|
||||||
|
|
||||||
def invoke_extras_command(self, name, *params):
|
|
||||||
command_name = "git-" + name
|
|
||||||
print(f"Invoke the git-extras command - {command_name} at {self._cwd}")
|
|
||||||
script = [os.path.join(GIT_EXTRAS_BIN, command_name), *list(params)]
|
|
||||||
print(f"Run the script \"{' '.join(script)}\"")
|
|
||||||
return subprocess.run(script, capture_output=True)
|
|
||||||
|
|
||||||
def invoke_installed_extras_command(self, name, *params):
|
|
||||||
command_name = "git-" + name
|
|
||||||
print(f"Invoke the git-extras command - {command_name} at {self._cwd}")
|
|
||||||
origin_extras_command = os.path.join(GIT_EXTRAS_BIN, command_name)
|
|
||||||
temp_extras_command = os.path.join(self._cwd, command_name)
|
|
||||||
helpers = [
|
|
||||||
os.path.join(GIT_EXTRAS_HELPER, "git-extra-utility"),
|
|
||||||
os.path.join(GIT_EXTRAS_HELPER, "is-git-repo"),
|
|
||||||
]
|
|
||||||
|
|
||||||
if not os.path.exists(temp_extras_command):
|
|
||||||
whole = []
|
|
||||||
with open(temp_extras_command, "w") as t:
|
|
||||||
for helper in helpers:
|
|
||||||
with open(helper) as h:
|
|
||||||
content = h.read()
|
|
||||||
whole.extend(content.splitlines())
|
|
||||||
with open(origin_extras_command) as o:
|
|
||||||
content = o.read()
|
|
||||||
first, *rest = content.splitlines()
|
|
||||||
whole.extend(rest)
|
|
||||||
whole.insert(0, first)
|
|
||||||
t.write("\n".join(whole))
|
|
||||||
print(f"Update file {temp_extras_command}")
|
|
||||||
os.chmod(temp_extras_command, 0o775)
|
|
||||||
|
|
||||||
script = [temp_extras_command, *params]
|
|
||||||
print(f'Run the script "{script}"')
|
|
||||||
return subprocess.run(script, capture_output=True)
|
|
||||||
|
|
||||||
def change_origin(self, origin_url):
|
|
||||||
try:
|
|
||||||
self._git_repo.git.remote("add", "origin", origin_url)
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
self._git_repo.git.remote("set-url", "origin", origin_url)
|
|
||||||
|
|
||||||
def change_origin_to_github(self):
|
|
||||||
self.change_origin(GITHUB_ORIGIN)
|
|
||||||
|
|
||||||
def change_origin_to_gitlab(self):
|
|
||||||
self.change_origin(GITLAB_ORIGIN)
|
|
||||||
|
|
||||||
def change_origin_to_bitbucket(self):
|
|
||||||
self.change_origin(BITBUCKET_ORIGIN)
|
|
||||||
148
tests/poetry.lock
generated
148
tests/poetry.lock
generated
|
|
@ -1,148 +0,0 @@
|
||||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "codespell"
|
|
||||||
version = "2.4.0"
|
|
||||||
description = "Fix common misspellings in text files"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
files = [
|
|
||||||
{file = "codespell-2.4.0-py3-none-any.whl", hash = "sha256:b4c5b779f747dd481587aeecb5773301183f52b94b96ed51a28126d0482eec1d"},
|
|
||||||
{file = "codespell-2.4.0.tar.gz", hash = "sha256:587d45b14707fb8ce51339ba4cce50ae0e98ce228ef61f3c5e160e34f681be58"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["Pygments", "build", "chardet", "pre-commit", "pytest", "pytest-cov", "pytest-dependency", "ruff", "tomli", "twine"]
|
|
||||||
hard-encoding-detection = ["chardet"]
|
|
||||||
toml = ["tomli"]
|
|
||||||
types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorama"
|
|
||||||
version = "0.4.6"
|
|
||||||
description = "Cross-platform colored terminal text."
|
|
||||||
optional = false
|
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
|
||||||
files = [
|
|
||||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
|
||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gitdb"
|
|
||||||
version = "4.0.11"
|
|
||||||
description = "Git Object Database"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.7"
|
|
||||||
files = [
|
|
||||||
{file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"},
|
|
||||||
{file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
smmap = ">=3.0.1,<6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gitpython"
|
|
||||||
version = "3.1.43"
|
|
||||||
description = "GitPython is a Python library used to interact with Git repositories"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.7"
|
|
||||||
files = [
|
|
||||||
{file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"},
|
|
||||||
{file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
gitdb = ">=4.0.1,<5"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"]
|
|
||||||
test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iniconfig"
|
|
||||||
version = "2.0.0"
|
|
||||||
description = "brain-dead simple config-ini parsing"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.7"
|
|
||||||
files = [
|
|
||||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
|
||||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "packaging"
|
|
||||||
version = "24.2"
|
|
||||||
description = "Core utilities for Python packages"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
files = [
|
|
||||||
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
|
|
||||||
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pluggy"
|
|
||||||
version = "1.5.0"
|
|
||||||
description = "plugin and hook calling mechanisms for python"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
files = [
|
|
||||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
|
||||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["pre-commit", "tox"]
|
|
||||||
testing = ["pytest", "pytest-benchmark"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pytest"
|
|
||||||
version = "8.1.2"
|
|
||||||
description = "pytest: simple powerful testing with Python"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
files = [
|
|
||||||
{file = "pytest-8.1.2-py3-none-any.whl", hash = "sha256:6c06dc309ff46a05721e6fd48e492a775ed8165d2ecdf57f156a80c7e95bb142"},
|
|
||||||
{file = "pytest-8.1.2.tar.gz", hash = "sha256:f3c45d1d5eed96b01a2aea70dee6a4a366d51d38f9957768083e4fecfc77f3ef"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
|
||||||
iniconfig = "*"
|
|
||||||
packaging = "*"
|
|
||||||
pluggy = ">=1.4,<2.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smmap"
|
|
||||||
version = "5.0.1"
|
|
||||||
description = "A pure Python implementation of a sliding window memory map manager"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.7"
|
|
||||||
files = [
|
|
||||||
{file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"},
|
|
||||||
{file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "testpath"
|
|
||||||
version = "0.6.0"
|
|
||||||
description = "Test utilities for code working with files and commands"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">= 3.5"
|
|
||||||
files = [
|
|
||||||
{file = "testpath-0.6.0-py3-none-any.whl", hash = "sha256:8ada9f80a2ac6fb0391aa7cdb1a7d11cfa8429f693eda83f74dde570fe6fa639"},
|
|
||||||
{file = "testpath-0.6.0.tar.gz", hash = "sha256:2f1b97e6442c02681ebe01bd84f531028a7caea1af3825000f52345c30285e0f"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
test = ["pytest"]
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
lock-version = "2.0"
|
|
||||||
python-versions = "^3.12"
|
|
||||||
content-hash = "fcf0ba3dd6655735da5c1e21ba32b94011d32bc5a30fbdaf31146d3820c1442a"
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
[tool.poetry]
|
|
||||||
name = "git-extras-tests"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "tests for git extras"
|
|
||||||
package-mode = false
|
|
||||||
authors = ["vanpipy <vanpipy@gmail.com>"]
|
|
||||||
license = "MIT"
|
|
||||||
readme = "README.md"
|
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
|
||||||
python = "^3.12"
|
|
||||||
|
|
||||||
[tool.poetry.group.test.dependencies]
|
|
||||||
pytest = "8.1.2"
|
|
||||||
gitpython = "3.1.43"
|
|
||||||
testpath = "0.6.0"
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
|
||||||
codespell = "2.4"
|
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
minversion = "7.4"
|
|
||||||
addopts = "-ra -q"
|
|
||||||
testpaths = ["."]
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry-core"]
|
|
||||||
build-backend = "poetry.core.masonry.api"
|
|
||||||
|
|
||||||
[tool.ruff]
|
|
||||||
# Exclude a variety of commonly ignored directories.
|
|
||||||
exclude = [
|
|
||||||
".bzr",
|
|
||||||
".direnv",
|
|
||||||
".eggs",
|
|
||||||
".git",
|
|
||||||
".git-rewrite",
|
|
||||||
".hg",
|
|
||||||
".ipynb_checkpoints",
|
|
||||||
".mypy_cache",
|
|
||||||
".nox",
|
|
||||||
".pants.d",
|
|
||||||
".pyenv",
|
|
||||||
".pytest_cache",
|
|
||||||
".pytype",
|
|
||||||
".ruff_cache",
|
|
||||||
".svn",
|
|
||||||
".tox",
|
|
||||||
".venv",
|
|
||||||
".vscode",
|
|
||||||
"__pypackages__",
|
|
||||||
"_build",
|
|
||||||
"buck-out",
|
|
||||||
"build",
|
|
||||||
"dist",
|
|
||||||
"node_modules",
|
|
||||||
"site-packages",
|
|
||||||
"venv",
|
|
||||||
]
|
|
||||||
|
|
||||||
# Same as Black.
|
|
||||||
line-length = 88
|
|
||||||
indent-width = 4
|
|
||||||
|
|
||||||
# Assume Python 3.9
|
|
||||||
target-version = "py39"
|
|
||||||
|
|
||||||
[tool.ruff.lint]
|
|
||||||
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
|
||||||
select = ["E4", "E7", "E9", "F"]
|
|
||||||
ignore = []
|
|
||||||
|
|
||||||
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
||||||
fixable = ["ALL"]
|
|
||||||
unfixable = []
|
|
||||||
|
|
||||||
# Allow unused variables when underscore-prefixed.
|
|
||||||
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
||||||
|
|
||||||
[tool.ruff.format]
|
|
||||||
# Like Black, use double quotes for strings.
|
|
||||||
quote-style = "double"
|
|
||||||
|
|
||||||
# Like Black, indent with spaces, rather than tabs.
|
|
||||||
indent-style = "space"
|
|
||||||
|
|
||||||
# Like Black, respect magic trailing commas.
|
|
||||||
skip-magic-trailing-comma = false
|
|
||||||
|
|
||||||
# Like Black, automatically detect the appropriate line ending.
|
|
||||||
line-ending = "auto"
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
from git import GitCommandError
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitAbort:
|
|
||||||
def test_init(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
tmp_file = temp_repo.get_file(0)
|
|
||||||
git.branch("A")
|
|
||||||
git.branch("B")
|
|
||||||
git.checkout("A")
|
|
||||||
temp_repo.writefile(tmp_file, "a")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "A")
|
|
||||||
git.checkout("B")
|
|
||||||
temp_repo.writefile(tmp_file, "b")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "B")
|
|
||||||
git.status()
|
|
||||||
|
|
||||||
def test_cherry_pick(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.cherry_pick("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
temp_repo.invoke_extras_command("abort")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_merge(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.merge("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
temp_repo.invoke_extras_command("abort")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_rebase(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.rebase("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
temp_repo.invoke_extras_command("abort")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_revert(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.revert("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
temp_repo.invoke_extras_command("abort")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
class TestGitAlias:
|
|
||||||
def test_init(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.config("--global", "alias.globalalias", "status")
|
|
||||||
git.config("--global", "alias.x", "status")
|
|
||||||
git.config("--local", "alias.localalias", "status")
|
|
||||||
git.config("--local", "alias.y", "status")
|
|
||||||
|
|
||||||
def test_list_all(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "globalalias = status" in actual
|
|
||||||
assert "x = status" in actual
|
|
||||||
assert "localalias = status" in actual
|
|
||||||
assert "y = status" in actual
|
|
||||||
|
|
||||||
def test_list_all_globally(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--global")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "globalalias = status" in actual
|
|
||||||
|
|
||||||
def test_list_all_locally(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--local")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "localalias = status" in actual
|
|
||||||
|
|
||||||
def test_search_globally(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--global", "global")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "globalalias = status" in actual
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--global", "local")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "" == actual
|
|
||||||
|
|
||||||
def test_search_locally(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--local", "local")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "localalias = status" in actual
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--local", "global")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "" == actual
|
|
||||||
|
|
||||||
def test_get_alias_globally_and_defaultly(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "globalalias")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "globalalias = status" in actual
|
|
||||||
|
|
||||||
def test_set_alias_globally_and_defaultly(self, temp_repo):
|
|
||||||
temp_repo.invoke_extras_command("alias", "globalalias", "diff")
|
|
||||||
actual = temp_repo.invoke_extras_command("alias")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "globalalias = diff" in actual
|
|
||||||
|
|
||||||
def test_get_alias_locally(self, temp_repo):
|
|
||||||
actual = temp_repo.invoke_extras_command("alias", "--local", "localalias")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "localalias = status" in actual
|
|
||||||
|
|
||||||
def test_set_alias_locally(self, temp_repo):
|
|
||||||
temp_repo.invoke_extras_command("alias", "--local", "localalias", "diff")
|
|
||||||
actual = temp_repo.invoke_extras_command("alias")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert "localalias = diff" in actual
|
|
||||||
|
|
||||||
def test_teardown(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.config("--global", "--unset", "alias.globalalias")
|
|
||||||
git.config("--global", "--unset", "alias.x")
|
|
||||||
git.config("--local", "--unset", "alias.localalias")
|
|
||||||
git.config("--local", "--unset", "alias.y")
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import os
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitArchiveFile:
|
|
||||||
def test_init(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
tmp_file = temp_repo.get_file(0)
|
|
||||||
temp_repo.writefile(tmp_file, "data")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "test: add data")
|
|
||||||
git.tag("0.1.0", "-m", "bump: 0.1.0")
|
|
||||||
|
|
||||||
def test_archive_file_on_tags_branch(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.checkout("-b", "tags0.1.0")
|
|
||||||
temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
filename = "{0}.{1}.zip".format(temp_repo.get_repo_dirname(), git.describe())
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
||||||
def test_archive_file_on_any_not_tags_branch_without_default_branch(
|
|
||||||
self, temp_repo
|
|
||||||
):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.checkout("-b", "not-tags-branch")
|
|
||||||
temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
filename = "{0}.{1}.{2}.zip".format(
|
|
||||||
temp_repo.get_repo_dirname(),
|
|
||||||
git.describe("--always", "--long"),
|
|
||||||
"not-tags-branch",
|
|
||||||
)
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
||||||
def test_archive_file_on_any_not_tags_branch_with_default_branch(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.checkout("default")
|
|
||||||
git.config("git-extras.default-branch", "default")
|
|
||||||
temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
filename = "{0}.{1}.zip".format(
|
|
||||||
temp_repo.get_repo_dirname(), git.describe("--always", "--long")
|
|
||||||
)
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
||||||
def test_archive_file_on_branch_name_has_slash(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.checkout("-b", "feature/slash")
|
|
||||||
temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
filename = "{0}.{1}.{2}.zip".format(
|
|
||||||
temp_repo.get_repo_dirname(),
|
|
||||||
git.describe("--always", "--long"),
|
|
||||||
"feature-slash",
|
|
||||||
)
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("named_temp_repo", ["backslash\\dir"], indirect=True)
|
|
||||||
def test_archive_file_on_dirname_has_backslash(self, named_temp_repo):
|
|
||||||
named_temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
git = named_temp_repo.get_repo_git()
|
|
||||||
filename = "{0}.{1}.{2}.zip".format(
|
|
||||||
"backslash-dir", git.describe("--always", "--long"), "default"
|
|
||||||
)
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
||||||
def test_archive_file_on_tag_name_has_slash(self, temp_repo):
|
|
||||||
temp_repo.switch_cwd_under_repo()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
git.checkout("default")
|
|
||||||
git.tag("--delete", "0.1.0")
|
|
||||||
git.tag("0.1.0/slash", "-m", "bump: 0.1.0")
|
|
||||||
temp_repo.invoke_installed_extras_command("archive-file")
|
|
||||||
description_include_version = git.describe("--always", "--long")
|
|
||||||
filename = "{0}.{1}.zip".format(
|
|
||||||
temp_repo.get_repo_dirname(), description_include_version.replace("/", "-")
|
|
||||||
)
|
|
||||||
assert filename in os.listdir()
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
expected_authors_list = (
|
|
||||||
"test <test@git-extras.com>\ntestagain <testagain@git-extras.com>\n"
|
|
||||||
)
|
|
||||||
expected_authors_list_without_email = "test\ntestagain\n"
|
|
||||||
authors_file = "AUTHORS"
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitAuthors:
|
|
||||||
def test_init(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
tmp_file = temp_repo.get_file(0)
|
|
||||||
temp_repo.writefile(tmp_file, "A")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "test: add data A")
|
|
||||||
git.config("--local", "user.name", "testagain")
|
|
||||||
git.config("--local", "user.email", "testagain@git-extras.com")
|
|
||||||
temp_repo.writefile(tmp_file, "B")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "test: add data B")
|
|
||||||
|
|
||||||
def test_output_authors_has_email_without_any_parameter(self, temp_repo):
|
|
||||||
temp_repo.get_repo_git()
|
|
||||||
temp_repo.invoke_extras_command("authors")
|
|
||||||
with open(authors_file) as f:
|
|
||||||
content = f.read()
|
|
||||||
print(content)
|
|
||||||
print(expected_authors_list)
|
|
||||||
assert content == expected_authors_list
|
|
||||||
|
|
||||||
def test_list_authors_has_email_defaultly(self, temp_repo):
|
|
||||||
temp_repo.get_repo_git()
|
|
||||||
actual = temp_repo.invoke_extras_command("authors", "--list")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert actual == expected_authors_list
|
|
||||||
actual = temp_repo.invoke_extras_command("authors", "-l")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert actual == expected_authors_list
|
|
||||||
|
|
||||||
def test_list_authors_has_not_email(self, temp_repo):
|
|
||||||
temp_repo.get_repo_git()
|
|
||||||
actual = temp_repo.invoke_extras_command("authors", "--list", "--no-email")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert actual == expected_authors_list_without_email
|
|
||||||
actual = temp_repo.invoke_extras_command("authors", "-l", "--no-email")
|
|
||||||
actual = actual.stdout.decode()
|
|
||||||
assert actual == expected_authors_list_without_email
|
|
||||||
|
|
@ -1,244 +0,0 @@
|
||||||
from testpath import MockCommand, modified_env
|
|
||||||
|
|
||||||
UNKNOWN_SITE_ORIGIN = "https://unknown-site.com/tj/git-extras.git"
|
|
||||||
|
|
||||||
|
|
||||||
def get_file_uri(mode, filename, git):
|
|
||||||
commit_hash = git.rev_parse("HEAD")
|
|
||||||
if mode == "github":
|
|
||||||
return "https://github.com/tj/git-extras/blob/" + commit_hash + "/" + filename
|
|
||||||
if mode == "gitlab":
|
|
||||||
return "https://gitlab.com/tj/git-extras/-/blob/" + commit_hash + "/" + filename
|
|
||||||
if mode == "bitbucket":
|
|
||||||
return "https://bitbucket.org/tj/git-extras/src/" + commit_hash + "/" + filename
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitBrowse:
|
|
||||||
def test_browse_github_file_on_mac(self, temp_repo):
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_on_mac(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_on_mac(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_file_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_file_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_file_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_file_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename)
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_file_with_line_number(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename, "10", "20")
|
|
||||||
expected_url = get_file_uri("github", filename, git)
|
|
||||||
openCommand.assert_called([expected_url + "#L10-L20"])
|
|
||||||
|
|
||||||
def test_browse_gitlab_file_with_line_number(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename, "10", "20")
|
|
||||||
expected_url = get_file_uri("gitlab", filename, git)
|
|
||||||
openCommand.assert_called([expected_url + "#L10-20"])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_file_with_line_number(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
git = temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename, "10", "20")
|
|
||||||
expected_url = get_file_uri("bitbucket", filename, git)
|
|
||||||
openCommand.assert_called([expected_url + "#lines-10:20"])
|
|
||||||
|
|
||||||
def test_browse_unknown_site_file(self, temp_repo):
|
|
||||||
temp_repo.change_origin(UNKNOWN_SITE_ORIGIN)
|
|
||||||
temp_repo.get_repo_git()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin")
|
|
||||||
openCommand.assert_called([UNKNOWN_SITE_ORIGIN[0:-4]])
|
|
||||||
|
|
||||||
def test_browse_unknown_site_file_with_line_number(self, temp_repo):
|
|
||||||
temp_repo.get_repo_git()
|
|
||||||
filename = temp_repo.get_filename(0)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse", "origin", filename, "10", "20")
|
|
||||||
openCommand.assert_called([UNKNOWN_SITE_ORIGIN[0:-4]])
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
from testpath import MockCommand, modified_env
|
|
||||||
|
|
||||||
UNKNOWN_SITE_ORIGIN = "https://unknown-site.com/tj/git-extras.git"
|
|
||||||
|
|
||||||
|
|
||||||
def get_ci_uri_by_domain(mode):
|
|
||||||
if mode == "github":
|
|
||||||
return "https://github.com/tj/git-extras/actions"
|
|
||||||
if mode == "gitlab":
|
|
||||||
return "https://gitlab.com/tj/git-extras/-/pipelines"
|
|
||||||
if mode == "bitbucket":
|
|
||||||
return "https://bitbucket.org/tj/git-extras/addon/pipelines/home"
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitBrowse:
|
|
||||||
def test_browse_github_ci_on_mac(self, temp_repo):
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("github")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_ci_on_mac(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("gitlab")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_ci_on_mac(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
with modified_env({"OSTYPE": "darwin"}), MockCommand("open") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("bitbucket")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_ci_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("github")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_ci_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("gitlab")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_ci_on_git_bash_on_window(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
with modified_env({"OSTYPE": "msys"}), MockCommand("start") as openCommand:
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("bitbucket")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_ci_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("github")
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_ci_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("gitlab")
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_ci_on_WSL_with_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "microsoft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("powershell.exe") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("bitbucket")
|
|
||||||
openCommand.assert_called(["-NoProfile", "start", expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_ci_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("github")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_ci_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("gitlab")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_ci_on_WSL_without_microsoft_key(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "linux"}),
|
|
||||||
MockCommand.fixed_output("uname", "no-micro-soft"),
|
|
||||||
MockCommand.fixed_output("command", "/powershell.exe"),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("bitbucket")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_github_ci_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_github()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("github")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_gitlab_ci_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_gitlab()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("gitlab")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_bitbucket_ci_not_mac_or_msys_or_linux(self, temp_repo):
|
|
||||||
temp_repo.change_origin_to_bitbucket()
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
expected_url = get_ci_uri_by_domain("bitbucket")
|
|
||||||
openCommand.assert_called([expected_url])
|
|
||||||
|
|
||||||
def test_browse_unknown_site_file(self, temp_repo):
|
|
||||||
temp_repo.change_origin(UNKNOWN_SITE_ORIGIN)
|
|
||||||
with (
|
|
||||||
modified_env({"OSTYPE": "unique-system"}),
|
|
||||||
MockCommand("xdg-open") as openCommand,
|
|
||||||
):
|
|
||||||
temp_repo.invoke_extras_command("browse-ci", "origin")
|
|
||||||
openCommand.assert_called([""])
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
from git import GitCommandError
|
|
||||||
|
|
||||||
|
|
||||||
class TestGitContinue:
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _init_repo(cls, repo):
|
|
||||||
git = repo.get_repo_git()
|
|
||||||
tmp_file = repo.get_file(0)
|
|
||||||
git.branch("A")
|
|
||||||
git.branch("B")
|
|
||||||
git.branch("C")
|
|
||||||
git.checkout("A")
|
|
||||||
repo.writefile(tmp_file, "a")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "A")
|
|
||||||
git.checkout("B")
|
|
||||||
repo.writefile(tmp_file, "b")
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "B")
|
|
||||||
|
|
||||||
def test_init(self, temp_repo_clean):
|
|
||||||
TestGitContinue._init_repo(temp_repo_clean)
|
|
||||||
git = temp_repo_clean.get_repo_git()
|
|
||||||
git.status()
|
|
||||||
|
|
||||||
def test_cherry_pick(self, temp_repo_clean):
|
|
||||||
TestGitContinue._init_repo(temp_repo_clean)
|
|
||||||
git = temp_repo_clean.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.cherry_pick("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
git.add(".")
|
|
||||||
temp_repo_clean.invoke_extras_command("continue")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_merge(self, temp_repo_clean):
|
|
||||||
TestGitContinue._init_repo(temp_repo_clean)
|
|
||||||
git = temp_repo_clean.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.merge("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "resolve conflict")
|
|
||||||
temp_repo_clean.invoke_extras_command("continue")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_rebase(self, temp_repo_clean):
|
|
||||||
TestGitContinue._init_repo(temp_repo_clean)
|
|
||||||
git = temp_repo_clean.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.rebase("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "resolve conflict")
|
|
||||||
temp_repo_clean.invoke_extras_command("continue")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
||||||
def test_revert(self, temp_repo_clean):
|
|
||||||
TestGitContinue._init_repo(temp_repo_clean)
|
|
||||||
git = temp_repo_clean.get_repo_git()
|
|
||||||
try:
|
|
||||||
git.revert("A")
|
|
||||||
except GitCommandError as err:
|
|
||||||
print(err)
|
|
||||||
result = git.status()
|
|
||||||
assert "Unmerged path" in result
|
|
||||||
git.add(".")
|
|
||||||
git.commit("-m", "resolve conflict")
|
|
||||||
temp_repo_clean.invoke_extras_command("continue")
|
|
||||||
result = git.status()
|
|
||||||
assert "nothing to commit, working tree clean" in result
|
|
||||||
|
|
@ -13,6 +13,29 @@ test_util.setup_file() {
|
||||||
PATH="$BATS_TEST_DIRNAME/../bin:$PATH"
|
PATH="$BATS_TEST_DIRNAME/../bin:$PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_util.install_command() {
|
||||||
|
local command_name="git-$1"
|
||||||
|
local install_dir="$BATS_FILE_TMPDIR/bin"
|
||||||
|
local target="$install_dir/$command_name"
|
||||||
|
|
||||||
|
mkdir -p "$install_dir"
|
||||||
|
{
|
||||||
|
head -n 1 "$BATS_TEST_DIRNAME/../bin/$command_name"
|
||||||
|
cat "$BATS_TEST_DIRNAME/../helper/reset-env"
|
||||||
|
cat "$BATS_TEST_DIRNAME/../helper/git-extra-utility"
|
||||||
|
if ! grep -qx "$command_name" "$BATS_TEST_DIRNAME/../not_need_git_repo"; then
|
||||||
|
cat "$BATS_TEST_DIRNAME/../helper/is-git-repo"
|
||||||
|
fi
|
||||||
|
if grep -qx "$command_name" "$BATS_TEST_DIRNAME/../need_git_commit"; then
|
||||||
|
cat "$BATS_TEST_DIRNAME/../helper/has-git-commit"
|
||||||
|
fi
|
||||||
|
tail -n +2 "$BATS_TEST_DIRNAME/../bin/$command_name"
|
||||||
|
} > "$target"
|
||||||
|
chmod 775 "$target"
|
||||||
|
|
||||||
|
PATH="$install_dir:$PATH"
|
||||||
|
}
|
||||||
|
|
||||||
test_util.cd_test() {
|
test_util.cd_test() {
|
||||||
cd "$BATS_TEST_TMPDIR"
|
cd "$BATS_TEST_TMPDIR"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue