Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 162 lines (132 sloc) 5.768 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
use v6;
use Test;

=begin description

Basic tests about variables having built-in types assigned

=end description

# L<S02/"Types as Constraints"/"A variable's type is a constraint indicating what sorts">

plan 50;

{
    ok(try {my Int $foo; 1}, 'compile my Int $foo');
    ok(try {my Str $bar; 1}, 'compile my Str $bar');
}

ok(do {my Int $foo; $foo ~~ Int}, 'Int $foo isa Int');
ok(do {my Str $bar; $bar ~~ Str}, 'Str $bar isa Str');

my Int $foo;
my Str $bar;

{
    #?pugs 1 todo
    dies_ok({$foo = 'xyz'}, 'Int restricts to integers');
    #?pugs todo
    dies_ok { $foo = Mu }, 'Int does not accept Mu';
    is(($foo = 42), 42, 'Int is an integer');

    #?pugs 1 todo
    dies_ok({$bar = 42}, 'Str restricts to strings');
    #?pugs todo
    dies_ok { $bar = Mu }, 'Str does not accept Mu';
    is(($bar = 'xyz'), 'xyz', 'Str is a strings');
}

#?niecza skip 'Trait of not available on variables'
#?pugs skip 'parsefail'
{
    my $baz of Int;
    dies_ok({$baz = 'xyz'}, 'of Int restricts to integers');
    is(($baz = 42), 42, 'of Int is an integer');
}

# L<S02/Variables Containing Undefined Values/Variables with native types do not support undefinedness>
#?niecza skip 'native types (noauto)'
{
    eval_lives_ok('my int $alpha = 1', 'Has native type int');
    eval_dies_ok('my int $alpha = Nil', 'native int type cannot be undefined');
    #?pugs todo
    lives_ok({my Int $beta = Nil}, 'object Int type can be undefined');
    eval_lives_ok('my num $alpha = 1e0', 'Has native type num');
    #?pugs 2 todo
    #?rakudo.jvm todo "nigh"
    #?rakudo.moar todo "nigh"
    # RT #121518
    eval_lives_ok('my num $alpha = Nil', 'native num type can be undefined');
    lives_ok({my Num $beta = Nil}, 'object Num type can be undefined');
}

# L<S02/Parameter types/Parameters may be given types, just like any other variable>
{
    sub paramtype (Int $i) {return $i+1}
    is(paramtype(5), 6, 'sub parameters with matching type');
    eval_dies_ok('paramtype("foo")', 'sub parameters with non-matching type dies');
}

{
    # test contributed by Ovid++
    sub fact (Int $n) {
        if 0 == $n {
            1;
        }
        else {
            $n * fact($n - 1);
        }
    }
    is fact(5), 120, 'recursive factorial with type contstraints work';
}

# Num does not accept Int (used to, then spec changed)
#?pugs todo
dies_ok { my Num $n; $n = 42; }, 'Num does not accept Int';

# L<S02/Return types/a return type can be specified before or after the name>
#?pugs skip 'parsefail'
{
    # Check with explicit return.
    my sub returntype1 (Bool $pass) returns Str { return $pass ?? 'ok' !! -1}
    my sub returntype2 (Bool $pass) of Int { return $pass ?? 42 !! 'no'}
    my Bool sub returntype3 (Bool $pass) { return $pass ?? Bool::True !! ':('}
    my sub returntype4 (Bool $pass --> Str) { return $pass ?? 'ok' !! -1}

    is(returntype1(Bool::True), 'ok', 'good return value works (returns)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype1(Bool::False) }, 'bad return value dies (returns)');
    is(returntype2(Bool::True), 42, 'good return value works (of)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype2(Bool::False) }, 'bad return value dies (of)');

    is(returntype3(Bool::True), True, 'good return value works (my Type sub)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype3(Bool::False) }, 'bad return value dies (my Type sub)');

    is(returntype4(Bool::True), 'ok', 'good return value works (-->)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype4(Bool::False) }, 'bad return value dies (-->)');
}

#?pugs skip 'parsefail'
{
    # Check with implicit return.
    my sub returntype1 (Bool $pass) returns Str { $pass ?? 'ok' !! -1}
    my sub returntype2 (Bool $pass) of Int { $pass ?? 42 !! 'no'}
    my Bool sub returntype3 (Bool $pass) { $pass ?? Bool::True !! ':('}
    my sub returntype4 (Bool $pass --> Str) { $pass ?? 'ok' !! -1}

    is(returntype1(Bool::True), 'ok', 'good implicit return value works (returns)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype1(Bool::False) }, 'bad implicit return value dies (returns)');
    is(returntype2(Bool::True), 42, 'good implicit return value works (of)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype2(Bool::False) }, 'bad implicit return value dies (of)');

    is(returntype3(Bool::True), True, 'good implicit return value works (my Type sub)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype3(Bool::False) }, 'bad implicit return value dies (my Type sub)');

    is(returntype4(Bool::True), 'ok', 'good implicit return value works (-->)');
    #?niecza todo 'retrun value type checking NYI'
    dies_ok({ returntype4(Bool::False) }, 'bad implicit return value dies (-->)');
}

{
    eval_dies_ok('my Int Str $x', 'multiple prefix constraints not allowed');
    eval_dies_ok('sub foo(Int Str $x) { }', 'multiple prefix constraints not allowed');
    eval_dies_ok('sub foo(--> Int Str) { }', 'multiple prefix constraints not allowed');
    eval_dies_ok('our Int Str sub foo() { }', 'multiple prefix constraints not allowed');
}

{
    # TODO: many more of these are possible
    ok Any ~~ Mu, 'Any ~~ Mu';
    ok Mu !~~ Any, 'Mu !~~ Any';
    ok Mu !~~ Int, 'Mu !~~ Int';

    #?pugs 2 skip "Numeric"
    ok Int ~~ Numeric, 'Int !~~ Numeric';
    ok Numeric !~~ Int, 'Numeric !~~ Int';

    ok Array ~~ List, 'Array is a kind of List';
    ok List !~~ Array, 'A List is not an Array';
    #?pugs skip "Positional"
    ok Array ~~ Positional, 'Array does Positional too';
}

done;

# vim: ft=perl6
Something went wrong with that request. Please try again.