The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

use Kelp::Base -strict;

use Kelp;
use Kelp::Module;
use Test::More;
use Test::Exception;
use Plack::Util;

dies_ok { Kelp::Module->new() } "Dies when no app";

my %types = (
    hash => { bar => 'foo' },
    array  => [ 9, 8, 7 ],
    object => Plack::Util::inline_object( something => sub {1} ),
    code => sub { "Moo!" }
);

my $app = Kelp->new( mode => 'test' );
my $m = Kelp::Module->new( app => $app );
isa_ok $m, 'Kelp::Module';

# Register
for my $name ( keys %types ) {
    my $type = $types{$name};
    $m->register( $name => $type );
    can_ok $app, $name;

    if ( ref $type eq 'CODE' ) {
        is $app->$name, $type->(), "CODE checks out";
    }
    else {
        is_deeply $app->$name, $type, ref($type) . " checks out";
    }
}

# Redefine
for my $name ( keys %types ) {
    my $type = $types{$name};

    # Redefine 'em all one by one.
    for my $t ( values %types ) {
        dies_ok { $m->register( $name => $t ) }
        "Dies when redefining " . ref $t;
    }

    # Now allow redefining and do it again
    $ENV{KELP_REDEFINE} = 1;
    for my $t (values %types) {
        $m->register( $name => $t );
        if ( ref $t eq 'CODE' ) {
            is $app->$name, $t->(), "Redefines CODE";
        }
        else {
            is ref $app->$name, ref $t, "Redefines " . ref $t;
        }
    }
    $ENV{KELP_REDEFINE} = 0;
}

done_testing;