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