/**
  * Attach middleware to the pipeline.
  *
  * Each middleware can be associated with a particular path; if that
  * path is matched when that middleware is invoked, it will be processed;
  * otherwise it is skipped.
  *
  * No path means it should be executed every request cycle.
  *
  * A handler CAN implement MiddlewareInterface, but MUST be callable.
  *
  * Handlers with arity >= 4 or those implementing ErrorMiddlewareInterface
  * are considered error handlers, and will be executed when a handler calls
  * $next with an error or raises an exception.
  *
  * @see MiddlewareInterface
  * @see ErrorMiddlewareInterface
  * @see Next
  * @param string|callable|object $path Either a URI path prefix, or middleware.
  * @param null|callable|object $middleware Middleware
  * @return self
  */
 public function pipe($path, $middleware = null)
 {
     if (null === $middleware && $this->isValidMiddleware($path)) {
         $middleware = $path;
         $path = '/';
     }
     // Decorate callable middleware as http-interop middleware if we have
     // a response prototype present.
     if (is_callable($middleware) && !$this->isInteropMiddleware($middleware) && !$this->isErrorMiddleware($middleware)) {
         $middleware = $this->decorateCallableMiddleware($middleware);
     }
     // Ensure we have a valid handler
     if (!$this->isValidMiddleware($middleware)) {
         throw InvalidMiddlewareException::fromValue($middleware);
     }
     $this->pipeline->enqueue(new Route($this->normalizePipePath($path), $middleware));
     // @todo Trigger event here with route details?
     return $this;
 }
 /**
  * Attach middleware to the pipeline.
  *
  * Each middleware can be associated with a particular path; if that
  * path is matched when that middleware is invoked, it will be processed;
  * otherwise it is skipped.
  *
  * No path means it should be executed every request cycle.
  *
  * A handler CAN implement MiddlewareInterface, but MUST be callable.
  *
  * Handlers with arity >= 4 or those implementing ErrorMiddlewareInterface
  * are considered error handlers, and will be executed when a handler calls
  * $next with an error or raises an exception.
  *
  * @see MiddlewareInterface
  * @see ErrorMiddlewareInterface
  * @see Next
  * @param string|callable|object $path Either a URI path prefix, or middleware.
  * @param null|callable|object $middleware Middleware
  * @return self
  */
 public function pipe($path, $middleware = null)
 {
     if (null === $middleware && is_callable($path)) {
         $middleware = $path;
         $path = '/';
     }
     // Ensure we have a valid handler
     if (!is_callable($middleware)) {
         throw InvalidMiddlewareException::fromValue($middleware);
     }
     $this->pipeline->enqueue(new Route($this->normalizePipePath($path), $middleware));
     // @todo Trigger event here with route details?
     return $this;
 }
 /**
  * @dataProvider invalidMiddlewareValues
  */
 public function testFromValueProvidesNewExceptionWithMessageRelatedToValue($value, $expected)
 {
     $e = InvalidMiddlewareException::fromValue($value);
     $this->assertEquals(sprintf('Middleware must be callable, %s found', $expected), $e->getMessage());
 }