use v6.e.PREVIEW; use Test; plan 10; my $ast; my $deparsed; my $raku; my @type = ; sub ast(RakuAST::Node:D $node --> Nil) { $ast := $node; $deparsed := $node.DEPARSE; $raku := 'use experimental :rakuast; ' ~ $node.raku; diag $deparsed.chomp; } subtest 'look up an existing type' => { ast RakuAST::Type::Simple.new( RakuAST::Name.from-identifier-parts('Proc', 'Async') ); is-deeply $deparsed, 'Proc::Async', 'deparse'; is-deeply $_, Proc::Async, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'type with definedness constraint' => { # Int:D ast RakuAST::Type::Definedness.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ), definite => True ); is-deeply $deparsed, 'Int:D', 'deparse'; is-deeply $_, Int:D, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'type with undefinedness constraint' => { # Int:U ast RakuAST::Type::Definedness.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ), definite => False ); is-deeply $deparsed, 'Int:U', 'deparse'; is-deeply $_, Int:U, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'type with unspecified coercion' => { # Int() ast RakuAST::Type::Coercion.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ), ); is-deeply $deparsed, 'Int()', 'deparse'; is-deeply $_, Int(), @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'type with specific coercion' => { # Int(Str) ast RakuAST::Type::Coercion.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ), constraint => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Str") ) ); is-deeply $deparsed, 'Int(Str)', 'deparse'; is-deeply $_, Int(Str), @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'type with chained coercion' => { # Int(Str()) ast RakuAST::Type::Coercion.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ), constraint => RakuAST::Type::Coercion.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Str") ) ) ); is-deeply $deparsed, 'Int(Str())', 'deparse'; is-deeply $_, Int(Str()), @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'parameterized type without type' => { # Rational[] ast RakuAST::Type::Parameterized.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Rational") ) ); is-deeply $deparsed, 'Rational', 'deparse'; is-deeply $_, Rational, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'parameterized type with type' => { # Rational[Int] ast RakuAST::Type::Parameterized.new( base-type => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Rational") ), args => RakuAST::ArgList.new( RakuAST::Type::Simple.new( RakuAST::Name.from-identifier("Int") ) ) ); is-deeply $deparsed, 'Rational[Int]', 'deparse'; is-deeply $_, Rational[Int], @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Single-part type from the setting' => { # SETTING:: ast RakuAST::Type::Setting.new( RakuAST::Name.from-identifier("Date") ); is-deeply $deparsed, 'SETTING::', 'deparse'; my \SETTING-Date := Date; for 'AST', $ast, 'Str', $deparsed, 'Raku', EVAL($raku) -> $type, $it { my class Date { } is-deeply EVAL($it), SETTING-Date, "$type: did we get the setting version"; } } subtest 'Multi-part type from the setting' => { # SETTING::.WHO.WHO ast RakuAST::Type::Setting.new( RakuAST::Name.from-identifier-parts("IO","Path","Parts") ); is-deeply $deparsed, 'SETTING::.WHO.WHO', 'deparse'; my \SETTING-Parts := IO::Path::Parts; for 'AST', $ast, 'Str', $deparsed, 'Raku', EVAL($raku) -> $type, $it { my class IO::Path::Parts { } todo "no actual lookup in SETTING only yet"; is-deeply EVAL($it), SETTING-Parts, "$type: did we get the setting version"; } } # vim: expandtab shiftwidth=4