### ----------------------------------------------------
### -- Menu::Simple
### -- Licenses: Artistic-2.0
### -- Authors: Steve Dondley
### -- File: t/00-sanity.rakutest
### ----------------------------------------------------
use v6.d;
use Menu::Simple;
use Test;
use Test::Output;


plan 35;

sub check-methods($class, List:D $methods) {
    for $methods.Array -> $method {
        is ::($class).^can($method).gist, "($method)", "has $method method";
    }
}

sub some-sub {
    say 'done!';
}

sub check-process($menu, $value, $expected) {
    $menu.selection = $value;
    is $menu.validate-selection, $expected, 'validates or invalidates selection';
}

is Menu, Menu, 'Menu class exists';
my %methods = Menu =>
    <display add-option add-options option-count display get-selection process-selection validate-selection display-prompt execute>;
for %methods { check-methods(.key, .value) }

is Simple::Option, Simple::Option, 'Item class exists';

my $menu = Menu.new();
$menu.add-option(display-string => 'Option 1');

is $menu.options.elems, 1, 'adds menu option';

$menu.add-option(display-string => 'Option 2');
is $menu.options.elems, 2, 'adds another menu option';

lives-ok { $menu.add-option: 'hello' }, 'can add option as string';

dies-ok { $menu.add-option() }, 'dies with no display string';

stdout-like { $menu.display }, /Option\s1\n/, 'outputs option 1';
stdout-like { $menu.display }, /Option\s2\n/, 'outputs option 2';
stdout-like { $menu.display }, /Make\sselection\:/, 'outputs prompt';

stdout-like { $menu.display }, /^^1\s\-\sOption/, 'outputs option format';

check-process($menu, 1, True );
check-process($menu, 2, True );
check-process($menu, 3, True );
check-process($menu, 4, False );
check-process($menu, '', False );
check-process($menu, "\n", False );
check-process($menu, 'kjksdjf', False );

$menu.selection = 0;
stdout-like { $menu.process-selection() }, /Sorry\,\sinvalid\sentry/, 'outputs option 2';
stdout-like { $menu.process-selection() }, /Make\sselection/, 'reprompts';

my $submenu = Menu.new.add-options: <one two three four>;
my $menu2 = Menu.new();
$menu2.add-option(display-string => 'Option 1', action => &some-sub);
$menu2.selection = 1;
$menu2.add-submenu($submenu, 1);
lives-ok { $menu2.add-submenu($submenu) }, 'adds submenu';
$menu2.process-selection();
my $option = $menu2.get-option($menu2.validated-selection);
stdout-like { $option.action()() }, /done/, 'executes action';
lives-ok { $menu2.add-action( { say 'do this' }) }, 'adds action';
lives-ok { $menu2.add-action( { say 'do this' }, 1) }, 'adds action';
is $option.submenu.^name, 'Simple::Menu', 'returns a menu';

# test menu IDs;
is 'Simple::Menu', Menu.get-menu(3).^name, 'gets a menu from a menu ID';


done-testing;




