Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add Test::Idempotency package
Add some tests for Signature .perl idempotency
Fudge a few of said tests, RT needed (rakudo misorders subsig/default)
Add a fudged test for :(:a(:b($a))).perl, RT needed
  • Loading branch information
skids committed Jul 4, 2015
1 parent fa49fa9 commit f713932
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 2 deletions.
41 changes: 39 additions & 2 deletions S06-signature/introspection.t
Expand Up @@ -2,7 +2,8 @@ use v6;
use Test;
use lib 't/spec/packages';
use Test::Util;
plan 56;
use Test::Idempotence;
plan 85;

# L<S06/Signature Introspection>

Expand Down Expand Up @@ -61,6 +62,8 @@ sub j(*@i) {
sub d(:x(:y(:z($a)))) { }; #OK not used
is ~&d.signature.params.[0].named_names.sort, 'x y z', 'multi named_names';
is ~&d.signature.params.[0].name, '$a', '... and .name still works';
#?rakudo todo 'needs/find RT: Logic to make :a($a) into :$a makes :a(:b($a) into ::b(:$a)';
is :(:a(:b($a))).perl, :(:b($a)).perl, '... and .perl abbreviates separated name/named_name';
}

#?niecza skip "Parameter separator ; NYI"
Expand Down Expand Up @@ -110,7 +113,6 @@ sub j(*@i) {
#?niecza 2 todo
ok $s ~~ /'$a' >> /, '.perl on a nested signature contains variables of the subsignature (1)';
ok $s ~~ /'$b' >> /, '.perl on a nested signature contains variables of the subsignature (2)';

}

#?niecza skip "Action method fakesignature not yet implemented"
Expand Down Expand Up @@ -140,6 +142,40 @@ sub j(*@i) {
is &xyz.signature.params[0].named, False, '.named on Capture param is True';
}

{
is-perl-idempotent(:($a, :$b),:eqv);
is-perl-idempotent(:(@a, :@b), :eqv);
is-perl-idempotent(:(%a, :%b), :eqv);
is-perl-idempotent(:(:a(:b($c))), :eqv);
is-perl-idempotent(:(|a), :eqv);
is-perl-idempotent(:(&a, :&b), :eqv);
is-perl-idempotent(:(\a), :eqv);
is-perl-idempotent(:(\a, $b, &c, :$d, |e), :eqv);
is-perl-idempotent(:($a = 2, :$b = 2), :eqv);
is-perl-idempotent(:(@a = [2, 3], :@b = [2,3]), :eqv);
is-perl-idempotent(:(%a = {:a(2)}, :%b = {:a(2)}), :eqv);
is-perl-idempotent(:(&a = &say, :&b = &say), Nil, { '= { ... }' => '= &say' },:eqv);
is-perl-idempotent(:(\a = 2), :eqv);
is-perl-idempotent(:(Int $a, Int :$b), :eqv);
is-perl-idempotent(:(Int @a, Int :@b), :eqv);
is-perl-idempotent(:(Int %a, Int :%b), :eqv);
is-perl-idempotent(:(Int :a(:b($c))), :eqv);
is-perl-idempotent(:(|a ($a)), :eqv);
is-perl-idempotent(:(Sub &a, Sub :&b), :eqv);
is-perl-idempotent(:(Int \a), :eqv);
is-perl-idempotent(:(Int \a, Int $b, Sub &c, Int :$d, |e), :eqv);
is-perl-idempotent(:(Int $a = 2, Int :$b = 2), Nil, { '= { ... }' => '= 2' }, :eqv);
is-perl-idempotent(:(Int @a = [2, 3], Int :@b = [2,3]), Nil, { '= { ... }' => '= [2,3]' }, :eqv);
is-perl-idempotent(:(Int %a = :a(2), Int :%b = :a(2)), Nil, { '= { ... }' => '= {:a(2)}' }, :eqv);
is-perl-idempotent(:(Sub &a = &say, Sub :&b = &say), Nil, { '= { ... }' => '= &say' },:eqv);
#?rakudo todo 'needs/find RT'
is-perl-idempotent(:(|a ($a) = 2), :eqv);
#?rakudo todo 'needs/find RT'
is-perl-idempotent(:(@a ($a) = [2]), :eqv);
#?rakudo todo 'needs/find RT'
is-perl-idempotent(:(%a (:a($b)) = {:a(2)}, %b (:c(:d($e))) = {:c(2)}), :eqv);
}

# RT #123895
{
is_run q[sub wtvr(|) {}; &wtvr.perl], { err => "", out => "" }, ".perl on unnamed | parameters doesn't err";
Expand All @@ -155,4 +191,5 @@ sub j(*@i) {
'";;" in signature stringifies correctly using .perl';
}


# vim: ft=perl6
96 changes: 96 additions & 0 deletions packages/Test/Idempotence.pm
@@ -0,0 +1,96 @@
unit module Test::Idempotence;

use Test;

sub is-perl-idempotent($thing, $desc?, %subst?, :$eqv = False) is export {
my $fail = 1;
my $stage1p;
my $stage2;
my $stage2p;
subtest {
plan $eqv ?? 3 !! 2;
try {
$stage1p = $thing.perl;
my $stage1r = $stage1p;
for %subst.kv -> $old, $new {
$stage1r ~~ s:g/$old/$new/;
}
$stage2 = EVAL $stage1r;
$stage2p = $stage2.perl;
CATCH {
default { $fail = $_ };
}
}
if ($eqv) {
ok $thing eqv $stage2, "Result is same as original";
}
is $stage1p, $stage2p, "Same .perl output";
is $fail, 1, "...and no failures.";
}, $desc // (".perl of " ~ $thing.gist ~ " is idempotent");
}

=begin pod
=head1 NAME
Test::Idempotence - Extra tests for idempotence related matters
=head1 SYNOPSIS
use Test;
use Test::Idempotence;
is-perl-idempotent("expression");
# 1..2
# ok 1 - Same .perl output
# ok 2 - ...and no failures.
# ok 1 - .perl of expression is idempotent
is-perl-idempotent(1, ".perl of one");
# 1..2
# ok 1 - Same .perl output
# ok 2 - ...and no failures.
# ok 1 - .perl of one
is-perl-idempotent(1, :eqv);
# 1..3
# ok 1 - Result is same as original
# ok 2 - Same .perl output
# ok 3 - ...and no failures.
# ok 1 - .perl of 1 is idempotent
is-perl-idempotent(:(Int $a = 1), "sig", { '= { ... }' => '= 1' }, :eqv);
# 1..3
# ok 1 - Result is same as original
# ok 2 - Same .perl output
# ok 3 - ...and no failures.
# ok 3 - sig
=head1 DESCRIPTION
Tests that assure that certain Perl 6 constructs produce identical
results when their output is fed back to them.
=head1 FUNCTIONS
=head2 is-perl-idempotent($thing, $desc, %subst?)
Ensures that C<$thing.perl> is the same string as C<(EVAL $thing.perl).perl>,
modulo any substitutions in C<%subst>. The C<%subst> parameter consists of patterns
as keys and the tet to substitute as values. It will not interpolate
regexp syntax; if you want that, feed it an object hash instead of a normal
hash, like so:
:{ rx/foo/ => 'bar' }
...in which case any keys that are Regex objects are used as such.
The substitutions are performed on $thing.perl before sending it to EVAL.
They are intended to be used to gloss over things that C<.perl> cannot
be reasonably expected to emit useable code for, and should be used sparingly.
The C<$desc> simply sets the description of the test which is output.
=end pod

# vim: ft=perl6

0 comments on commit f713932

Please sign in to comment.