use v6.e.PREVIEW;
use Test;

plan 7;

my $ast;
my $deparsed;
my $raku;
my @type = <AST Str Raku>;
sub ast(RakuAST::Node:D $node --> Nil) {
    $ast      := $node;
    $deparsed := $ast.DEPARSE;
    $raku     := 'use experimental :rakuast; ' ~ $ast.raku;
    diag $deparsed.chomp;
}

subtest 'Item contextualizer from empty sequence' => {
    # $()
    ast RakuAST::Contextualizer::Item.new(RakuAST::StatementSequence.new());
    is-deeply $deparsed, '$()', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, List.new(),
          "$type: Contextualizer gives expected result";
    }
}

subtest 'Hash contextualizer from empty sequence' => {
    # %()
    ast RakuAST::Contextualizer::Hash.new(RakuAST::StatementSequence.new());
    is-deeply $deparsed, '%()', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, Hash.new(),
          "$type: Contextualizer gives expected result";
    }
}

subtest 'List contextualizer from empty sequence' => {
    # @()
    ast RakuAST::Contextualizer::List.new(RakuAST::StatementSequence.new());
    is-deeply $deparsed, '@()', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, List.new(),
          "$type: Contextualizer gives expected result";
    }
}

subtest 'Item contextualizer with single value' => {
    # $(42)
    ast RakuAST::Contextualizer::Item.new(
      RakuAST::StatementSequence.new(
        RakuAST::Statement::Expression.new(
          expression => RakuAST::IntLiteral.new(42)
        )
      )
    );
    is-deeply $deparsed, '$(42)', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, 42,
          "$type: Contextualizer gives expected result";
    }
}

subtest 'Item contextualizer with multiple values' => {
    # $(42, 666)
    ast RakuAST::Contextualizer::Item.new(
      RakuAST::StatementSequence.new(
        RakuAST::Statement::Expression.new(
          expression => RakuAST::ApplyListInfix.new(
            infix => RakuAST::Infix.new(','),
            operands => [
              RakuAST::IntLiteral.new(42),
              RakuAST::IntLiteral.new(666)
            ]
          )
        )
      )
    );
    is-deeply $deparsed, '$(42, 666)', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, $(42, 666),
          "$type: Contextualizer gives expected result";
    }
}

subtest 'Hash contextualizer from pairs' => {
    # %(a => 1, b => 2)
    ast RakuAST::Contextualizer::Hash.new(
      RakuAST::StatementSequence.new(
        RakuAST::Statement::Expression.new(
          expression => RakuAST::ApplyListInfix.new(
            infix => RakuAST::Infix.new(','),
            operands => [
              RakuAST::FatArrow.new(key => 'a', value => RakuAST::IntLiteral.new(1)),
              RakuAST::FatArrow.new(key => 'b', value => RakuAST::IntLiteral.new(2))
            ]
          )
        )
      )
    );
    is-deeply $deparsed, '%(a => 1, b => 2)', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, Hash.new((a => 1, b => 2)),
          "$type: Contextualizer gives expected result";
    }
}

subtest 'List contextualizer from pairs' => {
    # @(a => 1, b => 2)
    ast RakuAST::Contextualizer::List.new(
      RakuAST::StatementSequence.new(
        RakuAST::Statement::Expression.new(
          expression => RakuAST::ApplyListInfix.new(
            infix => RakuAST::Infix.new(','),
            operands => [
              RakuAST::FatArrow.new(key => 'a', value => RakuAST::IntLiteral.new(1)),
              RakuAST::FatArrow.new(key => 'b', value => RakuAST::IntLiteral.new(2))
            ]
          )
        )
      )
    );
    is-deeply $deparsed, '@(a => 1, b => 2)', 'deparse';

    for
      'AST', EVAL($ast),
      'Str', EVAL($deparsed),
      'Raku', EVAL(EVAL $raku)
    -> $type, $result {
        is-deeply $result, (a => 1, b => 2),
          "$type: Contextualizer gives expected result";
    }
}

# vim: expandtab shiftwidth=4
