#!/usr/bin/perl # Copyright (C) 2001-2009, Parrot Foundation. use strict; use warnings; use lib qw( t . .. lib ../lib ../../lib ../../../lib ../../../../lib ); use Test::More; use Parrot::Test; use Parrot::Config; =head1 NAME examples/languages/abc/t/01-tests.t - test harness for Parrot abc =head1 DESCRIPTION This file is the current implementation for the abc test harness. The tests are actually in simple text files, this harness given this list of tests sources, executes all the tests. The test source is a plain text file divided in three columns. The columns are separated by three white spaces C<\s{3,}> or at least one tab C<\t+>. The three columns are: =over 4 =item B<expression> The exact expression that is passed to the abc compiler as source code. This input is pasted as a double quotes delimited string into PIR code. This means that you can use \n to indicate newlines. =item B<expected> The expected result for the compiled source. Note that you can (and probably should) use C<\n> in the expected result to represent newlines. =item B<description> This should be a string describing the test that is being made. =back Since this is supposed to be a temporary harness. We're expecting to be able to capture the result of the compilation to write this file in PIR. The skip and todo tests are defined in the test source file itself, so that later when the harness is changed we don't have to bother to convert the skip/todo tests list. So, you can simply set a test to be todo or skipped by adding the C<SKIP> or C<TODO> keywords in the begin of the test description. For example: 1+2+3 6 SKIP no add operation yet 1-2-3 6 TODO no minus operation yet B<NOTE:> to add more source test files remember to update the C<@files> array in this file. =head1 SYNOPSIS $ prove examples/languages/abc/t/01-tests.t =cut # abc build directory my $abcdir = "$PConfig{'build_dir'}/examples/languages/abc"; # files to load tests from my @files = qw( abc_basic abc_special_variables abc_statement abc_functions ); # for each test file given calculate full path my @test_files = map { "$abcdir/t/$_" } @files; # calculate total number of tests my $numtests = 0; foreach my $f (@test_files) { open my $TEST_FILE, '<', $f; # for each line in the given files if it's not a comment line # or an empty line, the it's a test while (<$TEST_FILE>) { $numtests++ unless ( ( $_ =~ m/^#/ ) or ( $_ =~ m/^\s*$/ ) ); } } # set plan plan tests => $numtests; # main loop foreach my $file (@test_files) { open my $TEST_FILE, '<', $file or die "can't open file"; while (<$TEST_FILE>) { chomp; s/\r//g; # skip comment lines $_ =~ /^#/ and next; # skip empty lines $_ =~ /^\s*$/ and next; # split by tabs or 3+ spaces my ( $expr, $expect, $description ) = split / *\t\s*|\s{3,}/, $_; # do some simple checking if ( $expr eq '' or $expect eq '' or $description eq '' ) { warn "$file line $. doesn't match a valid test!"; next; } $expr =~ s/"/\\"/g; # Escape the '"', as $expr will be # enclosed by '"' in the generated PIR $expect =~ s/^'(.*)'$/$1/; # remove surrounding quotes (for '') $expect =~ s/\\n/\n/g; # treat \n as newline # build pir code my $pir_code = abc_template(); $pir_code =~ s/<<EXPR>>/$expr/g; # check if we need to skip this test if ( $description =~ m/^(SKIP|skip)\s+(.*)/ ) { SKIP: { skip $2, 1; pir_output_is( $pir_code, $expect, $description ); } next; } # check if we need to todo this test if ( $description =~ m/^(TODO|todo)\s+(.*)/ ) { my @todo = (); push @todo, todo => $2; pir_output_is( $pir_code, $expect, $description, @todo ); next; } # no skip or todo -- run test pir_output_is( $pir_code, $expect, $description ); } } # end exit; sub abc_template { return <<"PIR"; .sub 'main' :main load_bytecode '$abcdir/abc.pbc' .local pmc compiler, code compiler = compreg 'abc' code = compiler.'compile'("<<EXPR>>") code() .end PIR } =head1 AUTHOR Nuno 'smash' Carvalho <mestre.smash@gmail.com> =cut # Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4: