238 lines
7.5 KiB
Perl
Executable File
238 lines
7.5 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
|
|
################################################################################
|
|
# A sub-class of Fcm::CLI::Invoker for testing
|
|
{
|
|
package TestInvoker;
|
|
use base qw{Fcm::CLI::Invoker};
|
|
|
|
our $LATEST_INSTANCE;
|
|
|
|
############################################################################
|
|
# Returns a test attrib
|
|
sub get_test_attrib {
|
|
my ($self) = @_;
|
|
return $self->{test_attrib};
|
|
}
|
|
|
|
############################################################################
|
|
# Invokes the sub-system
|
|
sub invoke {
|
|
my ($self) = @_;
|
|
$LATEST_INSTANCE = $self;
|
|
}
|
|
}
|
|
|
|
use Fcm::CLI::Config;
|
|
use Fcm::CLI::Subcommand;
|
|
use Test::More (tests => 25);
|
|
|
|
main();
|
|
|
|
sub main {
|
|
use_ok('Fcm::CLI');
|
|
test_invalid_subcommand();
|
|
test_invoker_not_implemented();
|
|
test_normal_invoke();
|
|
test_help_invoke();
|
|
test_get_invoker_normal();
|
|
test_load_invoker_class();
|
|
}
|
|
|
|
################################################################################
|
|
# Tests to ensure that an invalid subcommand results in an exception
|
|
sub test_invalid_subcommand {
|
|
Fcm::CLI::Config->instance({core_subcommands => [], vc_subcommands => []});
|
|
eval {
|
|
local(@ARGV) = ('foo');
|
|
Fcm::CLI::invoke();
|
|
};
|
|
like($@, qr{foo: unknown command}, 'invalid subcommand');
|
|
}
|
|
|
|
################################################################################
|
|
# Tests to ensure that an unimplemented invoker results in an exception
|
|
sub test_invoker_not_implemented {
|
|
Fcm::CLI::Config->instance({
|
|
core_subcommands => [
|
|
Fcm::CLI::Subcommand->new({names => ['foo']}),
|
|
Fcm::CLI::Subcommand->new({
|
|
names => ['bar'], invoker_class => 'barley',
|
|
}),
|
|
],
|
|
vc_subcommands => [],
|
|
});
|
|
eval {
|
|
local(@ARGV) = ('foo');
|
|
Fcm::CLI::invoke();
|
|
};
|
|
like($@, qr{foo: \s command \s not \s implemented}xms, 'not implemented');
|
|
eval {
|
|
local(@ARGV) = ('bar');
|
|
Fcm::CLI::invoke();
|
|
};
|
|
like($@, qr{barley: \s class \s loading \s failed}xms, 'not implemented');
|
|
}
|
|
|
|
################################################################################
|
|
# Tests normal usage of invoke
|
|
sub test_normal_invoke {
|
|
my $prefix = "normal invoke";
|
|
Fcm::CLI::Config->instance({
|
|
core_subcommands => [
|
|
Fcm::CLI::Subcommand->new({
|
|
names => ['foo'],
|
|
invoker_class => 'TestInvoker',
|
|
invoker_config => {test_attrib => 'test_attrib value'},
|
|
}),
|
|
],
|
|
vc_subcommands => [],
|
|
});
|
|
ok(!$TestInvoker::LATEST_INSTANCE, "$prefix: invoker not called");
|
|
local(@ARGV) = ('foo', 'bar', 'baz');
|
|
Fcm::CLI::invoke();
|
|
my $invoker = $TestInvoker::LATEST_INSTANCE;
|
|
if (!$invoker) {
|
|
fail($prefix);
|
|
}
|
|
else {
|
|
is($invoker->get_command(), 'foo', "$prefix: invoker command");
|
|
is_deeply({$invoker->get_options()}, {}, "$prefix: invoker options");
|
|
is_deeply([$invoker->get_arguments()], ['bar', 'baz'],
|
|
"$prefix: invoker arguments");
|
|
is($invoker->get_test_attrib(), 'test_attrib value',
|
|
"$prefix: invoker test attrib");
|
|
}
|
|
$TestInvoker::LATEST_INSTANCE = undef;
|
|
}
|
|
|
|
################################################################################
|
|
# Tests help usage of invoke
|
|
sub test_help_invoke {
|
|
my $prefix = "help invoke";
|
|
Fcm::CLI::Config->instance({
|
|
core_subcommands => [
|
|
Fcm::CLI::Subcommand->new({
|
|
names => ['foo'],
|
|
invoker_class => 'TestInvoker',
|
|
invoker_config => {test_attrib => 'test_attrib value normal'},
|
|
options => [
|
|
Fcm::CLI::Option->new({name => 'foo', is_help => 1}),
|
|
],
|
|
}),
|
|
Fcm::CLI::Subcommand->new({
|
|
names => [q{}],
|
|
invoker_class => 'TestInvoker',
|
|
}),
|
|
],
|
|
vc_subcommands => [],
|
|
});
|
|
ok(!$TestInvoker::LATEST_INSTANCE, "$prefix: invoker not called");
|
|
local(@ARGV) = ('foo', '--foo');
|
|
Fcm::CLI::invoke();
|
|
my $invoker = $TestInvoker::LATEST_INSTANCE;
|
|
if (!$invoker) {
|
|
fail($prefix);
|
|
}
|
|
else {
|
|
is_deeply([$invoker->get_arguments()], ['foo'],
|
|
"$prefix: invoker argument");
|
|
}
|
|
$TestInvoker::LATEST_INSTANCE = undef;
|
|
}
|
|
|
|
################################################################################
|
|
# Tests getting an invoker
|
|
sub test_get_invoker_normal {
|
|
my $prefix = 'get invoker normal';
|
|
my @options = (
|
|
Fcm::CLI::Option->new({name => 'foo'}),
|
|
Fcm::CLI::Option->new({name => 'bar'}),
|
|
Fcm::CLI::Option->new({name => 'baz'}),
|
|
Fcm::CLI::Option->new({
|
|
name => q{pork},
|
|
delimiter => q{,},
|
|
has_arg => Fcm::CLI::Option->ARRAY_ARG,
|
|
}),
|
|
);
|
|
my $subcommand = Fcm::CLI::Subcommand->new({options => \@options});
|
|
my %TEST = (
|
|
test1 => {
|
|
argv => ['--foo', '--bar', 'egg', 'ham', 'sausage'],
|
|
command => 'command',
|
|
options => {foo => 1, bar => 1},
|
|
arguments => ['egg', 'ham', 'sausage'],
|
|
},
|
|
test2 => {
|
|
argv => ['--baz', '--foo', '--bar'],
|
|
command => 'test',
|
|
options => {foo => 1, bar => 1, baz => 1},
|
|
arguments => [],
|
|
},
|
|
test3 => {
|
|
argv => ['egg', 'ham', 'sausage'],
|
|
command => 'meal',
|
|
options => {},
|
|
arguments => ['egg', 'ham', 'sausage'],
|
|
},
|
|
test4 => {
|
|
argv => ['--pork', 'ham', '--pork', 'sausage'],
|
|
command => 'pig',
|
|
options => {pork => ['ham', 'sausage']},
|
|
arguments => [],
|
|
},
|
|
test5 => {
|
|
argv => ['--pork', 'ham,sausage', '--pork', 'bacon', 'liver'],
|
|
command => 'pig',
|
|
options => {pork => ['ham', 'sausage', 'bacon']},
|
|
arguments => ['liver'],
|
|
},
|
|
);
|
|
for my $key (keys(%TEST)) {
|
|
local(@ARGV) = @{$TEST{$key}{argv}};
|
|
my ($opts_ref, $args_ref) = Fcm::CLI::_parse_argv_using($subcommand);
|
|
is_deeply($opts_ref, $TEST{$key}{options},
|
|
"$prefix $key: get options");
|
|
is_deeply($args_ref, $TEST{$key}{arguments},
|
|
"$prefix $key: get arguments");
|
|
}
|
|
my %BAD_TEST = (
|
|
test1 => {
|
|
argv => ['--egg', '--bar', 'foo', 'ham', 'sausage'],
|
|
},
|
|
test2 => {
|
|
argv => ['--foo=egg'],
|
|
},
|
|
);
|
|
for my $key (keys(%BAD_TEST)) {
|
|
local(@ARGV) = @{$BAD_TEST{$key}{argv}};
|
|
eval {
|
|
Fcm::CLI::_parse_argv_using($subcommand);
|
|
};
|
|
isa_ok($@, 'Fcm::CLI::Exception', "$prefix $key");
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
# Tests loading an invoker with a different class
|
|
sub test_load_invoker_class {
|
|
my $prefix = 'get invoker class';
|
|
eval {
|
|
my $subcommand = Fcm::CLI::Subcommand->new({invoker_class => 'foo'});
|
|
Fcm::CLI::_load_invoker_class_of($subcommand);
|
|
};
|
|
isa_ok($@, 'Fcm::Exception', "$prefix");
|
|
|
|
my $invoker_class = 'Fcm::CLI::Invoker::ConfigSystem';
|
|
my $subcommand
|
|
= Fcm::CLI::Subcommand->new({invoker_class => $invoker_class});
|
|
my $class = Fcm::CLI::_load_invoker_class_of($subcommand);
|
|
is($class, $invoker_class, "$prefix: $invoker_class");
|
|
}
|
|
|
|
__END__
|