trAvis - MANAGER
Edit File: descriptive.t
#!/usr/bin/perl use strict; use warnings; use Test::More tests => 42; use_ok("Getopt::Long::Descriptive"); # test constraints: # (look at P::V for names, too) # required => 1 # depends => [...] # precludes => [...] # sugar for only_one_of and all_or_none sub is_opt { my ($argv, $specs, $expect, $desc) = @_; local @ARGV = @$argv; eval { my ($opt, $usage) = describe_options( "test %o", @$specs, ); is_deeply( $opt, $expect, $desc, ); for my $key (keys %$expect) { is($opt->$key, $expect->{$key}, "...->$key"); } }; if ($@) { chomp($@); if (ref($expect) eq 'Regexp') { like($@, $expect, $desc); } else { # auto-fail is($@, "", "$desc: $@"); } } } sub is_hidden { my ($specs, $cmd, $text) = @_; eval { local @ARGV; my ($opt, $usage) = describe_options( "test %o", @$specs, ); like( $usage->text, $cmd, "hidden option in usage command", ); unlike( $usage->text, $text, "hidden option description", ); }; if ($@) { chomp($@); is($@, "", "hidden: $@"); ok(0); } } is_opt( [ ], [ [ "foo-bar=i", "foo integer", { default => 17 } ] ], { foo_bar => 17 }, "default foo_bar with no short option name", ); # test hidden is_hidden( [ [ "foo|f", "a foo option" ], [ "bar|b", "a bar option", { hidden => 1 } ], ], qr/test \[-f\] \[long options\.\.\.\]/i, qr/a bar option/, ); is_opt( [ '--nora' ], [ [ "nora", "Invisible Nora", { hidden => 1 } ] ], { nora => 1 }, "", ); ### tests for one_of my $foobar = [ [ 'foo' => 'a foo option' ], [ 'bar' => 'a bar option' ], ]; is_opt( [ ], [ [ mode => $foobar, { default => 'foo' }, ], ], { mode => 'foo' }, "basic usage, with default", ); is_opt( [ '--bar' ], [ [ mode => $foobar, ], ], { bar => 1, mode => 'bar' }, "basic usage, passed-in", ); # implicit hidden syntax is_hidden( [ [ mode => [] ] ], qr/test\s*\n/i, qr/mode/, ); is_opt( [ '--foo', '--bar' ], [ [ mode => $foobar ] ], #qr/\Qonly one 'mode' option (foo, bar)\E/, qr/it is 'foo' already/, "only one 'mode' option", ); is_opt( [ '--no-bar', '--baz' ], [ [ mode => [ [ foo => 'a foo option' ], [ 'bar!' => 'a negatable bar option' ], ], ], [ 'baz!' => 'a negatable baz option' ], ], { bar => 0, mode => 'bar', baz => 1 }, "negatable usage", ); is_opt( [ ], [ [ req => 'a required option' => { required => 1 } ], ], qr/mandatory parameter/i, "required option -- help text" ); { local @ARGV; my ($opt, $usage) = describe_options( "%c %o", [ foo => "a foo option" ], [], ['bar options:'], [ bar => "a bar option" ], ); like( $usage->text, qr/foo option\n\s+\n\tbar options:\n\s+--bar/, "spacer and non-option description found", ); local $SIG{__WARN__} = sub {}; # we know that this will warn; don't care like( $usage->(1), qr/foo option\n\s+\n\tbar options:\n\s+--bar/, "CODEISH: spacer and non-option description found", ); } { local @ARGV; my ($opt, $usage) = describe_options( "%c %o", [ 'foo' => "foo option" ], [ 'bar|b' => "bar option" ], [ 'string|s=s' => "string value" ], [ 'ostring|S:s' => "optional string value" ], [ 'list|l=s@' => "list of strings" ], [ 'hash|h=s%' => "hash values" ], [ 'optional|o!' => "optional" ], [ 'increment|i+' => "incremental option" ], ); like( $usage->text, qr/\[-bhiloSs\]/, "short options", ); } { local @ARGV = qw(--foo FOO --baz BAZ); my ($c_opt, $usage) = describe_options( "%c %o", [ "foo=s", '' ], [ "bar=s", '', { default => 'BAR' } ], [ "baz=s", '', { default => 'BAZ' } ], ); my $s_opt = $c_opt->_specified_opts; my $C_opt = $s_opt->_complete_opts; is($c_opt->foo, 'FOO', 'c_opt->foo is FOO'); is($C_opt->foo, 'FOO', 'C_opt->foo is FOO'); is($s_opt->foo, 'FOO', 's_opt->foo is FOO'); is($c_opt->bar, 'BAR', 'c_opt->foo is BAR'); is($C_opt->bar, 'BAR', 'C_opt->foo is BAR'); is($s_opt->bar, undef, 's_opt->foo is undef'); is($c_opt->baz, 'BAZ', 'c_opt->foo is BAZ'); is($C_opt->baz, 'BAZ', 'C_opt->foo is BAZ'); is($s_opt->baz, 'BAZ', 's_opt->foo is BAZ'); } { local @ARGV = qw(--foo); my ($opt, $usage) = describe_options( "%c %o", [ "foo", '' ], [ "bar", '' ], ); is( $opt->{foo}, 1, "empty-but-present description is ok" ); is( $opt->foo, 1, "empty-but-present description is ok" ); is( $opt->{bar}, undef, "entry not given is undef (exists? no guarantee)" ); is( $opt->bar, undef, "entry not given is undef (as method)"); } { local @ARGV = qw(--foo-bar); my ($opt) = describe_options( "%c %o", [ "foo:s", "foo option" ], [ "foo-bar", "foo-bar option", { implies => 'foo' } ], ); is_deeply($opt, { foo => 1, foo_bar => 1 }, "ok to imply option with optional argument"); is($opt->foo_bar, 1, 'given value (checked with method)'); is($opt->foo, 1, 'implied value (checked with method)'); } { local @ARGV; my ($opt, $usage) = describe_options( "%c %o", [ foo => "a foo option" ], [ bar => "a bar option" ], [ baz => "a baz option with a very long description." . " It just goes on for a really long time." . " This allows us to test line wrapping and" . " make sure the output always looks spiffy" ], ); my $expect = qr/ --baz a baz option with a very long description. It just goes on for a really long time. This allows us to test line wrapping and make sure the output always looks spiffy/; like($usage->text, $expect, 'long option description is wrapped cleanly'); } { local @ARGV; my ($opt, $usage) = describe_options( "%c %o", [ foo => "x" x 80 ], ); local $@; local $SIG{ALRM} = sub { die "ALRM\n" }; eval { alarm(2); like($usage->text, qr/@{["x" x 80]}/, "handled unwrappable description"); alarm(0); }; is($@, '', "no error in eval"); }