### ----------------------------------------------------
### -- Template::Nest::Fast
### -- Licenses: ISC
### -- Authors: Andinus <andinus@nand.sh>
### -- File: t/01-render.rakutest
### ----------------------------------------------------
use Test;
use Template::Nest::Fast;

plan 12;

my IO $output-dir = $*PROGRAM.IO.parent.add('output');
my IO $template-dir = $*PROGRAM.IO.parent.add('templates');
my $nest = Template::Nest::Fast.new( :$template-dir );

my %incomplete-page = %(
    TEMPLATE => '00-simple-page',
    variable => 'Simple Variable',
    simple_component => %(
        TEMPLATE => '01-simple-component',
        # empty.
    )
);

my %simple-page = %(
    TEMPLATE => '00-simple-page',
    variable => 'Simple Variable',
    simple_component => %(
        TEMPLATE => '01-simple-component',
        variable => 'Simple Variable in Simple Component'
    )
);

my %complex-page = %(
    TEMPLATE => '10-complex-page',
    title => 'Complex Page',
    pre_body => %(
        TEMPLATE => '18-styles',
    ),
    navigation => %(
        TEMPLATE => '11-navigation',
        banner => %(
            TEMPLATE => '12-navigation-banner',
        ),
        items => [
                  %( TEMPLATE => '13-navigation-item-00-services' ),
                  %( TEMPLATE => '13-navigation-item-01-resources' ),
              ]
    ),
    hero_section => %(
        TEMPLATE => '14-hero-section',
    ),
    main_content => [
                     %( TEMPLATE => '15-isdc-card', ),
                     %(
                         TEMPLATE => '16-vb-brand-cards',
                         cards => [
                                   %(
                                       TEMPLATE => '17-vb-brand-card-00',
                                       parent_classes => 'p-card brand-card col-4',
                                   ),
                                   %(
                                       TEMPLATE => '17-vb-brand-card-01',
                                       parent_classes => 'p-card brand-card col-4',
                                   ),
                                   %(
                                       TEMPLATE => '17-vb-brand-card-02',
                                       parent_classes => 'p-card brand-card col-4',
                                   ),
                               ]
                     )
                 ],
    post_footer => %(
        TEMPLATE => '19-scripts'
    )
);

# render test with simple string, template substitution.
is(
    $nest.render(%simple-page),
    $output-dir.add('01-simple-page.html').slurp,
    "Simple template is rendered."
);

# test with underscored options.
with Template::Nest::Fast.new(
    template_dir => $template-dir.absolute, :name_label<NAME>
) -> $nest-alt {
    is(
        $nest-alt.render(
            %(
                NAME => '00-simple-page',
                variable => 'Simple Variable',
                simple_component => %(
                    NAME => '01-simple-component',
                    variable => 'Simple Variable in Simple Component'
                )
            )
        ),
        $output-dir.add('01-simple-page.html').slurp,
        "Simple template is rendered with underscored option."
    );
}

# render test with simple string, template substitution and different
# name-label.
with Template::Nest::Fast.new(:$template-dir, :name-label<NAME>) -> $nest-alt {
    is(
        $nest-alt.render(
            %(
                NAME => '00-simple-page',
                variable => 'Simple Variable',
                simple_component => %(
                    NAME => '01-simple-component',
                    variable => 'Simple Variable in Simple Component'
                )
            )
        ),
        $output-dir.add('01-simple-page.html').slurp,
        "Simple template is rendered with alternate name-label."
    );
}

# check if returned HTML is a string.
isa-ok $nest.render(%simple-page), Str, "Rendered HTML is a string.";

# render test with complex template hash.
is(
    $nest.render(%complex-page),
    $output-dir.add('02-complex-page.html').slurp,
    "Complex template is rendered."
);

# render test with a template hash that does not have all the
# variables from template file.
is(
    $nest.render(%incomplete-page),
    $output-dir.add('03-incomplete-page.html').slurp,
    "Incomplete template is rendered."
);

# should die with non-existent template file.
throws-like(
    { $nest.render(%(TEMPLATE => 'this-template-file-does-not-exist')) }, Exception,
    "Dies with non-existent template file",
    message => /"Unrecognized template " .*/
);

# should die with invalid template hash (i.e. where there is no name
# label).
my %invalid-page = %(
    # no name-label.
    variable => 'Simple Variable',
);

my %invalid-page-more = %(
    TEMPLATE => '00-simple-page',
    variable => 'Simple Variable',
    simple_component => %(
        # no name-label.
        # empty.
    )
);

throws-like(
    { $nest.render(%invalid-page) }, Exception,
    "Dies with invalid template hash (i.e. without name label).",
    message => /^"Encountered hash with no name-label " .*/
);

throws-like(
    { $nest.render(%invalid-page-more) }, Exception,
    "Dies with invalid template hash (i.e. without name label) that is nested.",
    message => /^"Encountered hash with no name-label " .*/
);

my %simple-page-arrays = %(
    TEMPLATE => '00-simple-page',
    variable => 'Simple Variable',
    simple_component => [
                         # Hash passed.
                         %(
                             TEMPLATE => '01-simple-component',
                             variable => 'Simple Variable in Simple Component'
                         ),
                         # Can pass string as well.
                         "<strong>Another test</strong>",
                         # Or another level of nesting.
                         [
                             %(
                                 TEMPLATE => '01-simple-component',
                                 variable => 'Simple Variable in Simple Component'
                             ),
                             "<strong>Another nested test 2</strong>"
                         ]
                     ]
);
is(
    $nest.render(%simple-page-arrays),
    $output-dir.add('12-simple-page-arrays.html').slurp,
    "Simple template is rendered."
);

# should die if template-dir is unspecified.
throws-like(
    { Template::Nest::Fast.new() }, Exception,
    "Dies with unspecified template-dir.",
    message => /^"template-dir option must be set."$/
);

# render test with array of template hash.
is(
    $nest.render(
        [
            %( TEMPLATE => '01-simple-component',  variable => 'This is a variable' ),
            %( TEMPLATE => '01-simple-component',  variable => 'This is another variable' )
        ]
    ),
    $output-dir.add('13-render-with-array-of-template-hash.html').slurp.trim-trailing,
    "render with array of template hash."
);


