use Zef:ver($?DISTRIBUTION.meta // $?DISTRIBUTION.meta// '*'):api($?DISTRIBUTION.meta // '*'):auth($?DISTRIBUTION.meta // ''); use Zef::Utils::FileSystem:ver(Zef.^ver):api(Zef.^api):auth(Zef.^auth); class Zef::Service::Shell::Test does Tester { =begin pod =title class Zef::Service::Shell::Test =subtitle A raku executable based implementation of the Tester interface =head1 Synopsis =begin code :lang use Zef; use Zef::Service::Shell::Test; my $test = Zef::Service::Shell::Test.new; # Add logging if we want to see output my $stdout = Supplier.new; my $stderr = Supplier.new; $stdout.Supply.tap: { say $_ }; $stderr.Supply.tap: { note $_ }; # Assuming our current directory is a raku distribution # with no dependencies or all dependencies already installed... my $dist-to-test = $*CWD; my Str @includes = $*CWD.absolute; my $passed = so $test.test($dist-to-test, :@includes, :$stdout, :$stderr); say $passed ?? "PASS" !! "FAIL"; =end code =head1 Description C class for handling path based URIs ending in .rakutest / .t6 / .t using the C command. You probably never want to use this unless its indirectly through C; handling files and spawning processes will generally be easier using core language functionality. This class exists to provide the means for fetching a file using the C interfaces that the e.g. Test/TAP adapters use. =head1 Methods =head2 method probe method probe(--> Bool:D) Returns C if this module can successfully launch the C command (i.e. always returns C). =head2 method test-matcher method test-matcher(Str() :uri($) --> Bool:D) Returns C if this module knows how to test C<$uri>. This module always returns C right now since it just launches tests directly with the C command. =head2 method test method test(IO() $path, Str :@includes, Supplier :$stdout, Supplier :$stderr --> Bool:D) Test the files ending in C<.rakutest> C<.t6> or C<.t> in the C directory of the given C<$path> using the provided C<@includes> (e.g. C or C) via the C command. A C can be supplied as C<:$stdout> and C<:$stderr> to receive any output. Returns C if all test files exited with 0. =end pod #| Returns true always since it just uses $*EXECUTABLE method probe(--> Bool:D) { True } #| Return true if this Tester understands the given uri/path method test-matcher(Str() $ --> Bool:D) { return True } #| Test the given paths t/ directory using any provided @includes method test(IO() $path, :@includes, Supplier :$stdout, Supplier :$stderr --> Bool:D) { die "path does not exist: {$path}" unless $path.IO.e; my $test-path = $path.child('t'); return True unless $test-path.e; my @rel-test-files = sort map *.IO.relative($path), grep *.extension eq any('rakutest', 't', 't6'), list-paths($test-path.absolute, :f, :!d, :r); return True unless +@rel-test-files; my @results = @rel-test-files.map: -> $rel-test-file { my $passed; react { my $proc = Zef::zrun-async($*EXECUTABLE.absolute, @includes.map({ slip '-I', $_ }), $rel-test-file); whenever $proc.stdout.lines { $stdout.emit($_) } whenever $proc.stderr.lines { $stderr.emit($_) } whenever $proc.start(:cwd($path)) { $passed = $_.so } } $passed; } return so @results.all; } }