updating test to work with Container changes
[catagits/Catalyst-Runtime.git] / t / aggregate / unit_core_mvc.t
1 use Test::More;
2 use strict;
3 use warnings;
4
5 *Catalyst::Utils::ensure_class_loaded = sub { };
6
7 use Moose::Meta::Class;
8
9 our @complist_suffix = qw/C::Controller M::Model V::View Controller::C Model::M View::V Controller::Model::Dummy::Model Model::Dummy::Model/;
10
11 our @complist = map { "MyMVCTestApp::$_" } @complist_suffix;
12
13 foreach my $comp (@complist) {
14     Moose::Meta::Class->create(
15         $comp =>
16             version => '0.1',
17     );
18 }
19 our $warnings = 0;
20 our $loaded   = 0;
21
22 Moose::Meta::Class->create('Some::Test::Object');
23
24 Moose::Meta::Class->create(
25     'MyMVCTestApp::Model::Test::Object' =>
26         superclasses => [ 'Catalyst::Model', 'Some::Test::Object' ],
27 );
28
29 {
30     package MyMVCTestApp;
31
32     use base qw/Catalyst/;
33
34     no warnings 'redefine';
35
36     local *Catalyst::IOC::Container::build_locate_components_service = sub {
37         my $self = shift;
38
39         return Bread::Board::BlockInjection->new(
40             lifecycle => 'Singleton',
41             name      => 'locate_components',
42             block     => sub {
43                 return [@complist, 'MyMVCTestApp::Model::Test::Object'];
44
45             },
46         );
47     };
48     local *Catalyst::Log::warn = sub { $warnings++ };
49     *Class::MOP::load_class = sub {
50         my $class = shift;
51         $loaded++
52             if Class::MOP::is_class_loaded($class) && $class =~ /^MyMVCTestApp/
53     };
54
55     __PACKAGE__->setup;
56 }
57
58 ok( $warnings, 'Issues deprecated warnings' );
59 is( $loaded, scalar @complist + 1, 'Loaded all components' );
60
61 is( MyMVCTestApp->view('View'), 'MyMVCTestApp::V::View', 'V::View ok' );
62
63 is( MyMVCTestApp->controller('Controller'),
64     'MyMVCTestApp::C::Controller', 'C::Controller ok' );
65
66 is( MyMVCTestApp->model('Model'), 'MyMVCTestApp::M::Model', 'M::Model ok' );
67
68 is( MyMVCTestApp->model('Dummy::Model'), 'MyMVCTestApp::Model::Dummy::Model', 'Model::Dummy::Model ok' );
69
70 isa_ok( MyMVCTestApp->model('Test::Object'), 'Some::Test::Object', 'Test::Object ok' );
71
72 is( MyMVCTestApp->controller('Model::Dummy::Model'), 'MyMVCTestApp::Controller::Model::Dummy::Model', 'Controller::Model::Dummy::Model ok' );
73
74 is( MyMVCTestApp->view('V'), 'MyMVCTestApp::View::V', 'View::V ok' );
75
76 is( MyMVCTestApp->controller('C'), 'MyMVCTestApp::Controller::C', 'Controller::C ok' );
77
78 is( MyMVCTestApp->model('M'), 'MyMVCTestApp::Model::M', 'Model::M ok' );
79
80 # failed search
81 {
82     is( MyMVCTestApp->model('DNE'), undef, 'undef for invalid search' );
83 }
84
85 is_deeply( [ sort MyMVCTestApp->views ],
86            [ qw/V View/ ],
87            'views ok' );
88
89 is_deeply( [ sort MyMVCTestApp->controllers ],
90            [ qw/C Controller Model::Dummy::Model/ ],
91            'controllers ok');
92
93 is_deeply( [ sort MyMVCTestApp->models ],
94            [ qw/Dummy::Model M Model Test::Object/ ],
95            'models ok');
96
97 {
98     my $warnings = 0;
99     no warnings 'redefine';
100     local *Catalyst::Log::warn = sub { $warnings++ };
101
102     is( MyMVCTestApp->view , undef, 'view() w/o a default is undef' );
103     ok( $warnings, 'warnings thrown for view() w/o a default' );
104 }
105
106 is ( bless ({stash=>{current_view=>'V'}}, 'MyMVCTestApp')->view , 'MyMVCTestApp::View::V', 'current_view ok');
107
108 my $view = bless {} , 'MyMVCTestApp::View::V';
109 is ( bless ({stash=>{current_view_instance=> $view }}, 'MyMVCTestApp')->view , $view, 'current_view_instance ok');
110
111 is ( bless ({stash=>{current_view_instance=> $view, current_view=>'MyMVCTestApp::V::View' }}, 'MyMVCTestApp')->view , $view,
112   'current_view_instance precedes current_view ok');
113
114 {
115     my $warnings = 0;
116     no warnings 'redefine';
117     local *Catalyst::Log::warn = sub { $warnings++ };
118
119     is( MyMVCTestApp->model, undef, 'model() w/o a default is undef' );
120     ok( $warnings, 'warnings thrown for model() w/o a default' );
121 }
122
123 is ( bless ({stash=>{current_model=>'M'}}, 'MyMVCTestApp')->model , 'MyMVCTestApp::Model::M', 'current_model ok');
124
125 my $model = bless {} , 'MyMVCTestApp::Model::M';
126 is ( bless ({stash=>{current_model_instance=> $model }}, 'MyMVCTestApp')->model , $model, 'current_model_instance ok');
127
128 is ( bless ({stash=>{current_model_instance=> $model, current_model=>'MyMVCTestApp::M::Model' }}, 'MyMVCTestApp')->model , $model,
129   'current_model_instance precedes current_model ok');
130
131 {
132     use FindBin '$Bin';
133     use lib "$Bin/../lib";
134
135     use Catalyst::Test 'TestAppController';
136
137     is( get('/foo/test_controller'), 'bar', 'controller() with empty args returns current controller' );
138 }
139
140 our @complist_default_view =
141     map { "MyMVCTestAppDefaultView::$_" } @complist_suffix;
142
143 {
144     package MyMVCTestAppDefaultView;
145
146     use base qw/Catalyst/;
147     no warnings 'redefine';
148
149     local *Catalyst::IOC::Container::build_locate_components_service = sub {
150         my $self = shift;
151
152         return Bread::Board::BlockInjection->new(
153             lifecycle => 'Singleton',
154             name      => 'locate_components',
155             block     => sub {
156                 return \@complist_default_view;
157             },
158         );
159     };
160     local *Catalyst::Log::warn = sub { $warnings++ };
161     *Class::MOP::load_class = sub {
162         my $class = shift;
163         $loaded++
164             if Class::MOP::is_class_loaded($class) && $class =~ /^MyMVCTestAppDefaultView/
165     };
166
167     __PACKAGE__->config( default_view => 'V' );
168
169     __PACKAGE__->setup;
170 }
171
172 is( bless ({stash=>{}}, 'MyMVCTestAppDefaultView')->view, 'MyMVCTestAppDefaultView::View::V', 'default_view ok' );
173 is( MyMVCTestAppDefaultView->view , 'MyMVCTestAppDefaultView::View::V', 'default_view in class method ok' );
174
175 our @complist_default_model =
176     map { "MyMVCTestAppDefaultModel::$_" } @complist_suffix;
177
178 {
179     package MyMVCTestAppDefaultModel;
180
181     use base qw/Catalyst/;
182
183     no warnings 'redefine';
184
185     local *Catalyst::IOC::Container::build_locate_components_service = sub {
186         my $self = shift;
187
188         return Bread::Board::BlockInjection->new(
189             lifecycle => 'Singleton',
190             name      => 'locate_components',
191             block     => sub {
192                 return \@complist_default_model;
193             },
194         );
195     };
196     local *Catalyst::Log::warn = sub { $warnings++ };
197     *Class::MOP::load_class = sub {
198         my $class = shift;
199         $loaded++
200             if Class::MOP::is_class_loaded($class) && $class =~ /^MyMVCTestAppDefaultModel/
201     };
202
203     __PACKAGE__->config( default_model => 'M' );
204
205     __PACKAGE__->setup;
206 }
207
208 is( bless ({stash=>{}}, 'MyMVCTestAppDefaultModel')->model , 'MyMVCTestAppDefaultModel::Model::M', 'default_model ok' );
209 is( MyMVCTestAppDefaultModel->model , 'MyMVCTestAppDefaultModel::Model::M', 'default_model in class method ok' );
210
211 # regexp behavior tests
212 {
213     # is_deeply is used because regexp behavior means list context
214     is_deeply( [ MyMVCTestApp->view( qr{^V[ie]+w$} ) ], [ 'MyMVCTestApp::V::View' ], 'regexp view ok' );
215     is_deeply( [ MyMVCTestApp->controller( qr{Dummy\::Model$} ) ], [ 'MyMVCTestApp::Controller::Model::Dummy::Model' ], 'regexp controller ok' );
216     is_deeply( [ MyMVCTestApp->model( qr{Dum{2}y} ) ], [ 'MyMVCTestApp::Model::Dummy::Model' ], 'regexp model ok' );
217
218     # object w/ qr{}
219     is_deeply( [ MyMVCTestApp->model( qr{Test} ) ], [ MyMVCTestApp->components->{'MyMVCTestApp::Model::Test::Object'} ], 'Object returned' );
220
221     {
222         my $warnings = 0;
223         no warnings 'redefine';
224         local *Catalyst::Log::warn = sub { $warnings++ };
225
226         # object w/ regexp fallback
227         is( MyMVCTestApp->model( 'Test' ), undef, 'no regexp fallback' );
228         ok( $warnings, 'regexp fallback warnings' );
229     }
230
231     is( MyMVCTestApp->view('MyMVCTestApp::V::View$'), undef, 'no regexp fallback');
232
233     is( MyMVCTestApp->controller('MyMVCTestApp::C::Controller$'), undef, 'no regexp fallback');
234
235     is( MyMVCTestApp->model('MyMVCTestApp::M::Model$'), undef, 'no regexp fallback');
236 }
237
238 {
239     my @expected = qw( MyMVCTestApp::C::Controller MyMVCTestApp::Controller::C );
240     is_deeply( [ sort MyMVCTestApp->controller( qr{^C} ) ], \@expected, 'multiple controller returns from regexp search' );
241 }
242
243 {
244     my @expected = qw( MyMVCTestApp::V::View MyMVCTestApp::View::V );
245     is_deeply( [ sort MyMVCTestApp->view( qr{^V} ) ], \@expected, 'multiple view returns from regexp search' );
246 }
247
248 {
249     my @expected = qw( MyMVCTestApp::M::Model MyMVCTestApp::Model::M );
250     is_deeply( [ sort MyMVCTestApp->model( qr{^M} ) ], \@expected, 'multiple model returns from regexp search' );
251 }
252
253 # failed search
254 {
255     is( scalar MyMVCTestApp->controller( qr{DNE} ), 0, '0 results for failed search' );
256 }
257
258 #checking @args passed to ACCEPT_CONTEXT
259 {
260     my $args;
261
262     {
263         no warnings 'once';
264         *MyMVCTestApp::Model::M::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
265         *MyMVCTestApp::View::V::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
266     }
267
268     my $c = bless {}, 'MyMVCTestApp';
269
270     # test accept-context with class rather than instance
271     MyMVCTestApp->model('M', qw/foo bar/);
272     is_deeply($args, [qw/foo bar/], 'MyMVCTestApp->model args passed to ACCEPT_CONTEXT ok');
273
274
275     $c->model('M', qw/foo bar/);
276     is_deeply($args, [qw/foo bar/], '$c->model args passed to ACCEPT_CONTEXT ok');
277
278     my $x = $c->view('V', qw/foo2 bar2/);
279     is_deeply($args, [qw/foo2 bar2/], '$c->view args passed to ACCEPT_CONTEXT ok');
280
281 }
282
283 {
284     package MyApp::WithoutRegexFallback;
285
286     use base qw/Catalyst/;
287
288     no warnings 'redefine';
289
290     *Class::MOP::load_class = sub {
291         $loaded++;
292     };
293
294     __PACKAGE__->config( { disable_component_resolution_regex_fallback => 1 } );
295
296     __PACKAGE__->components( { map { ( ref($_)||$_ , $_ ) }
297         qw/MyApp::WithoutRegexFallback::Controller::Another::Foo/ } );
298
299     # allow $c->log->warn to work
300     __PACKAGE__->setup_log;
301 }
302
303 {
304     # test if non-regex component retrieval still works
305     is( MyApp::WithoutRegexFallback->controller('Another::Foo'),
306         'MyApp::WithoutRegexFallback::Controller::Another::Foo', 'controller Another::Foo found');
307 }
308
309 {
310     my $warnings = 0;
311     no warnings 'redefine';
312     local *Catalyst::Log::warn = sub { $warnings++ };
313
314     # try to get nonexisting object w/o regexp fallback
315     is( MyApp::WithoutRegexFallback->controller('Foo'), undef, 'no controller Foo found');
316 }
317
318 done_testing;