More aggregated tests.
[catagits/Catalyst-Runtime.git] / t / aggregate / unit_core_component_loading.t
CommitLineData
0756fe3b 1# 2 initial tests, and 6 per component in the loop below
2# (do not forget to update the number of components in test 3 as well)
b94b200c 3# 5 extra tests for the loading options
e1dd56e6 4# One test for components in inner packages
ac424253 5use Test::More tests => 2 + 6 * 24 + 8 + 1;
0756fe3b 6
7use strict;
8use warnings;
9
10use File::Spec;
11use File::Path;
12
13my $libdir = 'test_trash';
14unshift(@INC, $libdir);
15
16my $appclass = 'TestComponents';
17my @components = (
18 { type => 'Controller', prefix => 'C', name => 'Bar' },
19 { type => 'Controller', prefix => 'C', name => 'Foo::Bar' },
20 { type => 'Controller', prefix => 'C', name => 'Foo::Foo::Bar' },
21 { type => 'Controller', prefix => 'C', name => 'Foo::Foo::Foo::Bar' },
22 { type => 'Controller', prefix => 'Controller', name => 'Bar::Bar::Bar::Foo' },
23 { type => 'Controller', prefix => 'Controller', name => 'Bar::Bar::Foo' },
24 { type => 'Controller', prefix => 'Controller', name => 'Bar::Foo' },
25 { type => 'Controller', prefix => 'Controller', name => 'Foo' },
26 { type => 'Model', prefix => 'M', name => 'Bar' },
27 { type => 'Model', prefix => 'M', name => 'Foo::Bar' },
28 { type => 'Model', prefix => 'M', name => 'Foo::Foo::Bar' },
29 { type => 'Model', prefix => 'M', name => 'Foo::Foo::Foo::Bar' },
30 { type => 'Model', prefix => 'Model', name => 'Bar::Bar::Bar::Foo' },
31 { type => 'Model', prefix => 'Model', name => 'Bar::Bar::Foo' },
32 { type => 'Model', prefix => 'Model', name => 'Bar::Foo' },
33 { type => 'Model', prefix => 'Model', name => 'Foo' },
34 { type => 'View', prefix => 'V', name => 'Bar' },
35 { type => 'View', prefix => 'V', name => 'Foo::Bar' },
36 { type => 'View', prefix => 'V', name => 'Foo::Foo::Bar' },
37 { type => 'View', prefix => 'V', name => 'Foo::Foo::Foo::Bar' },
38 { type => 'View', prefix => 'View', name => 'Bar::Bar::Bar::Foo' },
39 { type => 'View', prefix => 'View', name => 'Bar::Bar::Foo' },
40 { type => 'View', prefix => 'View', name => 'Bar::Foo' },
41 { type => 'View', prefix => 'View', name => 'Foo' },
42);
43
5d50f369 44sub write_component_file {
b94b200c 45 my ($dir_list, $module_name, $content) = @_;
46
47 my $dir = File::Spec->catdir(@$dir_list);
48 my $file = File::Spec->catfile($dir, $module_name . '.pm');
49
50 mkpath(join(q{/}, @$dir_list) );
51 open(my $fh, '>', $file) or die "Could not open file $file for writing: $!";
52 print $fh $content;
53 close $fh;
54}
55
0756fe3b 56sub make_component_file {
57 my ($type, $prefix, $name) = @_;
58
59 my $compbase = "Catalyst::${type}";
60 my $fullname = "${appclass}::${prefix}::${name}";
61 my @namedirs = split(/::/, $name);
62 my $name_final = pop(@namedirs);
63 my @dir_list = ($libdir, $appclass, $prefix, @namedirs);
0756fe3b 64
b94b200c 65 write_component_file(\@dir_list, $name_final, <<EOF);
0756fe3b 66package $fullname;
f27f2c6d 67use MRO::Compat;
0756fe3b 68use base '$compbase';
69sub COMPONENT {
dbb2d5cd 70 my \$self = shift->next::method(\@_);
0756fe3b 71 no strict 'refs';
72 *{\__PACKAGE__ . "::whoami"} = sub { return \__PACKAGE__; };
73 \$self;
74}
751;
76
77EOF
0756fe3b 78}
79
80foreach my $component (@components) {
81 make_component_file($component->{type},
82 $component->{prefix},
83 $component->{name});
84}
85
f27f2c6d 86my $shut_up_deprecated_warnings = q{
0f52a840 87 __PACKAGE__->log(Catalyst::Log->new('fatal'));
f27f2c6d 88};
89
90eval "package $appclass; use Catalyst; $shut_up_deprecated_warnings __PACKAGE__->setup";
0756fe3b 91
92can_ok( $appclass, 'components');
93
94my $complist = $appclass->components;
95
96# the +1 below is for the app class itself
97is(scalar keys %$complist, 24+1, "Correct number of components loaded");
98
99foreach (keys %$complist) {
100
101 # Skip the component which happens to be the app itself
102 next if $_ eq $appclass;
103
104 my $instance = $appclass->component($_);
105 isa_ok($instance, $_);
106 can_ok($instance, 'whoami');
107 is($instance->whoami, $_);
108
109 if($_ =~ /^${appclass}::(?:V|View)::(.*)/) {
110 my $moniker = $1;
111 isa_ok($instance, 'Catalyst::View');
112 can_ok($appclass->view($moniker), 'whoami');
113 is($appclass->view($moniker)->whoami, $_);
114 }
115 elsif($_ =~ /^${appclass}::(?:M|Model)::(.*)/) {
116 my $moniker = $1;
117 isa_ok($instance, 'Catalyst::Model');
118 can_ok($appclass->model($moniker), 'whoami');
119 is($appclass->model($moniker)->whoami, $_);
120 }
121 elsif($_ =~ /^${appclass}::(?:C|Controller)::(.*)/) {
122 my $moniker = $1;
123 isa_ok($instance, 'Catalyst::Controller');
124 can_ok($appclass->controller($moniker), 'whoami');
125 is($appclass->controller($moniker)->whoami, $_);
126 }
127 else {
128 die "Something is wrong with this test, this should"
129 . " have been unreachable";
130 }
131}
132
133rmtree($libdir);
18de900e 134
135# test extra component loading options
136
137$appclass = 'ExtraOptions';
138push @components, { type => 'View', prefix => 'Extra', name => 'Foo' };
139
140foreach my $component (@components) {
141 make_component_file($component->{type},
142 $component->{prefix},
143 $component->{name});
144}
145
146eval qq(
147package $appclass;
148use Catalyst;
f27f2c6d 149$shut_up_deprecated_warnings
18de900e 150__PACKAGE__->config->{ setup_components } = {
151 search_extra => [ '::Extra' ],
152 except => [ "${appclass}::Controller::Foo" ]
153};
154__PACKAGE__->setup;
155);
156
157can_ok( $appclass, 'components');
158
159$complist = $appclass->components;
160
161is(scalar keys %$complist, 24+1, "Correct number of components loaded");
162
2d486591 163ok( !exists $complist->{ "${appclass}::Controller::Foo" }, 'Controller::Foo was skipped' );
164ok( exists $complist->{ "${appclass}::Extra::Foo" }, 'Extra::Foo was loaded' );
18de900e 165
b94b200c 166rmtree($libdir);
167
168$appclass = "ComponentOnce";
169
170write_component_file([$libdir, $appclass, 'Model'], 'TopLevel', <<EOF);
171package ${appclass}::Model::TopLevel;
172use base 'Catalyst::Model';
173sub COMPONENT {
5d50f369 174
dbb2d5cd 175 my \$self = shift->next::method(\@_);
b94b200c 176 no strict 'refs';
177 *{\__PACKAGE__ . "::whoami"} = sub { return \__PACKAGE__; };
e7e4c469 178 *${appclass}::Model::TopLevel::GENERATED::ACCEPT_CONTEXT = sub {
179 return bless {}, 'FooBarBazQuux';
180 };
b94b200c 181 \$self;
182}
183
184package ${appclass}::Model::TopLevel::Nested;
185
186sub COMPONENT { die "COMPONENT called in the wrong order!"; }
187
1881;
189
190EOF
191
192write_component_file([$libdir, $appclass, 'Model', 'TopLevel'], 'Nested', <<EOF);
193package ${appclass}::Model::TopLevel::Nested;
194use base 'Catalyst::Model';
195
ac424253 196my \$called=0;
b94b200c 197no warnings 'redefine';
ac424253 198sub COMPONENT { \$called++;return shift->next::method(\@_); }
199sub called { return \$called };
b94b200c 2001;
201
202EOF
203
204eval "package $appclass; use Catalyst; __PACKAGE__->setup";
205
206is($@, '', "Didn't load component twice");
ac424253 207is($appclass->model('TopLevel::Nested')->called,1, 'COMPONENT called once');
b94b200c 208
e7e4c469 209ok($appclass->model('TopLevel::Generated'), 'Have generated model');
210is(ref($appclass->model('TopLevel::Generated')), 'FooBarBazQuux',
211 'ACCEPT_CONTEXT in generated inner package fired as expected');
212
e1dd56e6 213$appclass = "InnerComponent";
214
215{
216 package InnerComponent::Controller::Test;
217 use base 'Catalyst::Controller';
218}
219
220$INC{'InnerComponent/Controller/Test.pm'} = 1;
221
222eval "package $appclass; use Catalyst; __PACKAGE__->setup";
223
224isa_ok($appclass->controller('Test'), 'Catalyst::Controller');
225
b94b200c 226rmtree($libdir);