use v6.e.PREVIEW; use Test; plan 15; 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; } class TestTarget { my $.route = 66; method subtract($x, $y) { $x - $y } submethod subby(--> 42) { } } subtest 'Can make a call on a method without arguments' => { # TestTarget.route ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('route') ) ); is-deeply $deparsed, 'TestTarget.route', 'deparsed'; is-deeply $_, 66, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a call on a submethod without arguments' => { # TestTarget.subby ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('subby') ) ); is-deeply $deparsed, 'TestTarget.subby', 'deparsed'; is-deeply $_, 42, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a call on a method with positional arguments' => { # TestTarget.subtract(14, 6) ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('subtract'), args => RakuAST::ArgList.new( RakuAST::IntLiteral.new(14), RakuAST::IntLiteral.new(6), ) ) ); is-deeply $deparsed, 'TestTarget.subtract(14, 6)', 'deparsed'; is-deeply $_, 8, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Method call WHAT compiles into MOP primitive' => { # 42.WHAT ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('WHAT') ) ); is-deeply $deparsed, '42.WHAT', 'deparsed'; is-deeply $_, Int, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Method call HOW compiles into MOP primitive' => { # 42.HOW ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('HOW') ) ); is-deeply $deparsed, '42.HOW', 'deparsed'; is-deeply $_, Int.HOW, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Method call WHO compiles into MOP primitive' => { # 42.WHO ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('WHO') ) ); is-deeply $deparsed, '42.WHO', 'deparsed'; isa-ok $_, Stash, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Method call DEFINITE compiles into MOP primitive' => { # 42.DEFINITE ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('DEFINITE') ) ); is-deeply $deparsed, '42.DEFINITE', 'deparsed'; is-deeply $_, True, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Method call REPR compiles into MOP primitive' => { # 42.REPR ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('REPR') ) ); is-deeply $deparsed, '42.REPR', 'deparsed'; is-deeply $_, 'P6opaque', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a quoted call on a method without arguments' => { # TestTarget."route"() ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::QuotedMethod.new( name => RakuAST::QuotedString.new( :segments[RakuAST::StrLiteral.new('route')] ) ) ); is-deeply $deparsed, 'TestTarget."route"()', 'deparsed'; is-deeply $_, 66, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a quoted call on a method with positional arguments' => { # TestTarget."subtract"(14, 6) ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::QuotedMethod.new( name => RakuAST::QuotedString.new( :segments[RakuAST::StrLiteral.new('subtract')] ), args => RakuAST::ArgList.new( RakuAST::IntLiteral.new(14), RakuAST::IntLiteral.new(6), ) ) ); is-deeply $deparsed, 'TestTarget."subtract"(14, 6)', 'deparsed'; is-deeply $_, 8, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a meta-method call' => { # 42.^name ast RakuAST::ApplyPostfix.new( operand => RakuAST::IntLiteral.new(42), postfix => RakuAST::Call::MetaMethod.new(name => 'name') ); is-deeply $deparsed, '42.^name', 'deparsed'; is-deeply $_, 'Int', @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a method call if the method exists' => { # TestTarget.?subtract(50,8) ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::MaybeMethod.new( name => 'subtract', args => RakuAST::ArgList.new( RakuAST::IntLiteral.new(50), RakuAST::IntLiteral.new(8), ) ) ); is-deeply $deparsed, 'TestTarget.?subtract(50, 8)', 'deparsed'; is-deeply $_, 42, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a method call if the method does not exist' => { # TestTarget.?dunno ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('TestTarget') ), postfix => RakuAST::Call::MaybeMethod.new( name => 'dunno' ) ); is-deeply $deparsed, 'TestTarget.?dunno', 'deparsed'; is-deeply $_, Nil, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } subtest 'Can make a private method call' => { class A { method !private(--> 42) { } # A!private ast RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('A') ), postfix => RakuAST::Call::PrivateMethod.new( name => RakuAST::Name.from-identifier('private') ) ); is-deeply $deparsed, 'A!private', 'deparsed'; is-deeply $_, 42, @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } } subtest 'Can make a method call on a sub' => { # "foo".&uc() ast RakuAST::ApplyPostfix.new( operand => RakuAST::StrLiteral.new("foo"), postfix => RakuAST::Call::VarMethod.new( name => RakuAST::Name.from-identifier('uc') ) ); is-deeply $deparsed, '"foo".&uc()', 'deparsed'; is-deeply $_, "FOO", @type[$++] for EVAL($ast), EVAL($deparsed), EVAL(EVAL $raku); } # vim: expandtab shiftwidth=4