aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2021-02-05 00:23:50 +0000
committerPaulo Custodio <pauloscustodio@gmail.com>2021-02-05 00:23:50 +0000
commit0c54c07d7ae051ae0bb070db975a0335997d0f44 (patch)
treed7f60215dfa77d20e92fb862d83c18d9f1905d9e
parent5e61259702034cbec63ade467ac7d3575a2f686c (diff)
downloadperlweeklychallenge-club-0c54c07d7ae051ae0bb070db975a0335997d0f44.tar.gz
perlweeklychallenge-club-0c54c07d7ae051ae0bb070db975a0335997d0f44.tar.bz2
perlweeklychallenge-club-0c54c07d7ae051ae0bb070db975a0335997d0f44.zip
Create a data-driven test script, with test data in YAML files
-rw-r--r--challenge-001/paulo-custodio/t/test-1.yaml13
-rw-r--r--challenge-001/paulo-custodio/t/test-2.yaml25
-rw-r--r--challenge-001/paulo-custodio/test.pl172
3 files changed, 155 insertions, 55 deletions
diff --git a/challenge-001/paulo-custodio/t/test-1.yaml b/challenge-001/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..4e72c56368
--- /dev/null
+++ b/challenge-001/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,13 @@
+- setup:
+ cleanup:
+ args: Perl Weekly Challenge
+ input:
+ output: |
+ 5 PErl WEEkly ChallEngE
+
+- setup:
+ cleanup:
+ args: Champion
+ input:
+ output: |
+ 0 Champion
diff --git a/challenge-001/paulo-custodio/t/test-2.yaml b/challenge-001/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..b596ac9f39
--- /dev/null
+++ b/challenge-001/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,25 @@
+- setup:
+ cleanup:
+ args: 20
+ input:
+ output: |
+ 1
+ 2
+ fizz
+ 4
+ buzz
+ fizz
+ 7
+ 8
+ fizz
+ buzz
+ 11
+ fizz
+ 13
+ 14
+ fizzbuzz
+ 16
+ 17
+ fizz
+ 19
+ buzz
diff --git a/challenge-001/paulo-custodio/test.pl b/challenge-001/paulo-custodio/test.pl
index 829837ad0b..6cc94723ba 100644
--- a/challenge-001/paulo-custodio/test.pl
+++ b/challenge-001/paulo-custodio/test.pl
@@ -1,73 +1,135 @@
#!/usr/bin/perl
+# run tests described in t/test-N.yaml
+
use strict;
use warnings;
-use Test::More;
use 5.030;
+use Test::More;
+use Path::Tiny;
+use YAML::Tiny;
-my $LUA = ($^O eq 'msys') ? "lua.exe" : "lua";
+our $EXE = $^O =~ /MSWin32|msys/ ? ".exe" : "";
-run("gcc c/ch-1.c -o c/ch-1");
-run("g++ cpp/ch-1.cpp -o cpp/ch-1");
-run("fbc basic/ch-1.bas -o basic/ch-1");
+# hack so that output redirection works in msys
+our $LUA = $^O eq "msys" ? "lua.exe" : "lua";
-for (["Perl Weekly Challenge" => "5 PErl WEEkly ChallEngE"],
- ["Champion" => "0 Champion"]) {
- my($in, $out) = @$_;
+our %LANG = (
+ ada => 'adb',
+ awk => 'awk',
+ basic => 'bas',
+ c => 'c',
+ cpp => 'cpp',
+ forth => 'fs',
+ lua => 'lua',
+ perl => 'pl',
+ python => 'py',
+);
- is capture( "$LUA lua/ch-1.lua $in"), "$out\n";
- is capture( "perl perl/ch-1.pl $in"), "$out\n";
- is capture( "gforth forth/ch-1.fs $in"), "$out\n";
- is capture("python python/ch-1.py $in"), "$out\n";
- is capture( "c/ch-1 $in"), "$out\n";
- is capture( "cpp/ch-1 $in"), "$out\n";
- is capture( "basic/ch-1 $in"), "$out\n";
+# filter tests if languages given on command line
+our %TESTS;
+if (!@ARGV) {
+ %TESTS = %LANG;
}
+else {
+ $TESTS{$_}=1 for @ARGV;
+}
+
+for my $lang (grep {-d} sort keys %LANG) {
+ next unless $TESTS{$lang};
+ for my $prog (path($lang)->children(qr/\.$LANG{$lang}$/)) {
+ $prog->basename =~ /^ch[-_](.*)\.$LANG{$lang}$/ or die $prog;
+ my $task = $1;
+
+ # compile if needed
+ my $exec = build($lang, $prog);
-run("gcc c/ch-2.c -o c/ch-2");
-run("g++ cpp/ch-2.cpp -o cpp/ch-2");
-run("fbc basic/ch-2.bas -o basic/ch-2");
-
-for ([20 => <<END]) {
-1
-2
-fizz
-4
-buzz
-fizz
-7
-8
-fizz
-buzz
-11
-fizz
-13
-14
-fizzbuzz
-16
-17
-fizz
-19
-buzz
-END
- my($in, $out) = @$_;
-
- is capture( "$LUA lua/ch-2.lua $in"), $out;
- is capture( "perl perl/ch-2.pl $in"), $out;
- is capture( "gforth forth/ch-2.fs $in"), $out;
- is capture("python python/ch-2.py $in"), $out;
- is capture( "c/ch-2 $in"), $out;
- is capture( "cpp/ch-2 $in"), $out;
- is capture( "basic/ch-2 $in"), $out;
+ for my $test (path("t")->children(qr/test-$task\.yaml$/)) {
+ # execute each test from test-N.yaml
+ my $yaml = YAML::Tiny->read($test);
+ for my $doc (@$yaml) {
+ for my $spec (@$doc) {
+ # run setup code
+ ok eval($spec->{setup}), $spec->{setup} if $spec->{setup};
+ $@ and die $@;
+
+ # build test command line
+ my $cmd = "$exec ".($spec->{args} // "");
+ chomp($cmd);
+ if($spec->{input}) {
+ path("in.txt")->spew($spec->{input});
+ $cmd .= " < in.txt";
+ }
+ if ($spec->{output}) {
+ path("out_exp.txt")->spew($spec->{output});
+ $cmd .= " > out.txt";
+ }
+
+ # run test
+ run($cmd);
+
+ # compare output
+ if ($spec->{output}) {
+ run("diff -w out_exp.txt out.txt");
+ }
+
+ # run cleaup code
+ if (Test::More->builder->is_passing) {
+ ok eval($spec->{cleanup}), $spec->{cleanup} if $spec->{cleanup};
+ $@ and die $@;
+ unlink("in.txt", "out.txt", "out_exp.txt");
+ }
+ else {
+ die "tests failed\n"; # to give chance to examine output
+ }
+ }
+ }
+ }
+ }
}
done_testing;
-sub capture {
- my($cmd) = @_;
- my $out = `$cmd`;
- $out =~ s/[ \t\v\f\r]*\n/\n/g;
- return $out;
+# compile if needed, return executable line
+sub build {
+ my($lang, $prog) = @_;
+ my $exe = ($prog =~ s/\.\w+/$EXE/r);
+ my $prog_wo_ext = ($prog =~ s/\.\w+//r);
+ my $prog_base = path($prog)->basename;
+ for ($lang) {
+ if (/ada/) {
+ run("cd ada; gnatmake $prog_base"); # gnatmake builds only if needed
+ return $exe;
+ }
+ if (/awk/) {
+ return "gawk -f $prog";
+ }
+ if (/basic/) {
+ run("fbc $prog -o $prog_wo_ext") if (!-f $exe || -M $exe > -M $prog);
+ return $exe;
+ }
+ if (/^c$/) {
+ run("gcc $prog -o $prog_wo_ext") if (!-f $exe || -M $exe > -M $prog);
+ return $exe;
+ }
+ if (/cpp/) {
+ run("g++ $prog -o $prog_wo_ext") if (!-f $exe || -M $exe > -M $prog);
+ return $exe;
+ }
+ if (/forth/) {
+ return "gforth $prog";
+ }
+ if (/lua/) {
+ return "$LUA $prog";
+ }
+ if (/perl/) {
+ return "perl $prog";
+ }
+ if (/python/) {
+ return "python $prog";
+ }
+ die "unsupported language $lang";
+ }
}
sub run {