diff --git a/composer.json b/composer.json index 81998e8..1672a1a 100644 --- a/composer.json +++ b/composer.json @@ -32,14 +32,9 @@ "phpstan/phpstan": "^1.6", "phpunit/phpunit": "^9.5" }, - "autoload": { - "psr-4": { - "ICanBoogie\\Binding\\View\\": "lib" - } - }, "autoload-dev": { "psr-4": { - "ICanBoogie\\Binding\\View\\": "tests/lib" + "Test\\ICanBoogie\\Binding\\View\\": "tests/lib" }, "classmap": [ "tests/Application.php" diff --git a/config/prototype.php b/config/prototype.php deleted file mode 100644 index 28df2a9..0000000 --- a/config/prototype.php +++ /dev/null @@ -1,11 +0,0 @@ - $config - ->bind(ControllerAbstract::class, 'lazy_get_view', [ Hooks::class, 'controller_get_view' ]) - ->bind(ControllerAbstract::class, 'get_template', [ Hooks::class, 'get_template' ]) - ->bind(ControllerAbstract::class, 'get_layout', [ Hooks::class, 'get_layout' ]); diff --git a/config/services.yml b/config/services.yml new file mode 100644 index 0000000..4417cf7 --- /dev/null +++ b/config/services.yml @@ -0,0 +1,9 @@ +services: + _defaults: + autowire: true + + ICanBoogie\View\LayoutResolver: + class: ICanBoogie\View\LayoutResolver\Basic + + ICanBoogie\View\ViewProvider: + class: ICanBoogie\View\ViewProvider\Basic diff --git a/lib/Hooks.php b/lib/Hooks.php deleted file mode 100644 index 4365609..0000000 --- a/lib/Hooks.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View; - -use ICanBoogie\PropertyNotDefined; -use ICanBoogie\Render\Renderer; -use ICanBoogie\Routing\ControllerAbstract; -use ICanBoogie\View\View; - -use function ICanBoogie\app; -use function ICanBoogie\emit; - -final class Hooks -{ - /* - * Prototypes - */ - - /** - * Returns a view for a controller. - */ - public static function controller_get_view(ControllerAbstract $controller): View - { - $view = new View($controller, app()->container->get(Renderer::class)); - - emit(new View\AlterEvent($view)); - - return $view; - } - - /** - * Avoids a trip to `assert_property_is_readable` for controllers or routes that do not - * define a `template` property. - * - * @throws PropertyNotDefined - */ - public static function get_template(object $target): void - { - throw new PropertyNotDefined([ 'template', $target ]); - } - - /** - * Avoids a trip to `assert_property_is_readable` for controllers or routes that do not - * define a `layout` property. - * - * @throws PropertyNotDefined - */ - public static function get_layout(object $target): void - { - throw new PropertyNotDefined([ 'layout', $target ]); - } -} diff --git a/tests/app/all/config/services.yml b/tests/app/all/config/services.yml new file mode 100644 index 0000000..c896219 --- /dev/null +++ b/tests/app/all/config/services.yml @@ -0,0 +1,7 @@ +services: + _defaults: + autowire: true + + Test\ICanBoogie\Binding\View\Acme\ArticleController: + public: true + shared: false diff --git a/tests/lib/Acme/Article.php b/tests/lib/Acme/Article.php new file mode 100644 index 0000000..2875597 --- /dev/null +++ b/tests/lib/Acme/Article.php @@ -0,0 +1,11 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Test\ICanBoogie\Binding\View\Acme; + +use ICanBoogie\Routing\Controller\ActionTrait; +use ICanBoogie\Routing\ControllerAbstract; +use ICanBoogie\View\View; +use ICanBoogie\View\ViewProvider; +use ICanBoogie\View\ViewTrait; + +final class ArticleController extends ControllerAbstract +{ + /** + * @uses show + */ + use ActionTrait; + use ViewTrait; + + public function __construct( + private readonly ViewProvider $view_provider + ) { + } + + private function show(): View + { + $article = new Article("Article A"); + + $this->response->headers->cache_control = 'public'; + $this->response->expires = '+3 hour'; + + return $this->view($article); + } +} diff --git a/tests/lib/ControllerBindingsTest.php b/tests/lib/ControllerBindingsTest.php deleted file mode 100644 index e24c722..0000000 --- a/tests/lib/ControllerBindingsTest.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View; - -use ICanBoogie\Binding\View\ControllerBindingsTest\BoundController; -use ICanBoogie\Binding\View\ControllerBindingsTest\BoundControllerWithLayout; -use ICanBoogie\Binding\View\ControllerBindingsTest\BoundControllerWithTemplate; -use ICanBoogie\PropertyNotDefined; -use ICanBoogie\View\View; -use PHPUnit\Framework\TestCase; - -class ControllerBindingsTest extends TestCase -{ - public function test_view() - { - $controller = $this - ->getMockBuilder(BoundController::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - /* @var $controller BoundController */ - - $view = $controller->view; - - $this->assertInstanceOf(View::class, $view); - $this->assertSame($view, $controller->view); - $this->assertObjectHasAttribute('view', $controller); - } - - public function test_template() - { - $controller = $this - ->getMockBuilder(BoundController::class) - ->getMockForAbstractClass(); - - /* @var $controller BoundController */ - - $this->expectException(PropertyNotDefined::class); - $controller->template; - } - - public function test_layout() - { - $controller = $this - ->getMockBuilder(BoundController::class) - ->getMockForAbstractClass(); - - /* @var $controller BoundController */ - - $this->expectException(PropertyNotDefined::class); - $controller->layout; - } - - public function test_template_when_defined() - { - $controller = $this - ->getMockBuilder(BoundControllerWithTemplate::class) - ->getMockForAbstractClass(); - - /* @var $controller BoundControllerWithTemplate */ - - $this->assertEquals('my-template', $controller->template); - } - - public function test_layout_when_defined() - { - $controller = $this - ->getMockBuilder(BoundControllerWithLayout::class) - ->getMockForAbstractClass(); - - /* @var $controller BoundControllerWithLayout */ - - $this->assertEquals('my-layout', $controller->layout); - } -} diff --git a/tests/lib/ControllerBindingsTest/BoundController.php b/tests/lib/ControllerBindingsTest/BoundController.php deleted file mode 100644 index e3143da..0000000 --- a/tests/lib/ControllerBindingsTest/BoundController.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View\ControllerBindingsTest; - -use ICanBoogie\Routing\ControllerAbstract; -use ICanBoogie\View\ControllerBindings as ViewBindings; - -abstract class BoundController extends ControllerAbstract -{ - use ViewBindings; -} diff --git a/tests/lib/ControllerBindingsTest/BoundControllerWithLayout.php b/tests/lib/ControllerBindingsTest/BoundControllerWithLayout.php deleted file mode 100644 index 81da8a6..0000000 --- a/tests/lib/ControllerBindingsTest/BoundControllerWithLayout.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View\ControllerBindingsTest; - -use ICanBoogie\Routing\ControllerAbstract; -use ICanBoogie\View\ControllerBindings as ViewBindings; - -abstract class BoundControllerWithLayout extends ControllerAbstract -{ - use ViewBindings; - - protected function get_layout() - { - return 'my-layout'; - } -} diff --git a/tests/lib/ControllerBindingsTest/BoundControllerWithTemplate.php b/tests/lib/ControllerBindingsTest/BoundControllerWithTemplate.php deleted file mode 100644 index 88b4407..0000000 --- a/tests/lib/ControllerBindingsTest/BoundControllerWithTemplate.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View\ControllerBindingsTest; - -use ICanBoogie\Routing\ControllerAbstract; -use ICanBoogie\View\ControllerBindings as ViewBindings; - -abstract class BoundControllerWithTemplate extends ControllerAbstract -{ - use ViewBindings; - - protected function get_template() - { - return 'my-template'; - } -} diff --git a/tests/lib/HooksTest.php b/tests/lib/HooksTest.php deleted file mode 100644 index 2d5537d..0000000 --- a/tests/lib/HooksTest.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ICanBoogie\Binding\View; - -use ICanBoogie\HTTP\Request; -use ICanBoogie\PropertyNotDefined; -use ICanBoogie\Routing\ControllerAbstract; -use ICanBoogie\View\ControllerBindings; -use ICanBoogie\View\View; -use LogicException; -use PHPUnit\Framework\TestCase; - -class HooksTest extends TestCase -{ - /** - * @var ControllerAbstract&ControllerBindings; - */ - private ControllerAbstract $controller; - - protected function setUp(): void - { - parent::setUp(); - - $this->controller = new class () extends ControllerAbstract { - use ControllerBindings; - - protected function action(Request $request): mixed - { - throw new LogicException(); - } - }; - } - - public function test_controller_get_view(): void - { - $view = $this->controller->view; - $this->assertInstanceOf(View::class, $view); - $this->assertSame($view, $this->controller->view); - } - - public function test_controller_get_template(): void - { - $this->expectException(PropertyNotDefined::class); - $this->assertNull($this->controller->template); - } - - public function test_controller_get_layout(): void - { - $this->expectException(PropertyNotDefined::class); - $this->assertNull($this->controller->layout); - } -} diff --git a/tests/lib/IntegrationTest.php b/tests/lib/IntegrationTest.php new file mode 100644 index 0000000..96ddcad --- /dev/null +++ b/tests/lib/IntegrationTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Test\ICanBoogie\Binding\View; + +use ICanBoogie\HTTP\Request; +use ICanBoogie\Routing\Route; +use ICanBoogie\View\View; +use PHPUnit\Framework\TestCase; +use Test\ICanBoogie\Binding\View\Acme\Article; +use Test\ICanBoogie\Binding\View\Acme\ArticleController; + +use function ICanBoogie\app; + +final class IntegrationTest extends TestCase +{ + private ArticleController $controller; + + protected function setUp(): void + { + parent::setUp(); + + $this->controller = app()->service_for_class(ArticleController::class); + } + + public function testViewAsResponse(): void + { + $route = new Route('/', 'articles:show'); + + $request = Request::from(); + $request->context->add($route); + + $response = $this->controller->respond($request); + + $this->assertEquals('public, max-age=10800', (string) $response->headers->cache_control); + + $body = $response->body; + $this->assertInstanceOf(View::class, $body); + $this->assertInstanceOf(Article::class, $body->content); + $this->assertEquals('articles/show', $body->template); + $this->assertEquals('default', $body->layout); + } +}