From 4b2c2eb4dd3eef5a23190008b887a0a5ee166936 Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Tue, 31 Dec 2024 19:08:42 -0500 Subject: [PATCH] Improve test running Move test running to a method on the Test class and improve output printing logic. --- bin/iutils | 21 +-------------------- lib/IUtils.rakumod | 35 ++++++++++++++++++++++++++++++++++- lib/IUtils/Compiler.rakumod | 8 +++++--- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/bin/iutils b/bin/iutils index 75ba450..a7334ad 100755 --- a/bin/iutils +++ b/bin/iutils @@ -41,26 +41,7 @@ multi MAIN( say "{colored '**', 'magenta bold'} Testing $colored-module" .indent(2); for $module.tests -> $test { - try { - # FIXME this doesn't actually capture the exit code - idris-exec $test.expr, $module.source.relative, $test.output-type; - } - my $testf = colored $test.name, 'underline'; - if $! ~~ ExpressionError { - # TODO: Don't show stdout if its empty - $module-failures += 1; - say "{colored '+', 'red'} $testf: {colored 'FAIL', 'red bold'}" - .indent(4); - say "stdout:".indent(6); - say $!.err.lines.map(*.indent(8)).join("\n"); - say (colored 'exit code', 'red').indent(6), - ": {$!.exit-code}"; - } elsif $! { - die $!; - } else { - say "{colored '+', 'green'} $testf: {colored 'pass', 'green'}" - .indent(4); - } + $module-failures += 1 if $test.run: $module.source; } if $module-failures == 0 { say "All $colored-module ".indent(4), diff --git a/lib/IUtils.rakumod b/lib/IUtils.rakumod index 64f5464..3832d49 100644 --- a/lib/IUtils.rakumod +++ b/lib/IUtils.rakumod @@ -3,6 +3,8 @@ unit module IUtils; need IUtils::IDEMode; +use Terminal::ANSIColor; + use IUtils::Regexes; use IUtils::Compiler; @@ -16,6 +18,38 @@ class Test { has Str:D $.expr is required; #| The output type of the test has ExprOutput:D $.output-type is required; + + #| Run this test, and return true if it failed, false if it passed + method run(IO::Path:D $source, Int:D $indent-level? = 4 --> Bool) { + CATCH { + when ExpressionError { + say "{colored '+', 'red'} $.name: {colored 'FAIL', 'red bold'}" + .indent($indent-level); + say "{colored('exit code', 'red')}: {$_.exit-code}" + .indent($indent-level + 2); + if $_.out.trim { + say colored('stdout:', 'underline') + .indent($indent-level + 2); + say $_.out.trim.lines.map(*.indent($indent-level + 2)) + .join("\n"); + } + if $_.err.trim { + say colored('stderr:', 'underline') + .indent($indent-level + 2); + say $_.err.trim.lines.map(*.indent($indent-level + 2)) + .join("\n"); + } + return True; + } + } + + idris-exec $.expr, $source.relative, $.output-type; + # The exception handler graps flow if the test failed, here the test passed + my $output = + "{colored '+', 'green'} $.name: {colored 'pass', 'green'}"; + say $output.indent($indent-level); + return False; + } } #| Structure representing the tests in a module @@ -60,7 +94,6 @@ class PackageInfo { when * eq 'Bool' {succeed Boolean}; when * eq 'Either' {succeed Either}; }; - say $output-type; my $test = Test.new(name => $match.Str, expr => $match.Str, diff --git a/lib/IUtils/Compiler.rakumod b/lib/IUtils/Compiler.rakumod index 544cc0a..6aad5de 100644 --- a/lib/IUtils/Compiler.rakumod +++ b/lib/IUtils/Compiler.rakumod @@ -88,9 +88,11 @@ my constant $bool-lambda = '(\x => if x then exitSuccess else exitFailure)'; # TODO: Implemenent support for the Either case -# TODO: Use the ide protocol to drive this so we can avoid the user needing to -# import anything -# Exec the expression with the given name in the given file +# TODO: Use the ide protocol to drive this so we can avoid the user needing to import anything +#| Exec the expression with the given name in the given file +#| +#| Uses the provided $output-type to hook up an adaptor for tests returning a +#| non () value sub idris-exec($expr, $file, $output-type? = Unit) is export { # Have idris compile an executable for the expression, given $output-type {