=begin pod :kind("Type") :subkind("module") :category("module")

=TITLE module Test

=SUBTITLE Writing and running tests

This module provides a testing framework, and is used in the official suite that
tests the specification. All its functions emit output conforming to the
L<Test Anything Protocol|https://testanything.org>.

Also see L<Writing and running tests in Raku|/language/testing>.

=head1 Methods

=head2 sub plan

Defined as:

    multi sub plan(Cool:D :skip-all($reason)!)
    multi sub plan($number_of_tests)

Specify the count of tests -- usually written at the beginning of a
test file.

=for code :preamble<use Test;>
plan 15;   # expect to run 15 tests

In C<subtest>s, C<plan> is used to specify the count of tests within
the subtest.

If a C<plan> is used, it's not necessary to specify the end of testing with
C<done-testing>.

You can also provide a C<:skip-all> named argument instead of a test count,
to indicate that you want to skip all of the tests. Such a plan will
call L«C<exit>|/routine/exit», unless used inside of a C<subtest>.

=for code :preamble<use Test;>
plan :skip-all<These tests are only for Windows> unless $*DISTRO.is-win;
plan 1;
ok dir 'C:/'; # this won't get run on non-Windows

If used in a C<subtest>, it will instead C<return> from that
C<subtest>'s L«C<Callable>|/type/Callable». For that reason, to be able to
use C<:skip-all> inside a C<subtest>, you must use a C<sub> instead of a
regular block:

=begin code :preamble<use Test;>
plan 2;
subtest "Some Windows tests" => sub { # <-- note the `sub`; can't use bare block
    plan :skip-all<We aren't on Windows> unless $*DISTRO.is-win;
    plan 1;
    ok dir 'C:/'; # this won't get run on non-Windows
}
ok 42; # this will run everywhere and isn't affected by skip-all inside subtest
=end code

Note that C<plan> with C<:skip-all> is to avoid performing any tests without
marking the test run as failed (i.e. the plan is to not run anything and that's
all good). Use
L«C<skip-rest>|/language/testing#index-entry-skip-rest-skip-rest($reason?)» to
skip all further tests, once the run has started (i.e. planned to run some
tests, maybe even ran some, but now we're skipping all the rest of them). Use
L«C<bail-out>|/language/testing#index-entry-bail-out-bail-out($reason?)» to fail
the test run without running any further tests (i.e. things are so bad, there's
no point in running anything else; we've failed).

=head2 sub done-testing

Defined as:

    sub done-testing()

Specify that testing has finished.  Use this function when you don't
have a C<plan> with the number of tests to run. A C<plan> is not
required when using C<done-testing>.

It's recommended that the C<done-testing> function be removed and replaced with
a C<plan> function when all tests are finalized. Use of C<plan> can help detect
test failures otherwise not reported because tests were accidentally skipped due
to bugs in the tests or bugs in the compiler. For example:

=for code :preamble<use Test;>
sub do-stuff {@};
use Test;
ok .is-prime for do-stuff;
done-testing;
# output:
1..0

The above example is where a C<done-testing> fails. C<do-stuff()> returned
nothing and tested nothing, even though it should've returned results to test.
But the test suite doesn't know how many tests were meant to be run, so it
passes.

Adding C<plan> gives a true picture of the test:

=for code :preamble<use Test;>
sub do-stuff {@};
use Test;
plan 1;
ok .is-prime for do-stuff;
# output:
1..1
# Looks like you planned 1 test, but ran 0

Note that leaving the C<done-testing> in place will have no effect on the new test
results, but it should be removed for clarity.

The C<done-testing> function returns C<False> if any test has failed or
less tests were run than planned, it returns C<True> otherwise.

=head2 sub ok

Defined as:

    multi sub ok(Mu $cond, $desc = '')

The C<ok> function marks a test as passed if the given C<$cond> evaluates to
C<True>. It also accepts an optional description of the test as second
argument.

=for code :preamble<use Test;>
my $response; my $query; ...;
ok $response.success, 'HTTP response was successful';

In principle, you could use C<ok> for every kind of comparison test, by
including the comparison in the expression passed to C<$cond>:

=for code :preamble<use Test;>
sub factorial($x) { ... };
ok factorial(6) == 720, 'Factorial - small integer';

However, where possible it's better to use one of the specialized comparison
test functions below, because they can print more helpful diagnostics output in
case the comparison fails.

=head2 sub nok

Defined as:

    multi sub nok(Mu $cond, $desc = '')

The C<nok> function marks a test as passed if the given C<$cond> evaluates to
C<False>. It also accepts an optional description of the test as second
argument.

=for code :preamble<use Test;>
my $response; my $query; ...;
nok $query.error, 'Query completed without error';

=head2 sub is

Defined as

    multi sub is(Mu $got, Mu:U $expected, $desc = '')
    multi sub is(Mu $got, Mu:D $expected, $desc = '')

Marks a test as passed if C<$got> and C<$expected> compare positively with the
L«C<eq> operator|/routine/eq», unless C<$expected> is a type object, in which case
L«C<===> operator|/routine/===» will be used instead; accepts an optional description of the
test as the last argument.

B<NOTE:> the C<eq> operator stringifies its operands, which means C<is()> is not
a good function for testing more complex things, such as lists: C<is (1, (2,
(3,))), [1, 2, 3]> passes the test, even though the operands are vastly
different. For those cases, use
L«C<is-deeply> routine|#sub_is-deeply»

=for code :preamble<use Test;>
my $pdf-document; sub factorial($x) { ... }; ...;
is $pdf-document.author, "Joe", 'Retrieving the author field';
is factorial(6),         720,   'Factorial - small integer';
my Int $a;
is $a, Int, 'The variable $a is an unassigned Int';

B<Note:> if I<only> whitespace differs between the values, C<is()> will output
failure message differently, to show the whitespace in each values. For example,
in the output below, the second test shows the literal C<\t> in the C<got:>
line:

=for code :preamble<use Test;>
is "foo\tbar", "foo\tbaz";   # expected: 'foo     baz'␤#      got: 'foo   bar'
is "foo\tbar", "foo    bar"; # expected: "foo    bar"␤#      got: "foo\tbar"

=head2 sub isnt

Defined as:

    multi sub isnt(Mu $got, Mu:U $expected, $desc = '')
    multi sub isnt(Mu $got, Mu:D $expected, $desc = '')

Marks a test as passed if C<$got> and C<$expected> are B<not> equal using
the same rules as C<is()>.  The function accepts an optional description
of the test.

=for code :preamble<use Test;>
isnt pi, 3, 'The constant π is not equal to 3';
my Int $a = 23;
$a = Nil;
isnt $a, Nil, 'Nil should not survive being put in a container';

=head2 sub is_approx

Defined as:

    multi sub is_approx(Mu $got, Mu $expected, $desc = '')

B<NOTE>: Deprecated as of version 6.d. Please use C<is-approx> instead.

Checks if result and the expected value are approximately equal to a certain
degree of tolerance, fixed to 1e-5 or one-millionth of the expected value is its
value is less than that.

=for code
use Test;
is_approx(1e4, 1e4-1e-6, "Real close"); # OUTPUT: «ok 1 - Real close␤»

(This will print also a deprecation notice if you're using 6.d)



=head2 sub is-approx

Defined as:

    multi sub is-approx(Numeric $got, Numeric $expected, $desc = '')

=for code :method
multi sub is-approx(Numeric $got, Numeric $expected, Numeric $abs-tol,
                    $desc = '')

=for code :method
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '',
                    Numeric :$rel-tol is required)

=for code :method
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '',
                    Numeric :$abs-tol is required)

=for code :method
multi sub is-approx(Numeric $got, Numeric $expected, $desc = '',
                    Numeric :$rel-tol is required,
                    Numeric :$abs-tol is required)

Marks a test as passed if the C<$got> and C<$expected> numerical values
are approximately equal to each other. The subroutine can be called in numerous
ways that let you test using relative tolerance (C<$rel-tol>) or
absolute tolerance (C<$abs-tol>) of different values.

If no tolerance is set, the function will base the tolerance on the I<absolute>
value of C<$expected>: if it's smaller than C<1e-6>, use absolute tolerance of
C<1e-5>; if it's larger, use relative tolerance of C<1e-6>.

=begin code :preamble<use Test;>
my Numeric ($value, $expected, $abs-tol, $rel-tol) = ...

is-approx $value, $expected;
is-approx $value, $expected, 'test description';

is-approx $value, $expected, $abs-tol;
is-approx $value, $expected, $abs-tol, 'test description';

is-approx $value, $expected, :$rel-tol;
is-approx $value, $expected, :$rel-tol, 'test description';

is-approx $value, $expected, :$abs-tol;
is-approx $value, $expected, :$abs-tol, 'test description';

is-approx $value, $expected, :$abs-tol, :$rel-tol;
is-approx $value, $expected, :$abs-tol, :$rel-tol, 'test description';
=end code

=head3 Absolute tolerance

When an absolute tolerance is set, it's used as the actual maximum value
by which the first and the second parameters can differ. For example:

=begin code :preamble<use Test;>
is-approx 3, 4, 2; # success
is-approx 3, 6, 2; # fail

is-approx 300, 302, 2; # success
is-approx 300, 400, 2; # fail
is-approx 300, 600, 2; # fail
=end code

Regardless of values given, the difference between them cannot be more
than C<2>.

=head3 Relative tolerance

When a relative tolerance is set, the test checks the relative difference
between values. Given the same tolerance, the larger the numbers given, the
larger the value they can differ by can be.

For example:

=begin code :preamble<use Test;>
is-approx 10, 10.5, :rel-tol<0.1>; # success
is-approx 10, 11.5, :rel-tol<0.1>; # fail

is-approx 100, 105, :rel-tol<0.1>; # success
is-approx 100, 115, :rel-tol<0.1>; # fail
=end code

Both versions use C<0.1> for relative tolerance, yet the first can differ
by about C<1> while the second can differ by about C<10>. The function used
to calculate the difference is:

=begin code :lang<text>
              |value - expected|
⁣rel-diff = ────────────────────────
           max(|value|, |expected|)
=end code

and the test will fail if C<rel-diff> is higher than C<$rel-tol>.

=head3 Both absolute and relative tolerance specified

=for code :preamble<use Test; my ($value, $expected);>
is-approx $value, $expected, :rel-tol<.5>, :abs-tol<10>;

When both absolute and relative tolerances are specified, each will be
tested independently, and the C<is-approx> test will succeed only if both pass.

=head2 sub is-approx-calculate

Defined as:

=for code :method
sub is-approx-calculate($got, $expected, $abs-tol where { !.defined or $_ >= 0 },
                        $rel-tol where { !.defined or $_ >= 0 }, $desc)

This is the actual routine called by
L<C<is-approx> when absolute and relative tolerance are specified|/type/Test#Both_absolute_and_relative_tolerance_specified>.
They are
tested independently, and the test succeeds only if both pass.

=head2 sub is-deeply

Defined as:

    multi sub is-deeply(Seq:D $got, Seq:D $expected, $reason = '')
    multi sub is-deeply(Seq:D $got, Mu $expected, $reason = '')
    multi sub is-deeply(Mu $got, Seq:D $expected, $reason = '')
    multi sub is-deeply(Mu $got, Mu $expected, $reason = '')

Marks a test as passed if the first and second parameters are equivalent, using the
same semantics as the L<eqv operator|/routine/eqv>. This is the best way to
check for equality of (deep) data structures. The function accepts an optional
description of the test as the last argument.

=begin code
use Test;
plan 1;

sub string-info(Str() $_) {
    Map.new: (
      length  =>  .chars,
      char-counts => Bag.new-from-pairs: (
          letters => +.comb(/<:letter>/),
          digits  => +.comb(/<:digit>/),
          other   => +.comb(/<.-:letter-:digit>/),
    ))
}

is-deeply string-info('42 Butterflies ♥ Raku'), Map.new((
    :21length,
    char-counts => Bag.new-from-pairs: ( :15letters, :2digits, :4other, )
)), 'string-info gives right info';
=end code

B<Note:> for L<historical reasons|https://github.com/rakudo/rakudo/commit/096bc17cd5>,
L<Seq:D|/type/Seq> arguments to C<is-deeply> get converted to
L<Lists|/type/List> by calling L<C<.cache>|/routine/cache> on them. If you
want to ensure strict C<Seq> comparisons, use
L«C<cmp-ok $got, 'eqv', $expected, $desc>|/language/testing#By_arbitrary_comparison»
instead.


=head2 sub cmp-ok

    multi sub cmp-ok(Mu $got is raw, $op, Mu $expected is raw, $desc = '')

Compares C<$got> and C<$expected> with the given C<$op> comparator and
passes the test if the comparison yields a C<True> value. The description
of the test is optional.

The C<$op> comparator can be either a L<Callable|/type/Callable> or
a L<Str|/type/Str> containing an infix operator, such as C<'=='>, a C<'~~'>, or a
user-defined infix.

=for code :preamble<use Test;>
cmp-ok 'my spelling is apperling', '~~', /perl/, "bad speller";

Metaoperators cannot be given as a string; pass them as a
L<Callable|/type/Callable> instead:

=for code :preamble<use Test;>
cmp-ok <a b c>, &[!eqv], <b d e>, 'not equal';

A L<Callable|/type/Callable> C<$op> lets you use custom comparisons:

=for code :preamble<use Test;>
sub my-comp { $^a / $^b  < rand };
cmp-ok 1, &my-comp, 2, 'the dice giveth and the dice taketh away'
cmp-ok 2, -> $a, $b { $a.is-prime and $b.is-prime and $a < $b }, 7,
    'we got primes, one larger than the other!';

=head2 sub isa-ok

Defined as:

    multi sub isa-ok(Mu $var, Mu $type, $desc = "The object is-a '$type.raku()'")

Marks a test as passed if the given object C<$var> is, or inherits from, the
given C<$type>.  For convenience, types may also be specified as a
string.  The function accepts an optional description of the test, which
defaults to a string that describes the object.

=begin code :preamble<use Test;>
class Womble {}
class GreatUncleBulgaria is Womble {}
my $womble = GreatUncleBulgaria.new;

isa-ok $womble, Womble, "Great Uncle Bulgaria is a womble";
isa-ok $womble, 'Womble';     # equivalent
=end code

=head2 sub can-ok

Defined as:

    multi sub can-ok(Mu $var, Str $meth, $desc = "..." )

Marks a test as passed if the given C<$var> can run the method named
C<$meth>.  The function accepts an optional description.  For
instance:

=begin code :preamble<use Test;>
class Womble {};
my $womble = Womble.new;

# with automatically generated test description
can-ok $womble, 'collect-rubbish';
#  => An object of type 'Womble' can do the method 'collect-rubbish'

# with human-generated test description
can-ok $womble, 'collect-rubbish', "Wombles can collect rubbish";
#  => Wombles can collect rubbish
=end code

=head2 sub does-ok

Defined as:

    multi sub does-ok(Mu $var, Mu $type, $desc = "...")

Marks a test as passed if the given C<$var> can do the given role C<$type>.
The function accepts an optional description of the test.

=begin code :preamble<use Test;>
# create a Womble who can invent
role Invent {
    method brainstorm { say "Aha!" }
}
class Womble {}
class Tobermory is Womble does Invent {}

# ... and later in the tests
use Test;

my $tobermory = Tobermory.new;

# with automatically generated test description
does-ok $tobermory, Invent;
#  => The object does role Type

does-ok $tobermory, Invent, "Tobermory can invent";
#  => Tobermory can invent
=end code

=head2 sub like

Defined as:

    sub like(Str() $got, Regex:D $expected, $desc = "text matches $expected.raku()")

Use it this way:

=for code :preamble<use Test;>
like 'foo', /fo/, 'foo looks like fo';

Marks a test as passed if the first parameter, when coerced to a string,
matches the regular expression specified as the second parameter.
The function accepts an optional description of the test with a default
value printing the expected match.

=head2 sub unlike

Defined as:

    multi sub unlike(Str() $got, Regex:D $expected, $desc = "text does not match $expected.raku()")

Used this way:

=for code :preamble<use Test;>
unlike 'foo', /bar/, 'foo does not look like bar';

Marks a test as passed if the first parameter, when coerced to a string,
does B<not> match the regular expression specified as the second
parameter.  The function accepts an optional description of the test,
which defaults to printing the text that did not match.

=head2 sub use-ok

Defined as:

    multi sub use-ok(Str $code, $desc = "$code module can be use-d ok")

Marks a test as passed if the given C<$module> loads correctly.

=for code :preamble<use Test;>
use-ok 'Full::Qualified::ModuleName';

Since C<$code> is being turned into an C<EVAL>, you can also pass arguments:

=for code :preamble<use Test;>
use-ok 'Full::Qualified::ModuleName :my-argument';

=head2 sub dies-ok

Defined as:

    multi sub dies-ok(Callable $code, $reason = '')

Marks a test as passed if the given C<$code> throws an exception.

The function accepts an optional description of the test.

=begin code :preamble<use Test;>
sub saruman(Bool :$ents-destroy-isengard) {
    die "Killed by Wormtongue" if $ents-destroy-isengard;
}

dies-ok { saruman(ents-destroy-isengard => True) }, "Saruman dies";
=end code

=head2 sub lives-ok

Defined as:

    multi sub lives-ok(Callable $code, $reason = '')

Marks a test as passed if the given C<$code> B<does not> throw an
exception.

The function accepts an optional description of the test.

=begin code :preamble<use Test;>
sub frodo(Bool :$destroys-ring) {
    die "Oops, that wasn't supposed to happen" unless $destroys-ring;
}

lives-ok { frodo(destroys-ring => True) }, "Frodo survives";
=end code

=head2 sub eval-dies-ok

Defined as:

    multi sub eval-dies-ok(Str $code, $reason = '')

Marks a test as passed if the given C<$string> throws an exception when
C<eval>ed as code.

The function accepts an optional description of the test.

=begin code :preamble<use Test;>
eval-dies-ok q[my $joffrey = "nasty";
               die "bye bye Ned" if $joffrey ~~ /nasty/],
    "Ned Stark dies";
=end code

=head2 sub eval-lives-ok

Defined as:

    multi sub eval-lives-ok(Str $code, $reason = '')

Marks a test as passed if the given C<$string> B<does not> throw an
exception when C<eval>ed as code.

The function accepts an optional description of the test.

=begin code :preamble<use Test;>
eval-lives-ok q[my $daenerys-burns = False;
                die "Oops, Khaleesi now ashes" if $daenerys-burns],
    "Dany is blood of the dragon";
=end code

=head2 sub throws-like

Defined as:

    sub throws-like($code, $ex_type, $reason?, *%matcher)

Marks a test as passed if the given C<$code> throws the specific exception
expected exception type C<$ex_type>. The code C<$code> may be specified as
something C<Callable> or as a string to be C<EVAL>ed. The exception may be
specified as a type object or as a string containing its type name.

If an exception was thrown, it will also try to match the matcher hash,
where the key is the name of the method to be called on the exception, and
the value is the value it should have to pass. For example:

=begin code :preamble<use Test;>
sub frodo(Bool :$destroys-ring) {
    fail "Oops. Frodo dies" unless $destroys-ring
};
throws-like { frodo }, Exception, message => /dies/;
=end code

The function accepts an optional description of the test as the third
positional argument.

The routine makes L<Failures|/type/Failure> fatal. If you wish to avoid that,
use L«C<no fatal> pragma|/language/pragmas#index-entry-fatal-fatal» and ensure
the tested code does not sink the possible L<Failures|/type/Failure>. If you
wish to test that the code returns a L<Failure|/type/Failure> instead of
throwing, use C<fails-like> routine instead.

=begin code :preamble<use Test;>
sub fails-not-throws { +"a" }
# test passes, even though it's just a Failure and would not always throw:
throws-like { fails-not-throws }, Exception;

# test detects nothing thrown, because our Failure wasn't sunk or made fatal:
throws-like { no fatal; my $ = fails-not-throws; Nil }, Exception;
=end code

Please note that you can only use the string form (for C<EVAL>) if you are not
referencing any symbols in the surrounding scope. If you are, you should
encapsulate your string with a block and an EVAL instead. For instance:

=for code :preamble<use Test;>
throws-like { EVAL q[ fac("foo") ] }, X::TypeCheck::Argument;

=head2 sub fails-like

Defined as:

    sub fails-like ( \test where Callable:D|Str:D, $ex-type, $reason?, *%matcher)

Same interface as C<throws-like>, except checks that the code returns a
L<Failure|/type/Failure> instead of throwing. If the code does throw or if the
returned L<Failure|/type/Failure> has already been L<handled|/routine/handled>,
that will be considered as a failed test.

=for code :preamble<use Test;>
fails-like { +"a" }, X::Str::Numeric,
    :message(/'Cannot convert string to number'/),
    'converting non-numeric string to number fails';

=head2 sub subtest

Defined as:

    multi sub subtest(Pair $what)
    multi sub subtest($desc, &subtests)
    multi sub subtest(&subtests, $desc = '')

The C<subtest> function executes the given block, consisting of usually more
than one test, possibly including a C<plan> or C<done-testing>, and counts as
I<one> test in C<plan>, C<todo>, or C<skip> counts. It will pass the
test only if B<all> tests in the block pass. The function accepts an
optional description of the subtest.

=begin code :preamble<use Test;>
class Womble {}

class GreatUncleBulgaria is Womble {
    has $.location = "Wimbledon Common";
    has $.spectacles = True;
}

subtest {
    my $womble = GreatUncleBulgaria.new;

    isa-ok $womble,            Womble,             "Correct type";
    is     $womble.location,   "Wimbledon Common", "Correct location";
    ok     $womble.spectacles,                     "Correct eyewear";

}, "Check Great Uncle Bulgaria";
=end code

You can also place the description as the first positional argument, or use a
C<Pair> with description as the key and subtest's code as the value. This can be
useful for subtests with large bodies.

=begin code :preamble<use Test;>
subtest 'A bunch of tests', {
    plan 42;
    ...
    ...
}

subtest 'Another bunch of tests' => {
    plan 72;
    ...
    ...
}
=end code

=head2 sub todo

Defined as:

    multi sub todo($reason, $count = 1)

Sometimes tests just aren't ready to be run, for instance a feature might
not yet be implemented, in which case tests can be marked as C<todo>. Or it
could be the case that a given feature only works on a particular platform -
in which case one would C<skip> the test on other platforms.

Mark C<$count> tests as TODO, giving a C<$reason> as to why.  By default
only one test will be marked TODO.

=begin code :preamble<use Test;>
sub my-custom-pi { 3 };

todo 'not yet precise enough';         # Mark the test as TODO.
is my-custom-pi(), pi, 'my-custom-pi'; # Run the test, but don't report
                                       # failure in test harness.
=end code

The result from the test code above will be something like:

=begin code :lang<TAP>
not ok 1 - my-custom-pi # TODO not yet precise enough
# Failed test 'my-custom-pi'
# at test-todo.t line 7
# expected: '3.14159265358979'
#      got: '3'
=end code

Note that if you C<todo> a C<subtest>, all of the failing tests inside of it
will be automatically marked TODO as well and will I<not> count towards your
original TODO count.

=head2 sub skip

Defined as:

    multi sub skip()
    multi sub skip($reason, $count = 1)

Skip C<$count> tests, giving a C<$reason> as to why.  By default only one
test will be skipped.  Use such functionality when a test (or tests) would
die if run.

=begin code :preamble<use Test;>
sub num-forward-slashes($arg) { ... } ;

if $*KERNEL ~~ 'linux' {
    is num-forward-slashes("/a/b"),             2;
    is num-forward-slashes("/a//b".IO.cleanup), 2;
}
else {
    skip "Can't use forward slashes on Windows", 2;
}
=end code

Note that if you mark a test as skipped, you must also prevent that
test from running.

=head2 sub skip-rest

Defined as:

    sub skip-rest($reason = '<unknown>')

Skip the remaining tests.  If the remainder of the tests in the test file
would all fail due to some condition, use this function to skip them,
providing an optional C<$reason> as to why.

=begin code :preamble<use Test;>
my $location; sub womble { ... }; ...;
unless $location ~~ "Wimbledon Common" {
    skip-rest "We can't womble, the remaining tests will fail";
    exit;
}

# tests requiring functional wombling
ok womble();
# ...
=end code

Note that C<skip-rest> requires a C<plan> to be set, otherwise the
C<skip-rest> call will throw an error. Note that C<skip-rest> does
not exit the test run. Do it manually, or use conditionals to
avoid running any further tests.

See also L«C<plan :skip-all('...')>|#sub_plan»
to avoid running any tests at all and
L«C<bail-out>|#sub_bail-out» to abort
the test run and mark it as failed.

=head2 sub bail-out

    sub bail-out ($desc?)

If you already know the tests will fail, you can bail out of the test run
using C<bail-out()>:

=begin code :preamble<use Test;>
my $has-db-connection;
...
$has-db-connection  or bail-out 'Must have database connection for testing';
=end code

The function aborts the current test run, signaling failure to the harness.
Takes an optional reason for bailing out. The subroutine will call
C<exit()>, so if you need to do a clean-up, do it before calling C<bail-out()>.

If you want to abort the test run, but without marking it as failed, see
L«C<skip-rest>|/language/testing#index-entry-skip-rest-skip-rest($reason?)»
or L«C<plan :skip-all('...')>|/language/testing#index-entry-plan-plan($count)»

=head2 sub pass

Defined as:

    multi sub pass($desc = '')

The C<pass> function marks a test as passed. C<flunk> marks a test as
B<not> passed. Both functions accept an optional test description.

=for code :preamble<use Test;>
pass "Actually, this test has passed";
flunk "But this one hasn't passed";

Since these subroutines do not provide indication of what value was received
and what was expected, they should be used sparingly, such as when evaluating
a complex test condition.

=head2 sub flunk

    multi sub flunk($reason = '')

The opposite of C<pass>, makes a test fail with an optional message.

=head2 sub diag

    sub diag($message)

Display diagnostic information in a TAP-compatible manner on the standard
error stream. This is usually used when a particular test has failed to
provide information that the test itself did not provide.  Or it can be used
to provide visual markers on how the testing of a test-file is progressing
(which can be important when doing stress testing).

=for code :preamble<use Test;>
diag "Yay!  The tests got to here!";

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
