Commit | Line | Data |
4bb0a920 |
1 | use strict; |
2 | use warnings; |
3 | |
72b52242 |
4 | use Test::More tests => 38; |
4bb0a920 |
5 | use Test::Exception; |
6 | |
7 | use Moose (); |
8 | BEGIN { use_ok('CatalystX::DynamicComponent') } |
9 | |
10 | my $testapp_counter = 0; |
11 | sub generate_testapp { |
12 | my $role_options = shift || {}; |
13 | my $meta = Moose->init_meta( for_class => "TestApp" . $testapp_counter++ ); |
14 | $meta->superclasses('Catalyst'); |
15 | Moose::Util::apply_all_roles($meta, 'CatalystX::DynamicComponent', $role_options); |
7191ab41 |
16 | $meta->name->setup; |
4bb0a920 |
17 | return $meta; |
18 | } |
19 | |
20 | throws_ok { generate_testapp(); } |
21 | qr/name\) is required/, 'name is required'; |
22 | |
23 | { |
24 | my $app_meta = generate_testapp({ name => 'dynamic_component_method' }); |
25 | my $app = $app_meta->name; |
26 | ok $app->can('dynamic_component_method'), 'dynamic component method added'; |
96e54fc3 |
27 | $app->dynamic_component_method( "Model::Foo", {} ); |
7191ab41 |
28 | my $foo = $app->model('Foo'); |
29 | ok $foo, 'Have added Foo component'; |
30 | isa_ok($foo, 'Catalyst::Component'); |
31 | } |
4bb0a920 |
32 | |
7191ab41 |
33 | { |
34 | my $COMPONENT = sub { return bless {}, 'TestClass' }; |
35 | my $app_meta = generate_testapp({ |
36 | name => 'dynamic_component_method', |
b20d38ca |
37 | methods => { |
38 | COMPONENT => $COMPONENT, |
39 | }, |
7191ab41 |
40 | }); |
41 | my $app = $app_meta->name; |
42 | ok $app->can('dynamic_component_method'), 'dynamic component method added'; |
96e54fc3 |
43 | $app->dynamic_component_method( "Model::Foo", {} ); |
7191ab41 |
44 | my $foo = $app->model('Foo'); |
45 | ok $foo, 'Have added Foo component'; |
46 | isa_ok($foo, 'TestClass', 'COMPONENT method returned totally different class'); |
47 | my $name = $app . "::Model::Foo"; |
48 | isa_ok(bless({}, $name), 'Catalyst::Component', 'Underlying $app::Model::Foo is a C::C'); |
49 | is($name->can('COMPONENT'), $COMPONENT, 'Supplied COMPONENT method is on $app::Model::Foo'); |
4bb0a920 |
50 | } |
b20d38ca |
51 | { |
52 | package My::Other::Superclass; |
53 | use Moose; |
54 | __PACKAGE__->meta->make_immutable; |
55 | } |
c52d8688 |
56 | { |
57 | package My::Model; |
58 | use Moose; |
59 | extends qw/Catalyst::Model/; |
60 | __PACKAGE__->meta->make_immutable; |
61 | } |
62 | { |
63 | package My::Role; |
64 | use Moose::Role; |
65 | sub _some_method_from_role {} |
66 | } |
67 | { |
b20d38ca |
68 | package My::Other::Role; |
69 | use Moose::Role; |
70 | sub _some_method_from_other_role {} |
71 | } |
72 | my %generator_config = ( |
73 | name => 'dynamic_component_method', |
74 | roles => [qw/My::Other::Role/], |
75 | superclasses => ['My::Other::Superclass'], |
76 | methods => { |
77 | my_other_injected_method => sub {}, |
78 | }, |
79 | ); |
80 | my $extra_config = { |
81 | superclasses => ['My::Model'], |
82 | roles => ['My::Role'], |
83 | methods => { |
84 | my_injected_method => sub { 'quuux' }, |
85 | } |
86 | }; |
87 | { |
88 | # Do not specify any resolve strategies, so get defaults: |
89 | # methods - merge |
90 | # superclasses - replace |
91 | # roles - merge |
c52d8688 |
92 | my $app_meta = generate_testapp({ |
b20d38ca |
93 | %generator_config, |
94 | }); |
95 | my $app = $app_meta->name; |
96e54fc3 |
96 | $app->dynamic_component_method( "Model::Foo", $extra_config ); |
b20d38ca |
97 | my $model = $app->model('Foo'); |
98 | isa_ok($model, 'My::Model', 'Correct superclass'); |
99 | ok(!$model->isa('My::Other::Superclass'), |
100 | 'superclass in extra config replaces by default'); |
101 | |
102 | ok $model->can('_some_method_from_role'), 'Has had role applied'; |
103 | ok !My::Model->can('_some_method_from_role'), 'Role applied at right place'; |
96e54fc3 |
104 | |
ac8aab7d |
105 | ok $model->can('_some_method_from_other_role'), |
b20d38ca |
106 | 'Role application merges by default'; |
107 | |
108 | ok $model->can('my_injected_method'), 'Injected method there as expected'; |
109 | is $model->my_injected_method, 'quuux', 'Injected method returns correct val'; |
110 | |
111 | ok $model->can('my_other_injected_method'), |
112 | 'Injected methods merged by default'; |
113 | } |
114 | { |
115 | # Specify resolve strategies, totally opposite the defaults: |
116 | my $app_meta = generate_testapp({ |
117 | %generator_config, |
118 | roles_resolve_strategy => 'replace', |
119 | superclasses_resolve_strategy => 'merge', |
120 | methods_resolve_strategy => 'replace', |
c52d8688 |
121 | }); |
122 | my $app = $app_meta->name; |
96e54fc3 |
123 | $app->dynamic_component_method( "Model::Foo", $extra_config ); |
c52d8688 |
124 | my $model = $app->model('Foo'); |
b20d38ca |
125 | isa_ok($model, 'My::Model', 'Correct superclass'); |
126 | isa_ok($model, 'My::Other::Superclass', |
127 | 'superclasses merged'); |
128 | |
c52d8688 |
129 | ok $model->can('_some_method_from_role'), 'Has had role applied'; |
130 | ok !My::Model->can('_some_method_from_role'), 'Role applied at right place'; |
96e54fc3 |
131 | |
95894323 |
132 | ok !$model->can('_some_method_from_other_role'), |
133 | 'Role application replaces when configured'; |
b20d38ca |
134 | |
c52d8688 |
135 | ok $model->can('my_injected_method'), 'Injected method there as expected'; |
136 | is $model->my_injected_method, 'quuux', 'Injected method returns correct val'; |
b20d38ca |
137 | |
138 | ok !$model->can('my_other_injected_method'), |
139 | 'Injected methods replaced'; |
c52d8688 |
140 | } |
95894323 |
141 | { |
142 | # Test that replace with blank config doesnt actually replace the config with blank |
143 | my $app_meta = generate_testapp({ |
144 | %generator_config, |
145 | roles_resolve_strategy => 'replace', |
146 | superclasses_resolve_strategy => 'replace', |
147 | methods_resolve_strategy => 'replace', |
148 | }); |
149 | |
150 | my $app = $app_meta->name; |
96e54fc3 |
151 | $app->dynamic_component_method( "Model::Foo", {} ); |
95894323 |
152 | my $model = $app->model('Foo'); |
153 | |
154 | ok $model->can('my_other_injected_method'), |
155 | 'Injected method present'; |
156 | |
157 | ok($model->isa('My::Other::Superclass'), |
158 | 'superclasses not replaced as not set'); |
159 | |
160 | ok $model->can('_some_method_from_other_role'), |
161 | 'Role application does not replace as not set'; |
162 | } |
163 | { |
164 | # Test that replace with explicit blanks does so. |
165 | my $app_meta = generate_testapp({ |
166 | %generator_config, |
167 | roles_resolve_strategy => 'replace', |
168 | superclasses_resolve_strategy => 'replace', |
169 | methods_resolve_strategy => 'replace', |
170 | }); |
171 | |
172 | my $app = $app_meta->name; |
96e54fc3 |
173 | $app->dynamic_component_method( "Model::Foo", { superclasses => [], roles => [], methods => {} } ); |
95894323 |
174 | my $model = $app->model('Foo'); |
175 | |
176 | ok !$model->can('my_other_injected_method'), |
177 | 'Injected method not present'; |
178 | |
179 | ok(!$model->isa('My::Other::Superclass'), |
180 | 'superclasses not replaced as set to []'); |
181 | |
182 | ok !$model->can('_some_method_from_other_role'), |
183 | 'Role application replaces as set to []'; |
184 | } |
72b52242 |
185 | { |
186 | # Test that base strings get listified. |
187 | my $app_meta = generate_testapp({ |
188 | %generator_config, |
189 | }); |
190 | |
191 | my $app = $app_meta->name; |
192 | $app->dynamic_component_method( "Model::Foo", { superclasses => 'My::Model', roles => 'My::Role', } ); |
193 | my $model = $app->model('Foo'); |
194 | |
195 | ok $model->can('my_other_injected_method'), |
196 | 'Injected method present'; |
197 | |
198 | ok(!$model->isa('My::Other::Superclass'), |
199 | 'superclasses replaced'); |
200 | |
201 | ok $model->can('_some_method_from_other_role'), |
202 | 'Role application merges'; |
203 | } |
204 | |
205 | { |
206 | # Test that base strings get listified. |
207 | my $app_meta = generate_testapp({ |
208 | %generator_config, |
209 | roles => 'My::Other::Role', |
210 | superclasses => 'My::Other::Superclass', |
211 | }); |
212 | |
213 | my $app = $app_meta->name; |
214 | $app->dynamic_component_method( "Model::Foo", { } ); |
215 | my $model = $app->model('Foo'); |
216 | |
217 | ok $model->can('my_other_injected_method'), |
218 | 'Injected method present'; |
219 | |
220 | ok($model->isa('My::Other::Superclass'), |
221 | 'superclasses from string'); |
222 | |
223 | ok $model->can('_some_method_from_other_role'), |
224 | 'Role application merges'; |
225 | } |
7191ab41 |
226 | |