Files
FlClash/tool/hooks/commit_msg_test.sh
T

121 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
checker="$script_dir/commit_msg.sh"
temp_dir="$(mktemp -d)"
trap 'rm -rf "$temp_dir"' EXIT
message_file="$temp_dir/COMMIT_EDITMSG"
failures=0
subject='fix(core): keep the socket alive'
run() {
printf '%s\n' "$@" >"$message_file"
set +e
bash "$checker" "$message_file" >"$temp_dir/out" 2>"$temp_dir/err"
local status=$?
set -e
return $status
}
expect_pass() {
local name="$1"
shift
if run "$@"; then
return
fi
echo "FAIL: $name should be accepted" >&2
cat "$temp_dir/err" >&2
failures=$((failures + 1))
}
expect_fail() {
local name="$1"
local needle="$2"
shift 2
if run "$@"; then
echo "FAIL: $name should be rejected" >&2
failures=$((failures + 1))
return
fi
if ! grep -q "$needle" "$temp_dir/err"; then
echo "FAIL: $name did not explain the problem ($needle)" >&2
cat "$temp_dir/err" >&2
failures=$((failures + 1))
fi
}
expect_stderr() {
local name="$1"
local needle="$2"
shift 2
expect_pass "$name" "$@"
if ! grep -q "$needle" "$temp_dir/err"; then
echo "FAIL: $name should have warned about $needle" >&2
failures=$((failures + 1))
fi
}
expect_pass 'a conventional subject' "$subject"
# A message left uncleaned starts with blank lines, and the subject then sits
# below line one. Cutting the body from line two would put the subject in it.
expect_fail 'a leading blank line does not hide a bad trailer' \
'Unknown changelog trailer' '' "$subject" '' 'Changelog-de: nope'
expect_pass 'a leading blank line still finds the subject' '' "$subject"
expect_pass 'a merge subject' 'Merge branch main into dev'
expect_pass 'a fixup subject' "fixup! $subject"
expect_pass 'a changelog trailer' \
'feat(profiles): support override scripts' \
'' \
'Changelog: Per-profile override scripts'
expect_pass 'a breaking commit with its footer' \
'feat(backup)!: new archive layout' \
'' \
'BREAKING CHANGE: Archives from 0.8.95 and earlier need re-import'
expect_pass 'a changelog type override' \
'refactor(tray): replace the fork' \
'' \
'Changelog: Rebuilt tray' \
'Changelog-Type: perf'
expect_fail 'an empty message' 'empty' ''
expect_fail 'a non conventional subject' 'Conventional Commits' 'Optimize core service'
expect_fail 'an upper case description' 'lower case' 'fix(core): Keep the socket alive'
expect_pass 'a camel case identifier' 'fix(ui): AppBar text is truncated'
expect_pass 'an acronym' 'fix(core): DNS leaks after wake'
expect_fail 'an upper case first word before punctuation' 'lower case' \
'fix(core): Keep, or drop, the socket'
expect_fail 'a trailing period' 'period' "$subject."
expect_fail 'a changelog translation trailer' 'Changelog-zh-CN' \
'feat: x' '' 'Changelog-zh-CN: 新功能'
expect_fail 'an unknown changelog trailer' 'Changelog-de' \
'feat: x' '' 'Changelog-de: Neu'
expect_fail 'a breaking translation trailer' 'Breaking-zh-CN' \
'feat: x' '' 'Breaking-zh-CN: 变更'
expect_fail 'an unknown changelog type' 'Changelog-Type' \
'chore: x' '' 'Changelog: X' 'Changelog-Type: docs'
expect_fail 'a breaking marker with no footer' 'BREAKING CHANGE' \
'feat(core)!: drop the legacy socket'
for trailer in \
'co-authored-by: Devin <devin@example.com>' \
'Co-authored-by: Review Helper <helper@openai.com>' \
'Co-authored-by: Cursor Agent <cursoragent@cursor.com>' \
'Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>'; do
expect_fail "an agent co-author ($trailer)" 'coding agent' \
"$subject" '' "$trailer"
done
expect_pass 'a human co-author' \
"$subject" '' 'Co-authored-by: Jane Doe <jane.doe@example.com>'
expect_stderr 'a user facing commit without a trailer' 'Changelog:' \
'feat(profiles): support override scripts'
if ((failures > 0)); then
echo "$failures check(s) failed" >&2
exit 1
fi
echo 'commit_msg.sh behaves as documented.'