fix a memory leak introduced by 1f8cad5e5a1875de94d63ac91d8ded4d2282c62e
[catagits/Web-Simple.git] / t / dispatch_misc.t
CommitLineData
35075f9d 1use strict;
2use warnings FATAL => 'all';
3no warnings::illegalproto;
4
5use Test::More;
6
7use HTTP::Request::Common qw(GET POST);
8use Web::Dispatch;
9use HTTP::Response;
efbff594 10use Web::Dispatch::Predicates 'match_true';
35075f9d 11
12my @dispatch;
13
14{
15 use Web::Simple 'MiscTest';
16
17 package MiscTest;
18 sub dispatch_request { @dispatch }
b2e37c62 19 sub string_method { [ 999, [], [""] ]; }
35075f9d 20}
21
22my $app = MiscTest->new;
23sub run_request { $app->run_test_request( @_ ); }
24
b2e37c62 25string_method_name();
35075f9d 26app_is_non_plack();
e5250d96 27app_is_object();
1f8cad5e 28app_is_just_sub();
35075f9d 29plack_app_return();
30broken_route_def();
19b1ef0b 31invalid_psgi_responses();
35075f9d 32middleware_as_only_route();
33route_returns_middleware_plus_extra();
34route_returns_undef();
efbff594 35matcher_nonsub_pair();
35075f9d 36
37done_testing();
38
b2e37c62 39sub string_method_name {
40 @dispatch = ( '/' => "string_method" );
41
42 my $get = run_request( GET => 'http://localhost/' );
43
44 cmp_ok $get->code, '==', 999, "a dispatcher that's a string matching a method on the dispatch object gets executed";
45}
46
35075f9d 47sub app_is_non_plack {
48
49 my $r = HTTP::Response->new( 999 );
50
e5250d96 51 my $d = Web::Dispatch->new( dispatch_app => $r );
35075f9d 52 eval { $d->call };
53
54 like $@, qr/No idea how we got here with HTTP::Response/,
55 "Web::Dispatch dies when run with an app() that is a non-PSGI object";
56 undef $@;
57}
58
e5250d96 59sub app_is_object {
60 {
61
62 package ObjectApp;
63 use Moo;
64 sub to_app { [ 999, [], ["ok"] ] }
65 }
66
1f727762 67 my $o = ObjectApp->new;
68 my $d = Web::Dispatch->new( dispatch_object => $o );
e5250d96 69 my $res = $d->call;
70
71 cmp_ok $res->[0], '==', 999, "Web::Dispatch can dispatch properly, given only an object with to_app method";
72}
73
1f8cad5e 74sub app_is_just_sub {
75 my $d = Web::Dispatch->new( dispatch_app => sub () { [ 999, [], ["ok"] ] } );
76 my $res = $d->call( {} );
77
78 cmp_ok $res->[0], '==', 999,
79 "Web::Dispatch can dispatch properly, given only an app that's just a sub, with no object involved";
80}
81
35075f9d 82sub plack_app_return {
83 {
84
85 package FauxPlackApp;
86 sub new { bless {}, $_[0] }
87
88 sub to_app {
89 return sub {
90 [ 999, [], [""] ];
91 };
92 }
93 }
94
95 @dispatch = (
96 sub (/) {
97 FauxPlackApp->new;
98 }
99 );
100
101 my $get = run_request( GET => 'http://localhost/' );
102
103 cmp_ok $get->code, '==', 999,
104 "when a route returns a thing that look like a Plack app, the web app redispatches to that thing";
105}
106
107sub broken_route_def {
108
109 @dispatch = ( '/' => "" );
110
111 my $get = run_request( GET => 'http://localhost/' );
112
113 cmp_ok $get->code, '==', 500, "a route definition by hash that doesn't pair a sub with a route dies";
114 like $get->content, qr[No idea how we got here with /], "the error message points out the broken definition";
115}
116
19b1ef0b 117sub invalid_psgi_responses {
118 undef $@;
35075f9d 119
19b1ef0b 120 my @responses = (
121 [ [ sub { } ], "an arrayref with a single sub in it" ],
122 [ ["moo"], "an arrayref with a scalar that is not a sub" ],
23dee6a3 123 [ bless( {}, "FauxObject" ), "an object without to_app method" ],
35075f9d 124 );
125
19b1ef0b 126 for my $response ( @responses ) {
127 @dispatch = ( sub (/) { $response->[0] } );
35075f9d 128
19b1ef0b 129 eval { run_request( GET => 'http://localhost/' ) };
130
131 like $@, qr/Can't call method "request" on an undefined value .*MockHTTP/,
132 sprintf(
133 "if a route returns %s, then that is returned as a response by WD, causing HTTP::Message::PSGI to choke",
134 $response->[1] );
135 undef $@;
136 }
35075f9d 137}
138
139sub middleware_as_only_route {
140 @dispatch = ( bless {}, "Plack::Middleware" );
141
142 my $get = run_request( GET => 'http://localhost/' );
143
144 cmp_ok $get->code, '==', 500, "a route definition consisting of only a middleware causes a bail";
145 like $get->content, qr[Multiple results but first one is a middleware \(Plack::Middleware=],
146 "the error message mentions the middleware class";
147}
148
149sub route_returns_middleware_plus_extra {
150 @dispatch = (
151 sub (/) {
152 return ( bless( {}, "Plack::Middleware" ), "" );
153 }
154 );
155
156 my $get = run_request( GET => 'http://localhost/' );
157
158 cmp_ok $get->code, '==', 500, "a route returning a middleware and at least one other variable causes a bail";
159 like $get->content,
160 qr[Multiple results but first one is a middleware \(Plack::Middleware=],
161 "the error message mentions the middleware class";
162}
163
164sub route_returns_undef {
165 @dispatch = (
166 sub (/) {
167 (
168 sub(/) {
169 undef;
170 },
171 sub(/) {
172 [ 900, [], [""] ];
173 }
174 );
175 },
176 sub () {
177 [ 400, [], [""] ];
178 }
179 );
180
181 my $get = run_request( GET => 'http://localhost/' );
182
183 cmp_ok $get->code, '==', 900, "a route that returns undef causes WD to ignore it and resume dispatching";
184}
efbff594 185
186sub matcher_nonsub_pair {
187 @dispatch = ( match_true() => 5 );
188
189 my $get = run_request( GET => 'http://localhost/' );
190
191 cmp_ok $get->code, '==', 500, "a route definition that pairs a WD::Matcher a non-sub dies";
192 like $get->content, qr[No idea how we got here with Web::Dispatch::M],
193 "the error message points out the broken definition";
194}