App-Sqitch
view release on metacpan or search on metacpan
t/checkout.t view on Meta::CPAN
$mock_cmd->unmock('usage');
# Mock the engine interface.
my $mock_engine = Test::MockModule->new('App::Sqitch::Engine::sqlite');
my (@dep_args, @dep_changes);
$mock_engine->mock(deploy => sub {
@dep_changes = map { $_->name } shift->plan->changes;
@dep_args = @_;
});
my (@rev_args, @rev_changes);
$mock_engine->mock(revert => sub {
@rev_changes = map { $_->name } shift->plan->changes;
@rev_args = @_;
});
my @vars;
$mock_engine->mock(set_variables => sub { shift; push @vars => [@_] });
# Load up the plan file without decoding and change the plan.
$captured = file(qw(t sql sqitch.plan))->slurp;
{
no utf8;
$captured =~ s/widgets/thingÃes/;
}
# Checkout with options.
isa_ok $checkout = $CLASS->new(
log_only => 1,
lock_timeout => 30,
verify => 1,
sqitch => $sqitch,
mode => 'tag',
deploy_variables => { foo => 'bar', one => 1 },
revert_variables => { hey => 'there' },
), $CLASS, 'Object with to and variables';
ok $checkout->execute('main'), 'Checkout main';
is_deeply \@probe_args, [$client, qw(rev-parse --abbrev-ref HEAD)],
'The proper args should again have been passed to rev-parse';
is_deeply \@capture_args, [$client, 'show', 'main:'
. File::Spec->catfile(File::Spec->curdir, $checkout->default_target->plan_file)
], 'Should have requested the plan file contents as of main';
is_deeply \@run_args, [$client, qw(checkout main)], 'Should have checked out other branch';
is_deeply +MockOutput->get_warn, [], 'Should have no warnings';
is_deeply +MockOutput->get_info, [[__x(
'Last change before the branches diverged: {last_change}',
last_change => 'users @alpha',
)]], 'Should have emitted info identifying the last common change';
# Did it revert?
is_deeply \@rev_args, [$checkout->default_target->plan->get('users')->id, 1, undef],
'"users" ID and 1 should be passed to the engine revert';
is_deeply \@rev_changes, [qw(roles users widgets)],
'Should have had the current changes for revision';
# Did it deploy?
is_deeply \@dep_args, [undef, 'tag'],
'undef, "tag", and 1 should be passed to the engine deploy';
is_deeply \@dep_changes, [qw(roles users thingÃes)],
'Should have had the other branch changes (decoded) for deploy';
ok $target->engine->with_verify, 'Engine should verify';
ok $target->engine->log_only, 'The engine should be set to log_only';
is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30';
is @vars, 2, 'Variables should have been passed to the engine twice';
is_deeply { @{ $vars[0] } }, { hey => 'there' },
'The revert vars should have been passed first';
is_deeply { @{ $vars[1] } }, { foo => 'bar', one => 1 },
'The deploy vars should have been next';
# Try passing a target.
@vars = ();
ok $checkout->execute('main', 'db:sqlite:foo'), 'Checkout main with target';
is $target->name, 'db:sqlite:foo', 'Target should be passed to engine';
is_deeply +MockOutput->get_warn, [], 'Should have no warnings';
# If nothing is deployed, or we are already at the revert target, the revert
# should be skipped.
isa_ok $checkout = $CLASS->new(
target => 'db:sqlite:hello',
log_only => 0,
verify => 0,
sqitch => $sqitch,
mode => 'tag',
deploy_variables => { foo => 'bar', one => 1 },
revert_variables => { hey => 'there' },
), $CLASS, 'Object with to and variables';
$mock_engine->mock(revert => sub { hurl { ident => 'revert', message => 'foo', exitval => 1 } });
@dep_args = @rev_args = @vars = ();
ok $checkout->execute('main'), 'Checkout main again';
is $target->name, 'db:sqlite:hello', 'Target should be passed to engine';
is_deeply +MockOutput->get_warn, [], 'Should have no warnings';
# Did it deploy?
ok !$target->engine->log_only, 'The engine should not be set to log_only';
is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(),
'The lock timeout should be set to the default';
ok !$target->engine->with_verify, 'The engine should not be set with_verfy';
is_deeply \@dep_args, [undef, 'tag'],
'undef, "tag", and 1 should be passed to the engine deploy again';
is_deeply \@dep_changes, [qw(roles users thingÃes)],
'Should have had the other branch changes (decoded) for deploy again';
is @vars, 2, 'Variables should again have been passed to the engine twice';
is_deeply { @{ $vars[0] } }, { hey => 'there' },
'The revert vars should again have been passed first';
is_deeply { @{ $vars[1] } }, { foo => 'bar', one => 1 },
'The deploy vars should again have been next';
# Should get a warning for two targets.
ok $checkout->execute('main', 'db:sqlite:'), 'Checkout main again with target';
is $target->name, 'db:sqlite:hello', 'Target should be passed to engine';
is_deeply +MockOutput->get_warn, [[__x(
'Too many targets specified; connecting to {target}',
target => 'db:sqlite:hello',
)]], 'Should have warning about two targets';
# Make sure we get an exception for unknown args.
throws_ok { $checkout->execute(qw(main greg)) } 'App::Sqitch::X',
'Should get an exception for unknown arg';
is $@->ident, 'checkout', 'Unknown arg ident should be "checkout"';
is $@->message, __nx(
'Unknown argument "{arg}"',
'Unknown arguments: {arg}',
1,
arg => 'greg',
), 'Should get an exception for two unknown arg';
throws_ok { $checkout->execute(qw(main greg widgets)) } 'App::Sqitch::X',
'Should get an exception for unknown args';
is $@->ident, 'checkout', 'Unknown args ident should be "checkout"';
is $@->message, __nx(
'Unknown argument "{arg}"',
'Unknown arguments: {arg}',
2,
arg => 'greg, widgets',
), 'Should get an exception for two unknown args';
# Should die for fatal, unknown, or confirmation errors.
for my $spec (
[ confirm => App::Sqitch::X->new(ident => 'revert:confirm', message => 'foo', exitval => 1) ],
[ fatal => App::Sqitch::X->new(ident => 'revert', message => 'foo', exitval => 2) ],
[ unknown => bless { } => __PACKAGE__ ],
) {
$mock_engine->mock(revert => sub { die $spec->[1] });
throws_ok { $checkout->execute('main') } ref $spec->[1],
"Should rethrow $spec->[0] exception";
}
done_testing;
( run in 0.829 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )