Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Test.pm6 more thread safe #1143

Merged
merged 4 commits into from Aug 29, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 39 additions & 37 deletions lib/Test.pm6
Expand Up @@ -84,14 +84,17 @@ multi sub plan (Cool:D :skip-all($reason)!) {
# It is also the default if nobody calls plan at all
multi sub plan($number_of_tests) is export {
_init_io() unless $output;

my str $str-message;

if $number_of_tests ~~ ::Whatever {
$no_plan = 1;
}
else {
$num_of_tests_planned = $number_of_tests;
$no_plan = 0;

$output.say: $indents ~ '1..' ~ $number_of_tests;
$str-message ~= $indents ~ '1..' ~ $number_of_tests;
}
# Get two successive timestamps to say how long it takes to read the
# clock, and to let the first test timing work just like the rest.
Expand All @@ -100,10 +103,11 @@ multi sub plan($number_of_tests) is export {
# lot slower than the non portable nqp::time_n.
$time_before = nqp::time_n;
$time_after = nqp::time_n;
$output.say: $indents
~ '# between two timestamps '
~ ceiling(($time_after-$time_before)*1_000_000) ~ ' microseconds'
$str-message ~= "$indents\n# between two timestamps " ~ ceiling(($time_after-$time_before)*1_000_000) ~ ' microseconds'
if nqp::iseq_i($perl6_test_times,1);

$output.say: $str-message;

# Take one more reading to serve as the begin time of the first test
$time_before = nqp::time_n;
}
Expand Down Expand Up @@ -170,8 +174,8 @@ multi sub is(Mu $got, Mu:D $expected, $desc = '') is export {
eq $expected.Str.subst(/\s/, '', :g)
{
# only white space differs, so better show it to the user
_diag "expected: {$expected.perl}\n"
~ " got: {$got.perl}";
_diag "expected: $expected.perl()\n"
~ " got: $got.perl()";
}
else {
_diag "expected: '$expected'\n"
Expand Down Expand Up @@ -242,8 +246,8 @@ multi sub cmp-ok(Mu $got, $op, Mu $expected, $desc = '') is export {
if $matcher {
$ok = proclaim($matcher($got,$expected), $desc);
if !$ok {
_diag "expected: '{$expected // $expected.^name}'\n"
~ " matcher: '{$matcher.?name || $matcher.^name}'\n"
_diag "expected: '" ~ ($expected // $expected.^name) ~ "'\n"
~ " matcher: '" ~ ($matcher.?name || $matcher.^name) ~ "'\n"
~ " got: '$got'";
}
}
Expand Down Expand Up @@ -618,7 +622,7 @@ sub throws-like($code, $ex_type, $reason?, *%matcher) is export {
default {
pass $msg;
my $type_ok = $_ ~~ $ex_type;
ok $type_ok , "right exception type ({$ex_type.^name})";
ok $type_ok , "right exception type ($ex_type.^name())";
if $type_ok {
for %matcher.kv -> $k, $v {
my $got is default(Nil) = $_."$k"();
Expand All @@ -630,14 +634,14 @@ sub throws-like($code, $ex_type, $reason?, *%matcher) is export {
}
}
} else {
_diag "Expected: {$ex_type.^name}\n"
~ "Got: {$_.^name}\n"
_diag "Expected: $ex_type.^name()\n"
~ "Got: $_.^name()\n"
~ "Exception message: $_.message()";
skip 'wrong exception type', %matcher.elems;
}
}
}
}, $reason // "did we throws-like {$ex_type.^name}?";
}, $reason // "did we throws-like $ex_type.^name()?";
}

sub _is_deeply(Mu $got, Mu $expected) {
Expand Down Expand Up @@ -668,19 +672,19 @@ sub eval_exception($code) {
}

# Take $cond as Mu so we don't thread with Junctions:
sub proclaim(Bool(Mu) $cond, $desc is copy, $uenscaped-prefix = '') {
sub proclaim(Bool(Mu) $cond, $desc is copy, $unescaped-prefix = '') {
_init_io() unless $output;
# exclude the time spent in proclaim from the test time
$num_of_tests_run = $num_of_tests_run + 1;
my $current_tests_run = cas $num_of_tests_run, -> $i { $i + 1 };

my $tap = $indents;
unless $cond {
$tap ~= "not ";

$num_of_tests_failed = $num_of_tests_failed + 1
unless $num_of_tests_run <= $todo_upto_test_num;
cas( $num_of_tests_failed, -> $i { $i + 1 } )
unless $current_tests_run <= $todo_upto_test_num;

$pseudo_fails = $pseudo_fails + 1 if $subtest_todo_reason;
cas( $pseudo_fails, -> $i { $i + 1 } ) if $subtest_todo_reason;
}

# TAP parsers do not like '#' in the description, they'd miss the '# TODO'
Expand All @@ -692,18 +696,17 @@ sub proclaim(Bool(Mu) $cond, $desc is copy, $uenscaped-prefix = '') {
nqp::split('#', $desc.Str))))
!! '';

$tap ~= $todo_reason && $num_of_tests_run <= $todo_upto_test_num
?? "ok $num_of_tests_run - $uenscaped-prefix$desc$todo_reason"
$tap ~= $todo_reason && $current_tests_run <= $todo_upto_test_num
?? "ok $current_tests_run - $unescaped-prefix$desc$todo_reason"
!! (! $cond && $subtest_todo_reason)
?? "ok $num_of_tests_run - $uenscaped-prefix$desc$subtest_todo_reason"
!! "ok $num_of_tests_run - $uenscaped-prefix$desc";
?? "ok $current_tests_run - $unescaped-prefix$desc$subtest_todo_reason"
!! "ok $current_tests_run - $unescaped-prefix$desc";

$output.say: $tap;
$output.say: $indents
~ "# t="
~ ceiling(($time_after-$time_before)*1_000_000)
$tap ~= ("\n$indents# t=" ~ ceiling(($time_after - $time_before)*1_000_000))
if nqp::iseq_i($perl6_test_times,1);

$output.say: $tap;

unless $cond {
my $caller;
# sub proclaim is not called directly, so 2 is minimum level
Expand All @@ -714,8 +717,8 @@ sub proclaim(Bool(Mu) $cond, $desc is copy, $uenscaped-prefix = '') {
}

_diag $desc
?? "Failed test '$desc'\nat {$caller.file} line {$caller.line}"
!! "Failed test at {$caller.file} line {$caller.line}";
?? "Failed test '$desc'\nat $caller.file() line $caller.line()"
!! "Failed test at $caller.file() line $caller.line()";
}

# must clear this between tests
Expand All @@ -736,16 +739,15 @@ sub done-testing() is export {
}

# Wrong quantity of tests
_diag("Looks like you planned $num_of_tests_planned test{
$num_of_tests_planned == 1 ?? '' !! 's'
}, but ran $num_of_tests_run")
if ($num_of_tests_planned or $num_of_tests_run)
&& ($num_of_tests_planned != $num_of_tests_run);

_diag("Looks like you failed $num_of_tests_failed test{
$num_of_tests_failed == 1 ?? '' !! 's'
} of $num_of_tests_run")
if $num_of_tests_failed && ! $subtest_todo_reason;
_diag("Looks like you planned $num_of_tests_planned test"
~ ($num_of_tests_planned == 1 ?? '' !! 's')
~ ", but ran $num_of_tests_run"
) if ($num_of_tests_planned or $num_of_tests_run) && ($num_of_tests_planned != $num_of_tests_run);

_diag("Looks like you failed $num_of_tests_failed test"
~ ($num_of_tests_failed == 1 ?? '' !! 's')
~ " of $num_of_tests_run"
) if $num_of_tests_failed && ! $subtest_todo_reason;
}

sub _init_vars {
Expand Down