# $Id: Perl6.pm 21463 2007-09-21 16:51:42Z paultcochrane $
# Copyright (C) 2006-2007, The Perl Foundation.
=head1 NAME
Parrot::Test::Perl6 -- testing routines for languages/perl6
=head1 SYNOPSIS
use Parrot::Test::Perl6 tests => 3;
perl6_output_is(<<'CODE', <<'OUTPUT', 'hello, world!');
say 'hello, world!';
CODE
hello, world!
OUTPUT
perl6_stderr_like($code, qr/$expected/, $desc);
perl6_stdout_isnt($code, qr/$expected/, $desc);
=head1 DESCRIPTION
This module provides Perl6 test functions. It has been heavily refactored
from Parrot::Test. Hopefully,similar refactoring will be carried out in
Parrot::Test someday soon.
=cut
package Parrot::Test::Perl6;
use strict;
use warnings;
use File::Basename;
use File::Spec;
use Parrot::Config;
require Exporter;
require Parrot::Test;
require Test::Builder;
require Test::More;
our @EXPORT = qw( plan skip );
my $lang = 'perl6';
my $streams = {
output => sub { return ( STDOUT => $_[0], STDERR => $_[0] ) },
stdout => sub { return ( STDOUT => $_[0], STDERR => File::Spec->devnull ) },
stderr => sub { return ( STDOUT => File::Spec->devnull, STDERR => $_[0] ) },
};
my $tests = {
is => 'is_eq',
like => 'like',
isnt => 'isnt_eq',
};
## create a map of test names and info
my $test_map = {};
for my $t ( keys %{$tests} ) {
for my $s ( keys %$streams ) {
$test_map->{ join( '_' => $lang, $s, $t ) } = {
lang => $lang,
stream => { name => $s, data => $streams->{$s}, },
test => { name => $t, data => $tests->{$t}, },
};
}
}
push @EXPORT => keys %{$test_map};
use base qw( Parrot::Test Exporter );
my $b = Test::Builder->new();
my $path_to_parrot = $INC{"Parrot/Config.pm"};
$path_to_parrot =~ s:lib/Parrot/Config.pm$::;
$path_to_parrot = File::Spec->curdir()
if $path_to_parrot eq '';
my $parrot = File::Spec->catfile( $path_to_parrot, 'parrot' . $PConfig{exe} );
my $perl6 = File::Spec->catfile( $path_to_parrot, qw/ languages perl6 p6shell.pir /, );
sub import {
my ( $class, $plan, @args ) = @_;
$b->plan( $plan, @args );
__PACKAGE__->export_to_level( 2, __PACKAGE__ );
}
sub set_test_info {
my $next_test_num = 1 + $b->current_test();
my $f_out = Parrot::Test::per_test( '.out', $next_test_num );
my $f_code = Parrot::Test::per_test( '.p6', $next_test_num );
$f_code = File::Spec->rel2abs($f_code);
return ( $next_test_num, $f_out, $f_code );
}
sub _generate_functions {
my ($package) = @_;
for my $func ( keys %$test_map ) {
no strict 'refs';
*{ $package . '::' . $func } = sub ($$;$%) {
my ( $code, $expected, $desc, %extra ) = @_;
Parrot::Test::convert_line_endings($code);
## set a default description
$desc = sprintf '(%s line %s)' => ( caller() )[ 1, 2 ]
unless $desc;
my ( $test_num, $f_out, $f_code ) = set_test_info();
## get test arguments from environment
my $args = $ENV{TEST_PROG_ARGS} || '';
Parrot::Test::write_code_to_file( $code, $f_code );
## build the command and set the run options
my $cmd = qq{$parrot $args $perl6 "$f_code"};
my $run_options = {
CD => '.',
$test_map->{$func}->{stream}->{data}->($f_out),
};
## run the command and capture the exit code
my $exit_code = Parrot::Test::run_command( $cmd, %{$run_options}, );
## read in the command output
my $actual_output = Parrot::Test::slurp_file($f_out);
## tell Test::Builder if the test is marked as a todo-item
my $call_pkg = $b->exported_to() || '';
local *{ $call_pkg . '::TODO' } = ## no critic Variables::ProhibitConditionalDeclarations
\$extra{todo}
if defined $extra{todo};
## run Test::Builder's test on actual vs. expected output
my $method = $test_map->{$func}->{test}->{data};
my $pass = $b->$method( $actual_output, $expected, $desc );
## print diagnostic info if the test fails
$b->diag("'$cmd' failed with exit code $exit_code")
if $exit_code and not $pass;
unless ( $ENV{POSTMORTEM} ) {
unlink $f_out;
}
return $pass;
};
}
}
__PACKAGE__->_generate_functions();
$_ ^= ~{ AUTHOR => 'particle' };
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4:
syntax highlighted by Code2HTML, v. 0.9.1