XS-Parse-Keyword

 view release on metacpan or  search on metacpan

t/71infix-wrapper.t  view on Meta::CPAN


   %opcounts = count_ops $code = sub { t::infix::addpairsfunc( \@pkgav, \@pkgav ) };
   ok( !$opcounts{srefgen}, 'callchecker made no OP_SREFGEN for \@pkgav' );
   is( [ $code->() ], [ 2, 4, 6 ], 'result of callcheckered code for list/list on \@pkgav' );

   # stress-test it

   %opcounts = count_ops $code = sub { t::infix::addpairsfunc( \@{ \@{ \@padav } }, \@{ \@{ \@padav } } ) };
   # Preserve the two sets of inner ones but remove the outer ones
   is( $opcounts{+REFGEN}, 4, 'callchecker removed one layer of OP_SREFGEN for stress-test' );
   is( [ $code->() ], [ 2, 4, 6 ], 'result of callcheckered code for list/list on stress-test' );

   package OneTwoThree {
      use overload '@{}' => sub { return [1, 2, 3] };
   }

   $code = sub { t::infix::addpairsfunc( bless( {}, "OneTwoThree" ), \@padav ) };
   is( [ $code->() ], [ 2, 4, 6 ], 'result of callcheckered code for list/list on blessed object' );

   # anonlist remains on LHS
   %opcounts = count_ops $code = sub { t::infix::addpairsfunc( [1,2,3], \@padav ) };
   ok( $opcounts{anonlist}, 'callchecker left OP_ANONLIST on LHS' );
   is( [ $code->() ], [ 2, 4, 6 ], 'result of callcheckered code for list/list on anonlist' );

   # anonlist is unwrapped on RHS
   %opcounts = count_ops $code = sub { t::infix::addpairsfunc( \@padav, [1,2,3] ) };
   ok( !$opcounts{anonlist}, 'callchecker removed OP_ANONLIST on RHS' );
   is( [ $code->() ], [ 2, 4, 6 ], 'result of callcheckered code for list/list on anonlist' );
}

# wrapper func by coderef
{
   my $wrapper = \&t::infix::addfunc;
   is( $wrapper->( 30, 40 ), 70, 'add wrapper func by CODE reference' );
}

# argument checking
{
   ok( !eval { t::infix::addfunc( 10, 20, 30 ) },
      'Wrapper func fails for too many args' );
   like( $@, qr/^Too many arguments for subroutine 't::infix::addfunc'/,
      'Failure message for too many args' );

   ok( !eval { t::infix::addfunc( 60 ) },
      'Wrapper func fails for too few args' );
   like( $@, qr/^Too few arguments for subroutine 't::infix::addfunc'/,
      'Failure message for too few args' );
}

sub is_deparsed
{
   my ( $sub, $exp, $name ) = @_;

   my $got = $deparser->coderef2text( $sub );

   # Deparsed output is '{ ... }'-wrapped
   $got = ( $got =~ m/^{\n(.*)\n}$/s )[0];

   # Deparsed output will have a lot of pragmata and so on; just grab the
   # final line
   $got = ( split m/\n/, $got )[-1];
   $got =~ s/^\s+//;

   is( $got, $exp, $name );
}

{
   # We need to ensure the wrapper function doesn't deparse to the actual
   # infix operator syntax in order to test this one
   BEGIN { delete $^H{"t::infix/permit"} }

   is_deparsed sub { t::infix::addfunc( $_[0], $_[1] ) },
      't::infix::addfunc($_[0], $_[1]);',
      'deparsed call to wrapper func';

   my @padav;
   our @pkgav;

   is_deparsed sub { t::infix::addpairsfunc( $_[0], $_[1] ) },
      't::infix::addpairsfunc($_[0], $_[1]);',
      'deparsed call to list/list wrapper func on slugs';
   is_deparsed sub { t::infix::addpairsfunc( \@padav, \@padav ) },
      't::infix::addpairsfunc(\@padav, \@padav);',
      'deparsed call to list/list wrapper func on padav';
   is_deparsed sub { t::infix::addpairsfunc( \@pkgav, \@pkgav ) },
      't::infix::addpairsfunc(\@pkgav, \@pkgav);',
      'deparsed call to list/list wrapper func on pkgav';
   is_deparsed sub { t::infix::addpairsfunc( [1,2], [3,4] ) },
      't::infix::addpairsfunc([1, 2], [3, 4]);',
      'deparsed call to list/list wrapper func on anonlist';
}

# list-associative
{
   # wrapper by direct call
   is( t::infix::catfunc( "a", "b", "c" ), "^abc^",
      'List-associative wrapper function by direct call' );

   # wrapper by direct call non-convertable
   my @args = qw( a b c );
   is( t::infix::catfunc( @args ), "^abc^",
      'List-associative wrapper function by non-convertable direct call' );

   my $wrapper = \&t::infix::catfunc;
   is( $wrapper->( "d", "e", "f" ), "^def^",
      'List-associative wrapper function by CODE reference' );
}

# call-checker for list-associative ops
{
   my $code;
   my %opcounts;

   # scalars
   %opcounts = count_ops $code = sub { t::infix::catfunc "X", "Y" };
   ok( (scalar grep { m/^infix_cat_0x/ } keys %opcounts),
      'callchecker generated an OP_CUSTOM call for listassoc scalars' );
   ok( !$opcounts{entersub}, 'callchecker removed an OP_ENTERSUB call for listassoc scalars' );
   is( $code->(), "^XY^", 'result of callcheckered code for listassoc scalars' );

   # lists



( run in 0.614 second using v1.01-cache-2.11-cpan-71847e10f99 )