From 212760d4c93ce14e9ae34ef207bbb8f48a7dd9a7 Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Thu, 21 Sep 2017 18:37:37 +0200 Subject: Changed Container to Illuminate/Container @see https://laravel.com/docs/5.5/container @see https://davejamesmiller.com/2017/06/15/laravel-illuminate-container-in-depth --- tests/Unit/ApplicationTest.php | 1 + 1 file changed, 1 insertion(+) (limited to 'tests/Unit/ApplicationTest.php') diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php index 77429f44..53fe3109 100644 --- a/tests/Unit/ApplicationTest.php +++ b/tests/Unit/ApplicationTest.php @@ -24,6 +24,7 @@ class ApplicationTest extends TestCase $this->assertSame($app, $app->get(Container::class)); $this->assertSame($app, $app->get(Application::class)); $this->assertSame($app, $app->get(ContainerInterface::class)); + $this->assertSame($app, Application::getInstance()); $this->assertSame($app, Container::getInstance()); } } -- cgit v1.2.3-54-g00ecf From d49e49c364c1b73e4e4e3b52dc10ee9d0150e447 Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Fri, 22 Sep 2017 14:02:02 +0200 Subject: Implemented service provider functionality --- config/app.php | 9 ++ includes/engelsystem_provider.php | 13 ++- includes/helper/internationalization_helper.php | 2 +- src/Application.php | 80 ++++++++++++- src/Container/ServiceProvider.php | 31 +++++ src/helpers.php | 50 +++++--- tests/Unit/ApplicationTest.php | 147 +++++++++++++++++++++++- 7 files changed, 310 insertions(+), 22 deletions(-) create mode 100644 config/app.php create mode 100644 src/Container/ServiceProvider.php (limited to 'tests/Unit/ApplicationTest.php') diff --git a/config/app.php b/config/app.php new file mode 100644 index 00000000..fe0a97c1 --- /dev/null +++ b/config/app.php @@ -0,0 +1,9 @@ + [ + ], +]; diff --git a/includes/engelsystem_provider.php b/includes/engelsystem_provider.php index e1669c57..3067ab62 100644 --- a/includes/engelsystem_provider.php +++ b/includes/engelsystem_provider.php @@ -26,6 +26,13 @@ require_once __DIR__ . '/autoload.php'; $app = new Application(realpath(__DIR__ . DIRECTORY_SEPARATOR . '..')); +/** + * Bootstrap application + */ +$appConfig = $app->make(Config::class); +$appConfig->set(app('path.config') . '/app.php'); +$app->bootstrap($appConfig); + /** * Load configuration */ @@ -40,6 +47,10 @@ if (file_exists(__DIR__ . '/../config/config.php')) { )); } + +/** + * Configure application + */ date_default_timezone_set($config->get('timezone')); @@ -55,7 +66,7 @@ $app->instance('request', $request); /** * Check for maintenance */ -if ($config->get('maintenance')) { +if ($app->get('config')->get('maintenance')) { echo file_get_contents(__DIR__ . '/../templates/maintenance.html'); die(); } diff --git a/includes/helper/internationalization_helper.php b/includes/helper/internationalization_helper.php index efbe5db5..7fa6518b 100644 --- a/includes/helper/internationalization_helper.php +++ b/includes/helper/internationalization_helper.php @@ -36,7 +36,7 @@ function gettext_init() } gettext_locale(); - bindtextdomain('default', realpath(__DIR__ . '/../../locale')); + bindtextdomain('default', app('path.lang')); bind_textdomain_codeset('default', 'UTF-8'); textdomain('default'); } diff --git a/src/Application.php b/src/Application.php index 80538396..b62b28a9 100644 --- a/src/Application.php +++ b/src/Application.php @@ -2,7 +2,9 @@ namespace Engelsystem; +use Engelsystem\Config\Config; use Engelsystem\Container\Container; +use Engelsystem\Container\ServiceProvider; use Psr\Container\ContainerInterface; class Application extends Container @@ -10,6 +12,16 @@ class Application extends Container /** @var string|null */ protected $appPath = null; + /** @var bool */ + protected $isBootstrapped = false; + + /** + * Registered service providers + * + * @var array + */ + protected $serviceProviders = []; + /** * Application constructor. * @@ -36,15 +48,73 @@ class Application extends Container } /** + * @param string|ServiceProvider $provider + * @return ServiceProvider + */ + public function register($provider) + { + if (is_string($provider)) { + $provider = $this->get($provider); + } + + $this->serviceProviders[] = $provider; + + $provider->register(); + + if ($this->isBootstrapped) { + $this->call([$provider, 'boot']); + } + + return $provider; + } + + /** + * Boot service providers + * + * @param Config|null $config + */ + public function bootstrap(Config $config = null) + { + if ($this->isBootstrapped) { + return; + } + + if ($config instanceof Config) { + foreach ($config->get('providers', []) as $provider) { + $this->register($provider); + } + } + + foreach ($this->serviceProviders as $provider) { + $this->call([$provider, 'boot']); + } + + $this->isBootstrapped = true; + } + + protected function registerPaths() + { + $appPath = $this->appPath; + + $this->instance('path', $appPath); + $this->instance('path.config', $appPath . DIRECTORY_SEPARATOR . 'config'); + $this->instance('path.lang', $appPath . DIRECTORY_SEPARATOR . 'locale'); + } + + /** + * Set app base path + * * @param string $appPath * @return static */ public function setAppPath($appPath) { + $appPath = realpath($appPath); $appPath = rtrim($appPath, DIRECTORY_SEPARATOR); $this->appPath = $appPath; - $this->instance('path', $appPath); + + $this->registerPaths(); return $this; } @@ -56,4 +126,12 @@ class Application extends Container { return $this->appPath; } + + /** + * @return bool + */ + public function isBooted() + { + return $this->isBootstrapped; + } } diff --git a/src/Container/ServiceProvider.php b/src/Container/ServiceProvider.php new file mode 100644 index 00000000..2a1bbebf --- /dev/null +++ b/src/Container/ServiceProvider.php @@ -0,0 +1,31 @@ +app = $app; + } + + /** + * Register container bindings + */ + public function register() { } + + /** + * Called after other services had been registered + */ + public function boot() { } +} diff --git a/src/helpers.php b/src/helpers.php index de303963..c3c727ec 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -23,6 +23,15 @@ function app($id = null) return Application::getInstance()->get($id); } +/** + * @param string $path + * @return string + */ +function base_path($path = '') +{ + return app('path') . (empty($path) ? '' : DIRECTORY_SEPARATOR . $path); +} + /** * Get or set config values * @@ -46,6 +55,15 @@ function config($key = null, $default = null) return $config->get($key, $default); } +/** + * @param string $path + * @return string + */ +function config_path($path = '') +{ + return app('path.config') . (empty($path) ? '' : DIRECTORY_SEPARATOR . $path); +} + /** * @param string $key * @param mixed $default @@ -78,22 +96,6 @@ function session($key = null, $default = null) return $session->get($key, $default); } -/** - * @param string $template - * @param mixed[] $data - * @return Renderer|string - */ -function view($template = null, $data = null) -{ - $renderer = app('renderer'); - - if (is_null($template)) { - return $renderer; - } - - return $renderer->render($template, $data); -} - /** * @param string $path * @param array $parameters @@ -109,3 +111,19 @@ function url($path = null, $parameters = []) return $urlGenerator->to($path, $parameters); } + +/** + * @param string $template + * @param mixed[] $data + * @return Renderer|string + */ +function view($template = null, $data = null) +{ + $renderer = app('renderer'); + + if (is_null($template)) { + return $renderer; + } + + return $renderer->render($template, $data); +} diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php index 53fe3109..78310134 100644 --- a/tests/Unit/ApplicationTest.php +++ b/tests/Unit/ApplicationTest.php @@ -3,19 +3,23 @@ namespace Engelsystem\Test\Config; use Engelsystem\Application; +use Engelsystem\Config\Config; use Engelsystem\Container\Container; +use Engelsystem\Container\ServiceProvider; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; use Psr\Container\ContainerInterface; +use ReflectionClass; class ApplicationTest extends TestCase { /** - * @covers \Engelsystem\Application::__construct - * @covers \Engelsystem\Application::registerBaseBindings + * @covers \Engelsystem\Application::__construct + * @covers \Engelsystem\Application::registerBaseBindings */ public function testConstructor() { - $app = new Application(); + $app = new Application('.'); $this->assertInstanceOf(Container::class, $app); $this->assertInstanceOf(ContainerInterface::class, $app); @@ -27,4 +31,141 @@ class ApplicationTest extends TestCase $this->assertSame($app, Application::getInstance()); $this->assertSame($app, Container::getInstance()); } + + /** + * @covers \Engelsystem\Application::setAppPath + * @covers \Engelsystem\Application::registerPaths + * @covers \Engelsystem\Application::path + */ + public function testAppPath() + { + $app = new Application(); + + $this->assertFalse($app->has('path')); + + $app->setAppPath('.'); + $this->assertTrue($app->has('path')); + $this->assertTrue($app->has('path.config')); + $this->assertTrue($app->has('path.lang')); + + $this->assertEquals(realpath('.'), $app->path()); + $this->assertEquals(realpath('.') . '/config', $app->get('path.config')); + + $app->setAppPath('./../'); + $this->assertEquals(realpath('../') . '/config', $app->get('path.config')); + } + + /** + * @covers \Engelsystem\Application::register + */ + public function testRegister() + { + $app = new Application(); + + $serviceProvider = $this->mockServiceProvider($app, ['register']); + $serviceProvider->expects($this->once()) + ->method('register'); + + $app->register($serviceProvider); + + $anotherServiceProvider = $this->mockServiceProvider($app, ['register', 'boot']); + $anotherServiceProvider->expects($this->once()) + ->method('register'); + $anotherServiceProvider->expects($this->once()) + ->method('boot'); + + $app->bootstrap(); + $app->register($anotherServiceProvider); + } + + /** + * @covers \Engelsystem\Application::register + */ + public function testRegisterBoot() + { + $app = new Application(); + $app->bootstrap(); + + $serviceProvider = $this->mockServiceProvider($app, ['register', 'boot']); + $serviceProvider->expects($this->once()) + ->method('register'); + $serviceProvider->expects($this->once()) + ->method('boot'); + + $app->register($serviceProvider); + } + + /** + * @covers \Engelsystem\Application::register + */ + public function testRegisterClassName() + { + $app = new Application(); + + $mockClassName = $this->getMockClass(ServiceProvider::class); + $serviceProvider = $this->getMockBuilder($mockClassName) + ->setConstructorArgs([$app]) + ->setMethods(['register']) + ->getMock(); + + $serviceProvider->expects($this->once()) + ->method('register'); + + $app->instance($mockClassName, $serviceProvider); + $app->register($mockClassName); + } + + /** + * @covers \Engelsystem\Application::bootstrap + * @covers \Engelsystem\Application::isBooted + */ + public function testBootstrap() + { + /** @var PHPUnit_Framework_MockObject_MockObject|Application $app */ + $app = $this->getMockBuilder(Application::class) + ->setMethods(['register']) + ->getMock(); + + $serviceProvider = $this->mockServiceProvider($app, ['boot']); + $serviceProvider->expects($this->once()) + ->method('boot'); + + $app->expects($this->once()) + ->method('register') + ->with($serviceProvider); + + $config = $this->getMockBuilder(Config::class) + ->getMock(); + + $config->expects($this->once()) + ->method('get') + ->with('providers') + ->willReturn([$serviceProvider]); + + $property = (new ReflectionClass($app))->getProperty('serviceProviders'); + $property->setAccessible(true); + $property->setValue($app, [$serviceProvider]); + + $app->bootstrap($config); + + $this->assertTrue($app->isBooted()); + + // Run bootstrap another time to ensure that providers are registered only once + $app->bootstrap($config); + } + + /** + * @param Application $app + * @param array $methods + * @return PHPUnit_Framework_MockObject_MockObject|ServiceProvider + */ + protected function mockServiceProvider(Application $app, $methods = []) + { + $serviceProvider = $this->getMockBuilder(ServiceProvider::class) + ->setConstructorArgs([$app]) + ->setMethods($methods) + ->getMockForAbstractClass(); + + return $serviceProvider; + } } -- cgit v1.2.3-54-g00ecf From e15e86362585f5d00d118653232584ed0920e533 Mon Sep 17 00:00:00 2001 From: Igor Scheller Date: Tue, 31 Oct 2017 14:23:23 +0100 Subject: Added tests for base_path and config_path --- .../DatabaseServiceProviderConnectionTest.php | 2 +- tests/Feature/Logger/EngelsystemLoggerTest.php | 2 +- tests/Feature/Model/LogEntriesModelTest.php | 38 +++++++++++++++++++ tests/Feature/Model/RoomModelTest.php | 40 ++++++++++++++++++++ tests/Feature/model/LogEntriesModelTest.php | 38 ------------------- tests/Feature/model/RoomModelTest.php | 40 -------------------- tests/Unit/ApplicationTest.php | 2 +- tests/Unit/Config/ConfigServiceProviderTest.php | 2 +- tests/Unit/Config/ConfigTest.php | 2 +- .../Unit/Database/DatabaseServiceProviderTest.php | 2 +- .../Exceptions/ExceptionsServiceProviderTest.php | 2 +- tests/Unit/HelpersTest.php | 43 +++++++++++++++++++++- tests/Unit/Logger/LoggerServiceProviderTest.php | 2 +- tests/Unit/Renderer/HtmlEngineTest.php | 2 +- .../Unit/Renderer/RendererServiceProviderTest.php | 2 +- tests/Unit/Renderer/RendererTest.php | 6 ++- tests/Unit/Routing/RoutingServiceProviderTest.php | 2 +- tests/Unit/Routing/UrlGeneratorTest.php | 2 +- 18 files changed, 136 insertions(+), 93 deletions(-) create mode 100644 tests/Feature/Model/LogEntriesModelTest.php create mode 100644 tests/Feature/Model/RoomModelTest.php delete mode 100644 tests/Feature/model/LogEntriesModelTest.php delete mode 100644 tests/Feature/model/RoomModelTest.php (limited to 'tests/Unit/ApplicationTest.php') diff --git a/tests/Feature/Database/DatabaseServiceProviderConnectionTest.php b/tests/Feature/Database/DatabaseServiceProviderConnectionTest.php index dd1ce729..636fba2e 100644 --- a/tests/Feature/Database/DatabaseServiceProviderConnectionTest.php +++ b/tests/Feature/Database/DatabaseServiceProviderConnectionTest.php @@ -1,6 +1,6 @@ assertNotFalse(LogEntry_create(LogLevel::WARNING, 'test_LogEntry_create')); + + // There should be one more log entry now + $this->assertEquals(count(LogEntries()), $count + 1); + } + + public function testClearAllLogEntries() + { + LogEntry_create(LogLevel::WARNING, 'test'); + $this->assertTrue(count(LogEntries()) > 0); + + $this->assertNotFalse(LogEntries_clear_all()); + $this->assertCount(0, LogEntries()); + } + + public function tearDown() + { + LogEntries_clear_all(); + } +} diff --git a/tests/Feature/Model/RoomModelTest.php b/tests/Feature/Model/RoomModelTest.php new file mode 100644 index 00000000..20b9e34d --- /dev/null +++ b/tests/Feature/Model/RoomModelTest.php @@ -0,0 +1,40 @@ +room_id = Room_create('test', false, true, ''); + } + + public function test_Room() + { + $this->create_Room(); + + $room = Room($this->room_id); + + $this->assertNotFalse($room); + $this->assertNotNull($room); + $this->assertEquals($room['Name'], 'test'); + + $this->assertNull(Room(-1)); + } + + public function tearDown() + { + if ($this->room_id != null) { + Room_delete($this->room_id); + } + } +} diff --git a/tests/Feature/model/LogEntriesModelTest.php b/tests/Feature/model/LogEntriesModelTest.php deleted file mode 100644 index 6d7b0ebc..00000000 --- a/tests/Feature/model/LogEntriesModelTest.php +++ /dev/null @@ -1,38 +0,0 @@ -assertNotFalse(LogEntry_create(LogLevel::WARNING, 'test_LogEntry_create')); - - // There should be one more log entry now - $this->assertEquals(count(LogEntries()), $count + 1); - } - - public function testClearAllLogEntries() - { - LogEntry_create(LogLevel::WARNING, 'test'); - $this->assertTrue(count(LogEntries()) > 0); - - $this->assertNotFalse(LogEntries_clear_all()); - $this->assertCount(0, LogEntries()); - } - - public function tearDown() - { - LogEntries_clear_all(); - } -} diff --git a/tests/Feature/model/RoomModelTest.php b/tests/Feature/model/RoomModelTest.php deleted file mode 100644 index 96be84a2..00000000 --- a/tests/Feature/model/RoomModelTest.php +++ /dev/null @@ -1,40 +0,0 @@ -room_id = Room_create('test', false, true, ''); - } - - public function test_Room() - { - $this->create_Room(); - - $room = Room($this->room_id); - - $this->assertNotFalse($room); - $this->assertNotNull($room); - $this->assertEquals($room['Name'], 'test'); - - $this->assertNull(Room(-1)); - } - - public function tearDown() - { - if ($this->room_id != null) { - Room_delete($this->room_id); - } - } -} diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php index 78310134..f58483ea 100644 --- a/tests/Unit/ApplicationTest.php +++ b/tests/Unit/ApplicationTest.php @@ -1,6 +1,6 @@ assertEquals($class, app('some.name')); } + /** + * @covers \base_path() + */ + public function testBasePath() + { + /** @var MockObject|Application $app */ + $app = $this->getMockBuilder(Container::class) + ->getMock(); + Application::setInstance($app); + + $app->expects($this->atLeastOnce()) + ->method('get') + ->with('path') + ->willReturn('/foo/bar'); + + $this->assertEquals('/foo/bar', base_path()); + $this->assertEquals('/foo/bar/bla-foo.conf', base_path('bla-foo.conf')); + } + /** * @covers \config */ @@ -53,6 +73,25 @@ class HelpersTest extends TestCase $this->assertEquals(['user' => 'FooBar'], config('mail')); } + /** + * @covers \config_path() + */ + public function testConfigPath() + { + /** @var MockObject|Application $app */ + $app = $this->getMockBuilder(Container::class) + ->getMock(); + Application::setInstance($app); + + $app->expects($this->atLeastOnce()) + ->method('get') + ->with('path.config') + ->willReturn('/foo/conf'); + + $this->assertEquals('/foo/conf', config_path()); + $this->assertEquals('/foo/conf/bar.php', config_path('bar.php')); + } + /** * @covers \env */ @@ -146,7 +185,7 @@ class HelpersTest extends TestCase /** * @param string $alias * @param object $object - * @return Application|\PHPUnit_Framework_MockObject_MockObject + * @return Application|MockObject */ protected function getAppMock($alias, $object) { diff --git a/tests/Unit/Logger/LoggerServiceProviderTest.php b/tests/Unit/Logger/LoggerServiceProviderTest.php index 66f63cf4..cef95d5b 100644 --- a/tests/Unit/Logger/LoggerServiceProviderTest.php +++ b/tests/Unit/Logger/LoggerServiceProviderTest.php @@ -1,6 +1,6 @@ getMockForAbstractClass(EngineInterface::class); $nullRenderer->expects($this->atLeastOnce()) @@ -20,6 +22,7 @@ class RendererTest extends TestCase ->willReturn(false); $renderer->addRenderer($nullRenderer); + /** @var MockObject|EngineInterface $mockRenderer */ $mockRenderer = $this->getMockForAbstractClass(EngineInterface::class); $mockRenderer->expects($this->atLeastOnce()) @@ -42,6 +45,7 @@ class RendererTest extends TestCase { $renderer = new Renderer(); + /** @var MockObject|LoggerInterface $loggerMock */ $loggerMock = $this->getMockForAbstractClass(LoggerInterface::class); $loggerMock ->expects($this->once()) diff --git a/tests/Unit/Routing/RoutingServiceProviderTest.php b/tests/Unit/Routing/RoutingServiceProviderTest.php index bb2a1d65..dd9441eb 100644 --- a/tests/Unit/Routing/RoutingServiceProviderTest.php +++ b/tests/Unit/Routing/RoutingServiceProviderTest.php @@ -1,6 +1,6 @@