summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold Daniels <arnold@jasny.net>2017-02-09 15:17:15 +0100
committerGitHub <noreply@github.com>2017-02-09 15:17:15 +0100
commit72c1e618610a1246dbfba143661777ca877a6a71 (patch)
tree31c199ff91436594acc35c6484798c6319715641
parent51c88bded1a907b19e44344de35871822ba95829 (diff)
parentc6cdff29b1a56ed530f93628d18d5ab44074ae98 (diff)
downloadcontroller-72c1e618610a1246dbfba143661777ca877a6a71.zip
controller-72c1e618610a1246dbfba143661777ca877a6a71.tar.gz
controller-72c1e618610a1246dbfba143661777ca877a6a71.tar.bz2
Merge pull request #13 from jasny/view-libraryv1.2.0
Moved view logic to own library
-rw-r--r--composer.json9
-rw-r--r--src/Controller.php7
-rw-r--r--src/Controller/CheckRequest.php2
-rw-r--r--src/Controller/RouteAction.php2
-rw-r--r--src/Controller/View.php94
-rw-r--r--src/Controller/View/PHP.php40
-rw-r--r--src/Controller/View/Twig.php171
-rw-r--r--src/ControllerInterface.php21
-rw-r--r--tests/Controller/ContentNegotiationTest.php108
-rw-r--r--tests/Controller/RouteActionTest.php9
-rw-r--r--tests/Controller/View/PHPTest.php54
-rw-r--r--tests/Controller/View/TwigTest.php297
-rw-r--r--tests/Controller/ViewTest.php83
-rw-r--r--tests/ControllerTest.php4
-rw-r--r--tests/support/TestHelper.php48
15 files changed, 425 insertions, 524 deletions
diff --git a/composer.json b/composer.json
index bd02105..185e3dd 100644
--- a/composer.json
+++ b/composer.json
@@ -23,12 +23,13 @@
},
"require-dev": {
"jasny/php-code-quality": "^2.0",
- "jasny/twig-extensions": "^1.0",
- "twig/twig": "^1.26"
+ "jasny/view": "^1.0.0@beta"
},
"suggest": {
- "jasny/twig-extensions": "Usefull extensions for Twig",
- "twig/twig": "Needed to work with Twig templates"
+ "jasny/view": "Use Twig or PHP templates with PSR-7 support",
+ "jasny/http-message": "A PSR-7 implementation for handling HTTP requests",
+ "jasny/router": "A versatile router with PSR-7 support",
+ "jasny/mvc": "Meta package for Jasny Router, Controller and View"
},
"autoload": {
"psr-4": {
diff --git a/src/Controller.php b/src/Controller.php
index 764d6f7..3f400e7 100644
--- a/src/Controller.php
+++ b/src/Controller.php
@@ -2,13 +2,14 @@
namespace Jasny;
+use Jasny\ControllerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
- * Controller
+ * Controller base class
*/
-abstract class Controller
+abstract class Controller implements ControllerInterface
{
use Controller\Input,
Controller\Output,
@@ -59,7 +60,7 @@ abstract class Controller
/**
* Get response. set for controller
*
- * @return ResponseInterface
+ * @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response)
{
diff --git a/src/Controller/CheckRequest.php b/src/Controller/CheckRequest.php
index 478266a..3fe3f1e 100644
--- a/src/Controller/CheckRequest.php
+++ b/src/Controller/CheckRequest.php
@@ -83,4 +83,4 @@ trait CheckRequest
return $referer && parse_url($referer, PHP_URL_HOST) === $host ? $referer : '';
}
-} \ No newline at end of file
+}
diff --git a/src/Controller/RouteAction.php b/src/Controller/RouteAction.php
index e8937b0..8051686 100644
--- a/src/Controller/RouteAction.php
+++ b/src/Controller/RouteAction.php
@@ -153,7 +153,7 @@ trait RouteAction
* @param \ReflectionFunctionAbstract $refl
* @return array
*/
- protected function getFunctionArgs($route, \ReflectionFunctionAbstract $refl)
+ protected function getFunctionArgs(\stdClass $route, \ReflectionFunctionAbstract $refl)
{
$args = [];
$params = $refl->getParameters();
diff --git a/src/Controller/View.php b/src/Controller/View.php
new file mode 100644
index 0000000..b32c285
--- /dev/null
+++ b/src/Controller/View.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Jasny\Controller;
+
+use Jasny\ViewInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * View using a template engine
+ */
+trait View
+{
+ /**
+ * @var ViewInterface
+ */
+ protected $viewer;
+
+ /**
+ * Get server request
+ *
+ * @return ServerRequestInterface
+ */
+ abstract public function getRequest();
+
+ /**
+ * Get server request
+ *
+ * @return ResponseInterface
+ */
+ abstract public function getResponse();
+
+ /**
+ * Get response. set for controller
+ *
+ * @param ResponseInterface $response
+ */
+ abstract public function setResponse(ResponseInterface $response);
+
+
+ /**
+ * Get the template engine abstraction
+ *
+ * @return ViewInterface
+ */
+ public function getViewer()
+ {
+ if (!isset($this->viewer)) {
+ throw new \LogicException("Viewer has not been set");
+ }
+
+ return $this->viewer;
+ }
+
+ /**
+ * Get the template engine abstraction
+ *
+ * @param ViewInterface $viewer
+ */
+ public function setViewer(ViewInterface $viewer)
+ {
+ $this->viewer = $viewer;
+ }
+
+
+ /**
+ * Get path of the view files
+ *
+ * @return string
+ */
+ public function getViewPath()
+ {
+ return getcwd();
+ }
+
+ /**
+ * View rendered template
+ *
+ * @param string $name Template name
+ * @param array $context Template context
+ */
+ public function view($name, array $context = [])
+ {
+ $context += ['current_url' => $this->getRequest()->getUri()];
+
+ if (method_exists($this, 'flash')) {
+ $context += ['flash' => $this->flash()];
+ }
+
+ $response = $this->getViewer()->render($this->getResponse(), $name, $context);
+
+ $this->setResponse($response);
+ }
+}
diff --git a/src/Controller/View/PHP.php b/src/Controller/View/PHP.php
new file mode 100644
index 0000000..0f7a5b7
--- /dev/null
+++ b/src/Controller/View/PHP.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Jasny\Controller\View;
+
+use Jasny\Controller\View;
+use Jasny\View\PHP as PHPView;
+
+/**
+ * View using PHP
+ */
+trait PHP
+{
+ use View;
+
+ /**
+ * Get the template engine abstraction
+ *
+ * @return PHPView
+ */
+ public function getViewer()
+ {
+ if (!isset($this->viewer)) {
+ $this->viewer = $this->createPHPView(['path' => $this->getViewPath()]);
+ }
+
+ return $this->viewer;
+ }
+
+ /**
+ * Create a twig view object.
+ * @ignore
+ * @codeCoverageIgnore
+ *
+ * @return PHPView;
+ */
+ protected function createPHPView($options)
+ {
+ return new PHPView($options);
+ }
+}
diff --git a/src/Controller/View/Twig.php b/src/Controller/View/Twig.php
index f74c05a..78df6b0 100644
--- a/src/Controller/View/Twig.php
+++ b/src/Controller/View/Twig.php
@@ -2,173 +2,40 @@
namespace Jasny\Controller\View;
-use Psr\Http\Message\ServerRequestInterface;
+use Jasny\Controller\View;
+use Jasny\View\Twig as TwigView;
/**
* View using Twig
*/
trait Twig
{
- /**
- * Twig environment
- * @var \Twig_Environment
- */
- protected $twig;
-
-
- /**
- * Get server request
- *
- * @return ServerRequestInterface
- */
- abstract public function getRequest();
-
- /**
- * Output result
- *
- * @param mixed $data
- * @param string $format Output format as MIME or extension
- * @return void
- */
- abstract public function output($data, $format = null);
-
-
- /**
- * Get path of the view files
- *
- * @return string
- */
- protected function getViewPath()
- {
- return getcwd();
- }
-
- /**
- * Assert valid variable, function and filter name
- *
- * @param string $name
- * @throws \InvalidArgumentException
- */
- protected function assertViewVariableName($name)
- {
- if (!is_string($name)) {
- $type = (is_object($name) ? get_class($name) . ' ' : '') . gettype($name);
- throw new \InvalidArgumentException("Expected name to be a string, not a $type");
- }
-
- if (!preg_match('/^[a-z]\w*$/i', $name)) {
- throw new \InvalidArgumentException("Invalid name '$name'");
- }
- }
+ use View;
/**
- * Add a global variable to the view.
- *
- * @param string $name Variable name
- * @param mixed $value
- * @return $this
- */
- public function setViewVariable($name, $value)
- {
- $this->assertViewVariableName($name);
-
- $this->getTwig()->addGlobal($name, $value);
-
- return $this;
- }
-
- /**
- * Expose a function to the view.
- *
- * @param string $name Function name
- * @param string|null $function
- * @param string $as 'function' or 'filter'
- * @return $this
- */
- public function setViewFunction($name, $function = null, $as = 'function')
- {
- $this->assertViewVariableName($name);
-
- if ($as === 'function') {
- $function = new \Twig_SimpleFunction($name, $function ?: $name);
- $this->getTwig()->addFunction($function);
- } elseif ($as === 'filter') {
- $filter = new \Twig_SimpleFilter($name, $function ?: $name);
- $this->getTwig()->addFilter($filter);
- } else {
- $not = is_string($as) ? "'$as'" : 'a ' . gettype($as);
- throw new \InvalidArgumentException("You should create either a 'function' or 'filter', not $not");
- }
-
- return $this;
- }
-
- /**
- * Get twig environment instance
- *
- * @return \Twig_Environment
- */
- public function createTwigEnvironment()
- {
- $path = $this->getViewPath();
- $loader = new \Twig_Loader_Filesystem($path);
-
- return new \Twig_Environment($loader);
- }
-
- /**
- * Initialize the Twig environment
+ * Get the template engine abstraction
+ *
+ * @return TwigView
*/
- protected function initTwig()
+ public function getViewer()
{
- $this->twig = $this->createTwigEnvironment();
-
- $extensions = ['DateExtension', 'PcreExtension', 'TextExtension', 'ArrayExtension'];
- foreach ($extensions as $name) {
- $class = "Jasny\Twig\\$name";
-
- if (class_exists($class)) {
- $this->twig->addExtension(new $class());
- }
+ if (!isset($this->viewer)) {
+ $this->viewer = $this->createTwigView(['path' => $this->getViewPath()]);
+ $this->viewer->addDefaultExtensions();
}
-
- $this->twig->addGlobal('current_url', $this->getRequest()->getUri());
- if (method_exists($this, 'flash')) {
- $this->twig->addGlobal('flash', $this->flash());
- }
- }
-
- /**
- * Get Twig environment
- *
- * @return \Twig_Environment
- */
- public function getTwig()
- {
- if (!isset($this->twig)) {
- $this->initTwig();
- }
-
- return $this->twig;
+ return $this->viewer;
}
-
-
+
/**
- * View rendered template
- *
- * @param string $name Template name
- * @param array $context Template context
+ * Create a twig view object.
+ * @ignore
+ * @codeCoverageIgnore
+ *
+ * @return TwigView;
*/
- public function view($name, array $context = [])
+ protected function createTwigView($options)
{
- if (!pathinfo($name, PATHINFO_EXTENSION)) {
- $name .= '.html.twig';
- }
-
- $twig = $this->getTwig();
- $tmpl = $twig->loadTemplate($name);
-
- $this->output($tmpl->render($context), 'text/html; charset=' . $twig->getCharset());
+ return new TwigView($options);
}
}
diff --git a/src/ControllerInterface.php b/src/ControllerInterface.php
new file mode 100644
index 0000000..8225457
--- /dev/null
+++ b/src/ControllerInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Jasny;
+
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Interface for controllers
+ */
+interface ControllerInterface
+{
+ /**
+ * Run the controller as function
+ *
+ * @param ServerRequestInterface $request
+ * @param ResponseInterface $response
+ * @return ResponseInterface
+ */
+ public function __invoke(ServerRequestInterface $request, ResponseInterface $response);
+}
diff --git a/tests/Controller/ContentNegotiationTest.php b/tests/Controller/ContentNegotiationTest.php
index 1a390a4..f760bcd 100644
--- a/tests/Controller/ContentNegotiationTest.php
+++ b/tests/Controller/ContentNegotiationTest.php
@@ -5,7 +5,7 @@ namespace Jasny\Controller;
use Jasny\Controller\ContentNegotiation;
use Psr\Http\Message\ServerRequestInterface;
use Jasny\Controller\TestHelper;
-use Negotiation\Negotiator;
+use Negotiation;
use Negotiation\BaseAccept;
/**
@@ -16,36 +16,6 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
use TestHelper;
/**
- * Test negotiation
- *
- * @dataProvider negotiateProvider
- * @param string $result
- * @param array $header
- * @param array $priorities
- */
- public function testNegotiate($method, $negotiatorClass, $type, $expected, $headerName, array $headerValue, array $priorities)
- {
- $request = $this->createMock(ServerRequestInterface::class);
- $request->expects($this->once())->method('getHeader')->with($this->equalTo($headerName))->will($this->returnValue($headerValue));
-
- $expectedObj = $this->createMock(BaseAccept::class);
- $expectedObj->expects($this->once())->method('getType')->will($this->returnValue($expected));
-
- $negotiator = $this->createMock($negotiatorClass);
- $negotiator->expects($this->once())->method('getBest')->with($this->equalTo(join(', ', $headerValue)), $this->equalTo($priorities))->will($this->returnValue($expectedObj));
-
- $trait = $this->getController(['getRequest', 'getNegotiator']);
- $trait->expects($this->once())->method('getRequest')->will($this->returnValue($request));
- $trait->expects($this->once())->method('getNegotiator')->with($this->equalTo($type))->will($this->returnValue($negotiator));
-
- $builtClass = $this->callProtectedMethod($trait, 'getNegotiatorName', [$type]);
- $result = $trait->{$method}($priorities);
-
- $this->assertEquals($builtClass, $negotiatorClass, "Obtained wrong negotiator class");
- $this->assertEquals($result, $expected, "Obtained result does not match expected result");
- }
-
- /**
* Provide data for testing negotiation
*
* @return array
@@ -55,7 +25,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
return [
[
'negotiateContentType',
- 'Negotiation\\Negotiator',
+ Negotiation\Negotiator::class,
'',
'text/html',
'Accept',
@@ -64,7 +34,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateContentType',
- 'Negotiation\\Negotiator',
+ Negotiation\Negotiator::class,
'',
'',
'Accept',
@@ -73,7 +43,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateLanguage',
- 'Negotiation\\LanguageNegotiator',
+ Negotiation\LanguageNegotiator::class,
'language',
'en',
'Accept-Language',
@@ -82,7 +52,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateLanguage',
- 'Negotiation\\LanguageNegotiator',
+ Negotiation\LanguageNegotiator::class,
'language',
'',
'Accept-Language',
@@ -91,7 +61,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateEncoding',
- 'Negotiation\\EncodingNegotiator',
+ Negotiation\EncodingNegotiator::class,
'encoding',
'gzip',
'Accept-Encoding',
@@ -100,7 +70,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateEncoding',
- 'Negotiation\\EncodingNegotiator',
+ Negotiation\EncodingNegotiator::class,
'encoding',
'',
'Accept-Encoding',
@@ -109,7 +79,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateCharset',
- 'Negotiation\\CharsetNegotiator',
+ Negotiation\CharsetNegotiator::class,
'charset',
'utf-8',
'Accept-Charset',
@@ -118,7 +88,7 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
],
[
'negotiateCharset',
- 'Negotiation\\CharsetNegotiator',
+ Negotiation\CharsetNegotiator::class,
'charset',
'',
'Accept-Charset',
@@ -129,6 +99,66 @@ class ContentNegotiationTest extends \PHPUnit_Framework_TestCase
}
/**
+ * Test negotiation
+ * @dataProvider negotiateProvider
+ *
+ * @param string $method
+ * @param string $negotiatorClass
+ * @param string $type
+ * @param string $expected
+ * @param string $headerName
+ * @param array $headerValue
+ * @param array $priorities
+ */
+ public function testNegotiate(
+ $method,
+ $negotiatorClass,
+ $type,
+ $expected,
+ $headerName,
+ array $headerValue,
+ array $priorities
+ ) {
+ $request = $this->createMock(ServerRequestInterface::class);
+ $request->expects($this->once())->method('getHeader')->with($this->equalTo($headerName))
+ ->will($this->returnValue($headerValue));
+
+ $expectedObj = $this->createMock(BaseAccept::class);
+ $expectedObj->expects($this->once())->method('getType')->will($this->returnValue($expected));
+
+ $negotiator = $this->createMock($negotiatorClass);
+ $negotiator->expects($this->once())->method('getBest')
+ ->with($this->equalTo(join(', ', $headerValue)), $this->equalTo($priorities))
+ ->will($this->returnValue($expectedObj));
+
+ $trait = $this->getController(['getRequest', 'getNegotiator']);
+ $trait->expects($this->once())->method('getRequest')->will($this->returnValue($request));
+ $trait->expects($this->once())->method('getNegotiator')->with($this->equalTo($type))
+ ->will($this->returnValue($negotiator));
+
+ $buildClass = $this->callPrivateMethod($trait, 'getNegotiatorName', [$type]);
+ $result = $trait->{$method}($priorities);
+
+ $this->assertEquals($buildClass, $negotiatorClass, "Obtained wrong negotiator class");
+ $this->assertEquals($result, $expected, "Obtained result does not match expected result");
+ }
+
+ /**
+ * Test negotiation
+ * @dataProvider negotiateProvider
+ *
+ * @param string $method
+ * @param string $negotiatorClass
+ * @param string $type
+ */
+ public function testGetNegotiator($method, $negotiatorClass, $type)
+ {
+ $controller = $this->getController();
+
+ $this->assertInstanceOf($negotiatorClass, $this->callPrivateMethod($controller, 'getNegotiator', [$type]));
+ }
+
+ /**
* Get the controller class
*
* @return string
diff --git a/tests/Controller/RouteActionTest.php b/tests/Controller/RouteActionTest.php
index fcab3ed..3e42d1d 100644
--- a/tests/Controller/RouteActionTest.php
+++ b/tests/Controller/RouteActionTest.php
@@ -14,7 +14,10 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase
use TestHelper {
getController as private _getController;
}
-
+
+ /**
+ * @return string
+ */
protected function getControllerClass()
{
return RouteActionController::class;
@@ -27,7 +30,7 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase
* @param string $className
* @return RouteActionController|\PHPUnit_Framework_MockObject_MockObject
*/
- protected function getController($methods = array(), $className = null)
+ protected function getController($methods = [], $className = null)
{
return $this->_getController(
array_merge($methods, ['getRequest', 'defaultAction', 'runTestAction', 'notFound', 'before', 'after']),
@@ -41,7 +44,7 @@ class RouteActionTest extends \PHPUnit_Framework_TestCase
{
return [
[(object)['args' => ['woo']], 'defaultAction', ['woo']],
- [(object)['action' => 'test-run'], 'testRunAction'],
+ [(object)['action' => 'run-test'], 'runTestAction'],
[(object)['action' => 'non-existent'], 'notFound']
];
}
diff --git a/tests/Controller/View/PHPTest.php b/tests/Controller/View/PHPTest.php
new file mode 100644
index 0000000..c9b8c3f
--- /dev/null
+++ b/tests/Controller/View/PHPTest.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Jasny\Controller\View;
+
+use Jasny\Controller\View;
+use Jasny\View\PHP as PHPView;
+use Jasny\Controller\TestHelper;
+
+/**
+ * @covers Jasny\Controller\View\PHP
+ */
+class PHPTest extends \PHPUnit_Framework_TestCase
+{
+ use TestHelper {
+ getController as private _getController;
+ }
+
+ /**
+ * @return string
+ */
+ protected function getControllerClass()
+ {
+ return View\PHP::class;
+ }
+
+ /**
+ * Get mock controller
+ *
+ * @param array $methods
+ * @param string $className
+ * @return RouteActionController|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected function getController($methods = [], $className = null)
+ {
+ $controller = $this->_getController(array_merge($methods, ['createPHPView', 'getViewPath']), $className);
+ $controller->method('getViewPath')->willReturn('/tmp');
+
+ return $controller;
+ }
+
+
+ public function testGetViewer()
+ {
+ $viewer = $this->createMock(PHPView::class);
+
+ $controller = $this->getController();
+ $controller->method('createPHPView')->willReturn($viewer);
+
+ $this->assertSame($viewer, $controller->getViewer());
+
+ // Idempotent
+ $this->assertSame($viewer, $controller->getViewer());
+ }
+}
diff --git a/tests/Controller/View/TwigTest.php b/tests/Controller/View/TwigTest.php
index e46757e..566787f 100644
--- a/tests/Controller/View/TwigTest.php
+++ b/tests/Controller/View/TwigTest.php
@@ -3,9 +3,7 @@
namespace Jasny\Controller\View;
use Jasny\Controller\View;
-use Jasny\Controller\Session\Flash;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Message\UriInterface;
+use Jasny\View\Twig as TwigView;
use Jasny\Controller\TestHelper;
/**
@@ -13,296 +11,45 @@ use Jasny\Controller\TestHelper;
*/
class TwigTest extends \PHPUnit_Framework_TestCase
{
- use TestHelper;
-
- protected function getControllerClass()
- {
- return View\Twig::class;
- }
-
- /**
- * Test creating twig environment
- */
- public function testCreateTwigEnvironment()
- {
- $controller = $this->getController([]);
- $twig = $controller->createTwigEnvironment();
-
- $this->assertInstanceOf(\Twig_Environment::class, $twig);
- $this->assertInstanceOf(\Twig_Loader_Filesystem::class, $twig->getLoader());
- $this->assertEquals([getcwd()], $twig->getLoader()->getPaths());
- }
-
- /**
- * Test intializing twig environment
- */
- public function testInitTwig()
- {
- $uri = $this->createMock(UriInterface::class);
-
- $request = $this->createMock(ServerRequestInterface::class);
- $request->expects($this->once())->method('getUri')->willReturn($uri);
-
- $twig = $this->createMock(\Twig_Environment::class);
- $twig->expects($this->once())->method('addGlobal')->with('current_url', $this->identicalTo($uri));
-
- $controller = $this->getController(['createTwigEnvironment']);
- $controller->expects($this->any())->method('getRequest')->willReturn($request);
- $controller->expects($this->once())->method('createTwigEnvironment')->willReturn($twig);
-
- $controller->getTwig();
- }
-
- /**
- * Test Jasny Twig extensions when intializing twig environment
- */
- public function testInitTwigWithJasnyExtensions()
- {
- $request = $this->createMock(ServerRequestInterface::class);
-
- $twig = $this->createMock(\Twig_Environment::class);
- $twig->expects($this->exactly(4))->method('addExtension')->withConsecutive(
- [$this->isInstanceOf('Jasny\Twig\DateExtension')],
- [$this->isInstanceOf('Jasny\Twig\PcreExtension')],
- [$this->isInstanceOf('Jasny\Twig\TextExtension')],
- [$this->isInstanceOf('Jasny\Twig\ArrayExtension')]
- );
-
- $controller = $this->getController(['createTwigEnvironment']);
- $controller->expects($this->any())->method('getRequest')->willReturn($request);
- $controller->expects($this->once())->method('createTwigEnvironment')->willReturn($twig);
-
- $controller->getTwig();
+ use TestHelper {
+ getController as private _getController;
}
/**
- * Test session flash when intializing twig environment
+ * @return string
*/
- public function testInitTwigWithSessionFlash()
- {
- $request = $this->createMock(ServerRequestInterface::class);
- $flash = $this->createMock(Flash::class);
-
- $twig = $this->createMock(\Twig_Environment::class);
- $twig->expects($this->any())->method('addGlobal')->withConsecutive([], ['flash', $flash]);
-
- $controller = $this->getController(['createTwigEnvironment', 'flash']);
- $controller->expects($this->any())->method('getRequest')->willReturn($request);
- $controller->expects($this->once())->method('flash')->willReturn($flash);
- $controller->expects($this->once())->method('createTwigEnvironment')->willReturn($twig);
-
- $controller->getTwig();
- }
-
- /**
- * Provide data for testing 'setViewVariable' method
- *
- * @return array
- */
- public function setViewVariableProvider()
- {
- return [
- ['foo', null],
- ['foo', 'bar'],
- ['foo', ['bar', 'zoo']],
- ['foo', (object)['a' => 'bar', 'b' => 'zoo']],
- ];
- }
-
- /**
- * Test 'setViewVariable' method
- *
- * @dataProvider setViewVariableProvider
- */
- public function testSetViewVariable($name, $value)
+ protected function getControllerClass()
{
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
-
- $twig->expects($this->once())->method('addGlobal')->with($name, $value);
-
- $result = $controller->setViewVariable($name, $value);
-
- $this->assertSame($controller, $result);
+ return View\Twig::class;
}
-
/**
- * Provide data for testing 'setViewFunction' method when creating functions
- *
- * @return array
- */
- public function setViewFunctionProvider()
- {
- return [
- ['test_name', function() {}],
- ['str_rot13'],
- ['obfuscate', 'str_rot13']
- ];
- }
-
- /**
- * Test 'setViewFunction' method for adding functions
- * @dataProvider setViewFunctionProvider
+ * Get mock controller
*
- * @param string $name
- * @param callable $callable
+ * @param array $methods
+ * @param string $className
+ * @return RouteActionController|\PHPUnit_Framework_MockObject_MockObject
*/
- public function testSetViewFunctionFunction($name, $callable = null)
+ protected function getController($methods = [], $className = null)
{
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
+ $controller = $this->_getController(array_merge($methods, ['createTwigView', 'getViewPath']), $className);
+ $controller->method('getViewPath')->willReturn('/tmp');
- $fn = $callable ?: $name;
-
- $twig->expects($this->once())->method('addFunction')
- ->with($this->callback(function($function) use ($name, $fn) {
- $this->assertInstanceOf(\Twig_SimpleFunction::class, $function);
- $this->assertEquals($name, $function->getName());
- $this->assertSame($fn, $function->getCallable());
- return true;
- }));
-
- $twig->expects($this->never())->method('addFilter');
-
- $controller->setViewFunction($name, $callable, 'function');
+ return $controller;
}
- /**
- * Test 'setViewFunction' method for adding filters
- * @dataProvider setViewFunctionProvider
- *
- * @param string $name
- * @param callable $callable
- */
- public function testSetViewFunctionFilter($name, $callable = null)
- {
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
-
- $fn = $callable ?: $name;
-
- $twig->expects($this->once())->method('addFilter')
- ->with($this->callback(function($function) use ($name, $fn) {
- $this->assertInstanceOf(\Twig_SimpleFilter::class, $function);
- $this->assertEquals($name, $function->getName());
- $this->assertSame($fn, $function->getCallable());
- return true;
- }));
-
- $twig->expects($this->never())->method('addFunction');
-
- $controller->setViewFunction($name, $callable, 'filter');
- }
-
- public function invalidAsProvider()
+ public function testGetViewer()
{
- return [
- ['foo', "'foo'"],
- [10, 'a integer'],
- [['filter'], 'a array']
- ];
- }
-
- /**
- * @dataProvider invalidAsProvider
- *
- * @param mixed $as
- * @param string $not
- */
- public function testSetViewFunctionInvalid($as, $not)
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage("You should create either a 'function' or 'filter', not $not");
-
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
-
- $controller->setViewFunction('abc', null, $as);
- }
-
-
- public function assertViewVariableNameProvider()
- {
- return [
- ['setViewVariable'],
- ['setViewFunction', 'function'],
- ['setViewFunction', 'filter']
- ];
- }
-
- /**
- * @dataProvider assertViewVariableNameProvider
- *
- * @expectedException InvalidArgumentException
- * @expectedExceptionMessage Expected name to be a string, not a stdClass object
- */
- public function testAssertViewVariableNameNonString($fn, $as = null)
- {
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
-
- $controller->$fn(new \stdClass(), null, $as);
- }
-
- /**
- * @dataProvider assertViewVariableNameProvider
- *
- * @expectedException InvalidArgumentException
- * @expectedExceptionMessage Invalid name 'hello world'
- */
- public function testAssertViewVariableNameInvalid($fn, $as = null)
- {
- $twig = $this->createMock(\Twig_Environment::class);
-
- $controller = $this->getController(['getTwig']);
- $controller->method('getTwig')->willReturn($twig);
-
- $controller->$fn('hello world', null, $as);
- }
-
-
- public function viewProvider()
- {
- return [
- ['foo', 'foo.html.twig'],
- ['foo.html.twig', 'foo.html.twig'],
- ['foo.html', 'foo.html']
- ];
- }
-
- /**
- * @dataProvider viewProvider
- *
- * @param string $name
- * @param string $filename
- */
- public function testView($name, $filename)
- {
- $context = ['foo' => 1, 'bar' => 2, 'zoo' => ['monkey', 'lion']];
-
- $template = $this->createMock(\Twig_TemplateInterface::class);
- $template->expects($this->once())->method('render')->with($context)->willReturn('hello world');
+ $viewer = $this->createMock(TwigView::class);
+ $viewer->expects($this->once())->method('addDefaultExtensions');
- $twig = $this->createMock(\Twig_Environment::class);
- $twig->expects($this->once())->method('loadTemplate')->with($filename)->willReturn($template);
- $twig->expects($this->once())->method('getCharset')->willReturn('test-charset');
+ $controller = $this->getController();
+ $controller->method('createTwigView')->willReturn($viewer);
- $controller = $this->getController(['getTwig', 'output']);
- $controller->expects($this->atLeastOnce())->method('getTwig')->willReturn($twig);
- $controller->expects($this->once())->method('output')->with('hello world', 'text/html; charset=test-charset');
+ $this->assertSame($viewer, $controller->getViewer());
- $controller->view($name, $context);
+ // Idempotent
+ $this->assertSame($viewer, $controller->getViewer());
}
}
diff --git a/tests/Controller/ViewTest.php b/tests/Controller/ViewTest.php
new file mode 100644
index 0000000..0473a3f
--- /dev/null
+++ b/tests/Controller/ViewTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Jasny\Controller\View;
+
+use Jasny\Controller\View;
+use Jasny\ViewInterface;
+use Jasny\Controller\TestHelper;
+use Jasny\Controller\Session\Flash;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * @covers Jasny\Controller\View
+ */
+class ViewTest extends \PHPUnit_Framework_TestCase
+{
+ use TestHelper;
+
+ /**
+ * @return string
+ */
+ protected function getControllerClass()
+ {
+ return View::class;
+ }
+
+ public function testGetViewer()
+ {
+ $viewer = $this->createMock(ViewInterface::class);
+
+ $controller = $this->getController();
+ $controller->setViewer($viewer);
+
+ $this->assertSame($viewer, $controller->getViewer());
+ }
+
+ /**
+ * @expectedException LogicException
+ * @expectedExceptionMessage Viewer has not been set
+ */
+ public function testGetViewerNotSet()
+ {
+ $this->getController()->getViewer();
+ }
+
+
+ public function testGetViewPath()
+ {
+ $this->assertSame(getcwd(), $this->getController()->getViewPath());
+ }
+
+
+ public function testView()
+ {
+ $uri = $this->createMock(UriInterface::class);
+
+ $request = $this->createMock(ServerRequestInterface::class);
+ $request->expects($this->once())->method('getUri')->willReturn($uri);
+
+ $response = $this->createMock(ResponseInterface::class);
+ $finalResponse = $this->createMock(ResponseInterface::class);
+
+ $flash = $this->createMock(Flash::class);
+
+ $name = 'foo';
+ $context = ['color' => 'blue', 'animal' => 'monkey'];
+
+ $viewer = $this->createMock(ViewInterface::class);
+ $viewer->expects($this->once())->method('render')
+ ->with($response, $name, $this->identicalTo($context + ['current_url' => $uri, 'flash' => $flash]))
+ ->willReturn($finalResponse);
+
+ $controller = $this->getController(['flash']);
+ $controller->method('getRequest')->willReturn($request);
+ $controller->method('getResponse')->willReturn($response);
+ $controller->method('flash')->willReturn($flash);
+ $controller->expects($this->once())->method('setResponse')->with($finalResponse);
+ $controller->setViewer($viewer);
+
+ $controller->view($name, $context);
+ }
+}
diff --git a/tests/ControllerTest.php b/tests/ControllerTest.php
index b980d48..b0f357f 100644
--- a/tests/ControllerTest.php
+++ b/tests/ControllerTest.php
@@ -5,14 +5,14 @@ namespace Jasny;
use Jasny\Controller;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
-use Jasny\Controller\TestHelper;
+use Jasny\Controller\TestHelper as ControllerTestHelper;
/**
* @covers Jasny\Controller
*/
class ControllerTest extends \PHPUnit_Framework_TestCase
{
- use TestHelper;
+ use ControllerTestHelper;
/**
* Test running controller
diff --git a/tests/support/TestHelper.php b/tests/support/TestHelper.php
index 05b40d7..b48f8b0 100644
--- a/tests/support/TestHelper.php
+++ b/tests/support/TestHelper.php
@@ -3,20 +3,15 @@
namespace Jasny\Controller;
use Jasny\Controller;
+use Jasny\TestHelper as Base;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
/**
* Additional test methods
*/
trait TestHelper
{
- /**
- * Returns a builder object to create mock objects using a fluent interface.
- *
- * @param string $className
- *
- * @return \PHPUnit_Framework_MockObject_MockBuilder
- */
- abstract public function getMockBuilder($className);
+ use Base;
/**
* Get the controller class
@@ -32,7 +27,7 @@ trait TestHelper
* Get mock for controller
*
* @param array $methods Methods to mock
- * @return Controller|Controller\Session|Controller\View\Twig|\PHPUnit_Framework_MockObject_MockObject
+ * @return Controller|Controller\Session|Controller\View|MockObject
*/
public function getController($methods = [], $mockClassName = null)
{
@@ -50,39 +45,4 @@ trait TestHelper
$getMock = trait_exists($class) ? 'getMockForTrait' : 'getMockForAbstractClass';
return $builder->$getMock();
}
-
- /**
- * Set a private or protected property of the given object
- *
- * @param object $object
- * @param string $property
- * @param mixed $value
- */
- protected function setPrivateProperty($object, $property, $value)
- {
- if (!is_object($object)) {
- throw new \InvalidArgumentException("Excpected an object, got a " . gettype($object));
- }
-
- $refl = new \ReflectionProperty($object, $property);
- $refl->setAccessible(true);
- $refl->setValue($object, $value);
- }
-
- /**
- * Call protected method on some object
- *
- * @param object $object
- * @param string $name Method name
- * @param array $args
- * @return mixed Result of method call
- */
- protected function callProtectedMethod($object, $name, $args)
- {
- $class = new \ReflectionClass($object);
- $method = $class->getMethod($name);
- $method->setAccessible(true);
-
- return $method->invokeArgs($object, $args);
- }
}