/
type.t
151 lines (122 loc) · 5.49 KB
/
type.t
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
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 51;
{
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;
{
dies_ok({$foo = 'xyz'}, 'Int restricts to integers');
dies_ok { $foo = Mu }, 'Int does not accept Mu';
is(($foo = 42), 42, 'Int is an integer');
dies_ok({$bar = 42}, 'Str restricts to strings');
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'
{
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');
lives_ok({my Int $beta = Nil}, 'object Int type can be undefined');
eval_lives_ok('my num $alpha = 1e0', 'Has native type num');
#?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');
# RT #93982
lives_ok({my Str ($a) = ()}, 'object Str type can be undefined, list context');
}
# 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)
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>
{
# 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 (-->)');
}
{
# 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';
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';
ok Array ~~ Positional, 'Array does Positional too';
}
done;
# vim: ft=perl6