/
coercion-types.t
115 lines (100 loc) · 2.94 KB
/
coercion-types.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
use v6;
use lib <t/spec/packages>;
use Test;
use Test::Util;
plan 21;
# coercion types in parameter lists
{
sub inside(Str(Cool) $x) {
isa-ok $x, Str, 'coercion type on the inside';
}
inside(23);
sub f(Str(Cool) $x) {
$x
}
isa-ok f(42), Str, 'Coercion type coerces';
is f(42), '42', 'Coercion type coerces to correct value';
throws-like q[ sub g(Str(Cool) $x) { $x }; g(Any) ], X::TypeCheck::Binding,
'coercion type still type-checks';
}
class Child { ... };
class Parent {
method Child() { Child }
# returns an object not conforming to NastyChild
method NastyChild() { Child }
}
class Child is Parent { };
class NastyChild is Parent { };
# with custom classes
{
sub c(Child(Parent) $x) { $x }
isa-ok c(Parent), Child, 'Coercion with user-defined types';
sub nasty(NastyChild(Parent) $x) { $x }
#?rakudo todo 'missing checks'
dies-ok { EVAL 'nasty(Parent)' },
'coercion that does not produce the target type dies';
}
# with definedness checks
# RT #124839 / RT#123770
{
sub f1(Str:D(Cool:D) $x) { $x }
sub f2(Str(Cool:D) $x) { $x; }
throws-like { EVAL 'f1(Cool)' }, X::TypeCheck::Binding::Parameter, message => /expected\sCool\:D/;
throws-like { EVAL 'f2(Cool)' }, X::TypeCheck::Binding::Parameter, message => /expected\sCool\:D/;
isa-ok f1(23), Str, 'Definedness check + coercion (1)';
isa-ok f2(23), Str, 'Definedness check + coercion (2)';
sub f3(Child:D(Parent) $x) { $x }
dies-ok { EVAL 'f3(Parent)' },
'Coercion dies if it doees not satisfy definedness constraint of target';
}
# enums!
{
enum A <b c d>;
ok A(0) === A::b, 'basic enum sanity';
sub en(A(Any) $x ) { $x }
#?rakudo skip 'dies'
ok en(0) === A::b, 'coercion to enum';
}
# coercion types on variables
#?rakudo skip 'NYI RT #124840'
#?DOES 3
{
my Int(Any) $x;
isa-ok $x, Int, 'Coercion type on variable';
$x = '24';
isa-ok $x, Int, 'Coercion type on variable after assignment (type)';
is $x, 24, 'Coercion type on variable after assignment (value)';
}
# methods exist, too
#?rakudo skip 'NYI RT #124841'
#?DOES 2
{
class Co {
class SubCo is Co { }
method SubCo() { SubCo.new }
method erce(Array(Any) $x) {
$x.^name;
}
method invocant(SubCo(Co) SELF:) {
SELF;
}
}
is Co.erce((1, 2)), 'Array', 'coercion on method param';
isa-ok Co.invocant, SubCo, 'Can coerce invocant to subclass';
}
is Str(Any).gist, '(Str(Any))', 'Can gist a coercion type';
# RT #131611
{
my \a = -42;
is Int(a), -42, "Sigilless variable does not confuse coercion type parsing";
}
# RT #130479
is_run 「
class Foo { method Bar {die} }
class Bar is Foo {}
-> Bar(Foo) $foo?, Bar(Foo) :$bar {
say $foo; say $bar;
}()
」, {:err(''), :out("(Bar)\n(Bar)\n"), :0status},
'coercers do not attempt to coerce optional params that were not given';
# vim: ft=perl6