use warnings; use strict; use Test::More tests => 10; BEGIN { use_ok "Sub::Mutate", qw(when_sub_bodied sub_body_type); } our @acted; sub action($;$) { my($id, $extra) = @_; return sub { push @acted, [ $_[0], sub_body_type($_[0]), $id ]; if($extra) { $extra->($_[0]); push @acted, [ $_[0], sub_body_type($_[0]), $id."x" ]; } }; } sub match_acted($$) { my($expected, $desc) = @_; ok(@acted == @$expected && !(grep { my $got = $acted[$_]; my $exp = $expected->[$_]; !($got->[0] == $exp->[0] && $got->[1] eq $exp->[1] && $got->[2] eq $exp->[2]); } 0..$#acted), $desc); } @acted = (); when_sub_bodied(\&sub_body_type, action("0")); match_acted [ [ \&sub_body_type, "XSUB", "0" ] ], "xsub immediate 0"; @acted = (); sub t0 { } when_sub_bodied(\&t0, action("1")); match_acted [ [ \&t0, "PERL", "1" ] ], "perl immediate 1"; @acted = (); when_sub_bodied(\&sub_body_type, action("2", sub { when_sub_bodied($_[0], action("3")) })); match_acted [ [ \&sub_body_type, "XSUB", "2" ], [ \&sub_body_type, "XSUB", "2x" ], [ \&sub_body_type, "XSUB", "3" ], ], "xsub immediate 2/3"; @acted = (); sub t1 { } when_sub_bodied(\&t1, action("4", sub { when_sub_bodied($_[0], action("5")) })); match_acted [ [ \&t1, "PERL", "4" ], [ \&t1, "PERL", "4x" ], [ \&t1, "PERL", "5" ], ], "perl immediate 4/5"; sub MODIFY_CODE_ATTRIBUTES { shift(@_); my $subject = shift(@_); foreach my $attr (@_) { when_sub_bodied($subject, action($attr, sub { when_sub_bodied($_[0], action($attr."e")) })); } return (); } @acted = (); eval q{ sub t2 :a0 :a1 { } 1 } or die $@; match_acted "$]" >= 5.015004 ? [ [ \&t2, "PERL", "a0" ], [ \&t2, "PERL", "a0x" ], [ \&t2, "PERL", "a0e" ], [ \&t2, "PERL", "a1" ], [ \&t2, "PERL", "a1x" ], [ \&t2, "PERL", "a1e" ], ] : [ [ \&t2, "PERL", "a0" ], [ \&t2, "PERL", "a0x" ], [ \&t2, "PERL", "a1" ], [ \&t2, "PERL", "a1x" ], [ \&t2, "PERL", "a0e" ], [ \&t2, "PERL", "a1e" ], ], "perl attrib a0/a1"; @acted = (); eval q{ sub t3 :a2 :a3; 1 } or die $@; match_acted [], "undef attrib a2/a3"; @acted = (); eval q{ sub t3 :a4 :a5 { } 1 } or die $@; SKIP: { skip "predeclarations cause attribute lossage on pre-5.10 perl", 1 unless "$]" >= 5.010; match_acted "$]" >= 5.015004 ? [ [ \&t3, "PERL", "a4" ], [ \&t3, "PERL", "a4x" ], [ \&t3, "PERL", "a4e" ], [ \&t3, "PERL", "a5" ], [ \&t3, "PERL", "a5x" ], [ \&t3, "PERL", "a5e" ], ] : [ [ \&t3, "PERL", "a4" ], [ \&t3, "PERL", "a4x" ], [ \&t3, "PERL", "a5" ], [ \&t3, "PERL", "a5x" ], [ \&t3, "PERL", "a4e" ], [ \&t3, "PERL", "a5e" ], ], "perl attrib a4/a5"; } @acted = (); eval q{ sub t3 :a6 :a7; 1 } or die $@; match_acted [ [ \&t3, "PERL", "a6" ], [ \&t3, "PERL", "a6x" ], [ \&t3, "PERL", "a6e" ], [ \&t3, "PERL", "a7" ], [ \&t3, "PERL", "a7x" ], [ \&t3, "PERL", "a7e" ], ], "perl immediate a6/a7"; @acted = (); sub t4 { } sub t5 { } when_sub_bodied(\&t4, action("6", sub { when_sub_bodied(\&t5, action("7", sub { when_sub_bodied(\&t4, action("8")); when_sub_bodied(\&t5, action("9")); })); })); match_acted [ [ \&t4, "PERL", "6" ], [ \&t5, "PERL", "7" ], [ \&t5, "PERL", "7x" ], [ \&t5, "PERL", "9" ], [ \&t4, "PERL", "6x" ], [ \&t4, "PERL", "8" ], ], "perl immediate 6/7/8/9"; 1;