# -*- 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 title has 0 lines but should have only 1/, ''); check_cannot_commit('deny without required title', qr/log title has 2 lines but should have only 1/, <<'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 one with 73/, <<'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'); }