File: pp-parameterized.t

package info (click to toggle)
libspecio-perl 0.53-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,136 kB
  • sloc: perl: 5,209; sh: 23; makefile: 2
file content (130 lines) | stat: -rw-r--r-- 3,060 bytes parent folder | download
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
BEGIN {
    $ENV{SPECIO_TEST_PP} = 1;
}

use strict;
use warnings;

use Test::Fatal;
use Test::More 0.96;

use Specio::Declare;
use Specio::Library::Builtins;

{
    my $arrayref = t('ArrayRef');

    ok(
        $arrayref->value_is_valid( [ {}, 42, 'foo' ] ),
        'ArrayRef does not care about member types'
    );

    my $from_method = t1($arrayref);

    for my $pair (
        [ filename   => __FILE__ ],
        [ line       => 42 ],
        [ package    => 'main' ],
        [ subroutine => 'main::t1' ],
    ) {

        my ( $key, $expect ) = @{$pair};
        is(
            $from_method->declared_at->$key,
            $expect,
            "declared_at $key is the expected value for parameterized type made from ->parameterize"
        );
    }

    my $from_t = t2();

    for my $pair (
        [ filename   => __FILE__ ],
        [ line       => 84 ],
        [ package    => 'main' ],
        [ subroutine => 'main::t2' ],
    ) {

        my ( $key, $expect ) = @{$pair};
        is(
            $from_t->declared_at->$key,
            $expect,
            "declared_at $key is the expected value for parameterized type made from calling t"
        );
    }

    declare(
        'ArrayRefOfInt',
        parent => t( 'ArrayRef', of => t('Int') ),
    );

    ok(
        t('ArrayRefOfInt'),
        'there is an ArrayRefOfInt type declared'
    );

    my $anon = anon(
        parent => t( 'ArrayRef', of => t('Int') ),
    );

    for my $pair (
        [ $from_method,       '->parameterize' ],
        [ $from_t,            't(...)' ],
        [ t('ArrayRefOfInt'), 'named type' ],
        [ $anon,              'anon type' ],
    ) {

        my ( $arrayref_of_int, $desc ) = @{$pair};

        ok(
            !$arrayref_of_int->value_is_valid( [ {}, 42, 'foo' ] ),
            "ArrayRef of Int [$desc] does care about member types"
        );

        ok(
            $arrayref_of_int->value_is_valid( [ -1, 42, 1_000_000 ] ),
            "ArrayRef of Int [$desc] accepts array ref of all integers"
        );

        ok(
            !$arrayref_of_int->value_is_valid(42),
            "ArrayRef of Int [$desc] rejects integer"
        );

        ok(
            !$arrayref_of_int->value_is_valid( {} ),
            "ArrayRef of Int [$desc] rejects hashref"
        );
    }
}

{
    like(
        exception {
            declare(
                'MyInt',
                where => sub { $_[0] =~ /\A-?[0-9]+\z/ },
            );
            declare(
                'ArrayRefOfMyInt',
                parent => t( 'ArrayRef', of => t('MyInt') ),
            );
        },
        qr/\QThe "of" parameter passed to ->parameterize must be an inlinable constraint if the parameterizable type has an inline_generator/,
        'A parameterizable type with an inline generator cannot be parameterized with a type that cannot be inlined',
    );
}

done_testing();

sub t1 {
    my $arrayref = shift;
# line 42
    return $arrayref->parameterize( of => t('Int') );
}

sub t2 {
# line 84
    return t( 'ArrayRef', of => t('Int') ),;
}