### ----------------------------------------------------
### -- Raku::Pod::Render
### -- Licenses: Artistic-2.0
### -- Authors: Richard Hainsworth
### -- File: xt/15-templates.rakutest
### ----------------------------------------------------
use v6.d;
use Test;
use ProcessedPod;
use Test::Output;

# A helper sub for RakuClosureTemplates
sub gen-closure-template (Str $tag) is export {
    my $start = '<' ~ $tag ~ '>';
    my $end = '</' ~ $tag ~ '>';
    return sub (%prm, %tml? --> Str) {
        $start ~ (%prm<contents> // '') ~ $end;
    }
}

plan 14;

my $processor;

lives-ok { $processor = ProcessedPod.new }, 'instantiates';

my $pod = Pod::FormattingCode.new(:type('B'), :contents(['hello world']));

throws-like { $processor.render-block($pod) },
        X::ProcessedPod::MissingTemplates,
        message=>/'No templates loaded'/,
        "Catches the absence of templates";

use RenderPod::Templating;
my @templates = SetupTemplates.new.required;


my %templates = @templates Z=> ( "[beg]$_\[end]" for @templates );
        # this creates a set of pseudo templates

%templates<format-c>:delete; # assumes format-c is a required template

throws-like { $processor.templates(%templates) }, X::ProcessedPod::MissingTemplates,
        message=> / 'but are not:' \s* 'format-c' \s* /,
        "Catches the missing template";

# testing with the default RakuClosureTemplates.

%templates  = @templates Z=> @templates.map( { gen-closure-template( $_ ) });
$processor.verbose = True;
stderr-like { $processor.templates(%templates) }, / 'Using RakuClosureTemplater' /, 'full set of RakuClosure templates';
is $processor.templater.Str, 'RakuClosureTemplater', 'Stringify templater yields its type';
isa-ok $processor.tmpl<format-b>, Callable, 'Got a Callable in first place';
is $processor.tmpl.prior('format-b'), Nil, 'Linked list last is Nil';
like $processor.rendition('format-b', %(:contents('Hello world'))),
        / '<format-b>' 'Hello world' '</format-b>' /, 'basic interpolation correct';

$processor.modify-templates( %(
        format-b => sub ( %params, %tml ) { '#' x %params<level> ~ ' ' ~ %params<text> ~ "\n" },
    ));
isa-ok $processor.tmpl<format-b>, Callable, 'Got a Callable in first place';
isa-ok $processor.tmpl.prior('format-b'), Callable, 'Next item in linked list is now Callable';

like $processor.rendition('format-b', %(:text('Hello World'), :level(5) )),
        / \# **5 \s* 'Hello World' /, 'template replaced';

$processor.modify-templates( %(
    :newone(-> %prm, %tml { '<container>' ~ %prm<contents> ~ '</container>'}),
    :format-b( -> %prm, %tml { %tml<newone>(%prm,%tml)  ~  ' is wrapped'} ),
) );
like $processor.rendition('format-b', %(:contents('Hello world'))),
        / '<container>' 'Hello world' '</container> is wrapped' /, 'interpolation with partials correct';

# test the ability to access previous template value
$processor.modify-templates( %(
    format-b => sub ( %prm, %tml) {
        'new stuff, then old ' ~
        %tml.prior('format-b').( %prm, %tml )
    }
));
like $processor.rendition('format-b', %(:contents('Hello world'))),
        /
        'new stuff, then old ' \s*
        '<container>' 'Hello world' '</container> is wrapped'
        /, 'got new and interpolation with partials';

# is a non-existent template trapped?
$processor.modify-templates( %(
    format-b => sub ( %prm, %tml) {
        'new stuff, then old ' ~
        %tml<format-bx>.( %prm, %tml )
    }
));

throws-like { $processor.rendition('format-b', %(:contents('Hello world'))) },
        X::ProcessedPod::Unexpected-Template,
        message=>/ 'Have you called ｢format-bx｣ inside another template' /,
        "Catches the non-existent template";

done-testing;


