[sub{ }] can now be returned by a route to be used for streaming
Christian Walde [Wed, 2 Nov 2011 21:07:49 +0000 (22:07 +0100)]
lib/Web/Dispatch.pm
t/dispatch_misc.t
t/stream_test.t [new file with mode: 0644]

index c6dcded..ef437da 100644 (file)
@@ -28,7 +28,9 @@ sub _build__parser {
 
 sub call {
   my ($self, $env) = @_;
-  $self->_dispatch($env, $self->app);
+  my $res = $self->_dispatch($env, $self->app);
+  return $res->[0] if ref($res) eq 'ARRAY' and @{$res} == 1 and ref($res->[0]) eq 'CODE';
+  return $res;
 }
 
 sub _dispatch {
@@ -63,7 +65,7 @@ sub _have_result {
   my ($self, $first, $result, $match, $env) = @_;
 
   if (ref($first) eq 'ARRAY') {
-    return $self->_unpack_array_match($first);
+    return $first;
   }
   elsif (blessed($first) && $first->isa('Plack::Middleware')) {
     return $self->_uplevel_middleware($first, $result);
@@ -78,12 +80,6 @@ sub _have_result {
   return;
 }
 
-sub _unpack_array_match {
-  my ($self, $match) = @_;
-  return $match->[0] if @{$match} == 1 and ref($match->[0]) eq 'CODE';
-  return $match;
-}
-
 sub _uplevel_middleware {
   my ($self, $match, $results) = @_;
   die "Multiple results but first one is a middleware ($match)"
index 094c76a..0c11f2c 100644 (file)
@@ -89,10 +89,10 @@ sub array_with_sub {
         }
     );
 
-    my $get = run_request( GET => 'http://localhost/' );
+    eval { run_request( GET => 'http://localhost/' ) };
 
-    cmp_ok $get->code, '==', 999,
-      "if a route returns an arrayref with a single sub in it, then WD redispatches to that sub";
+    like $@, qr/Can't call method "request" on an undefined value .*MockHTTP/,
+"if a route returns an arrayref with a single sub in it, then that sub is returned as a response by WD, causing HTTP::Message::PSGI to choke";
 }
 
 sub array_with_no_sub {
diff --git a/t/stream_test.t b/t/stream_test.t
new file mode 100644 (file)
index 0000000..38118fe
--- /dev/null
@@ -0,0 +1,46 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Test::More (
+  eval { require HTTP::Request::AsCGI }
+    ? 'no_plan'
+    : (skip_all => 'No HTTP::Request::AsCGI')
+);
+
+use HTTP::Request::Common qw(GET POST);
+
+my $app = StreamTest->new;
+
+ok run_request( $app, GET 'http://localhost/' )->is_success;
+is run_request( $app, GET 'http://localhost/' )->content, "foo";
+
+done_testing;
+
+sub run_request {
+    my ( $app, $request ) = @_;
+    my $c = HTTP::Request::AsCGI->new( $request )->setup;
+    $app->run;
+    $c->restore;
+    return $c->response;
+}
+
+{
+
+    package StreamTest;
+    use Web::Simple;
+
+    sub dispatch_request {
+
+        sub (GET) {
+            [
+                sub {
+                    my $respond = shift;
+                    my $writer = $respond->( [ 200, [ "Content-type" => "text/plain" ] ] );
+                    $writer->write( 'f' );
+                    $writer->write( 'o' );
+                    $writer->write( 'o' );
+                  }
+            ];
+        },;
+    }
+}