Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Raise deprecation notice by MiddlewarePipe if $out is omitted
Browse files Browse the repository at this point in the history
We need to notify users that `$out` cannot be omitted starting with
version 2.0.0.
  • Loading branch information
weierophinney committed Sep 26, 2016
1 parent 5b86130 commit 2aa080d
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 44 deletions.
12 changes: 12 additions & 0 deletions src/MiddlewarePipe.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public function __construct()
* $next has exhausted the pipeline; otherwise, a FinalHandler instance
* is created and passed to $next during initialization.
*
* @todo Make $out required for 2.0.0.
* @todo Remove trigger of deprecation notice when preparing for 2.0.0.
* @param Request $request
* @param Response $response
* @param callable $out
Expand All @@ -70,6 +72,16 @@ public function __invoke(Request $request, Response $response, callable $out = n
$request = $this->decorateRequest($request);
$response = $this->decorateResponse($response);

if (null === $out) {
trigger_error(sprintf(
'The third argument to %s() ($out) will be required starting with '
. 'Stratigility version 2; please see '
. 'https://docs.zendframework.com/zend-stratigility/migration/to-v2/ for '
. 'more details on how to update your application to remove this message.',
__CLASS__
), E_USER_DEPRECATED);
}

$done = $out ?: new FinalHandler([], $response);
$next = new Next($this->pipeline, $done);
$result = $next($request, $response);
Expand Down
133 changes: 89 additions & 44 deletions test/MiddlewarePipeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,46 @@
use Zend\Stratigility\Http\Request as RequestDecorator;
use Zend\Stratigility\Http\Response as ResponseDecorator;
use Zend\Stratigility\MiddlewarePipe;
use Zend\Stratigility\NoopFinalHandler;
use Zend\Stratigility\Utils;

class MiddlewarePipeTest extends TestCase
{
public $deprecationsSuppressed = false;

public function setUp()
{
$this->deprecationsSuppressed = false;
$this->request = new Request([], [], 'http://example.com/', 'GET', 'php://memory');
$this->response = new Response();
$this->middleware = new MiddlewarePipe();
}

public function tearDown()
{
if (false !== $this->deprecationsSuppressed) {
restore_error_handler();
}
}

/**
* @return NoopFinalHandler
*/
public function createFinalHandler()
{
return new NoopFinalHandler();
}

public function suppressDeprecationNotice()
{
$this->deprecationsSuppressed = set_error_handler(function ($errno, $errstr) {
if (false === strstr($errstr, 'docs.zendframework.com')) {
return false;
}
return true;
}, E_USER_DEPRECATED);
}

public function invalidHandlers()
{
return [
Expand Down Expand Up @@ -63,13 +92,13 @@ public function testHandleInvokesUntilFirstHandlerThatDoesNotCallNext()
$this->middleware->pipe(function ($req, $res, $next) {
$res->write("Third\n");
});
$phpunit = $this;
$this->middleware->pipe(function ($req, $res, $next) use ($phpunit) {
$phpunit->fail('Should not hit fourth handler!');

$this->middleware->pipe(function ($req, $res, $next) {
$this->fail('Should not hit fourth handler!');
});

$request = new Request([], [], 'http://local.example.com/foo', 'GET', 'php://memory');
$this->middleware->__invoke($request, $this->response);
$this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$body = (string) $this->response->getBody();
$this->assertContains('First', $body);
$this->assertContains('Second', $body);
Expand Down Expand Up @@ -136,46 +165,35 @@ public function testHandleInvokesOutHandlerIfQueueIsExhausted()
$this->assertTrue($triggered);
}

public function testPipeWillCreateErrorClosureForObjectImplementingHandle()
{
$this->markTestIncomplete();
$handler = new TestAsset\ErrorHandler();
$this->middleware->pipe($handler);
$r = new ReflectionProperty($this->middleware, 'queue');
$r->setAccessible(true);
$queue = $r->getValue($this->middleware);
$route = $queue[$queue->count() - 1];
$this->assertInstanceOf('Zend\Stratigility\Route', $route);
$handler = $route->handler;
$this->assertInstanceOf('Closure', $handler);
$this->assertEquals(4, Utils::getArity($handler));
}

public function testCanUseDecoratedRequestAndResponseDirectly()
{
$baseRequest = new Request([], [], 'http://local.example.com/foo', 'GET', 'php://memory');

$request = new RequestDecorator($baseRequest);
$response = new ResponseDecorator($this->response);
$phpunit = $this;
$executed = false;

$middleware = $this->middleware;
$middleware->pipe(function ($req, $res, $next) use ($phpunit, $request, $response, &$executed) {
$phpunit->assertSame($request, $req);
$phpunit->assertSame($response, $res);
$middleware->pipe(function ($req, $res, $next) use ($request, $response, &$executed) {
$this->assertSame($request, $req);
$this->assertSame($response, $res);
$executed = true;
});

$middleware($request, $response, function ($err = null) use ($phpunit) {
$phpunit->fail('Next should not be called');
$middleware($request, $response, function ($err = null) {
$this->fail('Next should not be called');
});

$this->assertTrue($executed);
}

public function testReturnsOrigionalResponseIfQueueDoesNotReturnAResponse()
/**
* @todo Update invocation to provide a no-op final handler for 2.0
*/
public function testReturnsOrigionalResponseIfQueueDoesNotReturnAResponseAndNoFinalHandlerRegistered()
{
$this->suppressDeprecationNotice();

$this->middleware->pipe(function ($req, $res, $next) {
$next($req, $res);
});
Expand Down Expand Up @@ -208,13 +226,13 @@ public function testReturnsResponseReturnedByQueue()
$this->middleware->pipe(function ($req, $res, $next) use ($return) {
return $return;
});
$phpunit = $this;
$this->middleware->pipe(function ($req, $res, $next) use ($phpunit) {
$phpunit->fail('Should not hit fourth handler!');

$this->middleware->pipe(function ($req, $res, $next) {
$this->fail('Should not hit fourth handler!');
});

$request = new Request([], [], 'http://local.example.com/foo', 'GET', 'php://memory');
$result = $this->middleware->__invoke($request, $this->response);
$result = $this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$this->assertSame($return, $result, var_export([
spl_object_hash($return) => get_class($return),
spl_object_hash($result) => get_class($result),
Expand All @@ -226,12 +244,13 @@ public function testSlashShouldNotBeAppendedInChildMiddlewareWhenLayerDoesNotInc
$this->middleware->pipe('/admin', function ($req, $res, $next) {
return $next($req, $res);
});
$phpunit = $this;
$this->middleware->pipe(function ($req, $res, $next) use ($phpunit) {

$this->middleware->pipe(function ($req, $res, $next) {
return $res->write($req->getUri()->getPath());
});

$request = new Request([], [], 'http://local.example.com/admin', 'GET', 'php://memory');
$result = $this->middleware->__invoke($request, $this->response);
$result = $this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$body = (string) $result->getBody();
$this->assertSame('/admin', $body);
}
Expand All @@ -241,12 +260,13 @@ public function testSlashShouldBeAppendedInChildMiddlewareWhenRequestUriIncludes
$this->middleware->pipe('/admin', function ($req, $res, $next) {
return $next($req, $res);
});
$phpunit = $this;
$this->middleware->pipe(function ($req, $res, $next) use ($phpunit) {

$this->middleware->pipe(function ($req, $res, $next) {
return $res->write($req->getUri()->getPath());
});

$request = new Request([], [], 'http://local.example.com/admin/', 'GET', 'php://memory');
$result = $this->middleware->__invoke($request, $this->response);
$result = $this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$body = (string) $result->getBody();
$this->assertSame('/admin/', $body);
}
Expand All @@ -271,7 +291,7 @@ public function testNestedMiddlewareMayInvokeDoneToInvokeNextOfParent()
});

$request = new Request([], [], 'http://local.example.com/test', 'GET', 'php://memory');
$result = $this->middleware->__invoke($request, $this->response);
$result = $this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$this->assertTrue($triggered);
$this->assertInstanceOf('Zend\Stratigility\Http\Response', $result);
$this->assertSame($this->response, $result->getOriginalResponse());
Expand All @@ -280,16 +300,14 @@ public function testNestedMiddlewareMayInvokeDoneToInvokeNextOfParent()
public function testMiddlewareRequestPathMustBeTrimmedOffWithPipeRoutePath()
{
$request = new Request([], [], 'http://local.example.com/foo/bar', 'GET', 'php://memory');

$phpunit = $this;
$executed = false;

$this->middleware->pipe('/foo', function ($req, $res, $next) use ($phpunit, &$executed) {
$phpunit->assertEquals('/bar', $req->getUri()->getPath());
$this->middleware->pipe('/foo', function ($req, $res, $next) use (&$executed) {
$this->assertEquals('/bar', $req->getUri()->getPath());
$executed = true;
});

$this->middleware->__invoke($request, $this->response);
$this->middleware->__invoke($request, $this->response, $this->createFinalHandler());
$this->assertTrue($executed);
}

Expand All @@ -314,7 +332,7 @@ public function testMiddlewareTreatsBothSlashAndEmptyPathAsTheRootPath($path)
$uri = (new Uri())->withPath($path);
$request = (new Request)->withUri($uri);

$response = $middleware($request, $this->response);
$response = $middleware($request, $this->response, $this->createFinalHandler());
$this->assertTrue($response->hasHeader('x-found'));
}

Expand Down Expand Up @@ -440,7 +458,7 @@ public function testNestedMiddlewareMatchesOnlyAtPathBoundaries($topPath, $neste

$uri = (new Uri())->withPath($fullPath);
$request = (new Request)->withUri($uri);
$response = $middleware($request, $this->response);
$response = $middleware($request, $this->response, $this->createFinalHandler());
$this->$assertion(
$response->hasHeader('X-Found'),
sprintf(
Expand Down Expand Up @@ -470,6 +488,7 @@ public function testNestedMiddlewareMatchesOnlyAtPathBoundaries($topPath, $neste
*/
public function testPassesOriginalResponseToFinalHandler()
{
$this->suppressDeprecationNotice();
$request = new Request([], [], 'http://local.example.com/foo', 'GET', 'php://memory');
$response = new Response();
$test = new Response();
Expand All @@ -484,4 +503,30 @@ public function testPassesOriginalResponseToFinalHandler()
$result = $pipeline($request, $response);
$this->assertSame($test, $result);
}

public function testOmittingFinalHandlerDuringInvocationRaisesDeprecationNotice()
{
$request = new Request([], [], 'http://local.example.com/foo', 'GET', 'php://memory');
$response = new Response();
$triggered = false;

$this->deprecationsSuppressed = set_error_handler(function ($errno, $errstr) use (&$triggered) {
$this->assertContains(MiddlewarePipe::class . '()', $errstr);
$triggered = true;
return true;
}, E_USER_DEPRECATED);

$pipeline = new MiddlewarePipe();
$pipeline->pipe(function ($req, $res, $next) {
$res->write('Some content');
return $res->withStatus(201);
});

$result = $pipeline($request, $response);

$this->assertNotSame($response, $result);
$this->assertEquals(201, $result->getStatusCode());
$this->assertEquals('Some content', (string) $result->getBody());
$this->assertTrue($triggered, 'Error handler was not triggered');
}
}

0 comments on commit 2aa080d

Please sign in to comment.