diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml new file mode 100644 index 0000000..8f5a47b --- /dev/null +++ b/.github/workflows/lint-php.yml @@ -0,0 +1,30 @@ +name: Lint PHP +on: [push, pull_request] + +jobs: + php-cs-fixer: + name: PHP-CS-Fixer + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Action + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHP-CS-Fixer + run: | + docker-compose run web \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/php-cs-fixer fix --dry-run + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Action + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHPStan + run: | + docker-compose run web \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/phpstan analyse src/ test/ bin diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..fdbca73 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,61 @@ +name: Test +on: [push, pull_request] +jobs: + ingest: + name: PHPUnit/Ingest + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Install + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHPUnit + run: | + docker-compose run web \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/paratest \ + --testsuite=Ingest + + human: + name: PHPUnit/Human + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Install + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHPUnit + run: | + docker-compose run test \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/phpunit \ + --testsuite=Human + + models: + name: PHPUnit/Models + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Install + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHPUnit + run: | + docker-compose run test \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/phpunit \ + --testsuite=Models + services: + name: PHPUnit/Services + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + - name: Composer Install + run: docker run -v $PWD/:/app gone/php:cli-7.4 /usr/local/bin/composer install + - name: PHPUnit + run: | + docker-compose run test \ + phpdbg -qrr -d memory_limit=-1 \ + vendor/bin/phpunit \ + --testsuite=Services diff --git a/.gitignore b/.gitignore index e30f107..1c2f231 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ vendor/ .php_cs.cache docs phploc.xml -cghooks.lock \ No newline at end of file +cghooks.lock +/.php-cs-fixer.cache +/.coverage +/phpunit.xml \ No newline at end of file diff --git a/composer.json b/composer.json index 43249f1..e7532cd 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "sort-packages": true }, "require": { - "php": ">=8.0", + "php": ">=8.2", "ext-apcu": "*", "ext-curl": "*", "ext-iconv": "*", @@ -62,6 +62,7 @@ "slim/twig-view": "^3.2", "squizlabs/php_codesniffer": "3.*", "swaggest/json-schema": "^0.12.39", + "symfony/polyfill-intl-icu": "^1.29", "symfony/translation": "^5.1", "symfony/twig-bridge": "^5.1", "symfony/yaml": "^5.1", @@ -91,7 +92,11 @@ }, "autoload": { "psr-4": { - "Benzine\\": "src", + "Benzine\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { "Benzine\\Tests\\": "tests/" } }, diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2816c7b --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" + bootstrap="tests/bootstrap.php" + enforceTimeLimit="true" + defaultTimeLimit="3" + executionOrder="depends,defects" + cacheResult="true" + cacheResultFile=".phpunit.result.cache" + testdox="true" + colors="true" + failOnRisky="true" + failOnWarning="true" + failOnIncomplete="false" + failOnSkipped="false" + failOnDeprecation="true" + failOnEmptyTestSuite="true" + failOnNotice="true" + displayDetailsOnSkippedTests="true" + displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnTestsThatTriggerErrors="true" + displayDetailsOnTestsThatTriggerNotices="true" + displayDetailsOnTestsThatTriggerWarnings="true" + beStrictAboutOutputDuringTests="true" + stopOnDefect="false" +> + <php> + <ini name="memory_limit" value="128M" /> + <ini name="display_errors" value="On"/> + <ini name="display_startup_errors" value="On"/> + <ini name="error_reporting" value="E_ALL"/> + <env name="BENZINE_CONFIG_PATH" value="tests/.benzine.yml"/> + <env name="XDEBUG_MODE" value="coverage"/> + </php> + <coverage includeUncoveredFiles="true" cacheDirectory=".coverage/cache"> + <report> + <clover outputFile=".coverage/clover.xml"/> + <html outputDirectory=".coverage/html"/> + <text outputFile="php://stdout" showOnlySummary="true"/> + </report> + </coverage> + <extensions> + <bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension"/> + </extensions> + <testsuites> + <testsuite name="Test Suite"> + <directory>./tests/</directory> + </testsuite> + </testsuites> + <source> + <include> + <directory suffix=".php">src</directory> + </include> + <exclude> + <directory suffix=".php">src/Fixtures</directory> + </exclude> + </source> +</phpunit> diff --git a/src/Services/EnvironmentService.php b/src/Services/EnvironmentService.php index 34e3dcd..5f781a7 100644 --- a/src/Services/EnvironmentService.php +++ b/src/Services/EnvironmentService.php @@ -26,7 +26,7 @@ class EnvironmentService return $this->environmentVariables; } - public function get(string $key, ?string $default = null) + public function get(string $key, mixed $default = null) { if (isset($this->environmentVariables[$key])) { return $this->environmentVariables[$key]; diff --git a/src/Services/SessionService.php b/src/Services/SessionService.php index 16f2424..014a113 100644 --- a/src/Services/SessionService.php +++ b/src/Services/SessionService.php @@ -55,24 +55,24 @@ class SessionService implements \SessionHandlerInterface session_start(); } - public function close() + public function close(): bool { return true; } - public function destroy($session_id) + public function destroy(string $id): bool { - $this->oldID = $session_id; + $this->oldID = $id; return true; } - public function gc($maxlifetime) + public function gc(int $max_lifetime): false | int { - return true; + return 0; } - public function open($save_path, $name) + public function open(string $path, string $name): bool { return true; } @@ -86,25 +86,23 @@ class SessionService implements \SessionHandlerInterface return $this->redisIsAvailable; } - public function read($session_id) + public function read(string $id): false | string { if ($this->useAPCU()) { - if (apcu_exists('read-' . $session_id)) { - return apcu_fetch('read-' . $session_id); + if (apcu_exists('read-' . $id)) { + return apcu_fetch('read-' . $id); } } - if (!empty($this->oldID)) { - $session_id = $this->oldID ? $this->oldID : $session_id; - } + $id = !empty($this->oldID) ? $this->oldID : $id; $result = ''; if ($this->useRedis()) { - $serialised = $this->redis->get("session:{$session_id}"); + $serialised = $this->redis->get("session:{$id}"); if (null != $serialised) { if (!empty($this->oldID)) { // clean up old session after regenerate - $this->redis->del("session:{$session_id}"); + $this->redis->del("session:{$id}"); $this->oldID = null; } $result = unserialize($serialised); @@ -112,9 +110,9 @@ class SessionService implements \SessionHandlerInterface } if ($this->useAPCU()) { - apcu_store('read-' . $session_id, $result, 30); + apcu_store('read-' . $id, $result, 30); } else { - $this->dirtyCheck['read-' . $session_id] = crc32($result); + $this->dirtyCheck['read-' . $id] = crc32($result); } return $result; diff --git a/tests/.benzine.yml b/tests/.benzine.yml new file mode 100644 index 0000000..78d4250 --- /dev/null +++ b/tests/.benzine.yml @@ -0,0 +1,6 @@ +application: + name: Core Self Test App + core: Benzine\Tests\TestApp + default_access: public + debug: true + root: /app/tests diff --git a/tests/AbstractCoreTest.php b/tests/AbstractCoreTest.php new file mode 100644 index 0000000..c0c3471 --- /dev/null +++ b/tests/AbstractCoreTest.php @@ -0,0 +1,18 @@ +<?php + +declare(strict_types=1); + +namespace Benzine\Tests; + +use Benzine\App; + +abstract class AbstractCoreTest extends AbstractTestCase +{ + protected App $app; + + public function setUp(): void + { + parent::setUp(); + $this->app = new TestApp(); + } +} diff --git a/tests/Dependencies/Monolog/MonologTest.php b/tests/Dependencies/Monolog/MonologTest.php new file mode 100644 index 0000000..f71813b --- /dev/null +++ b/tests/Dependencies/Monolog/MonologTest.php @@ -0,0 +1,23 @@ +<?php + +declare(strict_types=1); + +namespace Benzine\Tests\Dependencies\Monolog; + +use Benzine\Tests\AbstractCoreTest; +use Monolog\Logger; +use Psr\Log\LoggerInterface; + +/** + * @internal + * + * @coversNothing + */ +class MonologTest extends AbstractCoreTest +{ + public function testMonolog(): void + { + $logger = $this->app->get(Logger::class); + $this->assertInstanceOf(LoggerInterface::class, $logger); + } +} diff --git a/tests/TestApp.php b/tests/TestApp.php new file mode 100644 index 0000000..6e33ef0 --- /dev/null +++ b/tests/TestApp.php @@ -0,0 +1,9 @@ +<?php + +declare(strict_types=1); + +namespace Benzine\Tests; + +use Benzine\App; + +class TestApp extends App {} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..e895da4 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,8 @@ +<?php + +declare(strict_types=1); + +ini_set('xdebug.mode=coverage', 'on'); +define('APP_ROOT', __DIR__ . '/..'); + +require_once APP_ROOT . '/vendor/autoload.php';