summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Phillips <bphillips@cpan.org>2012-12-04 22:53:27 -0600
committerAsh Berlin <ash_github@firemirror.com>2013-04-18 14:48:30 +0100
commit55f68bf78836700f664fd44cfedcee537627ac4e (patch)
tree62d75475dfc0495f843b4a9dd1903cd212b12bf0
parentChanges entry for adding PATCH support (Closes #13) (diff)
downloadnet-http-spore-55f68bf78836700f664fd44cfedcee537627ac4e.tar.gz
support for anonymous middlewares
-rw-r--r--Changes1
-rw-r--r--lib/Net/HTTP/Spore.pm4
-rw-r--r--lib/Net/HTTP/Spore/Role/Middleware.pm16
-rw-r--r--t/spore-middleware/anonymous.t55
4 files changed, 74 insertions, 2 deletions
diff --git a/Changes b/Changes
index f999bcf..3d27d03 100644
--- a/Changes
+++ b/Changes
@@ -2,6 +2,7 @@
     - Fix random test failure in t/spore-method/base.t related to random hash
       ordering in perl 5.17.6+ (#19)
     - Add support for PATCH HTTP method (#13, Andreas Marienborg)
+    - Allow anonymous subs to be used as middleware (Brian Phillips)
 
 0.05 Sun Nov 25 11:40:24 2012
     - Fix a memory leak in Net::HTTP::Spore::Meta::Method (michaelr)
diff --git a/lib/Net/HTTP/Spore.pm b/lib/Net/HTTP/Spore.pm
index 38ba4f7..d4fd8af 100644
--- a/lib/Net/HTTP/Spore.pm
+++ b/lib/Net/HTTP/Spore.pm
@@ -192,6 +192,10 @@ or only on some path
 
     $client->enable_if(sub{$_->[0]->path =~ m!/path/to/json/stuff!}, 'Format::JSON');
 
+For very simple middlewares, you can simple pass in an anonymous function
+
+    $client->enable( sub { my $request = shift; ... } );
+
 =head2 METHODS
 
 =over 4
diff --git a/lib/Net/HTTP/Spore/Role/Middleware.pm b/lib/Net/HTTP/Spore/Role/Middleware.pm
index 9ff23c0..88d64d4 100644
--- a/lib/Net/HTTP/Spore/Role/Middleware.pm
+++ b/lib/Net/HTTP/Spore/Role/Middleware.pm
@@ -1,6 +1,7 @@
 package Net::HTTP::Spore::Role::Middleware;
 
 use Moose::Role;
+use Scalar::Util qw/blessed/;
 
 has middlewares => (
     is         => 'rw',
@@ -15,7 +16,7 @@ has middlewares => (
 sub _load_middleware {
     my ( $self, $mw, $cond, @args ) = @_;
 
-    Class::MOP::load_class($mw);
+    Class::MOP::load_class($mw) unless blessed($mw);
 
     my $code = $mw->wrap( $cond, @args );
     $self->_trace_msg('== enabling middleware %s', $mw);
@@ -49,7 +50,18 @@ sub enable_if {
 
     confess "condition must be a code ref" if (!$cond || ref $cond ne 'CODE');
 
-    $mw = $self->_complete_mw_name($mw);
+    if(ref($mw) eq 'CODE'){ # anonymous middleware
+        Class::MOP::load_class('Net::HTTP::Spore::Middleware');
+        my $anon = Class::MOP::Class->create_anon_class(
+            superclasses => ['Net::HTTP::Spore::Middleware'],
+            methods => {
+                call => $mw
+            }
+        );
+        $mw = $anon->new_object;
+    } else {
+        $mw = $self->_complete_mw_name($mw);
+    }
     $self->_load_middleware($mw, $cond, @args);
     $self;
 }
diff --git a/t/spore-middleware/anonymous.t b/t/spore-middleware/anonymous.t
new file mode 100644
index 0000000..30039c8
--- /dev/null
+++ b/t/spore-middleware/anonymous.t
@@ -0,0 +1,55 @@
+use strict;
+use warnings;
+use Test::More;
+
+plan tests => 4;
+
+use JSON;
+
+use Net::HTTP::Spore;
+
+my $content = { keys => [qw/1 2 3/] };
+
+my $mock_server = {
+    '/api/show' => sub {
+        my $req = shift;
+        $req->new_response(
+            200,
+            [ 'Content-Type' => 'application/json' ],
+            JSON::encode_json($content),
+        );
+    },
+};
+
+my $api = {
+    base_url => 'http://services.org/api',
+    methods      => {
+        'show' => {
+            path   => '/show',
+            method => 'GET',
+        }
+    }
+};
+
+ok my $client = Net::HTTP::Spore->new_from_string( JSON::encode_json($api) );
+
+my $request_middleware = 0;
+my $response_middleware = 0;
+$client->enable(
+    sub {
+        $request_middleware++;
+        return sub {
+            ok $request_middleware,  'request middleware called';
+            ok $response_middleware, 'response middleware called';
+        }
+    }
+);
+$client->enable(
+    sub {
+        ok !$response_middleware, 'response not called yet';
+        return sub { $response_middleware++ }
+    }
+);
+# use Devel::SimpleTrace;
+$client->enable( 'Mock', tests => $mock_server );
+$client->show;