Skip to content

Commit

Permalink
test(git-authors): add unit test
Browse files Browse the repository at this point in the history
    * remove the opening default editor after the AUTHORS generated
    * avoid the empty authors list
        https://stackoverflow.com/questions/19741957/emacs-why-shell-command-git-log-works-but-git-shortlog-doesnt/43042420#43042420
  • Loading branch information
vanpipy committed Oct 31, 2023
1 parent 5ca2f45 commit fb1139f
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 38 deletions.
89 changes: 51 additions & 38 deletions bin/git-authors
Original file line number Diff line number Diff line change
@@ -1,56 +1,69 @@
#!/usr/bin/env bash

LIST=false
NO_EMAIL=false
FILE=""
EDITOR=$(git var GIT_EDITOR)
list=0
no_email=0
output=""
file=""

if [[ $# = 1 ]] && [[ "$1" = "--no-email" ]]; then
echo >&2 "--no-email option only can be used with --list | -l | --output"
exit 1
fi

#
# list authors sorted by number of commits (descending).
#
authors() {
if [[ $no_email = 1 ]]; then
# email will be used to uniq authors.
git shortlog HEAD -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++' \
| awk -F'<' '{gsub(/ +$/, "", $1); print $1}'
else
git shortlog HEAD -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++'
fi
}

if [[ -z "$file" ]]; then
file=$(find . -mindepth 1 -maxdepth 1 -iregex '.*\(authors\|contributors\).*' | head -n1)
if [[ -z "$file" ]]; then
file="AUTHORS"
fi
fi

if [[ $# = 0 ]]; then
authors >> "$file"
exit 0
fi

while [[ $# -gt 0 ]]; do
case $1 in
-l|--list )
LIST=true
shift
list=1
;;
--no-email )
NO_EMAIL=true
shift
no_email=1
;;
--output )
if [[ -n $2 ]] && [[ $2 =~ ^[a-zA-Z] ]]; then
output=$2
shift
else
echo >&2 "option $1 requires a value"
exit 1
fi
;;
* )
break
esac
shift
done

if ! $LIST; then
FILE=$1
if [ -z "$FILE" ]; then
FILE=$(find . -mindepth 1 -maxdepth 1 \( -iname '*authors*' -o -iname '*contributors*' \) | head -n1)
if [ -z "$FILE" ]; then
FILE='AUTHORS'
fi
fi
if [[ -n "$output" ]]; then
authors >> "$output"
exit 0
fi

#
# list authors sorted by number of commits (descending).
#

authors() {
if $NO_EMAIL; then
# email will be used to uniq authors.
git shortlog -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++' \
| awk -F'<' '{gsub(/ +$/, "", $1); print $1}'
else
git shortlog -sne | awk '{$1=""; sub(" ", ""); print}' | awk -F'<' '!x[$1]++' | awk -F'<' '!x[$2]++'
fi
}

#
# authors.
#

if $LIST; then
if [[ $list = 1 ]]; then
authors
else
authors >> "$FILE"
test -n "$EDITOR" && $EDITOR "$FILE"
exit 0
fi
78 changes: 78 additions & 0 deletions tests/test_authors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import os, subprocess

expected_authors_list = "test <[email protected]>\ntestagain <[email protected]>\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", "[email protected]")
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):
git = temp_repo.get_repo_git()
rs = 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):
git = 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):
git = 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

def test_output_authors_has_email_into_AUTHORS(self, temp_repo):
git = temp_repo.get_repo_git()
temp_repo.invoke_extras_command("authors", "--output")
with open(authors_file) as f:
content = f.read()
assert content == expected_authors_list

def test_output_authors_has_email_into_target_file(self, temp_repo):
git = temp_repo.get_repo_git()
temp_repo.invoke_extras_command("authors", "--output", "AUTHORS_TARGET_FILE_A")
with open("AUTHORS_TARGET_FILE_A") as f:
content = f.read()
assert content == expected_authors_list

def test_output_authors_has_not_email_into_target_file(self, temp_repo):
git = temp_repo.get_repo_git()
rs = temp_repo.invoke_extras_command("authors", "--output", "AUTHORS_TARGET_FILE_B", "--no-email")
with open("AUTHORS_TARGET_FILE_B") as f:
content = f.read()
assert content == expected_authors_list_without_email

def test_fail_to_output_authors_when_an_option_like_follow_output_parameter(self, temp_repo):
git = temp_repo.get_repo_git()
actual = temp_repo.invoke_extras_command("authors", "--output", "--no-email")
actual = actual.stderr.decode()
assert actual == "option --output requires a value\n"

def test_fail_to_output_authors_when_only_no_email_option(self, temp_repo):
git = temp_repo.get_repo_git()
actual = temp_repo.invoke_extras_command("authors", "--no-email")
actual = actual.stderr.decode()
assert actual == "--no-email option only can be used with --list | -l | --output\n"

0 comments on commit fb1139f

Please sign in to comment.