summaryrefslogtreecommitdiff
path: root/t/roles/role_compose_requires.t
blob: 06337ffbf5108abafeede08bb4d79e5d31b0a729 (plain)
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
use strict;
use warnings;

# See https://rt.cpan.org/Ticket/Display.html?id=46347

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

{
    package My::Role1;
    use Moose::Role;
    requires 'test_output';
}

{
    package My::Role2;
    use Moose::Role;
    has test_output => ( is => 'rw' );
    with 'My::Role1';
}

{
    package My::Role3;
    use Moose::Role;
    sub test_output { }
    with 'My::Role1';
}

{
    package My::Role4;
    use Moose::Role;
    has test_output => ( is => 'rw' );
}

{
    package My::Role5;
    use Moose::Role;
    sub test_output { }
}

{
    package My::Base1;
    use Moose;
    has test_output => ( is => 'rw' );
}

{
    package My::Base2;
    use Moose;
    sub test_output { }
}

# Roles providing attributes/methods should satisfy requires() of other
# roles they consume.
{
    local $TODO = "role attributes don't satisfy method requirements";
    is( exception { package My::Test1; use Moose; with 'My::Role2'; }, undef, 'role2(provides attribute) consumes role1' );
}

is( exception { package My::Test2; use Moose; with 'My::Role3'; }, undef, 'role3(provides method) consumes role1' );

# As I understand the design, Roles composed in the same with() statement
# should NOT demonstrate ordering dependency. Alter these tests if that
# assumption is false. -Vince Veselosky
{
    local $TODO = "role attributes don't satisfy method requirements";
    is( exception { package My::Test3; use Moose; with 'My::Role4', 'My::Role1'; }, undef, 'class consumes role4(provides attribute), role1' );
}

{
    local $TODO = "role attributes don't satisfy method requirements";
    is( exception { package My::Test4; use Moose; with 'My::Role1', 'My::Role4'; }, undef, 'class consumes role1, role4(provides attribute)' );
}

is( exception { package My::Test5; use Moose; with 'My::Role5', 'My::Role1'; }, undef, 'class consumes role5(provides method), role1' );

is( exception { package My::Test6; use Moose; with 'My::Role1', 'My::Role5'; }, undef, 'class consumes role1, role5(provides method)' );

# Inherited methods/attributes should satisfy requires(), as long as
# extends() comes first in code order.
is( exception {
    package My::Test7;
    use Moose;
    extends 'My::Base1';
    with 'My::Role1';
}, undef, 'class extends base1(provides attribute), consumes role1' );

is( exception {
    package My::Test8;
    use Moose;
    extends 'My::Base2';
    with 'My::Role1';
}, undef, 'class extends base2(provides method), consumes role1' );

# Attributes/methods implemented in class should satisfy requires()
is( exception {

    package My::Test9;
    use Moose;
    has 'test_output', is => 'rw';
    with 'My::Role1';
}, undef, 'class provides attribute, consumes role1' );

is( exception {

    package My::Test10;
    use Moose;
    sub test_output { }
    with 'My::Role1';
}, undef, 'class provides method, consumes role1' );

# Roles composed in separate with() statements SHOULD demonstrate ordering
# dependency. See comment with tests 3-6 above.
is( exception {
    package My::Test11;
    use Moose;
    with 'My::Role4';
    with 'My::Role1';
}, undef, 'class consumes role4(provides attribute); consumes role1' );

isnt( exception { package My::Test12; use Moose; with 'My::Role1'; with 'My::Role4'; }, undef, 'class consumes role1; consumes role4(provides attribute)' );

is( exception {
    package My::Test13;
    use Moose;
    with 'My::Role5';
    with 'My::Role1';
}, undef, 'class consumes role5(provides method); consumes role1' );

isnt( exception { package My::Test14; use Moose; with 'My::Role1'; with 'My::Role5'; }, undef, 'class consumes role1; consumes role5(provides method)' );

done_testing;