# -*- cperl -*-
use 5.010;
use strict;
use warnings;
use lib 't';
use Test::More tests => 21;
use File::Slurp;
use File::Spec::Functions 'catfile';
BEGIN { require "test-functions.pl" };
my ($repo, $file, $clone, $T) = new_repos();
my $msgfile = catfile($T, 'msg.txt');
sub check_can_commit {
my ($testname, $msg) = @_;
write_file($msgfile, {err_mode => 'carp'}, $msg)
or BAIL_OUT("check_can_commit: can't write_file('$msgfile', '$msg')\n");
append_file($file, {err_mode => 'carp'}, $testname)
or BAIL_OUT("check_can_commit: can't append_file('$file', '$testname')\n");
$repo->command(add => $file);
test_ok($testname, $repo, 'commit', '-F', $msgfile);
}
sub check_cannot_commit {
my ($testname, $regex, $msg) = @_;
write_file($msgfile, {err_mode => 'carp'}, $msg)
or BAIL_OUT("check_cannot_commit: can't write_file('$msgfile', '$msg')\n");
append_file($file, {err_mode => 'carp'}, $testname)
or BAIL_OUT("check_cannot_commit: can't append_file('$file', '$testname')\n");
$repo->command(add => $file);
if ($regex) {
test_nok_match($testname, $regex, $repo, 'commit', '-F', $msgfile);
} else {
test_nok($testname, $repo, 'commit', '-F', $msgfile);
}
}
sub check_can_push {
my ($testname, $ref) = @_;
new_commit($repo, $file, $testname);
test_ok($testname, $repo,
'push', $clone->repo_path(), $ref || 'master');
}
sub check_cannot_push {
my ($testname, $regex, $ref) = @_;
new_commit($repo, $file, $testname);
test_nok_match($testname, $regex, $repo,
'push', $clone->repo_path(), $ref || 'master');
}
install_hooks($repo, undef, 'commit-msg');
$repo->command(config => "githooks.commit-msg", 'CheckLog');
# title-required
check_cannot_commit('deny an empty message', qr/log needs a title line/, '');
check_cannot_commit('deny without required title', qr/commit's log needs a title line/, <<'EOF');
No
Title
EOF
check_can_commit('allow with required title', <<'EOF');
Title
Body
EOF
check_can_commit('allow with required title only', <<'EOF');
Title
EOF
$repo->command(config => 'CheckLog.title-required', 0);
check_can_commit('allow without non-required title', <<'EOF');
No
Title
EOF
$repo->command(config => 'CheckLog.title-required', 1);
# title-period
check_can_commit('allow without denied period', <<'EOF');
Title
EOF
check_cannot_commit('deny with denied period', qr/log title SHOULD NOT end in a period/, <<'EOF');
Title.
EOF
$repo->command(config => 'CheckLog.title-period', 'require');
check_cannot_commit('deny without required period', qr/log title SHOULD end in a period/, <<'EOF');
Title
EOF
check_can_commit('allow with required period', <<'EOF');
Title.
EOF
$repo->command(config => 'CheckLog.title-period', 'allow');
check_can_commit('allow without allowed period', <<'EOF');
Title
EOF
check_can_commit('allow with allowed period', <<'EOF');
Title.
EOF
$repo->command(config => 'CheckLog.title-period', 'invalid');
check_cannot_commit('deny due to invalid value', qr/Invalid value for the/, <<'EOF');
Title
EOF
$repo->command(config => 'CheckLog.title-period', 'deny');
# title-max-width
check_cannot_commit('deny large title', qr/log title should be at most 50 characters wide, but it has 51/, <<'EOF');
123456789012345678901234567890123456789012345678901
The above title has 51 characters.
EOF
$repo->command(config => 'CheckLog.title-max-width', 0);
check_can_commit('allow large title', <<'EOF');
123456789012345678901234567890123456789012345678901
The above title has 51 characters.
EOF
$repo->command(config => 'CheckLog.title-max-width', 50);
# body-max-width
check_cannot_commit('deny large body', qr/log body lines should be at most 72 characters wide, but there is 1 bigger/, <<'EOF');
Title
Body first line.
1234567890123456789012345678901234567890123456789012345678901234567890123
The previous line has 73 characters.
EOF
$repo->command(config => 'CheckLog.body-max-width', 0);
check_can_commit('allow large body', <<'EOF');
Title
Body first line.
123456789012345678901234567890123456789012345678900123456789001234567890123
The previous line has 73 characters.
EOF
$repo->command(config => 'CheckLog.body-max-width', 72);
# match
$repo->command(config => 'CheckLog.match', '^has to have');
$repo->command(config => '--add', 'CheckLog.match', '!^must not have');
check_can_commit('allow if matches', <<'EOF');
Title
has to have
EOF
check_cannot_commit('deny if do not match positive regex', qr/log SHOULD match/, <<'EOF');
Title
abracadabra
EOF
check_cannot_commit('deny if match negative regex', qr/log SHOULD NOT match/, <<'EOF');
Title
has to have
must not have
EOF
$repo->command(config => '--unset-all', 'CheckLog.match');
# encoding
# spelling
SKIP: {
use Git::Hooks::CheckLog;
my $checker = eval {
local $SIG{__WARN__} = sub {}; # supress warnings in this block
Git::Hooks::CheckLog::_spell_checker($repo, 'word');
};
skip "Text::SpellChecker isn't properly installed", 2 unless $checker;
check_can_commit('allow misspelling without checking', <<'EOF');
xytxuythiswordshouldnotspell
EOF
$repo->command(config => '--add', 'CheckLog.spelling', 1);
check_cannot_commit('deny misspelling with checking', qr/log has the following spelling problems in it/, <<'EOF');
xytxuythiswordshouldnotspell
EOF
$repo->command(config => '--unset-all', 'CheckLog.spelling');
}