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 )