Code-TidyAll
view release on metacpan or search on metacpan
t/lib/TestFor/Code/TidyAll/Git.pm view on Meta::CPAN
sub test_git : Tests {
my ($self) = @_;
return unless $self->require_executable('git');
my ( $temp_dir, $work_dir, $pushd ) = $self->_make_working_dir_and_repo;
subtest 'add foo.txt', sub {
$work_dir->child('foo.txt')->spew_raw("abc\n");
cmp_deeply( [ git_files_to_commit($work_dir) ], [], 'no files to commit' );
runx(qw( git add foo.txt ));
cmp_deeply(
[ map { $_->stringify } git_files_to_commit($work_dir) ],
[ $work_dir->child('foo.txt')->stringify ], 'one file to commit'
);
};
subtest 'attempt to commit untidy file', sub {
my $output = capture_stderr { system(qw( git commit -q -m changed -a )) };
like( $output, qr/1 file did not pass tidyall check/, '1 file did not pass tidyall check' );
like( $output, qr/needs tidying/, 'needs tidying' );
$self->_assert_something_to_commit($work_dir);
};
subtest 'successfully commit tidied file', sub {
$work_dir->child('foo.txt')->spew_raw("ABC\n");
my $output = capture_stderr { runx(qw( git commit -q -m changed -a )) };
like( $output, qr/\[checked\] foo\.txt/, 'checked foo.txt' );
$self->_assert_nothing_to_commit($work_dir);
};
subtest 'add another file which is tidied', sub {
$work_dir->child('bar.txt')->spew_raw('ABC');
runx(qw( git add bar.txt ));
runx(qw( git commit -q -m bar.txt ));
$work_dir->child('bar.txt')->spew('def');
cmp_deeply( [ git_files_to_commit($work_dir) ], [], 'no files to commit' );
cmp_deeply(
[ map { $_->stringify } git_modified_files($work_dir) ],
["$work_dir/bar.txt"],
'one file was modified'
);
};
my ( $shared_dir, $clone_dir );
subtest 'create bare repo and clone it', sub {
$shared_dir = $temp_dir->child('shared');
$clone_dir = $temp_dir->child('clone');
runx( qw( git clone -q --bare ), map { _quote_for_win32($_) } $work_dir, $shared_dir );
runx( qw( git clone -q ), map { _quote_for_win32($_) } $shared_dir, $clone_dir );
chdir($clone_dir);
$self->_assert_nothing_to_commit($work_dir);
};
my $prereceive_hook_file = $shared_dir->child(qw( hooks pre-receive ));
my $prereceive_hook = sprintf( $prereceive_hook_template, $self->_lib_dirs );
$prereceive_hook_file->spew($prereceive_hook);
$prereceive_hook_file->chmod(0775);
subtest 'untidy file and attempt to commit it via commit -a', sub {
$clone_dir->child('foo.txt')->spew_raw("def\n");
runx(qw( git commit -q -m changed -a ));
$self->_assert_nothing_to_commit($work_dir);
$self->_assert_branch_is_ahead_of_origin;
};
subtest 'cannot push untidy file', sub {
my $output = capture_stderr { system(qw( git push )) };
like( $output, qr/master -> master/, 'master -> master' );
like( $output, qr/1 file did not pass tidyall check/, '1 file did not pass tidyall check' );
like( $output, qr/needs tidying/, 'needs tidying' );
$self->_assert_branch_is_ahead_of_origin;
};
subtest 'can push tidied file', sub {
$clone_dir->child('foo.txt')->spew_raw("DEF\n");
capture_stderr { runx(qw( git commit -q -m changed -a )) };
$self->_assert_nothing_to_commit($work_dir);
my $output = capture_stderr { system(qw( git push )) };
like( $output, qr/master -> master/, 'push succeeded' );
$self->_assert_nothing_to_push;
};
subtest 'untidy file and commit it', sub {
$clone_dir->child('foo.txt')->spew_raw("def\n");
runx(qw( git commit -q -m changed -a ));
$self->_assert_nothing_to_commit($work_dir);
$self->_assert_branch_is_ahead_of_origin;
};
subtest 'cannot push when file is untidy', sub {
$self->_assert_branch_is_ahead_of_origin;
my $output = capture_stderr { system(qw( git push )) };
like( $output, qr/needs tidying/, 'needs tidying' );
$self->_assert_branch_is_ahead_of_origin;
};
subtest 'cannot push when file is untidy (2nd try)', sub {
$self->_assert_branch_is_ahead_of_origin;
my $output = capture_stderr { system(qw( git push )) };
like( $output, qr/needs tidying/, 'needs tidying' );
like( $output, qr/Identical push seen 2 times/, 'Identical push seen 2 times' );
$self->_assert_branch_is_ahead_of_origin;
};
}
sub test_copied_status : Tests {
my ($self) = @_;
return unless $self->require_executable('git');
my ( $temp_dir, $work_dir, $pushd ) = $self->_make_working_dir_and_repo;
my $foo_file = $work_dir->child('foo.txt');
# If the file isn't long enough the new file doesn't end up with the
# "copied" status.
$foo_file->spew_raw( "ABC\n" x 500 );
t/lib/TestFor/Code/TidyAll/Git.pm view on Meta::CPAN
$work_dir->child('file1.txt')->spew("A\nB\n");
$work_dir->child('file2.txt')->spew("A\nB\n");
runx(qw( git add file1.txt file2.txt ));
runx( qw( git commit -m ), 'Add files in master' );
$work_dir->child('file1.txt')->append("C\n");
$work_dir->child('file2.txt')->append("C\n");
runx( qw( git commit -a -m ), 'Update files in master' );
runx(qw( git checkout -b my-branch ));
runx(qw( git reset --hard HEAD~1 ));
$work_dir->child('file1.txt')->append("D\n");
$work_dir->child('file2.txt')->append("C\n");
runx(qw( git add file1.txt file2.txt ));
runx( qw( git commit -m ), 'Update files in my-branch' );
# This will exit with 1 because of the conflict.
runx( [1], qw( git merge master ) );
like(
$work_dir->child(qw( .git MERGE_MSG ))->slurp,
qr/Conflicts:.+file1\.txt/s,
'merge produced a conflict with file.txt'
);
$work_dir->child('file1.txt')->spew("A\nB\nD\n");
# We need a change that will be stashed to trigger the bug.
$work_dir->child('file2.txt')->append("E\n");
runx(qw( git add file1.txt ));
runx( qw( git commit -m ), 'Add file1.txt in my-branch for real' );
my $output = capturex(qw( git log -n 1 ));
like( $output, qr/Merge: [0-9a-f]+ [0-9a-f]+/, 'last commit was a merge commit' );
}
sub _make_working_dir_and_repo {
my $self = shift;
my $temp_dir = tempdir_simple;
my $work_dir = $temp_dir->child('work');
my $hooks_dir = $work_dir->child(qw( .git hooks ));
runx( qw( git init -q ), _quote_for_win32($work_dir) );
# This dir doesn't exist unless there's a git dir template that includes
# the hooks subdir.
$hooks_dir->mkpath( { verbose => 0, mode => 0755 } );
ok( -d $_, "$_ exists" ) for ( $work_dir, $hooks_dir );
my $pushd = pushd($work_dir);
$work_dir->child('tidyall.ini')->spew($tidyall_ini_template);
$work_dir->child('.gitignore')->spew('.tidyall.d');
runx(qw( git add tidyall.ini .gitignore ));
runx(qw( git commit -q -m added tidyall.ini .gitignore ));
my $precommit_hook_file = $hooks_dir->child('pre-commit');
my $precommit_hook = sprintf( $precommit_hook_template, $self->_lib_dirs );
$precommit_hook_file->spew($precommit_hook);
$precommit_hook_file->chmod(0755);
return ( $temp_dir, $work_dir, $pushd );
}
sub _quote_for_win32 {
# The docs for IPC::System::Simple lie about how it works on Windows. On
# Windows it _always_ invokes a shell, so we need to quote a path with
# spaces.
return $_[0] unless IS_WIN32 && $_[0] =~ / /;
return qq{"$_[0]"};
}
sub _lib_dirs {
my %dirs = map { $_ => 1 } map { path($Bin)->parent->child($_) } qw( lib t/lib );
if ( $ENV{PERL5LIB} ) {
my $sep = $^O eq 'MSWin32' ? q{;} : q{:};
$dirs{$_} = 1 for split /\Q$sep/, $ENV{PERL5LIB};
}
return join q{ }, sort keys %dirs;
}
sub _assert_nothing_to_commit {
shift;
my @files = git_files_to_commit(shift);
is( scalar @files, 0, 'there are no files to commit' )
or diag("@files");
}
sub _assert_something_to_commit {
shift;
my @files = git_files_to_commit(shift);
cmp_ok( scalar @files, '>=', 0, 'there are files to commit' );
}
sub _assert_nothing_to_push {
unlike(
capturex( 'git', 'status' ),
qr/Your branch is ahead/,
'branch is up to date with origin'
);
}
sub _assert_branch_is_ahead_of_origin {
like( capturex( 'git', 'status' ), qr/Your branch is ahead/, 'branch is ahead of origin' );
}
$precommit_hook_template = '#!' . $^X . "\n" . <<'EOF';
use lib qw(%s);
use Code::TidyAll::Git::Precommit;
use strict;
use warnings;
Code::TidyAll::Git::Precommit->check(
tidyall_options => { verbose => 1 }
);
EOF
$prereceive_hook_template = '#!' . $^X . "\n" . <<'EOF';
use lib qw(%s);
( run in 0.666 second using v1.01-cache-2.11-cpan-39bf76dae61 )