diff options
Diffstat (limited to 'tests')
26 files changed, 1073 insertions, 120 deletions
diff --git a/tests/Feature/Database/DatabaseServiceProviderTest.php b/tests/Feature/Database/DatabaseServiceProviderTest.php new file mode 100644 index 00000000..d5fdd108 --- /dev/null +++ b/tests/Feature/Database/DatabaseServiceProviderTest.php @@ -0,0 +1,40 @@ +<?php + +namespace Engelsystem\Test\Feature\Database; + +use Engelsystem\Application; +use Engelsystem\Config\Config; +use Engelsystem\Database\DatabaseServiceProvider; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +class DatabaseServiceProviderTest extends DatabaseTest +{ + /** + * @covers \Engelsystem\Database\DatabaseServiceProvider::register() + */ + public function testRegister() + { + /** @var MockObject|Config $config */ + $config = $this->getMockBuilder(Config::class) + ->getMock(); + + /** @var MockObject|Application $app */ + $app = $this->getMockBuilder(Application::class) + ->setMethods(['get']) + ->getMock(); + Application::setInstance($app); + + $app->expects($this->once()) + ->method('get') + ->with('config') + ->willReturn($config); + + $config->expects($this->atLeastOnce()) + ->method('get') + ->with('database') + ->willReturn($this->getDbConfig()); + + $serviceProvider = new DatabaseServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Feature/Database/DatabaseTest.php b/tests/Feature/Database/DatabaseTest.php new file mode 100644 index 00000000..11df6779 --- /dev/null +++ b/tests/Feature/Database/DatabaseTest.php @@ -0,0 +1,25 @@ +<?php + +namespace Engelsystem\Test\Feature\Database; + +use PHPUnit\Framework\TestCase; + +abstract class DatabaseTest extends TestCase +{ + /** + * Returns the database config + * + * @return string[] + */ + protected function getDbConfig() + { + $configValues = require __DIR__ . '/../../../config/config.default.php'; + $configFile = __DIR__ . '/../../../config/config.php'; + + if (file_exists($configFile)) { + $configValues = array_replace_recursive($configValues, require $configFile); + } + + return $configValues['database']; + } +} diff --git a/tests/Feature/Logger/EngelsystemLoggerTest.php b/tests/Feature/Logger/EngelsystemLoggerTest.php index 63a01318..8886d4ba 100644 --- a/tests/Feature/Logger/EngelsystemLoggerTest.php +++ b/tests/Feature/Logger/EngelsystemLoggerTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test\Logger; +namespace Engelsystem\Test\Feature\Logger; use Engelsystem\Logger\EngelsystemLogger; use PHPUnit\Framework\TestCase; @@ -12,7 +12,7 @@ class EngelsystemLoggerTest extends TestCase { public static function setUpBeforeClass() { - require_once __DIR__ . '/../../../includes/engelsystem_provider.php'; + require_once __DIR__ . '/../../../includes/engelsystem.php'; } /** diff --git a/tests/Feature/model/LogEntriesModelTest.php b/tests/Feature/Model/LogEntriesModelTest.php index 6d7b0ebc..036f5692 100644 --- a/tests/Feature/model/LogEntriesModelTest.php +++ b/tests/Feature/Model/LogEntriesModelTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test; +namespace Engelsystem\Test\Feature\Model; use PHPUnit\Framework\TestCase; use Psr\Log\LogLevel; @@ -9,7 +9,7 @@ class LogEntriesModelTest extends TestCase { public static function setUpBeforeClass() { - require_once __DIR__ . '/../../../includes/engelsystem_provider.php'; + require_once __DIR__ . '/../../../includes/engelsystem.php'; } public function testCreateLogEntry() diff --git a/tests/Feature/model/RoomModelTest.php b/tests/Feature/Model/RoomModelTest.php index 96be84a2..3114ba2d 100644 --- a/tests/Feature/model/RoomModelTest.php +++ b/tests/Feature/Model/RoomModelTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test; +namespace Engelsystem\Test\Feature\Model; use PHPUnit\Framework\TestCase; @@ -10,7 +10,7 @@ class RoomModelTest extends TestCase public static function setUpBeforeClass() { - require_once __DIR__ . '/../../../includes/engelsystem_provider.php'; + require_once __DIR__ . '/../../../includes/engelsystem.php'; } public function create_Room() diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php index 77429f44..f58483ea 100644 --- a/tests/Unit/ApplicationTest.php +++ b/tests/Unit/ApplicationTest.php @@ -1,21 +1,25 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit; 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); @@ -24,6 +28,144 @@ 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()); } + + /** + * @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; + } } diff --git a/tests/Unit/Config/ConfigServiceProviderTest.php b/tests/Unit/Config/ConfigServiceProviderTest.php new file mode 100644 index 00000000..c8be4b7d --- /dev/null +++ b/tests/Unit/Config/ConfigServiceProviderTest.php @@ -0,0 +1,45 @@ +<?php + +namespace Engelsystem\Test\Unit\Config; + +use Engelsystem\Application; +use Engelsystem\Config\Config; +use Engelsystem\Config\ConfigServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject; + +class ConfigServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Config\ConfigServiceProvider::register() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|Config $config */ + $config = $this->getMockBuilder(Config::class) + ->getMock(); + + $app = $this->getApp(['make', 'instance', 'get']); + Application::setInstance($app); + + $this->setExpects($app, 'make', [Config::class], $config); + $this->setExpects($app, 'instance', ['config', $config]); + $this->setExpects($app, 'get', ['path.config'], __DIR__ . '/../../../config', $this->atLeastOnce()); + + $this->setExpects($config, 'set', null, null, $this->exactly(2)); + $this->setExpects($config, 'get', [null], []); + + $configFile = __DIR__ . '/../../../config/config.php'; + $configExists = file_exists($configFile); + if (!$configExists) { + file_put_contents($configFile, '<?php return [];'); + } + + $serviceProvider = new ConfigServiceProvider($app); + $serviceProvider->register(); + + if (!$configExists) { + unlink($configFile); + } + } +} diff --git a/tests/Unit/Config/ConfigTest.php b/tests/Unit/Config/ConfigTest.php index ce11ebd6..043599fd 100644 --- a/tests/Unit/Config/ConfigTest.php +++ b/tests/Unit/Config/ConfigTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit\Config; use Engelsystem\Config\Config; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Container/ContainerTest.php b/tests/Unit/Container/ContainerTest.php deleted file mode 100644 index 89c34209..00000000 --- a/tests/Unit/Container/ContainerTest.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php - -namespace Engelsystem\Test\Config; - -use Engelsystem\Container\Container; -use PHPUnit\Framework\TestCase; - -class ContainerTest extends TestCase -{ - /** - * @covers \Engelsystem\Container\Container::get - */ - public function testGet() - { - $container = new Container(); - $class = new class - { - }; - - $container->instance('foo', $class); - $this->assertSame($class, $container->get('foo')); - } - - /** - * @covers \Engelsystem\Container\Container::get - * @expectedException \Engelsystem\Container\NotFoundException - */ - public function testGetException() - { - $container = new Container(); - - $container->get('not.registered.service'); - } - - /** - * @covers \Engelsystem\Container\Container::instance - * @covers \Engelsystem\Container\Container::resolve - */ - public function testInstance() - { - $container = new Container(); - $class = new class - { - }; - - $container->instance('foo', $class); - $this->assertSame($class, $container->get('foo')); - } - - /** - * @covers \Engelsystem\Container\Container::has - */ - public function testHas() - { - $container = new Container(); - - $this->assertFalse($container->has('test')); - - $class = new class - { - }; - - $container->instance('test', $class); - $this->assertTrue($container->has('test')); - } - - /** - * @covers \Engelsystem\Container\Container::singleton - */ - public function testSingleton() - { - $container = new Container(); - $class = new class - { - }; - - $container->singleton('foo', $class); - $this->assertSame($class, $container->get('foo')); - $this->assertSame($class, $container->get('foo')); - } - - /** - * @covers \Engelsystem\Container\Container::setInstance - * @covers \Engelsystem\Container\Container::getInstance - */ - public function testContainerSingleton() - { - // Ensure that no container has been initialized - $reflection = new \ReflectionProperty(Container::class, 'instance'); - $reflection->setAccessible(true); - $reflection->setValue(null, null); - $reflection->setAccessible(false); - - $container0 = new Container(); - $container = Container::getInstance(); - - $this->assertNotSame($container0, $container); - - $container1 = new Container; - Container::setInstance($container1); - - $this->assertSame($container1, Container::getInstance()); - } -} diff --git a/tests/Unit/Container/ServiceProviderTest.php b/tests/Unit/Container/ServiceProviderTest.php new file mode 100644 index 00000000..8a9cb76e --- /dev/null +++ b/tests/Unit/Container/ServiceProviderTest.php @@ -0,0 +1,22 @@ +<?php + +namespace Engelsystem\Test\Unit\Container; + +use Engelsystem\Container\ServiceProvider; +use Engelsystem\Test\Unit\Container\Stub\ServiceProviderImplementation; +use Engelsystem\Test\Unit\ServiceProviderTest; + +class ConfigServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Container\ServiceProvider::__construct + */ + public function testRegister() + { + $app = $this->getApp(); + + $serviceProvider = new ServiceProviderImplementation($app); + + $this->assertInstanceOf(ServiceProvider::class, $serviceProvider); + } +} diff --git a/tests/Unit/Container/Stub/ServiceProviderImplementation.php b/tests/Unit/Container/Stub/ServiceProviderImplementation.php new file mode 100644 index 00000000..36ae2c38 --- /dev/null +++ b/tests/Unit/Container/Stub/ServiceProviderImplementation.php @@ -0,0 +1,10 @@ +<?php + +namespace Engelsystem\Test\Unit\Container\Stub; + +use Engelsystem\Container\ServiceProvider; + +class ServiceProviderImplementation extends ServiceProvider +{ + +} diff --git a/tests/Unit/Database/DatabaseServiceProviderTest.php b/tests/Unit/Database/DatabaseServiceProviderTest.php new file mode 100644 index 00000000..61848c35 --- /dev/null +++ b/tests/Unit/Database/DatabaseServiceProviderTest.php @@ -0,0 +1,37 @@ +<?php + +namespace Engelsystem\Test\Unit\Database; + +use Engelsystem\Config\Config; +use Engelsystem\Database\DatabaseServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use Exception; +use PHPUnit_Framework_MockObject_MockObject; + +class DatabaseServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Database\DatabaseServiceProvider::register() + * @covers \Engelsystem\Database\DatabaseServiceProvider::exitOnError() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|Config $config */ + $config = $this->getMockBuilder(Config::class) + ->getMock(); + + $app = $this->getApp(['get']); + + $this->setExpects($app, 'get', ['config'], $config); + $this->setExpects($config, 'get', ['database'], [ + 'host' => 'localhost', + 'db' => 'database', + 'user' => 'user', + 'pw' => 'password', + ], $this->atLeastOnce()); + $this->expectException(Exception::class); + + $serviceProvider = new DatabaseServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/Database/DbTest.php b/tests/Unit/Database/DbTest.php new file mode 100644 index 00000000..63607cad --- /dev/null +++ b/tests/Unit/Database/DbTest.php @@ -0,0 +1,192 @@ +<?php + +namespace Engelsystem\Test\Unit\Database; + +use Engelsystem\Database\Db; +use PDO; +use PDOStatement; +use PHPUnit\Framework\TestCase; +use ReflectionObject; +use Throwable; + +class DbTest extends TestCase +{ + /** + * @covers \Engelsystem\Database\Db::connect() + */ + public function testConnect() + { + $result = Db::connect('mysql:host=localhost;dbname=someTestDatabaseThatDoesNotExist;charset=utf8'); + $this->assertFalse($result); + + $result = Db::connect('sqlite::memory:'); + $this->assertTrue($result); + } + + /** + * @covers \Engelsystem\Database\Db::query() + */ + public function testQuery() + { + $stm = Db::query('SELECT * FROM test_data'); + $this->assertEquals('00000', $stm->errorCode()); + + $stm = Db::query('SELECT * FROM test_data WHERE id = ?', [4]); + $this->assertEquals('00000', $stm->errorCode()); + } + + /** + * @covers \Engelsystem\Database\Db::unprepared() + */ + public function testUnprepared() + { + $return = Db::unprepared('SELECT * FROM test_data WHERE id = 3'); + $this->assertTrue($return); + } + + /** + * @covers \Engelsystem\Database\Db::select() + */ + public function testSelect() + { + $return = Db::select('SELECT * FROM test_data'); + $this->assertTrue(count($return) > 3); + + $return = Db::select('SELECT * FROM test_data WHERE id = ?', [2]); + $this->assertCount(1, $return); + } + + /** + * @covers \Engelsystem\Database\Db::selectOne() + */ + public function testSelectOne() + { + $return = Db::selectOne('SELECT * FROM test_data'); + $this->assertEquals('Foo', $return['data']); + + $return = Db::selectOne('SELECT * FROM test_data WHERE id = -1'); + $this->assertEmpty($return); + + $return = Db::selectOne('SELECT * FROM test_data WHERE id = ?', [3]); + $return = array_pop($return); + $this->assertTrue(!is_array($return)); + } + + /** + * @covers \Engelsystem\Database\Db::insert() + */ + public function testInsert() + { + $count = Db::insert("INSERT INTO test_data (id, data) VALUES (5, 'Some random text'), (6, 'another text')"); + $this->assertEquals(2, $count); + + $count = Db::insert('INSERT INTO test_data(id, data) VALUES (:id, :alias)', ['id' => 7, 'alias' => 'Blafoo']); + $this->assertEquals(1, $count); + } + + /** + * @covers \Engelsystem\Database\Db::update() + */ + public function testUpdate() + { + $count = Db::update("UPDATE test_data SET data='NOPE' WHERE data LIKE '%Replaceme%'"); + $this->assertEquals(3, $count); + + $count = Db::update("UPDATE test_data SET data=? WHERE data LIKE '%NOPE%'", ['Some random text!']); + $this->assertEquals(3, $count); + } + + /** + * @covers \Engelsystem\Database\Db::delete() + */ + public function testDelete() + { + $count = Db::delete('DELETE FROM test_data WHERE id=1'); + $this->assertEquals(1, $count); + + $count = Db::delete('DELETE FROM test_data WHERE data LIKE ?', ['%Replaceme%']); + $this->assertEquals(3, $count); + } + + /** + * @covers \Engelsystem\Database\Db::statement() + */ + public function testStatement() + { + $return = Db::statement('SELECT * FROM test_data WHERE id = 3'); + $this->assertTrue($return); + + $return = Db::statement('SELECT * FROM test_data WHERE id = ?', [2]); + $this->assertTrue($return); + } + + /** + * @covers \Engelsystem\Database\Db::getError() + */ + public function testGetError() + { + try { + Db::statement('foo'); + } catch (Throwable $e) { + } + + $error = Db::getError(); + $this->assertTrue(is_array($error)); + $this->assertEquals('near "foo": syntax error', $error[2]); + + $db = new Db(); + $refObject = new ReflectionObject($db); + $refProperty = $refObject->getProperty('stm'); + $refProperty->setAccessible(true); + $refProperty->setValue(null, null); + + $error = Db::getError(); + $this->assertEquals([-1, null, null], $error); + } + + /** + * @covers \Engelsystem\Database\Db::getPdo() + */ + public function testGetPdo() + { + $pdo = Db::getPdo(); + $this->assertInstanceOf(PDO::class, $pdo); + } + + /** + * @covers \Engelsystem\Database\Db::getStm() + */ + public function testGetStm() + { + $stm = Db::getStm(); + $this->assertInstanceOf(PDOStatement::class, $stm); + } + + /** + * Setup in memory database + */ + protected function setUp() + { + Db::connect('sqlite::memory:'); + Db::getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + Db::query( + ' + CREATE TABLE test_data( + id INT PRIMARY KEY NOT NULL, + data TEXT NOT NULL + ); + '); + Db::query('CREATE UNIQUE INDEX test_data_id_uindex ON test_data (id);'); + Db::insert(" + INSERT INTO test_data (id, data) + VALUES + (1, 'Foo'), + (2, 'Bar'), + (3, 'Batz'), + (4, 'Lorem ipsum dolor sit'), + (10, 'Replaceme ipsum dolor sit amet'), + (11, 'Lorem Replaceme dolor sit amet'), + (12, 'Lorem ipsum Replaceme sit amet') + ;"); + } +} diff --git a/tests/Unit/Exceptions/ExceptionsServiceProviderTest.php b/tests/Unit/Exceptions/ExceptionsServiceProviderTest.php new file mode 100644 index 00000000..9c943d52 --- /dev/null +++ b/tests/Unit/Exceptions/ExceptionsServiceProviderTest.php @@ -0,0 +1,29 @@ +<?php + +namespace Engelsystem\Test\Unit\Exceptions; + +use Engelsystem\Exceptions\ExceptionsServiceProvider; +use Engelsystem\Exceptions\Handler as ExceptionHandler; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject; + +class ExceptionsServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Exceptions\ExceptionsServiceProvider::register() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|ExceptionHandler $exceptionHandler */ + $exceptionHandler = $this->getMockBuilder(ExceptionHandler::class) + ->getMock(); + + $app = $this->getApp(); + + $this->setExpects($app, 'make', [ExceptionHandler::class], $exceptionHandler); + $this->setExpects($app, 'instance', ['error.handler', $exceptionHandler]); + + $serviceProvider = new ExceptionsServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php index d9782888..0a8d5d2b 100644 --- a/tests/Unit/HelpersTest.php +++ b/tests/Unit/HelpersTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit; use Engelsystem\Application; use Engelsystem\Config\Config; @@ -9,6 +9,7 @@ use Engelsystem\Http\Request; use Engelsystem\Renderer\Renderer; use Engelsystem\Routing\UrlGenerator; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; use Symfony\Component\HttpFoundation\Session\Session; class HelpersTest extends TestCase @@ -29,6 +30,25 @@ class HelpersTest extends TestCase } /** + * @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 */ public function testConfig() @@ -54,6 +74,39 @@ class HelpersTest extends TestCase } /** + * @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 + */ + public function testEnv() + { + putenv('envTestVar=someContent'); + + $env = env('envTestVar'); + $this->assertEquals('someContent', $env); + + $env = env('someRandomEnvVarThatShouldNeverExist', 'someDefaultValue'); + $this->assertEquals('someDefaultValue', $env); + } + + /** * @covers \request */ public function testRequest() @@ -132,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/Http/RequestServiceProviderTest.php b/tests/Unit/Http/RequestServiceProviderTest.php new file mode 100644 index 00000000..a137b0ac --- /dev/null +++ b/tests/Unit/Http/RequestServiceProviderTest.php @@ -0,0 +1,29 @@ +<?php + +namespace Engelsystem\Test\Unit\Http; + +use Engelsystem\Http\Request; +use Engelsystem\Http\RequestServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +class RequestServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Http\RequestServiceProvider::register() + */ + public function testRegister() + { + /** @var MockObject|Request $request */ + $request = $this->getMockBuilder(Request::class) + ->getMock(); + + $app = $this->getApp(['call', 'instance']); + + $this->setExpects($app, 'call', [[Request::class, 'createFromGlobals']], $request); + $this->setExpects($app, 'instance', ['request', $request]); + + $serviceProvider = new RequestServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/Http/RequestTest.php b/tests/Unit/Http/RequestTest.php new file mode 100644 index 00000000..3f317367 --- /dev/null +++ b/tests/Unit/Http/RequestTest.php @@ -0,0 +1,98 @@ +<?php + +namespace Engelsystem\Test\Unit\Http; + +use Engelsystem\Http\Request; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +class RequestTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Request::postData + */ + public function testPostData() + { + $request = new Request( + ['foo' => 'I\'m a test!'], + ['foo' => 'bar'] + ); + + $this->assertEquals('bar', $request->postData('foo')); + $this->assertEquals('LoremIpsum', $request->postData('test-key', 'LoremIpsum')); + } + + /** + * @covers \Engelsystem\Http\Request::input + */ + public function testInput() + { + $request = new Request( + ['foo' => 'I\'m a test!'], + ['foo' => 'bar'] + ); + + $this->assertEquals('I\'m a test!', $request->input('foo')); + $this->assertEquals('LoremIpsum', $request->input('test-key', 'LoremIpsum')); + } + + /** + * @covers \Engelsystem\Http\Request::has + */ + public function testHas() + { + $request = new Request([ + 'foo' => 'I\'m a test!', + 'bar' => '', + ]); + + $this->assertTrue($request->has('foo')); + $this->assertFalse($request->has('bar')); + } + + /** + * @covers \Engelsystem\Http\Request::path + */ + public function testPath() + { + /** @var MockObject|Request $request */ + $request = $this + ->getMockBuilder(Request::class) + ->setMethods(['getPathInfo']) + ->getMock(); + + $request + ->expects($this->atLeastOnce()) + ->method('getPathInfo') + ->willReturnOnConsecutiveCalls( + '/foo', + '/' + ); + + $this->assertEquals('foo', $request->path()); + $this->assertEquals('/', $request->path()); + } + + /** + * @covers \Engelsystem\Http\Request::url + */ + public function testUrl() + { + /** @var MockObject|Request $request */ + $request = $this + ->getMockBuilder(Request::class) + ->setMethods(['getUri']) + ->getMock(); + + $request + ->expects($this->atLeastOnce()) + ->method('getUri') + ->willReturnOnConsecutiveCalls( + 'http://foo.bar/bla/foo/', + 'https://lorem.ipsum/dolor/sit?amet=consetetur&sadipscing=elitr' + ); + + $this->assertEquals('http://foo.bar/bla/foo', $request->url()); + $this->assertEquals('https://lorem.ipsum/dolor/sit', $request->url()); + } +} diff --git a/tests/Unit/Http/SessionServiceProviderTest.php b/tests/Unit/Http/SessionServiceProviderTest.php new file mode 100644 index 00000000..0f17a1af --- /dev/null +++ b/tests/Unit/Http/SessionServiceProviderTest.php @@ -0,0 +1,126 @@ +<?php + +namespace Engelsystem\Test\Unit\Http; + +use Engelsystem\Http\Request; +use Engelsystem\Http\SessionServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; +use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface as StorageInterface; + +class SessionServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Http\SessionServiceProvider::register() + * @covers \Engelsystem\Http\SessionServiceProvider::getSessionStorage() + */ + public function testRegister() + { + $app = $this->getApp(['make', 'instance', 'bind', 'get']); + + $sessionStorage = $this->getMockForAbstractClass(StorageInterface::class); + $sessionStorage2 = $this->getMockForAbstractClass(StorageInterface::class); + + $session = $this->getSessionMock(); + $request = $this->getRequestMock(); + + /** @var MockObject|SessionServiceProvider $serviceProvider */ + $serviceProvider = $this->getMockBuilder(SessionServiceProvider::class) + ->setConstructorArgs([$app]) + ->setMethods(['isCli']) + ->getMock(); + $serviceProvider->expects($this->exactly(2)) + ->method('isCli') + ->willReturnOnConsecutiveCalls(true, false); + + $app->expects($this->exactly(4)) + ->method('make') + ->withConsecutive( + [MockArraySessionStorage::class], + [Session::class], + [NativeSessionStorage::class, ['options' => ['cookie_httponly' => true]]], + [Session::class] + ) + ->willReturnOnConsecutiveCalls( + $sessionStorage, + $session, + $sessionStorage2, + $session + ); + $app->expects($this->atLeastOnce()) + ->method('instance') + ->withConsecutive( + ['session.storage', $sessionStorage], + ['session', $session] + ); + + $this->setExpects($app, 'bind', [StorageInterface::class, 'session.storage'], null, $this->atLeastOnce()); + $this->setExpects($app, 'get', ['request'], $request, $this->atLeastOnce()); + $this->setExpects($request, 'setSession', [$session], null, $this->atLeastOnce()); + $this->setExpects($session, 'start', null, null, $this->atLeastOnce()); + + $serviceProvider->register(); + $serviceProvider->register(); + } + + /** + * @covers \Engelsystem\Http\SessionServiceProvider::isCli() + */ + public function testIsCli() + { + $app = $this->getApp(['make', 'instance', 'bind', 'get']); + + $sessionStorage = $this->getMockForAbstractClass(StorageInterface::class); + + $session = $this->getSessionMock(); + $request = $this->getRequestMock(); + + $app->expects($this->exactly(2)) + ->method('make') + ->withConsecutive( + [MockArraySessionStorage::class], + [Session::class] + ) + ->willReturnOnConsecutiveCalls( + $sessionStorage, + $session + ); + $app->expects($this->exactly(2)) + ->method('instance') + ->withConsecutive( + ['session.storage', $sessionStorage], + ['session', $session] + ); + + $this->setExpects($app, 'bind', [StorageInterface::class, 'session.storage']); + $this->setExpects($app, 'get', ['request'], $request); + $this->setExpects($request, 'setSession', [$session]); + $this->setExpects($session, 'start'); + + $serviceProvider = new SessionServiceProvider($app); + $serviceProvider->register(); + } + + /** + * @return MockObject + */ + private function getSessionMock() + { + return $this->getMockBuilder(Session::class) + ->setMethods(['start']) + ->getMock(); + } + + /** + * @return MockObject + */ + private function getRequestMock() + { + return $this->getMockBuilder(Request::class) + ->setMethods(['setSession']) + ->getMock(); + } +} diff --git a/tests/Unit/Logger/LoggerServiceProviderTest.php b/tests/Unit/Logger/LoggerServiceProviderTest.php new file mode 100644 index 00000000..cef95d5b --- /dev/null +++ b/tests/Unit/Logger/LoggerServiceProviderTest.php @@ -0,0 +1,37 @@ +<?php + +namespace Engelsystem\Test\Unit\Logger; + +use Engelsystem\Logger\EngelsystemLogger; +use Engelsystem\Logger\LoggerServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject; +use Psr\Log\LoggerInterface; + +class LoggerServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Logger\LoggerServiceProvider::register() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|EngelsystemLogger $logger */ + $logger = $this->getMockBuilder(EngelsystemLogger::class) + ->getMock(); + + $app = $this->getApp(['make', 'instance', 'bind']); + + $this->setExpects($app, 'make', [EngelsystemLogger::class], $logger); + $this->setExpects($app, 'instance', ['logger', $logger]); + + $app->expects($this->atLeastOnce()) + ->method('bind') + ->withConsecutive( + [LoggerInterface::class, 'logger'], + [EngelsystemLogger::class, 'logger'] + ); + + $serviceProvider = new LoggerServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/Renderer/HtmlEngineTest.php b/tests/Unit/Renderer/HtmlEngineTest.php index 0b317b72..8c262932 100644 --- a/tests/Unit/Renderer/HtmlEngineTest.php +++ b/tests/Unit/Renderer/HtmlEngineTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit\Renderer; use Engelsystem\Renderer\HtmlEngine; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Renderer/RendererServiceProviderTest.php b/tests/Unit/Renderer/RendererServiceProviderTest.php new file mode 100644 index 00000000..3826da7e --- /dev/null +++ b/tests/Unit/Renderer/RendererServiceProviderTest.php @@ -0,0 +1,81 @@ +<?php + +namespace Engelsystem\Test\Unit\Renderer; + +use Engelsystem\Renderer\EngineInterface; +use Engelsystem\Renderer\HtmlEngine; +use Engelsystem\Renderer\Renderer; +use Engelsystem\Renderer\RendererServiceProvider; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject; + +class RendererServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Renderer\RendererServiceProvider::register() + * @covers \Engelsystem\Renderer\RendererServiceProvider::registerRenderer() + * @covers \Engelsystem\Renderer\RendererServiceProvider::registerHtmlEngine() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|Renderer $renderer */ + $renderer = $this->getMockBuilder(Renderer::class) + ->getMock(); + /** @var PHPUnit_Framework_MockObject_MockObject|HtmlEngine $htmlEngine */ + $htmlEngine = $this->getMockBuilder(HtmlEngine::class) + ->getMock(); + + $app = $this->getApp(['make', 'instance', 'tag']); + + $app->expects($this->exactly(2)) + ->method('make') + ->withConsecutive( + [Renderer::class], + [HtmlEngine::class] + )->willReturnOnConsecutiveCalls( + $renderer, + $htmlEngine + ); + + $app->expects($this->exactly(2)) + ->method('instance') + ->withConsecutive( + ['renderer', $renderer], + ['renderer.htmlEngine', $htmlEngine] + ); + + $this->setExpects($app, 'tag', ['renderer.htmlEngine', ['renderer.engine']]); + + $serviceProvider = new RendererServiceProvider($app); + $serviceProvider->register(); + } + + /** + * @covers \Engelsystem\Renderer\RendererServiceProvider::boot() + */ + public function testBoot() + { + /** @var PHPUnit_Framework_MockObject_MockObject|Renderer $renderer */ + $renderer = $this->getMockBuilder(Renderer::class) + ->getMock(); + /** @var PHPUnit_Framework_MockObject_MockObject|EngineInterface $engine1 */ + $engine1 = $this->getMockForAbstractClass(EngineInterface::class); + /** @var PHPUnit_Framework_MockObject_MockObject|EngineInterface $engine2 */ + $engine2 = $this->getMockForAbstractClass(EngineInterface::class); + + $app = $this->getApp(['get', 'tagged']); + + $engines = [$engine1, $engine2]; + + $this->setExpects($app, 'get', ['renderer'], $renderer); + $this->setExpects($app, 'tagged', ['renderer.engine'], $engines); + + $invocation = $renderer + ->expects($this->exactly(count($engines))) + ->method('addRenderer'); + call_user_func_array([$invocation, 'withConsecutive'], $engines); + + $serviceProvider = new RendererServiceProvider($app); + $serviceProvider->boot(); + } +} diff --git a/tests/Unit/Renderer/RendererTest.php b/tests/Unit/Renderer/RendererTest.php index b0238078..969ced7f 100644 --- a/tests/Unit/Renderer/RendererTest.php +++ b/tests/Unit/Renderer/RendererTest.php @@ -1,10 +1,11 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit\Renderer; use Engelsystem\Renderer\EngineInterface; use Engelsystem\Renderer\Renderer; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; use Psr\Log\LoggerInterface; class RendererTest extends TestCase @@ -13,6 +14,7 @@ class RendererTest extends TestCase { $renderer = new Renderer(); + /** @var MockObject|EngineInterface $nullRenderer */ $nullRenderer = $this->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 new file mode 100644 index 00000000..dd9441eb --- /dev/null +++ b/tests/Unit/Routing/RoutingServiceProviderTest.php @@ -0,0 +1,29 @@ +<?php + +namespace Engelsystem\Test\Unit\Routing; + +use Engelsystem\Routing\RoutingServiceProvider; +use Engelsystem\Routing\UrlGenerator; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit_Framework_MockObject_MockObject; + +class RoutingServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Routing\RoutingServiceProvider::register() + */ + public function testRegister() + { + /** @var PHPUnit_Framework_MockObject_MockObject|UrlGenerator $urlGenerator */ + $urlGenerator = $this->getMockBuilder(UrlGenerator::class) + ->getMock(); + + $app = $this->getApp(); + + $this->setExpects($app, 'make', [UrlGenerator::class], $urlGenerator); + $this->setExpects($app, 'instance', ['routing.urlGenerator', $urlGenerator]); + + $serviceProvider = new RoutingServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/Routing/UrlGeneratorTest.php b/tests/Unit/Routing/UrlGeneratorTest.php index fc23520a..6da59a4f 100644 --- a/tests/Unit/Routing/UrlGeneratorTest.php +++ b/tests/Unit/Routing/UrlGeneratorTest.php @@ -1,6 +1,6 @@ <?php -namespace Engelsystem\Test\Config; +namespace Engelsystem\Test\Unit\Routing; use Engelsystem\Application; use Engelsystem\Container\Container; diff --git a/tests/Unit/ServiceProviderTest.php b/tests/Unit/ServiceProviderTest.php new file mode 100644 index 00000000..dc58a65e --- /dev/null +++ b/tests/Unit/ServiceProviderTest.php @@ -0,0 +1,50 @@ +<?php + +namespace Engelsystem\Test\Unit; + +use Engelsystem\Application; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_Matcher_InvokedRecorder as InvokedRecorder; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +abstract class ServiceProviderTest extends TestCase +{ + /** + * @param array $methods + * @return Application|MockObject + */ + protected function getApp($methods = ['make', 'instance']) + { + /** @var MockObject|Application $app */ + return $this->getMockBuilder(Application::class) + ->setMethods($methods) + ->getMock(); + } + + /** + * @param MockObject $object + * @param string $method + * @param array $arguments + * @param mixed $return + * @param InvokedRecorder $times + */ + protected function setExpects($object, $method, $arguments = null, $return = null, $times = null) + { + if (is_null($times)) { + $times = $this->once(); + } + + $invocation = $object->expects($times) + ->method($method); + + if (is_null($arguments)) { + $invocation->withAnyParameters(); + } else { + call_user_func_array([$invocation, 'with'], $arguments); + } + + if (!is_null($return)) { + $invocation->willReturn($return); + } + } +} diff --git a/tests/autoload.php b/tests/autoload.php new file mode 100644 index 00000000..3168ce3d --- /dev/null +++ b/tests/autoload.php @@ -0,0 +1,8 @@ +<?php + +use Composer\Autoload\ClassLoader; + +require_once __DIR__ . '/../includes/autoload.php'; + +/** @var $loader ClassLoader */ +$loader->addPsr4('Engelsystem\\Test\\', __DIR__ . '/'); |