Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rewrites user example compilation test
Now everything is compiled via -c, instead of using EVAL. This is
slower, but closes #2764 since apparently the evaluation of so much
code was gobbling up memory, and closes #2782 since either the memory
itself or the creation of multiple objects was affecting this
somehow. It also causes #2789, so some changes are trying to fix that.
  • Loading branch information
JJ committed May 12, 2019
1 parent 73314de commit 4311d97
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 34 deletions.
8 changes: 4 additions & 4 deletions doc/Language/testing.pod6
Expand Up @@ -9,17 +9,17 @@ Testing code is an integral part of software development. Tests provide
automated, repeatable verifications of code behavior, and ensures your
code works as expected.
In Perl 6, the L<Test|/type/Test> module provides a testing framework, used also by
Perl 6's official spectest suite.
In Perl 6, the L<Test|/type/Test> module provides a testing framework, used also
by Perl 6's official spectest suite.
The testing functions emit output conforming to the L<Test Anything Protocol|https://testanything.org>. In general, they are used in sink context:
=for code :preamble<my ($meta,$relaxed-name); sub check-name($meta,:$relaxed-name){}>
=for code :preamble<use Test; my ($meta,$relaxed-name); sub check-name($meta,:$relaxed-name){}>
ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'"
but all functions also return as a Boolean if the test has been successful or not, which can be used to print a message if the test fails:
=begin code :preamble<my ($meta,$relaxed-name); sub check-name($meta,:$relaxed-name){}>
=begin code :preamble<use Test; my ($meta,$relaxed-name); sub check-name($meta,:$relaxed-name){}>
ok check-name($meta, :$relaxed-name), "name has a hyphen rather than '::'" \
or diag "\nTo use hyphen in name, pass :relaxed-name to meta-ok\n";
=end code
Expand Down
67 changes: 46 additions & 21 deletions doc/Type/Test.pod6
Expand Up @@ -20,7 +20,8 @@ Defined as:
Specify the count of tests -- usually written at the beginning of a
test file.
plan 15; # expect to run 15 tests
=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.
Expand Down Expand Up @@ -76,11 +77,11 @@ 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
Expand All @@ -91,11 +92,11 @@ 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
Expand All @@ -114,13 +115,15 @@ C<True>. The C<nok> function marks a test as passed if the given value evaluates
to C<False>. Both functions accept an optional description of the test as second
parameter.
=for code :preamble<use Test;>
my $response; my $query; ...;
ok $response.success, 'HTTP response was successful';
nok $query.error, 'Query completed without error';
In principle, you could use C<ok> for every kind of comparison test, by
including the comparison in the expression passed to C<$value>:
=for code :preamble<use Test;>
sub factorial($x) { ... };
ok factorial(6) == 720, 'Factorial - small integer';
Expand All @@ -138,6 +141,7 @@ The C<nok> function marks a test as passed if the given value 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; ...;
ok $response.success, 'HTTP response was successful';
nok $query.error, 'Query completed without error';
Expand All @@ -161,6 +165,7 @@ a good function for testing more complex things, such as lists: C<is (1, (2,
different. For those cases, use
L«C<is-deeply> routine|/language/testing#index-entry-is-deeply-is-deeply($value,_$expected,_$description?)»
=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';
Expand All @@ -172,7 +177,7 @@ 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
=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"
Expand All @@ -187,8 +192,8 @@ Marks a test as passed if C<$value> 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';
Expand Down Expand Up @@ -245,6 +250,8 @@ 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;
Expand All @@ -261,18 +268,22 @@ C<1e-5>; if it's larger, use relative tolerance of C<1e-6>.
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 C<$value> and C<$expected> 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>.
Expand All @@ -285,11 +296,13 @@ 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
Expand All @@ -305,7 +318,7 @@ and the test will fail if C<rel-diff> is higher than C<$rel-tol>.
=head3 Both absolute and relative tolerance specified
=for code :skip-test<compile time error>
=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
Expand Down Expand Up @@ -375,18 +388,20 @@ The C<$comparison> 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:
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<$comparison> 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!';
Expand All @@ -401,12 +416,14 @@ given C<$expected-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
Expand All @@ -418,6 +435,7 @@ Marks a test as passed if the given C<$variable> can run the given
C<$method-name>. The function accepts an optional description. For
instance:
=begin code :preamble<use Test;>
class Womble {};
my $womble = Womble.new;
Expand All @@ -428,6 +446,7 @@ instance:
# with human-generated test description
can-ok $womble, 'collect-rubbish', "Wombles can collect rubbish";
# => Wombles can collect rubbish
=end code
=head2 sub does-ok
Expand All @@ -438,6 +457,7 @@ Defined as:
Marks a test as passed if the given C<$variable> can do the given C<$role>.
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!" }
Expand All @@ -456,7 +476,7 @@ The function accepts an optional description of the test.
does-ok $tobermory, Invent, "Tobermory can invent";
# => Tobermory can invent
=end code
=head2 sub like
Expand All @@ -466,6 +486,7 @@ Defined as:
Use it this way:
=for code :preamble<use Test;>
like 'foo', /fo/, 'foo looks like fo';
Marks a test as passed if the C<$value>, when coerced to a string, matches the
Expand All @@ -480,6 +501,7 @@ Defined as:
Used this way:
=for code :preamble<use Test;>
unlike 'foo', /bar/, 'foo does not look like bar';
Marks a test as passed if the C<$value>, when coerced to a string, does B<not>
Expand All @@ -494,6 +516,7 @@ Defined as:
Marks a test as passed if the given C<$module> loads correctly.
=for code :preamble<use Test;>
use-ok 'Full::Qualified::ModuleName';
=head2 sub dies-ok
Expand All @@ -506,7 +529,7 @@ Marks a test as passed if the given C<$code> throws an exception.
The function accepts an optional description of the test.
=begin code
=begin code :preamble<use Test;>
sub saruman(Bool :$ents-destroy-isengard) {
die "Killed by Wormtongue" if $ents-destroy-isengard;
}
Expand All @@ -525,7 +548,7 @@ exception.
The function accepts an optional description of the test.
=begin code
=begin code :preamble<use Test;>
sub frodo(Bool :$destroys-ring) {
die "Oops, that wasn't supposed to happen" unless $destroys-ring;
}
Expand All @@ -544,7 +567,7 @@ C<eval>ed as code.
The function accepts an optional description of the test.
=begin code
=begin code :preamble<use Test;>
eval-dies-ok q[my $joffrey = "nasty";
die "bye bye Ned" if $joffrey ~~ /nasty/],
"Ned Stark dies";
Expand All @@ -561,7 +584,7 @@ exception when C<eval>ed as code.
The function accepts an optional description of the test.
=begin code
=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";
Expand All @@ -582,7 +605,7 @@ 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
=begin code :preamble<use Test;>
sub frodo(Bool :$destroys-ring) {
fail "Oops. Frodo dies" unless $destroys-ring
};
Expand All @@ -598,7 +621,7 @@ 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
=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;
Expand All @@ -617,14 +640,16 @@ encapsulate your string with a block and an EVAL instead. For instance:
Defined as:
=for code
=for code :preamble<use Test;>
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';
Expand All @@ -643,7 +668,7 @@ 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
=begin code :preamble<use Test;>
class Womble {}
class GreatUncleBulgaria is Womble {
Expand All @@ -665,7 +690,7 @@ 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
=begin code :preamble<use Test;>
subtest 'A bunch of tests', {
plan 42;
...
Expand Down Expand Up @@ -725,7 +750,7 @@ 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
=begin code :preamble<use Test;>
sub num-forward-slashes($arg) { ... } ;
if $*KERNEL ~~ 'linux' {
Expand All @@ -750,7 +775,7 @@ 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
=begin code :preamble<use Test;>
my $location; sub womble { ... }; ...;
unless $location ~~ "Wimbledon Common" {
skip-rest "We can't womble, the remaining tests will fail";
Expand Down

0 comments on commit 4311d97

Please sign in to comment.