From 0b91f9a2a011165523b60a32e7e1d87681c0df9f Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 15 Mar 2026 19:00:28 -0400 Subject: [PATCH 01/12] composer require flightphp/container:^1.3 --dev -W --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ae0925e..562624b 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ }, "require-dev": { "ext-pdo_sqlite": "*", - "flightphp/container": "^1.0", + "flightphp/container": "^1.3", "flightphp/runway": "^1.2", "league/container": "^4.2", "level-2/dice": "^4.0", From b2ad4cada878017f92e5f596d7c0df76abb7387e Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 15 Mar 2026 19:00:59 -0400 Subject: [PATCH 02/12] composer require squizlabs/php_codesniffer:^4.0 --dev -W --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 562624b..8c85fa0 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^9.6", "rregeer/phpunit-coverage-check": "^0.3.1", - "squizlabs/php_codesniffer": "^3.11" + "squizlabs/php_codesniffer": "^4.0" }, "config": { "allow-plugins": { @@ -97,4 +97,4 @@ "replace": { "mikecao/flight": "2.0.2" } -} \ No newline at end of file +} From 17b300680dbe39079bbf09197f5992586e00c0b0 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 16 Mar 2026 22:31:40 -0400 Subject: [PATCH 03/12] apply lsp-intelephense format to flight folder --- flight/net/UploadedFile.php | 2 +- phpcs.xml.dist | 58 ++++++++----------------------------- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/flight/net/UploadedFile.php b/flight/net/UploadedFile.php index c2f3ad3..a8868be 100644 --- a/flight/net/UploadedFile.php +++ b/flight/net/UploadedFile.php @@ -154,7 +154,7 @@ class UploadedFile $uploadFunctionToCall = $isUploadedFile === true ? // Standard POST upload - use move_uploaded_file for security 'move_uploaded_file' : - // Handle non-POST uploads (PATCH, PUT, DELETE) or other valid temp files + // Handle non-POST uploads (PATCH, PUT, DELETE) or other valid temp files 'rename'; $result = $uploadFunctionToCall($this->tmpName, $targetPath); diff --git a/phpcs.xml.dist b/phpcs.xml.dist index e320c09..e21e213 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,54 +1,20 @@ - - Created with the PHP Coding Standard Generator. - http://edorian.github.io/php-coding-standard-generator/ - + xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"> + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - flight/ - tests/ - tests/views/* + + index.php + flight + tests From 85c4b3885860ccb9c6fac6e9a3f25c94151bcc7e Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 16 Mar 2026 22:46:50 -0400 Subject: [PATCH 04/12] apply lsp-intelephense format to tests folder --- tests/DispatcherTest.php | 20 +- tests/EngineTest.php | 341 +++++++++--------- tests/EventSystemTest.php | 30 +- tests/LoaderTest.php | 4 +- tests/PdoWrapperTest.php | 8 +- tests/RenderTest.php | 2 +- tests/RouterTest.php | 8 +- tests/SimplePdoTest.php | 2 +- tests/UploadedFileTest.php | 16 +- tests/ViewTest.php | 2 +- tests/classes/Factory.php | 4 +- .../FlightRouteCompactSyntaxTest.php | 6 +- tests/groupcompactsyntax/PostsController.php | 28 +- tests/groupcompactsyntax/TodosController.php | 8 +- tests/named-arguments/FlightTest.php | 2 +- tests/performance/performance_tests.sh | 2 +- tests/run_all_tests.sh | 2 +- tests/server-v2/template.phtml | 2 +- tests/server/LayoutMiddleware.php | 84 ++--- tests/server/index.php | 8 +- tests/server/template.phtml | 8 +- tests/server/test_file.txt | 2 +- tests/views/layouts/layout.php | 2 +- tests/views/world.html | 2 +- 24 files changed, 282 insertions(+), 311 deletions(-) diff --git a/tests/DispatcherTest.php b/tests/DispatcherTest.php index b4f51c7..e70b9e9 100644 --- a/tests/DispatcherTest.php +++ b/tests/DispatcherTest.php @@ -38,23 +38,21 @@ class DispatcherTest extends TestCase public function testFunctionMapping(): void { - $this->dispatcher->set('map2', fn (): string => 'hello'); + $this->dispatcher->set('map2', fn(): string => 'hello'); $this->assertSame('hello', $this->dispatcher->run('map2')); } public function testHasEvent(): void { - $this->dispatcher->set('map-event', function (): void { - }); + $this->dispatcher->set('map-event', function (): void {}); $this->assertTrue($this->dispatcher->has('map-event')); } public function testClearAllRegisteredEvents(): void { - $customFunction = $anotherFunction = function (): void { - }; + $customFunction = $anotherFunction = function (): void {}; $this->dispatcher ->set('map-event', $customFunction) @@ -71,8 +69,7 @@ class DispatcherTest extends TestCase public function testClearDeclaredRegisteredEvent(): void { - $customFunction = $anotherFunction = function (): void { - }; + $customFunction = $anotherFunction = function (): void {}; $this->dispatcher ->set('map-event', $customFunction) @@ -110,7 +107,7 @@ class DispatcherTest extends TestCase public function testBeforeAndAfter(): void { - $this->dispatcher->set('hello', fn (string $name): string => "Hello, $name!"); + $this->dispatcher->set('hello', fn(string $name): string => "Hello, $name!"); $this->dispatcher ->hook('hello', Dispatcher::FILTER_BEFORE, function (array &$params): void { @@ -129,7 +126,7 @@ class DispatcherTest extends TestCase public function testBeforeAndAfterWithShortAfterFilterSyntax(): void { - $this->dispatcher->set('hello', fn (string $name): string => "Hello, $name!"); + $this->dispatcher->set('hello', fn(string $name): string => "Hello, $name!"); $this->dispatcher ->hook('hello', Dispatcher::FILTER_BEFORE, function (array &$params): void { @@ -246,8 +243,7 @@ class DispatcherTest extends TestCase $output = ''; $invalidCallable = 'invalidGlobalFunction'; - $validCallable = function (): void { - }; + $validCallable = function (): void {}; $this->dispatcher->filter([$validCallable, $invalidCallable], $params, $output); } @@ -341,6 +337,6 @@ class DispatcherTest extends TestCase $this->expectException(Exception::class); $this->expectExceptionMessage('This is an exception in the constructor'); - $this->dispatcher->invokeCallable([ ClassWithExceptionInConstruct::class, '__construct' ]); + $this->dispatcher->invokeCallable([ClassWithExceptionInConstruct::class, '__construct']); } } diff --git a/tests/EngineTest.php b/tests/EngineTest.php index bdb5302..d89e453 100644 --- a/tests/EngineTest.php +++ b/tests/EngineTest.php @@ -40,16 +40,16 @@ class EngineTest extends TestCase }; $this->assertTrue($engine->getInitializedVar()); - // we need to setup a dummy route - $engine->route('/someRoute', function () { }); - $engine->request()->url = '/someRoute'; + // we need to setup a dummy route + $engine->route('/someRoute', function () {}); + $engine->request()->url = '/someRoute'; $engine->start(); $this->assertFalse($engine->router()->caseSensitive); $this->assertTrue($engine->response()->content_length); } - public function testInitBeforeStartV2OutputBuffering(): void + public function testInitBeforeStartV2OutputBuffering(): void { $engine = new class extends Engine { public function getInitializedVar(): bool @@ -57,12 +57,12 @@ class EngineTest extends TestCase return $this->initialized; } }; - $engine->set('flight.v2.output_buffering', true); + $engine->set('flight.v2.output_buffering', true); $this->assertTrue($engine->getInitializedVar()); $engine->start(); - // This is a necessary evil because of how the v2 output buffer works. - ob_end_clean(); + // This is a necessary evil because of how the v2 output buffer works. + ob_end_clean(); $this->assertFalse($engine->router()->caseSensitive); $this->assertTrue($engine->response()->content_length); @@ -96,8 +96,7 @@ class EngineTest extends TestCase $engine = new Engine(); $this->expectException(Exception::class); $this->expectExceptionMessage('Cannot override an existing framework method.'); - $engine->map('_start', function () { - }); + $engine->map('_start', function () {}); } public function testRegisterExistingMethod(): void @@ -111,7 +110,7 @@ class EngineTest extends TestCase public function testSetArrayOfValues(): void { $engine = new Engine(); - $engine->set([ 'key1' => 'value1', 'key2' => 'value2']); + $engine->set(['key1' => 'value1', 'key2' => 'value2']); $this->assertEquals('value1', $engine->get('key1')); $this->assertEquals('value2', $engine->get('key2')); } @@ -153,8 +152,8 @@ class EngineTest extends TestCase $this->expectOutputString('

404 Not Found

The page you have requested could not be found.

'); $engine->start(); } - - public function testStartWithRouteButReturnedValueThrows404V2OutputBuffering(): void + + public function testStartWithRouteButReturnedValueThrows404V2OutputBuffering(): void { $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_URI'] = '/someRoute'; @@ -165,7 +164,7 @@ class EngineTest extends TestCase return $this->initialized; } }; - $engine->set('flight.v2.output_buffering', true); + $engine->set('flight.v2.output_buffering', true); $engine->route('/someRoute', function () { echo 'i ran'; return true; @@ -185,18 +184,18 @@ class EngineTest extends TestCase return $this->initialized; } }; - + // First route that returns true (should continue routing) $engine->route('/someRoute', function () { echo 'first route ran, '; return true; }, true); - + // Second route that should be found and executed $engine->route('/someRoute', function () { echo 'second route executed!'; }, true); - + $this->expectOutputString('first route ran, second route executed!'); $engine->start(); } @@ -211,13 +210,13 @@ class EngineTest extends TestCase { return $this->initialized; } - + public function getLoader() { return $this->loader; } }; - + // Mock response to prevent actual headers $engine->getLoader()->register('response', function () { return new class extends Response { @@ -227,23 +226,23 @@ class EngineTest extends TestCase } }; }); - + // First route that returns true and matches POST $engine->route('POST /someRoute', function () { echo 'first POST route ran, '; return true; }, true); - + // Second route that matches URL but wrong method (GET) - should be captured for 405 $engine->route('GET /someRoute', function () { echo 'should not execute'; }, true); - + // Third route that matches POST and should execute $engine->route('POST /someRoute', function () { echo 'second POST route executed!'; }, true); - + $this->expectOutputString('first POST route ran, second POST route executed!'); $engine->start(); } @@ -259,46 +258,46 @@ class EngineTest extends TestCase return $this->initialized; } }; - + // Route that returns true (continues iteration) $engine->route('/someRoute', function () { echo 'first route ran, '; return true; }, true); - + // Route with different URL that won't match $engine->route('/differentRoute', function () { echo 'should not execute'; }, true); - + // No more matching routes - should reach end of iterator and return 404 $this->expectOutputString('

404 Not Found

The page you have requested could not be found.

'); $engine->start(); } - public function testDoubleStart(): void + public function testDoubleStart(): void { - $engine = new Engine(); - $engine->route('/someRoute', function () { - echo 'i ran'; - }, true); - $engine->request()->url = '/someRoute'; - $engine->start(); + $engine = new Engine(); + $engine->route('/someRoute', function () { + echo 'i ran'; + }, true); + $engine->request()->url = '/someRoute'; + $engine->start(); - $request = $engine->request(); - $response = $engine->response(); + $request = $engine->request(); + $response = $engine->response(); - // This is pretending like this is embodied in a platform like swoole where - // another request comes in while still holding all the same state. - $_SERVER['REQUEST_METHOD'] = 'GET'; - $_SERVER['REQUEST_URI'] = '/someRoute'; - $engine->start(); + // This is pretending like this is embodied in a platform like swoole where + // another request comes in while still holding all the same state. + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['REQUEST_URI'] = '/someRoute'; + $engine->start(); - $this->assertFalse($request === $engine->request()); - $this->assertFalse($response === $engine->response()); + $this->assertFalse($request === $engine->request()); + $this->assertFalse($response === $engine->response()); - $this->expectOutputString('i rani ran'); - } + $this->expectOutputString('i rani ran'); + } public function testStopWithCode(): void { @@ -323,7 +322,7 @@ class EngineTest extends TestCase $this->assertEquals(500, $engine->response()->status()); } - public function testStopWithCodeV2OutputBuffering(): void + public function testStopWithCodeV2OutputBuffering(): void { $engine = new class extends Engine { public function getLoader() @@ -340,13 +339,13 @@ class EngineTest extends TestCase } }; }); - $engine->set('flight.v2.output_buffering', true); - $engine->route('/testRoute', function () use ($engine) { - echo 'I am a teapot'; - $engine->stop(500); - }); - $engine->request()->url = '/testRoute'; - $engine->start(); + $engine->set('flight.v2.output_buffering', true); + $engine->route('/testRoute', function () use ($engine) { + echo 'I am a teapot'; + $engine->stop(500); + }); + $engine->request()->url = '/testRoute'; + $engine->start(); $this->expectOutputString('I am a teapot'); $this->assertEquals(500, $engine->response()->status()); } @@ -409,7 +408,7 @@ class EngineTest extends TestCase $this->expectOutputString(''); } - public function testOptionsRoute(): void + public function testOptionsRoute(): void { $engine = new Engine(); $engine->route('GET /someRoute', function () { @@ -421,7 +420,7 @@ class EngineTest extends TestCase // No body should be sent $this->expectOutputString(''); - $this->assertEquals('GET, HEAD, OPTIONS', $engine->response()->headers()['Allow']); + $this->assertEquals('GET, HEAD, OPTIONS', $engine->response()->headers()['Allow']); } public function testHalt(): void @@ -498,46 +497,46 @@ class EngineTest extends TestCase $engine->json(['key1' => 'value1', 'key2' => 'value2']); $this->assertEquals('application/json', $engine->response()->headers()['Content-Type']); $this->assertEquals(200, $engine->response()->status()); - $this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody()); - } - - public function testJsonWithDuplicateDefaultFlags() - { - $engine = new Engine(); - $flags = JSON_HEX_TAG | JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - // utf8 emoji - $engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => '😀'], 201, true, '', $flags); - $this->assertEquals('application/json', $engine->response()->headers()['Content-Type']); - $this->assertEquals(201, $engine->response()->status()); - $this->assertEquals('{"key1":"value1","key2":"value2","utf8_emoji":"😀"}', $engine->response()->getBody()); - } - - public function testJsonThrowOnErrorByDefault(): void - { - $engine = new Engine(); - $this->expectException(Exception::class); - $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded'); - $engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => "\xB1\x31"]); - } - - public function testJsonV2OutputBuffering(): void + $this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody()); + } + + public function testJsonWithDuplicateDefaultFlags() { $engine = new Engine(); - $engine->response()->v2_output_buffering = true; + $flags = JSON_HEX_TAG | JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; + // utf8 emoji + $engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => '😀'], 201, true, '', $flags); + $this->assertEquals('application/json', $engine->response()->headers()['Content-Type']); + $this->assertEquals(201, $engine->response()->status()); + $this->assertEquals('{"key1":"value1","key2":"value2","utf8_emoji":"😀"}', $engine->response()->getBody()); + } + + public function testJsonThrowOnErrorByDefault(): void + { + $engine = new Engine(); + $this->expectException(Exception::class); + $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded'); + $engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => "\xB1\x31"]); + } + + public function testJsonV2OutputBuffering(): void + { + $engine = new Engine(); + $engine->response()->v2_output_buffering = true; $engine->json(['key1' => 'value1', 'key2' => 'value2']); $this->expectOutputString('{"key1":"value1","key2":"value2"}'); $this->assertEquals('application/json', $engine->response()->headers()['Content-Type']); $this->assertEquals(200, $engine->response()->status()); } - public function testJsonHalt(): void + public function testJsonHalt(): void { $engine = new Engine(); - $this->expectOutputString('{"key1":"value1","key2":"value2"}'); + $this->expectOutputString('{"key1":"value1","key2":"value2"}'); $engine->jsonHalt(['key1' => 'value1', 'key2' => 'value2']); $this->assertEquals('application/json', $engine->response()->headers()['Content-Type']); $this->assertEquals(200, $engine->response()->status()); - $this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody()); + $this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody()); } public function testJsonP(): void @@ -547,13 +546,13 @@ class EngineTest extends TestCase $engine->jsonp(['key1' => 'value1', 'key2' => 'value2']); $this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']); $this->assertEquals(200, $engine->response()->status()); - $this->assertEquals('whatever({"key1":"value1","key2":"value2"});', $engine->response()->getBody()); + $this->assertEquals('whatever({"key1":"value1","key2":"value2"});', $engine->response()->getBody()); } - public function testJsonPV2OutputBuffering(): void + public function testJsonPV2OutputBuffering(): void { $engine = new Engine(); - $engine->response()->v2_output_buffering = true; + $engine->response()->v2_output_buffering = true; $engine->request()->query['jsonp'] = 'whatever'; $engine->jsonp(['key1' => 'value1', 'key2' => 'value2']); $this->expectOutputString('whatever({"key1":"value1","key2":"value2"});'); @@ -570,10 +569,10 @@ class EngineTest extends TestCase $this->assertEquals(200, $engine->response()->status()); } - public function testJsonpBadParamV2OutputBuffering(): void + public function testJsonpBadParamV2OutputBuffering(): void { $engine = new Engine(); - $engine->response()->v2_output_buffering = true; + $engine->response()->v2_output_buffering = true; $engine->jsonp(['key1' => 'value1', 'key2' => 'value2']); $this->expectOutputString('({"key1":"value1","key2":"value2"});'); $this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']); @@ -608,7 +607,7 @@ class EngineTest extends TestCase $engine = new Engine; $_SERVER['HTTP_IF_MODIFIED_SINCE'] = 'Fri, 13 Feb 2009 23:31:30 GMT'; $engine->lastModified(1234567890); - $this->assertTrue(empty($engine->response()->headers()['Last-Modified'])); + $this->assertTrue(empty($engine->response()->headers()['Last-Modified'])); $this->assertEquals(304, $engine->response()->status()); } @@ -618,7 +617,7 @@ class EngineTest extends TestCase $engine->route('/path1/@param:[0-9]{3}', function () { echo 'I win'; }, false, 'path1'); - $url = $engine->getUrl('path1', [ 'param' => 123 ]); + $url = $engine->getUrl('path1', ['param' => 123]); $this->assertEquals('/path1/123', $url); } @@ -628,7 +627,7 @@ class EngineTest extends TestCase $engine->route('/item/@item_param:[a-z0-9]{16}/by-status/@token:[a-z0-9]{16}', function () { echo 'I win'; }, false, 'path_item_1'); - $url = $engine->getUrl('path_item_1', [ 'item_param' => 1234567890123456, 'token' => 6543210987654321 ]); + $url = $engine->getUrl('path_item_1', ['item_param' => 1234567890123456, 'token' => 6543210987654321]); $this->assertEquals('/item/1234567890123456/by-status/6543210987654321', $url); } @@ -666,8 +665,7 @@ class EngineTest extends TestCase public function testMiddlewareCallableFunctionReturnFalse(): void { - $engine = new class extends Engine { - }; + $engine = new class extends Engine {}; $engine->route('/path1/@id', function ($id) { echo 'OK' . $id; }) @@ -742,7 +740,7 @@ class EngineTest extends TestCase $this->expectOutputString('OK123after123'); } - public function testMiddlewareClassStringNoContainer(): void + public function testMiddlewareClassStringNoContainer(): void { $middleware = new class { public function after($params) @@ -761,10 +759,10 @@ class EngineTest extends TestCase $this->expectOutputString('OK123after123'); } - public function testMiddlewareClassStringWithContainer(): void + public function testMiddlewareClassStringWithContainer(): void { - $engine = new Engine(); + $engine = new Engine(); $dice = new \Dice\Dice(); $dice = $dice->addRule('*', [ 'substitutions' => [ @@ -774,7 +772,7 @@ class EngineTest extends TestCase $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - + $engine->route('/path1/@id', function ($id) { echo 'OK' . $id; @@ -794,8 +792,7 @@ class EngineTest extends TestCase return false; } }; - $engine = new class extends Engine { - }; + $engine = new class extends Engine {}; $engine->route('/path1/@id', function ($id) { echo 'OK' . $id; @@ -850,7 +847,7 @@ class EngineTest extends TestCase $engine = new Engine(); $engine->route('/path1/@id/subpath1/@another_id', function () { echo 'OK'; - })->addMiddleware([ $middleware, $middleware2 ]); + })->addMiddleware([$middleware, $middleware2]); $engine->request()->url = '/path1/123/subpath1/456'; $engine->start(); @@ -887,14 +884,15 @@ class EngineTest extends TestCase $router->map('/@cool_id', function () { echo 'OK'; }); - }, [ $middleware, $middleware2 ]); + }, [$middleware, $middleware2]); $engine->request()->url = '/path1/123/subpath1/456'; $engine->start(); $this->expectOutputString('before456before123OKafter123456after123'); } - public function testContainerBadClass() { + public function testContainerBadClass() + { $engine = new Engine(); $this->expectException(InvalidArgumentException::class); @@ -902,47 +900,50 @@ class EngineTest extends TestCase $engine->registerContainerHandler('BadClass'); } - public function testContainerDice() { + public function testContainerDice() + { $engine = new Engine(); $dice = new \Dice\Dice(); $dice = $dice->addRules([ PdoWrapper::class => [ 'shared' => true, - 'constructParams' => [ 'sqlite::memory:' ] + 'constructParams' => ['sqlite::memory:'] ] ]); $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - - $engine->route('/container', Container::class.'->testTheContainer'); + + $engine->route('/container', Container::class . '->testTheContainer'); $engine->request()->url = '/container'; $engine->start(); $this->expectOutputString('yay! I injected a collection, and it has 1 items'); } - public function testContainerDicePdoWrapperTest() { + public function testContainerDicePdoWrapperTest() + { $engine = new Engine(); $dice = new \Dice\Dice(); $dice = $dice->addRules([ PdoWrapper::class => [ 'shared' => true, - 'constructParams' => [ 'sqlite::memory:' ] + 'constructParams' => ['sqlite::memory:'] ] ]); $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - - $engine->route('/container', Container::class.'->testThePdoWrapper'); + + $engine->route('/container', Container::class . '->testThePdoWrapper'); $engine->request()->url = '/container'; $engine->start(); $this->expectOutputString('Yay! I injected a PdoWrapper, and it returned the number 5 from the database!'); } - public function testContainerDiceFlightEngine() { + public function testContainerDiceFlightEngine() + { $engine = new Engine(); $engine->set('test_me_out', 'You got it boss!'); $dice = new \Dice\Dice(); @@ -954,44 +955,46 @@ class EngineTest extends TestCase $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - - $engine->route('/container', ContainerDefault::class.'->echoTheContainer'); + + $engine->route('/container', ContainerDefault::class . '->echoTheContainer'); $engine->request()->url = '/container'; $engine->start(); $this->expectOutputString('You got it boss!'); } - public function testContainerDiceBadClass() { + public function testContainerDiceBadClass() + { $engine = new Engine(); $dice = new \Dice\Dice(); $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - + $engine->route('/container', 'BadClass->testTheContainer'); $engine->request()->url = '/container'; - + $this->expectException(Exception::class); $this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?"); - + $engine->start(); } - public function testContainerDiceBadMethod() { + public function testContainerDiceBadMethod() + { $engine = new Engine(); $dice = new \Dice\Dice(); $dice = $dice->addRules([ PdoWrapper::class => [ 'shared' => true, - 'constructParams' => [ 'sqlite::memory:' ] + 'constructParams' => ['sqlite::memory:'] ] ]); $engine->registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); }); - - $engine->route('/container', Container::class.'->badMethod'); + + $engine->route('/container', Container::class . '->badMethod'); $engine->request()->url = '/container'; $this->expectException(Exception::class); @@ -1000,46 +1003,49 @@ class EngineTest extends TestCase $engine->start(); } - public function testContainerPsr11(): void { + public function testContainerPsr11(): void + { $engine = new Engine(); $container = new \League\Container\Container(); $container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class); $container->add(Collection::class); $container->add(PdoWrapper::class)->addArgument('sqlite::memory:'); $engine->registerContainerHandler($container); - - $engine->route('/container', Container::class.'->testTheContainer'); + + $engine->route('/container', Container::class . '->testTheContainer'); $engine->request()->url = '/container'; $engine->start(); $this->expectOutputString('yay! I injected a collection, and it has 1 items'); } - public function testContainerPsr11ClassNotFound() { + public function testContainerPsr11ClassNotFound() + { $engine = new Engine(); $container = new \League\Container\Container(); $container->add(Container::class)->addArgument(Collection::class); $container->add(Collection::class); $engine->registerContainerHandler($container); - + $engine->route('/container', 'BadClass->testTheContainer'); $engine->request()->url = '/container'; - + $this->expectException(Exception::class); $this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?"); - + $engine->start(); } - public function testContainerPsr11MethodNotFound(): void { + public function testContainerPsr11MethodNotFound(): void + { $engine = new Engine(); $container = new \League\Container\Container(); $container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class); $container->add(Collection::class); $container->add(PdoWrapper::class)->addArgument('sqlite::memory:'); $engine->registerContainerHandler($container); - - $engine->route('/container', Container::class.'->badMethod'); + + $engine->route('/container', Container::class . '->badMethod'); $engine->request()->url = '/container'; $this->expectException(Exception::class); @@ -1048,7 +1054,8 @@ class EngineTest extends TestCase $engine->start(); } - public function testRouteFoundButBadMethod(): void { + public function testRouteFoundButBadMethod(): void + { $engine = new class extends Engine { public function getLoader() { @@ -1068,30 +1075,30 @@ class EngineTest extends TestCase }; }); - $engine->route('POST /path1/@id', function ($id) { - echo 'OK' . $id; - }); + $engine->route('POST /path1/@id', function ($id) { + echo 'OK' . $id; + }); - $engine->route('GET /path2/@id', function ($id) { - echo 'OK' . $id; - }); + $engine->route('GET /path2/@id', function ($id) { + echo 'OK' . $id; + }); - $engine->route('PATCH /path3/@id', function ($id) { - echo 'OK' . $id; - }); + $engine->route('PATCH /path3/@id', function ($id) { + echo 'OK' . $id; + }); - $engine->request()->url = '/path1/123'; - $engine->request()->method = 'GET'; + $engine->request()->url = '/path1/123'; + $engine->request()->method = 'GET'; $engine->start(); - $this->expectOutputString('Method Not Allowed. Allowed Methods are: POST, OPTIONS'); + $this->expectOutputString('Method Not Allowed. Allowed Methods are: POST, OPTIONS'); $this->assertEquals(405, $engine->response()->status()); - $this->assertEquals('Method Not Allowed. Allowed Methods are: POST, OPTIONS', $engine->response()->getBody()); - $this->assertEquals('POST, OPTIONS', $engine->response()->headers()['Allow']); - } + $this->assertEquals('Method Not Allowed. Allowed Methods are: POST, OPTIONS', $engine->response()->getBody()); + $this->assertEquals('POST, OPTIONS', $engine->response()->headers()['Allow']); + } - public function testDownload(): void + public function testDownload(): void { $engine = new class extends Engine { public function getLoader() @@ -1102,26 +1109,26 @@ class EngineTest extends TestCase // doing this so we can overwrite some parts of the response $engine->getLoader()->register('response', function () { return new class extends Response { - public $headersSent = []; + public $headersSent = []; public function setRealHeader( string $header_string, bool $replace = true, int $response_code = 0 ): self { - $this->headersSent[] = $header_string; + $this->headersSent[] = $header_string; return $this; } }; }); - $tmpfile = tmpfile(); - fwrite($tmpfile, 'I am a teapot'); - $streamPath = stream_get_meta_data($tmpfile)['uri']; - $this->expectOutputString('I am a teapot'); + $tmpfile = tmpfile(); + fwrite($tmpfile, 'I am a teapot'); + $streamPath = stream_get_meta_data($tmpfile)['uri']; + $this->expectOutputString('I am a teapot'); $engine->download($streamPath); - $this->assertContains('Content-Disposition: attachment; filename="'.basename($streamPath).'"', $engine->response()->headersSent); + $this->assertContains('Content-Disposition: attachment; filename="' . basename($streamPath) . '"', $engine->response()->headersSent); } - public function testDownloadWithDefaultFileName(): void + public function testDownloadWithDefaultFileName(): void { $engine = new class extends Engine { public function getLoader() @@ -1132,30 +1139,30 @@ class EngineTest extends TestCase // doing this so we can overwrite some parts of the response $engine->getLoader()->register('response', function () { return new class extends Response { - public $headersSent = []; + public $headersSent = []; public function setRealHeader( string $header_string, bool $replace = true, int $response_code = 0 ): self { - $this->headersSent[] = $header_string; + $this->headersSent[] = $header_string; return $this; } }; }); - $tmpfile = tmpfile(); - fwrite($tmpfile, 'I am a teapot'); - $streamPath = stream_get_meta_data($tmpfile)['uri']; - $this->expectOutputString('I am a teapot'); + $tmpfile = tmpfile(); + fwrite($tmpfile, 'I am a teapot'); + $streamPath = stream_get_meta_data($tmpfile)['uri']; + $this->expectOutputString('I am a teapot'); $engine->download($streamPath, 'something.txt'); - $this->assertContains('Content-Disposition: attachment; filename="something.txt"', $engine->response()->headersSent); + $this->assertContains('Content-Disposition: attachment; filename="something.txt"', $engine->response()->headersSent); } - public function testDownloadBadPath() { - $engine = new Engine(); - $this->expectException(Exception::class); - $this->expectExceptionMessage("/path/to/nowhere cannot be found."); - $engine->download('/path/to/nowhere'); - } - + public function testDownloadBadPath() + { + $engine = new Engine(); + $this->expectException(Exception::class); + $this->expectExceptionMessage("/path/to/nowhere cannot be found."); + $engine->download('/path/to/nowhere'); + } } diff --git a/tests/EventSystemTest.php b/tests/EventSystemTest.php index 2a75cdd..1e42194 100644 --- a/tests/EventSystemTest.php +++ b/tests/EventSystemTest.php @@ -122,8 +122,7 @@ class EventSystemTest extends TestCase Flight::map('onEvent', function ($event, $callback) use (&$called) { $called = true; }); - Flight::onEvent('test.event', function () { - }); + Flight::onEvent('test.event', function () {}); $this->assertTrue($called, 'Overridden onEvent method should be called.'); } @@ -233,8 +232,7 @@ class EventSystemTest extends TestCase { $this->assertFalse(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should not have listeners before registration'); - Flight::onEvent('test.event', function () { - }); + Flight::onEvent('test.event', function () {}); $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners after registration'); } @@ -244,10 +242,8 @@ class EventSystemTest extends TestCase */ public function testGetListeners(): void { - $callback1 = function () { - }; - $callback2 = function () { - }; + $callback1 = function () {}; + $callback2 = function () {}; $this->assertEmpty(Flight::eventDispatcher()->getListeners('test.event'), 'Event should have no listeners before registration'); @@ -277,10 +273,8 @@ class EventSystemTest extends TestCase { $this->assertEmpty(Flight::eventDispatcher()->getAllRegisteredEvents(), 'No events should be registered initially'); - Flight::onEvent('test.event1', function () { - }); - Flight::onEvent('test.event2', function () { - }); + Flight::onEvent('test.event1', function () {}); + Flight::onEvent('test.event2', function () {}); $events = Flight::eventDispatcher()->getAllRegisteredEvents(); $this->assertCount(2, $events, 'Should return all registered event names'); @@ -317,12 +311,9 @@ class EventSystemTest extends TestCase */ public function testRemoveAllListeners(): void { - Flight::onEvent('test.event', function () { - }); - Flight::onEvent('test.event', function () { - }); - Flight::onEvent('another.event', function () { - }); + Flight::onEvent('test.event', function () {}); + Flight::onEvent('test.event', function () {}); + Flight::onEvent('another.event', function () {}); $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners before removal'); $this->assertTrue(Flight::eventDispatcher()->hasListeners('another.event'), 'Another event should have listeners'); @@ -339,8 +330,7 @@ class EventSystemTest extends TestCase public function testRemoveListenersForNonexistentEvent(): void { // Should not throw any errors - Flight::eventDispatcher()->removeListener('nonexistent.event', function () { - }); + Flight::eventDispatcher()->removeListener('nonexistent.event', function () {}); Flight::eventDispatcher()->removeAllListeners('nonexistent.event'); $this->assertTrue(true, 'Removing listeners for nonexistent events should not throw errors'); diff --git a/tests/LoaderTest.php b/tests/LoaderTest.php index 04293f1..de37efa 100644 --- a/tests/LoaderTest.php +++ b/tests/LoaderTest.php @@ -121,7 +121,7 @@ class LoaderTest extends TestCase { $this->loader->register('g', User::class); $current_class = $this->loader->get('g'); - $this->assertEquals([ User::class, [], null ], $current_class); + $this->assertEquals([User::class, [], null], $current_class); $this->loader->unregister('g'); $unregistered_class_result = $this->loader->get('g'); $this->assertNull($unregistered_class_result); @@ -129,7 +129,7 @@ class LoaderTest extends TestCase public function testNewInstance6Params(): void { - $TesterClass = $this->loader->newInstance(TesterClass::class, ['Bob','Fred', 'Joe', 'Jane', 'Sally', 'Suzie']); + $TesterClass = $this->loader->newInstance(TesterClass::class, ['Bob', 'Fred', 'Joe', 'Jane', 'Sally', 'Suzie']); $this->assertEquals('Bob', $TesterClass->param1); $this->assertEquals('Fred', $TesterClass->param2); $this->assertEquals('Joe', $TesterClass->param3); diff --git a/tests/PdoWrapperTest.php b/tests/PdoWrapperTest.php index d2eeb45..dc5d1ae 100644 --- a/tests/PdoWrapperTest.php +++ b/tests/PdoWrapperTest.php @@ -99,7 +99,7 @@ class PdoWrapperTest extends TestCase public function testFetchAllWithNamedParams(): void { - $rows = $this->pdo_wrapper->fetchAll('SELECT * FROM test WHERE name = :name', [ 'name' => 'two']); + $rows = $this->pdo_wrapper->fetchAll('SELECT * FROM test WHERE name = :name', ['name' => 'two']); $this->assertCount(1, $rows); $this->assertEquals(2, $rows[0]['id']); $this->assertEquals('two', $rows[0]['name']); @@ -107,19 +107,19 @@ class PdoWrapperTest extends TestCase public function testFetchAllWithInInt(): void { - $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id IN(? )', [ [1,2 ]]); + $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id IN(? )', [[1, 2]]); $this->assertEquals(2, count($rows)); } public function testFetchAllWithInString(): void { - $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE name IN(?)', [ ['one','two' ]]); + $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE name IN(?)', [['one', 'two']]); $this->assertEquals(2, count($rows)); } public function testFetchAllWithInStringCommas(): void { - $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id > ? AND name IN( ?) ', [ 0, 'one,two' ]); + $rows = $this->pdo_wrapper->fetchAll('SELECT id FROM test WHERE id > ? AND name IN( ?) ', [0, 'one,two']); $this->assertEquals(2, count($rows)); } diff --git a/tests/RenderTest.php b/tests/RenderTest.php index 31d250a..ab71965 100644 --- a/tests/RenderTest.php +++ b/tests/RenderTest.php @@ -31,6 +31,6 @@ class RenderTest extends TestCase $this->app->render('hello', ['name' => 'Bob'], 'content'); $this->app->render('layouts/layout'); - $this->expectOutputString('Hello, Bob!'); + $this->expectOutputString("Hello, Bob!\n"); } } diff --git a/tests/RouterTest.php b/tests/RouterTest.php index 620ecc3..dabb8ef 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -411,16 +411,14 @@ class RouterTest extends TestCase public function testRouteBeingReturned(): void { - $route = $this->router->map('/hi', function () { - }); + $route = $this->router->map('/hi', function () {}); $route_in_router = $this->router->getRoutes()[0]; $this->assertSame($route, $route_in_router); } public function testRouteSetAlias(): void { - $route = $this->router->map('/hi', function () { - }); + $route = $this->router->map('/hi', function () {}); $route->setAlias('hello'); $this->assertEquals('hello', $route->alias); } @@ -773,7 +771,7 @@ class RouterTest extends TestCase public function testStripMultipleSlashesFromUrlAndStillMatch(): void { - $this->router->get('/', [ $this, 'ok' ]); + $this->router->get('/', [$this, 'ok']); $this->request->url = '///'; $this->request->method = 'GET'; $this->check('OK'); diff --git a/tests/SimplePdoTest.php b/tests/SimplePdoTest.php index 03428d1..44866c1 100644 --- a/tests/SimplePdoTest.php +++ b/tests/SimplePdoTest.php @@ -88,7 +88,7 @@ class SimplePdoTest extends TestCase public function testRunQueryWithoutParamsWithMaxQueryMetrics(): void { - $db = new class ('sqlite::memory:', null, null, null, ['maxQueryMetrics' => 2, 'trackApmQueries' => true]) extends SimplePdo { + $db = new class('sqlite::memory:', null, null, null, ['maxQueryMetrics' => 2, 'trackApmQueries' => true]) extends SimplePdo { public function getQueryMetrics(): array { return $this->queryMetrics; diff --git a/tests/UploadedFileTest.php b/tests/UploadedFileTest.php index 8aefb07..23fa2c2 100644 --- a/tests/UploadedFileTest.php +++ b/tests/UploadedFileTest.php @@ -41,14 +41,14 @@ class UploadedFileTest extends TestCase public function getFileErrorMessageTests(): array { return [ - [ UPLOAD_ERR_INI_SIZE, 'The uploaded file exceeds the upload_max_filesize directive in php.ini.', ], - [ UPLOAD_ERR_FORM_SIZE, 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', ], - [ UPLOAD_ERR_PARTIAL, 'The uploaded file was only partially uploaded.', ], - [ UPLOAD_ERR_NO_FILE, 'No file was uploaded.', ], - [ UPLOAD_ERR_NO_TMP_DIR, 'Missing a temporary folder.', ], - [ UPLOAD_ERR_CANT_WRITE, 'Failed to write file to disk.', ], - [ UPLOAD_ERR_EXTENSION, 'A PHP extension stopped the file upload.', ], - [ -1, 'An unknown error occurred. Error code: -1' ] + [UPLOAD_ERR_INI_SIZE, 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',], + [UPLOAD_ERR_FORM_SIZE, 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',], + [UPLOAD_ERR_PARTIAL, 'The uploaded file was only partially uploaded.',], + [UPLOAD_ERR_NO_FILE, 'No file was uploaded.',], + [UPLOAD_ERR_NO_TMP_DIR, 'Missing a temporary folder.',], + [UPLOAD_ERR_CANT_WRITE, 'Failed to write file to disk.',], + [UPLOAD_ERR_EXTENSION, 'A PHP extension stopped the file upload.',], + [-1, 'An unknown error occurred. Error code: -1'] ]; } diff --git a/tests/ViewTest.php b/tests/ViewTest.php index ddbf32b..54a0939 100644 --- a/tests/ViewTest.php +++ b/tests/ViewTest.php @@ -104,7 +104,7 @@ class ViewTest extends TestCase $this->view->render('world'); - $this->expectOutputString('Hello world, Bob!'); + $this->expectOutputString("Hello world, Bob!\n"); } public function testGetTemplateAbsolutePath(): void diff --git a/tests/classes/Factory.php b/tests/classes/Factory.php index a99ab3d..13ccc39 100644 --- a/tests/classes/Factory.php +++ b/tests/classes/Factory.php @@ -7,9 +7,7 @@ namespace tests\classes; class Factory { // Cannot be instantiated - private function __construct() - { - } + private function __construct() {} public static function create(): self { diff --git a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php index 1f438bb..611b589 100644 --- a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php +++ b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php @@ -38,7 +38,7 @@ final class FlightRouteCompactSyntaxTest extends TestCase public function testOptionsOnly(): void { Flight::resource('/users', UsersController::class, [ - 'only' => [ 'index', 'destroy' ] + 'only' => ['index', 'destroy'] ]); $routes = Flight::router()->getRoutes(); @@ -100,7 +100,7 @@ final class FlightRouteCompactSyntaxTest extends TestCase public function testOptionsExcept(): void { Flight::resource('/todos', TodosController::class, [ - 'except' => [ 'create', 'store', 'update', 'destroy', 'edit' ] + 'except' => ['create', 'store', 'update', 'destroy', 'edit'] ]); $routes = Flight::router()->getRoutes(); @@ -119,7 +119,7 @@ final class FlightRouteCompactSyntaxTest extends TestCase public function testOptionsMiddlewareAndAliasBase(): void { Flight::resource('/todos', TodosController::class, [ - 'middleware' => [ 'auth' ], + 'middleware' => ['auth'], 'alias_base' => 'nothanks' ]); diff --git a/tests/groupcompactsyntax/PostsController.php b/tests/groupcompactsyntax/PostsController.php index bae8242..6339387 100644 --- a/tests/groupcompactsyntax/PostsController.php +++ b/tests/groupcompactsyntax/PostsController.php @@ -6,31 +6,17 @@ namespace tests\groupcompactsyntax; final class PostsController { - public function index(): void - { - } + public function index(): void {} - public function show(string $id): void - { - } + public function show(string $id): void {} - public function create(): void - { - } + public function create(): void {} - public function store(): void - { - } + public function store(): void {} - public function edit(string $id): void - { - } + public function edit(string $id): void {} - public function update(string $id): void - { - } + public function update(string $id): void {} - public function destroy(string $id): void - { - } + public function destroy(string $id): void {} } diff --git a/tests/groupcompactsyntax/TodosController.php b/tests/groupcompactsyntax/TodosController.php index 39d6348..56b536f 100644 --- a/tests/groupcompactsyntax/TodosController.php +++ b/tests/groupcompactsyntax/TodosController.php @@ -6,11 +6,7 @@ namespace tests\groupcompactsyntax; final class TodosController { - public function index(): void - { - } + public function index(): void {} - public function show(string $id): void - { - } + public function show(string $id): void {} } diff --git a/tests/named-arguments/FlightTest.php b/tests/named-arguments/FlightTest.php index 0d5abff..6593450 100644 --- a/tests/named-arguments/FlightTest.php +++ b/tests/named-arguments/FlightTest.php @@ -75,7 +75,7 @@ final class FlightTest extends TestCase { $dateTime = new DateTimeImmutable(); - $controller = new class ($dateTime) { + $controller = new class($dateTime) { public function __construct(private DateTimeImmutable $dateTime) { // diff --git a/tests/performance/performance_tests.sh b/tests/performance/performance_tests.sh index 605e242..e3ffe28 100644 --- a/tests/performance/performance_tests.sh +++ b/tests/performance/performance_tests.sh @@ -69,4 +69,4 @@ echo "----------------------------------------" echo "Getting post-test memory reading..." final_memory_response=$(curl -s "${URL}?memory=1") final_memory=$(echo "$final_memory_response" | grep "Memory:" | awk '{print $2}') -echo "Final memory usage: ${final_memory} KB" \ No newline at end of file +echo "Final memory usage: ${final_memory} KB" diff --git a/tests/run_all_tests.sh b/tests/run_all_tests.sh index 72ec8ba..74e0b25 100644 --- a/tests/run_all_tests.sh +++ b/tests/run_all_tests.sh @@ -23,4 +23,4 @@ for ((i = 0; i < count; i++)); do echo " ${php_versions[$i]} vendor/bin/phpcs --standard=phpcs.xml -n" ${php_versions[$i]} vendor/bin/phpcs --standard=phpcs.xml -n fi -done \ No newline at end of file +done diff --git a/tests/server-v2/template.phtml b/tests/server-v2/template.phtml index d2ab1fa..e7fb2e1 100644 --- a/tests/server-v2/template.phtml +++ b/tests/server-v2/template.phtml @@ -1 +1 @@ -Route text: Template works! +Route text: Template works! diff --git a/tests/server/LayoutMiddleware.php b/tests/server/LayoutMiddleware.php index 4556b83..32d6a06 100644 --- a/tests/server/LayoutMiddleware.php +++ b/tests/server/LayoutMiddleware.php @@ -9,50 +9,50 @@ class LayoutMiddleware $final_route = Flight::getUrl('final_group'); echo << - ul { - list-style-type: none; - margin: 0; - padding: 0; - overflow: hidden; - background-color: #333; - } + ul { + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; + background-color: #333; + } - li { - float: left; - } - #infotext { - font-weight: bold; - color: blueviolet; - } - li a { - display: block; - color: white; - text-align: center; - padding: 14px 16px; - text-decoration: none; - } + li { + float: left; + } + #infotext { + font-weight: bold; + color: blueviolet; + } + li a { + display: block; + color: white; + text-align: center; + padding: 14px 16px; + text-decoration: none; + } - li a:hover { - background-color: #111; - } - #container { - color: #333; - font-size: 16px; - line-height: 1.5; - margin: 20px 0; - padding: 10px; - border: 1px solid #ddd; - background-color: #f9f9f9; - } - #debugrequest { - color: #333; - font-size: 16px; - line-height: 1.5; - margin: 20px 0; - padding: 10px; - border: 1px solid #ddd; - background-color: #f9f9f9; - } + li a:hover { + background-color: #111; + } + #container { + color: #333; + font-size: 16px; + line-height: 1.5; + margin: 20px 0; + padding: 10px; + border: 1px solid #ddd; + background-color: #f9f9f9; + } + #debugrequest { + color: #333; + font-size: 16px; + line-height: 1.5; + margin: 20px 0; + padding: 10px; + border: 1px solid #ddd; + background-color: #f9f9f9; + }
  • Root Route
  • diff --git a/tests/server/index.php b/tests/server/index.php index bca95f7..5fd7a66 100644 --- a/tests/server/index.php +++ b/tests/server/index.php @@ -14,7 +14,7 @@ use tests\classes\ContainerDefault; * @author Kristaps Muižnieks https://github.com/krmu */ - require file_exists(__DIR__ . '/../../vendor/autoload.php') ? __DIR__ . '/../../vendor/autoload.php' : __DIR__ . '/../../flight/autoload.php'; +require file_exists(__DIR__ . '/../../vendor/autoload.php') ? __DIR__ . '/../../vendor/autoload.php' : __DIR__ . '/../../flight/autoload.php'; Flight::set('flight.content_length', false); Flight::set('flight.views.path', './'); @@ -137,7 +137,7 @@ Flight::group('', function () { ob_flush(); } echo "is successful!!"; - })->streamWithHeaders(['Content-Type' => 'text/html', 'status' => 200 ]); + })->streamWithHeaders(['Content-Type' => 'text/html', 'status' => 200]); // Test 14: Overwrite the body with a middleware Flight::route('/overwrite', function () { @@ -163,7 +163,7 @@ Flight::group('', function () { Flight::route('/no-container', ContainerDefault::class . '->testUi'); Flight::route('/dice', Container::class . '->testThePdoWrapper'); Flight::route('/Pascal_Snake_Case', Pascal_Snake_Case::class . '->doILoad'); -}, [ new LayoutMiddleware() ]); +}, [new LayoutMiddleware()]); // Test 9: JSON output (should not output any other html) Flight::route('/json', function () { @@ -209,7 +209,7 @@ Flight::map('start', function () { $dice = $dice->addRules([ PdoWrapper::class => [ 'shared' => true, - 'constructParams' => [ 'sqlite::memory:' ] + 'constructParams' => ['sqlite::memory:'] ] ]); Flight::registerContainerHandler(function ($class, $params) use ($dice) { diff --git a/tests/server/template.phtml b/tests/server/template.phtml index 8e14b9a..7ef24dc 100644 --- a/tests/server/template.phtml +++ b/tests/server/template.phtml @@ -1,5 +1,5 @@ - -Route text: Template works! - -Route text: Template with variable name "data" works! See: + + Route text: Template works! + + Route text: Template with variable name "data" works! See: diff --git a/tests/server/test_file.txt b/tests/server/test_file.txt index 1a47dab..e9396a3 100644 --- a/tests/server/test_file.txt +++ b/tests/server/test_file.txt @@ -1 +1 @@ -This file downloaded successfully! \ No newline at end of file +This file downloaded successfully! diff --git a/tests/views/layouts/layout.php b/tests/views/layouts/layout.php index f232bc5..5f93f6d 100644 --- a/tests/views/layouts/layout.php +++ b/tests/views/layouts/layout.php @@ -1 +1 @@ - \ No newline at end of file + diff --git a/tests/views/world.html b/tests/views/world.html index 05d95c0..f4c856e 100644 --- a/tests/views/world.html +++ b/tests/views/world.html @@ -1 +1 @@ -Hello world, ! \ No newline at end of file +Hello world, ! From 29595ef9e18528b07520c64546e4da1e23fb4b77 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 16 Mar 2026 23:03:29 -0400 Subject: [PATCH 05/12] composer exec phpcbf -- --standard=PSR2 --- flight/commands/RouteCommand.php | 8 +--- flight/core/Dispatcher.php | 10 +---- flight/net/Request.php | 10 +---- phpcs.xml.dist | 3 ++ tests/DispatcherTest.php | 18 +++++--- tests/EventSystemTest.php | 40 ++++++++++++----- tests/RouterTest.php | 8 +++- tests/classes/Factory.php | 5 ++- tests/groupcompactsyntax/PostsController.php | 47 ++++++++++++++------ tests/groupcompactsyntax/TodosController.php | 10 ++++- 10 files changed, 102 insertions(+), 57 deletions(-) diff --git a/flight/commands/RouteCommand.php b/flight/commands/RouteCommand.php index 1667934..4273c2c 100644 --- a/flight/commands/RouteCommand.php +++ b/flight/commands/RouteCommand.php @@ -118,13 +118,7 @@ class RouteCommand extends AbstractBaseCommand $methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; foreach ($methods as $method) { $lowercaseMethod = strtolower($method); - if ( - $this->{$lowercaseMethod} === true && - ( - $route->methods[0] === '*' || - in_array($method, $route->methods, true) === true - ) - ) { + if ($this->{$lowercaseMethod} === true && ($route->methods[0] === '*' || in_array($method, $route->methods, true) === true)) { $boolval = true; break; } diff --git a/flight/core/Dispatcher.php b/flight/core/Dispatcher.php index 2d45a49..00565e9 100644 --- a/flight/core/Dispatcher.php +++ b/flight/core/Dispatcher.php @@ -64,10 +64,7 @@ class Dispatcher { $containerInterfaceNS = '\Psr\Container\ContainerInterface'; - if ( - is_a($containerHandler, $containerInterfaceNS) - || is_callable($containerHandler) - ) { + if (is_a($containerHandler, $containerInterfaceNS) || is_callable($containerHandler)) { $this->containerHandler = $containerHandler; return; @@ -289,10 +286,7 @@ class Dispatcher */ public function execute($callback, array &$params = []) { - if ( - is_string($callback) === true - && (strpos($callback, '->') !== false || strpos($callback, '::') !== false) - ) { + if (is_string($callback) === true && (strpos($callback, '->') !== false || strpos($callback, '::') !== false)) { $callback = $this->parseStringClassAndMethod($callback); } diff --git a/flight/net/Request.php b/flight/net/Request.php index 845b55c..2e0a193 100644 --- a/flight/net/Request.php +++ b/flight/net/Request.php @@ -439,15 +439,7 @@ class Request */ public static function getScheme(): string { - if ( - (strtolower(self::getVar('HTTPS')) === 'on') - || - (self::getVar('HTTP_X_FORWARDED_PROTO') === 'https') - || - (self::getVar('HTTP_FRONT_END_HTTPS') === 'on') - || - (self::getVar('REQUEST_SCHEME') === 'https') - ) { + if ((strtolower(self::getVar('HTTPS')) === 'on') || (self::getVar('HTTP_X_FORWARDED_PROTO') === 'https') || (self::getVar('HTTP_FRONT_END_HTTPS') === 'on') || (self::getVar('REQUEST_SCHEME') === 'https')) { return 'https'; } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index e21e213..118cf85 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -14,6 +14,9 @@ + + + index.php flight tests diff --git a/tests/DispatcherTest.php b/tests/DispatcherTest.php index e70b9e9..7935765 100644 --- a/tests/DispatcherTest.php +++ b/tests/DispatcherTest.php @@ -45,14 +45,18 @@ class DispatcherTest extends TestCase public function testHasEvent(): void { - $this->dispatcher->set('map-event', function (): void {}); + $this->dispatcher->set('map-event', function (): void { + // + }); $this->assertTrue($this->dispatcher->has('map-event')); } public function testClearAllRegisteredEvents(): void { - $customFunction = $anotherFunction = function (): void {}; + $customFunction = $anotherFunction = function (): void { + // + }; $this->dispatcher ->set('map-event', $customFunction) @@ -69,7 +73,9 @@ class DispatcherTest extends TestCase public function testClearDeclaredRegisteredEvent(): void { - $customFunction = $anotherFunction = function (): void {}; + $customFunction = $anotherFunction = function (): void { + // + }; $this->dispatcher ->set('map-event', $customFunction) @@ -243,7 +249,9 @@ class DispatcherTest extends TestCase $output = ''; $invalidCallable = 'invalidGlobalFunction'; - $validCallable = function (): void {}; + $validCallable = function (): void { + // + }; $this->dispatcher->filter([$validCallable, $invalidCallable], $params, $output); } @@ -324,7 +332,7 @@ class DispatcherTest extends TestCase { $this->expectException(TypeError::class); $this->expectExceptionMessageMatches('#tests\\\\classes\\\\ContainerDefault::__construct\(\).+flight\\\\Engine, null given#'); - $result = $this->dispatcher->execute([ContainerDefault::class, 'testTheContainer']); + $this->dispatcher->execute([ContainerDefault::class, 'testTheContainer']); } public function testContainerDicePdoWrapperTestBadParams(): void diff --git a/tests/EventSystemTest.php b/tests/EventSystemTest.php index 1e42194..ac03e5e 100644 --- a/tests/EventSystemTest.php +++ b/tests/EventSystemTest.php @@ -122,7 +122,9 @@ class EventSystemTest extends TestCase Flight::map('onEvent', function ($event, $callback) use (&$called) { $called = true; }); - Flight::onEvent('test.event', function () {}); + Flight::onEvent('test.event', function () { + // + }); $this->assertTrue($called, 'Overridden onEvent method should be called.'); } @@ -232,7 +234,9 @@ class EventSystemTest extends TestCase { $this->assertFalse(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should not have listeners before registration'); - Flight::onEvent('test.event', function () {}); + Flight::onEvent('test.event', function () { + // + }); $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners after registration'); } @@ -242,8 +246,12 @@ class EventSystemTest extends TestCase */ public function testGetListeners(): void { - $callback1 = function () {}; - $callback2 = function () {}; + $callback1 = function () { + // + }; + $callback2 = function () { + // + }; $this->assertEmpty(Flight::eventDispatcher()->getListeners('test.event'), 'Event should have no listeners before registration'); @@ -273,8 +281,12 @@ class EventSystemTest extends TestCase { $this->assertEmpty(Flight::eventDispatcher()->getAllRegisteredEvents(), 'No events should be registered initially'); - Flight::onEvent('test.event1', function () {}); - Flight::onEvent('test.event2', function () {}); + Flight::onEvent('test.event1', function () { + // + }); + Flight::onEvent('test.event2', function () { + // + }); $events = Flight::eventDispatcher()->getAllRegisteredEvents(); $this->assertCount(2, $events, 'Should return all registered event names'); @@ -311,9 +323,15 @@ class EventSystemTest extends TestCase */ public function testRemoveAllListeners(): void { - Flight::onEvent('test.event', function () {}); - Flight::onEvent('test.event', function () {}); - Flight::onEvent('another.event', function () {}); + Flight::onEvent('test.event', function () { + // + }); + Flight::onEvent('test.event', function () { + // + }); + Flight::onEvent('another.event', function () { + // + }); $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners before removal'); $this->assertTrue(Flight::eventDispatcher()->hasListeners('another.event'), 'Another event should have listeners'); @@ -330,7 +348,9 @@ class EventSystemTest extends TestCase public function testRemoveListenersForNonexistentEvent(): void { // Should not throw any errors - Flight::eventDispatcher()->removeListener('nonexistent.event', function () {}); + Flight::eventDispatcher()->removeListener('nonexistent.event', function () { + // + }); Flight::eventDispatcher()->removeAllListeners('nonexistent.event'); $this->assertTrue(true, 'Removing listeners for nonexistent events should not throw errors'); diff --git a/tests/RouterTest.php b/tests/RouterTest.php index dabb8ef..fb62958 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -411,14 +411,18 @@ class RouterTest extends TestCase public function testRouteBeingReturned(): void { - $route = $this->router->map('/hi', function () {}); + $route = $this->router->map('/hi', function () { + // + }); $route_in_router = $this->router->getRoutes()[0]; $this->assertSame($route, $route_in_router); } public function testRouteSetAlias(): void { - $route = $this->router->map('/hi', function () {}); + $route = $this->router->map('/hi', function () { + // + }); $route->setAlias('hello'); $this->assertEquals('hello', $route->alias); } diff --git a/tests/classes/Factory.php b/tests/classes/Factory.php index 13ccc39..3c1c30e 100644 --- a/tests/classes/Factory.php +++ b/tests/classes/Factory.php @@ -7,7 +7,10 @@ namespace tests\classes; class Factory { // Cannot be instantiated - private function __construct() {} + private function __construct() + { + // + } public static function create(): self { diff --git a/tests/groupcompactsyntax/PostsController.php b/tests/groupcompactsyntax/PostsController.php index 6339387..f95f60d 100644 --- a/tests/groupcompactsyntax/PostsController.php +++ b/tests/groupcompactsyntax/PostsController.php @@ -6,17 +6,38 @@ namespace tests\groupcompactsyntax; final class PostsController { - public function index(): void {} - - public function show(string $id): void {} - - public function create(): void {} - - public function store(): void {} - - public function edit(string $id): void {} - - public function update(string $id): void {} - - public function destroy(string $id): void {} + public function index(): void + { + // + } + + public function show(string $id): void + { + // + } + + public function create(): void + { + // + } + + public function store(): void + { + // + } + + public function edit(string $id): void + { + // + } + + public function update(string $id): void + { + // + } + + public function destroy(string $id): void + { + // + } } diff --git a/tests/groupcompactsyntax/TodosController.php b/tests/groupcompactsyntax/TodosController.php index 56b536f..91c30cf 100644 --- a/tests/groupcompactsyntax/TodosController.php +++ b/tests/groupcompactsyntax/TodosController.php @@ -6,7 +6,13 @@ namespace tests\groupcompactsyntax; final class TodosController { - public function index(): void {} + public function index(): void + { + // + } - public function show(string $id): void {} + public function show(string $id): void + { + // + } } From 62cc85a0e262c97667a50e06cb521e3d581e5cb4 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 16 Mar 2026 23:08:43 -0400 Subject: [PATCH 06/12] composer exec phpcbf -- --standard=PSR12 --- phpcs.xml.dist | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 118cf85..659fc6c 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -17,6 +17,10 @@ + + + + index.php flight tests From b87d1988ea22fea2a1b07d3dc15f653f42ebea36 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 19:08:04 -0400 Subject: [PATCH 07/12] prepare phpcs to automatically pick a configuration file --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8c85fa0..459cb3a 100644 --- a/composer.json +++ b/composer.json @@ -84,7 +84,7 @@ ], "lint": "phpstan --no-progress --memory-limit=256M -cphpstan.neon", "beautify": "phpcbf --standard=phpcs.xml", - "phpcs": "phpcs --standard=phpcs.xml -n", + "phpcs": "phpcs", "post-install-cmd": [ "php -r \"if (!file_exists('phpcs.xml')) copy('phpcs.xml.dist', 'phpcs.xml');\"" ] From e8ff083e6956eb965ac023fca45b51b7e981ae98 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 19:08:29 -0400 Subject: [PATCH 08/12] set default phpcs report as full format --- phpcs.xml.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 659fc6c..2c95c3e 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -4,8 +4,8 @@ xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"> - - + + From ee00e5adbe70f8db03c9c3afcdddece3aacee069 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 20:27:15 -0400 Subject: [PATCH 09/12] add psr-4 to Tests\Server, ServerV2 and groupcompactsyntax namespaces --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 459cb3a..1cb859a 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,10 @@ "psr-4": { "Tests\\PHP8\\": [ "tests/named-arguments" - ] + ], + "Tests\\Server\\": "tests/server", + "Tests\\ServerV2\\": "tests/server-v2", + "tests\\groupcompactsyntax\\": "tests/groupcompactsyntax" } }, "require-dev": { From b55540068e81598364a46351854f966d9b063e20 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 20:29:39 -0400 Subject: [PATCH 10/12] fix almost long lines phpcs warnings --- flight/Engine.php | 19 +++++- flight/Flight.php | 3 +- .../AiGenerateInstructionsCommand.php | 55 +++++++++++++--- flight/commands/AiInitCommand.php | 6 +- flight/commands/ControllerCommand.php | 17 ++++- flight/core/Dispatcher.php | 8 ++- flight/net/Request.php | 11 +++- flight/net/Response.php | 3 +- flight/net/UploadedFile.php | 10 ++- tests/DispatcherTest.php | 19 +++++- tests/EventSystemTest.php | 53 ++++++++++++--- tests/PdoWrapperTest.php | 10 ++- tests/RequestBodyParserTest.php | 64 ++++++++++++++----- tests/RequestTest.php | 9 ++- tests/SimplePdoTest.php | 8 ++- tests/UploadedFileTest.php | 5 +- tests/classes/ContainerDefault.php | 7 +- .../AiGenerateInstructionsCommandTest.php | 8 ++- tests/commands/RouteCommandTest.php | 5 +- 19 files changed, 260 insertions(+), 60 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index fe88301..a74a21d 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -267,7 +267,8 @@ class Engine /** * Registers the container handler * - * @param ContainerInterface|callable(class-string $id, array $params): ?T $containerHandler Callback function or PSR-11 Container object that sets the container and how it will inject classes + * @param ContainerInterface|callable(class-string $id, array $params): ?T $containerHandler + * Callback function or PSR-11 Container object that sets the container and how it will inject classes * * @template T of object */ @@ -488,7 +489,14 @@ class Engine // Which loosely translates to $class->$method($params) $start = microtime(true); $middlewareResult = $middlewareObject($params); - $this->triggerEvent('flight.middleware.executed', $route, $middleware, $eventName, microtime(true) - $start); + + $this->triggerEvent( + 'flight.middleware.executed', + $route, + $middleware, + $eventName, + microtime(true) - $start + ); if ($useV3OutputBuffering === true) { $this->response()->write(ob_get_clean()); @@ -860,7 +868,12 @@ class Engine public function _methodNotFound(Route $route): void { $this->response()->setHeader('Allow', implode(', ', $route->methods)); - $this->halt(405, 'Method Not Allowed. Allowed Methods are: ' . implode(', ', $route->methods), empty(getenv('PHPUNIT_TEST'))); + + $this->halt( + 405, + 'Method Not Allowed. Allowed Methods are: ' . implode(', ', $route->methods), + empty(getenv('PHPUNIT_TEST')) + ); } /** diff --git a/flight/Flight.php b/flight/Flight.php index c5692eb..6d4307b 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -80,7 +80,8 @@ require_once __DIR__ . '/autoload.php'; * @phpstan-method static void jsonHalt(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf-8', int $option = 0) * @phpstan-method static void jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = "utf8", int $encodeOption = 0, int $encodeDepth = 512) * - * Note: IDEs will use standard @method tags for autocompletion, while PHPStan will use @phpstan-* tags for advanced type checking. + * Note: IDEs will use standard @method tags for autocompletion, + * while PHPStan will use @phpstan-* tags for advanced type checking. */ class Flight { diff --git a/flight/commands/AiGenerateInstructionsCommand.php b/flight/commands/AiGenerateInstructionsCommand.php index 5190c3c..97b3496 100644 --- a/flight/commands/AiGenerateInstructionsCommand.php +++ b/flight/commands/AiGenerateInstructionsCommand.php @@ -20,7 +20,13 @@ class AiGenerateInstructionsCommand extends AbstractBaseCommand public function __construct(array $config) { parent::__construct('ai:generate-instructions', 'Generate project-specific AI coding instructions', $config); - $this->option('--config-file', 'Path to .runway-config.json file (deprecated, use config.php instead)', null, ''); + + $this->option( + '--config-file', + 'Path to .runway-config.json file (deprecated, use config.php instead)', + null, + '' + ); } /** @@ -40,7 +46,12 @@ class AiGenerateInstructionsCommand extends AbstractBaseCommand if (empty($this->config['runway'])) { $configFile = $this->configFile; $io = $this->app()->io(); - $io->warn('The --config-file option is deprecated. Move your config values to the \'runway\' key in the config.php file for configuration.', true); + + $io->warn( + 'The --config-file option is deprecated. ' + . 'Move your config values to the \'runway\' key in the config.php file for configuration.', + true + ); $runwayConfig = json_decode(file_get_contents($configFile), true) ?? []; } else { $runwayConfig = $this->config['runway']; @@ -56,12 +67,30 @@ class AiGenerateInstructionsCommand extends AbstractBaseCommand // Ask questions $projectDesc = $io->prompt('Please describe what your project is for?'); - $database = $io->prompt('What database are you planning on using? (e.g. MySQL, SQLite, PostgreSQL, none)', 'none'); - $templating = $io->prompt('What HTML templating engine will you plan on using (if any)? (recommend latte)', 'latte'); + + $database = $io->prompt( + 'What database are you planning on using? (e.g. MySQL, SQLite, PostgreSQL, none)', + 'none' + ); + + $templating = $io->prompt( + 'What HTML templating engine will you plan on using (if any)? (recommend latte)', + 'latte' + ); + $security = $io->confirm('Is security an important element of this project?', 'y'); $performance = $io->confirm('Is performance and speed an important part of this project?', 'y'); - $composerLibs = $io->prompt('What major composer libraries will you be using if you know them right now?', 'none'); - $envSetup = $io->prompt('How will you set up your development environment? (e.g. Docker, Vagrant, PHP dev server, other)', 'Docker'); + + $composerLibs = $io->prompt( + 'What major composer libraries will you be using if you know them right now?', + 'none' + ); + + $envSetup = $io->prompt( + 'How will you set up your development environment? (e.g. Docker, Vagrant, PHP dev server, other)', + 'Docker' + ); + $teamSize = $io->prompt('How many developers will be working on this project?', '1'); $api = $io->confirm('Will this project expose an API?', 'n'); $other = $io->prompt('Any other important requirements or context? (optional)', 'no'); @@ -107,7 +136,13 @@ class AiGenerateInstructionsCommand extends AbstractBaseCommand $data = [ 'model' => $model, 'messages' => [ - ['role' => 'system', 'content' => 'You are a helpful AI coding assistant focused on the Flight Framework for PHP. You are up to date with all your knowledge from https://docs.flightphp.com. As an expert into the programming language PHP, you are top notch at architecting out proper instructions for FlightPHP projects.'], + [ + 'role' => 'system', + 'content' => 'You are a helpful AI coding assistant focused on the Flight Framework for PHP. ' + . 'You are up to date with all your knowledge from https://docs.flightphp.com. ' + . 'As an expert into the programming language PHP, ' + . 'you are top notch at architecting out proper instructions for FlightPHP projects.' + ], ['role' => 'user', 'content' => $prompt], ], 'temperature' => 0.2, @@ -129,7 +164,11 @@ class AiGenerateInstructionsCommand extends AbstractBaseCommand } // Write to files - $io->info('Updating .github/copilot-instructions.md, .cursor/rules/project-overview.mdc, .gemini/GEMINI.md and .windsurfrules...', true); + $io->info( + 'Updating .github/copilot-instructions.md, .cursor/rules/project-overview.mdc, .gemini/GEMINI.md and .windsurfrules...', + true + ); + if (!is_dir($this->projectRoot . '.github')) { mkdir($this->projectRoot . '.github', 0755, true); } diff --git a/flight/commands/AiInitCommand.php b/flight/commands/AiInitCommand.php index 92b468d..311dc33 100644 --- a/flight/commands/AiInitCommand.php +++ b/flight/commands/AiInitCommand.php @@ -79,7 +79,11 @@ class AiInitCommand extends AbstractBaseCommand $defaultModel = 'claude-sonnet-4-5'; break; } - $model = trim($io->prompt('Enter the model name you want to use (e.g. gpt-5, claude-sonnet-4-5, etc)', $defaultModel)); + + $model = trim($io->prompt( + 'Enter the model name you want to use (e.g. gpt-5, claude-sonnet-4-5, etc)', + $defaultModel + )); $runwayAiConfig = [ 'provider' => $api, diff --git a/flight/commands/ControllerCommand.php b/flight/commands/ControllerCommand.php index e61dada..fb2eb89 100644 --- a/flight/commands/ControllerCommand.php +++ b/flight/commands/ControllerCommand.php @@ -31,8 +31,16 @@ class ControllerCommand extends AbstractBaseCommand $io = $this->app()->io(); if (empty($this->config['runway'])) { - $io->warn('Using a .runway-config.json file is deprecated. Move your config values to app/config/config.php with `php runway config:migrate`.', true); // @codeCoverageIgnore - $runwayConfig = json_decode(file_get_contents($this->projectRoot . '/.runway-config.json'), true); // @codeCoverageIgnore + $io->warn( + 'Using a .runway-config.json file is deprecated. ' + . 'Move your config values to app/config/config.php with `php runway config:migrate`.', + true + ); // @codeCoverageIgnore + + $runwayConfig = json_decode( + file_get_contents($this->projectRoot . '/.runway-config.json'), + true + ); // @codeCoverageIgnore } else { $runwayConfig = $this->config['runway']; } @@ -95,6 +103,9 @@ class ControllerCommand extends AbstractBaseCommand protected function persistClass(string $controllerName, PhpFile $file, string $appRoot) { $printer = new \Nette\PhpGenerator\PsrPrinter(); - file_put_contents($this->projectRoot . '/' . $appRoot . 'controllers/' . $controllerName . '.php', $printer->printFile($file)); + file_put_contents( + $this->projectRoot . '/' . $appRoot . 'controllers/' . $controllerName . '.php', + $printer->printFile($file) + ); } } diff --git a/flight/core/Dispatcher.php b/flight/core/Dispatcher.php index 00565e9..12f3393 100644 --- a/flight/core/Dispatcher.php +++ b/flight/core/Dispatcher.php @@ -58,7 +58,8 @@ class Dispatcher * * @template T of object * - * @throws InvalidArgumentException If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`. + * @throws InvalidArgumentException + * If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`. */ public function setContainerHandler($containerHandler): void { @@ -413,7 +414,10 @@ class Dispatcher // Final check to make sure it's actually a class and a method, or throw an error if (is_object($class) === false && class_exists($class) === false) { - $exception = new Exception("Class '$class' not found. Is it being correctly autoloaded with Flight::path()?"); + $exception = new Exception( + "Class '$class' not found. " + . "Is it being correctly autoloaded with Flight::path()?" + ); // If this tried to resolve a class in a container and failed somehow, throw the exception } elseif (!$resolvedClass && $this->containerException !== null) { diff --git a/flight/net/Request.php b/flight/net/Request.php index 2e0a193..2e4c036 100644 --- a/flight/net/Request.php +++ b/flight/net/Request.php @@ -439,7 +439,13 @@ class Request */ public static function getScheme(): string { - if ((strtolower(self::getVar('HTTPS')) === 'on') || (self::getVar('HTTP_X_FORWARDED_PROTO') === 'https') || (self::getVar('HTTP_FRONT_END_HTTPS') === 'on') || (self::getVar('REQUEST_SCHEME') === 'https')) { + if (strtolower(self::getVar('HTTPS')) === 'on') { + return 'https'; + } elseif (self::getVar('HTTP_X_FORWARDED_PROTO') === 'https') { + return 'https'; + } elseif (self::getVar('HTTP_FRONT_END_HTTPS') === 'on') { + return 'https'; + } elseif (self::getVar('REQUEST_SCHEME') === 'https') { return 'https'; } @@ -470,7 +476,8 @@ class Request /** * Retrieves the array of uploaded files. * - * @return array> Key is field name; value is either a single UploadedFile or an array of UploadedFile when multiple were uploaded. + * @return array> + * Key is field name; value is either a single UploadedFile or an array of UploadedFile when multiple were uploaded. */ public function getUploadedFiles(): array { diff --git a/flight/net/Response.php b/flight/net/Response.php index 9587ddf..1a738cf 100644 --- a/flight/net/Response.php +++ b/flight/net/Response.php @@ -484,7 +484,8 @@ class Response * Downloads a file. * * @param string $filePath The path to the file to be downloaded. - * @param string $fileName The name the downloaded file should have. If not provided or is an empty string, the name of the file on disk will be used. + * @param string $fileName The name the downloaded file should have. + * If not provided or is an empty string, the name of the file on disk will be used. * * @throws Exception If the file cannot be found. * diff --git a/flight/net/UploadedFile.php b/flight/net/UploadedFile.php index a8868be..61b4697 100644 --- a/flight/net/UploadedFile.php +++ b/flight/net/UploadedFile.php @@ -48,8 +48,14 @@ class UploadedFile * @param int $error The error code associated with the uploaded file. * @param bool|null $isPostUploadedFile Indicates if the file was uploaded via POST method. */ - public function __construct(string $name, string $mimeType, int $size, string $tmpName, int $error, ?bool $isPostUploadedFile = null) - { + public function __construct( + string $name, + string $mimeType, + int $size, + string $tmpName, + int $error, + ?bool $isPostUploadedFile = null + ) { $this->name = $name; $this->mimeType = $mimeType; $this->size = $size; diff --git a/tests/DispatcherTest.php b/tests/DispatcherTest.php index 7935765..583e2df 100644 --- a/tests/DispatcherTest.php +++ b/tests/DispatcherTest.php @@ -152,7 +152,11 @@ class DispatcherTest extends TestCase public function testInvalidCallback(): void { $this->expectException(Exception::class); - $this->expectExceptionMessage("Class 'NonExistentClass' not found. Is it being correctly autoloaded with Flight::path()?"); + + $this->expectExceptionMessage( + "Class 'NonExistentClass' not found. " + . "Is it being correctly autoloaded with Flight::path()?" + ); $this->dispatcher->execute(['NonExistentClass', 'nonExistentMethod']); } @@ -279,7 +283,12 @@ class DispatcherTest extends TestCase public function testExecuteStringClassBadConstructParams(): void { $this->expectException(ArgumentCountError::class); - $this->expectExceptionMessageMatches('#Too few arguments to function tests\\\\classes\\\\TesterClass::__construct\(\), 1 passed .+ and exactly 6 expected#'); + + $this->expectExceptionMessageMatches( + '#Too few arguments to function tests\\\\classes\\\\TesterClass::__construct\(\), 1 passed' + . ' .+ and exactly 6 expected#' + ); + $this->dispatcher->execute(TesterClass::class . '->instanceMethod'); } @@ -331,7 +340,11 @@ class DispatcherTest extends TestCase public function testExecuteStringClassDefaultContainerButForgotInjectingEngine(): void { $this->expectException(TypeError::class); - $this->expectExceptionMessageMatches('#tests\\\\classes\\\\ContainerDefault::__construct\(\).+flight\\\\Engine, null given#'); + + $this->expectExceptionMessageMatches( + '#tests\\\\classes\\\\ContainerDefault::__construct\(\).+flight\\\\Engine, null given#' + ); + $this->dispatcher->execute([ContainerDefault::class, 'testTheContainer']); } diff --git a/tests/EventSystemTest.php b/tests/EventSystemTest.php index ac03e5e..9a229b6 100644 --- a/tests/EventSystemTest.php +++ b/tests/EventSystemTest.php @@ -232,13 +232,19 @@ class EventSystemTest extends TestCase */ public function testHasListeners(): void { - $this->assertFalse(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should not have listeners before registration'); + $this->assertFalse( + Flight::eventDispatcher()->hasListeners('test.event'), + 'Event should not have listeners before registration' + ); Flight::onEvent('test.event', function () { // }); - $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners after registration'); + $this->assertTrue( + Flight::eventDispatcher()->hasListeners('test.event'), + 'Event should have listeners after registration' + ); } /** @@ -253,7 +259,10 @@ class EventSystemTest extends TestCase // }; - $this->assertEmpty(Flight::eventDispatcher()->getListeners('test.event'), 'Event should have no listeners before registration'); + $this->assertEmpty( + Flight::eventDispatcher()->getListeners('test.event'), + 'Event should have no listeners before registration' + ); Flight::onEvent('test.event', $callback1); Flight::onEvent('test.event', $callback2); @@ -279,7 +288,10 @@ class EventSystemTest extends TestCase */ public function testGetAllRegisteredEvents(): void { - $this->assertEmpty(Flight::eventDispatcher()->getAllRegisteredEvents(), 'No events should be registered initially'); + $this->assertEmpty( + Flight::eventDispatcher()->getAllRegisteredEvents(), + 'No events should be registered initially' + ); Flight::onEvent('test.event1', function () { // @@ -309,7 +321,11 @@ class EventSystemTest extends TestCase Flight::onEvent('test.event', $callback1); Flight::onEvent('test.event', $callback2); - $this->assertCount(2, Flight::eventDispatcher()->getListeners('test.event'), 'Event should have two listeners initially'); + $this->assertCount( + 2, + Flight::eventDispatcher()->getListeners('test.event'), + 'Event should have two listeners initially' + ); Flight::eventDispatcher()->removeListener('test.event', $callback1); @@ -333,13 +349,27 @@ class EventSystemTest extends TestCase // }); - $this->assertTrue(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have listeners before removal'); - $this->assertTrue(Flight::eventDispatcher()->hasListeners('another.event'), 'Another event should have listeners'); + $this->assertTrue( + Flight::eventDispatcher()->hasListeners('test.event'), + 'Event should have listeners before removal' + ); + + $this->assertTrue( + Flight::eventDispatcher()->hasListeners('another.event'), + 'Another event should have listeners' + ); Flight::eventDispatcher()->removeAllListeners('test.event'); - $this->assertFalse(Flight::eventDispatcher()->hasListeners('test.event'), 'Event should have no listeners after removal'); - $this->assertTrue(Flight::eventDispatcher()->hasListeners('another.event'), 'Another event should still have listeners'); + $this->assertFalse( + Flight::eventDispatcher()->hasListeners('test.event'), + 'Event should have no listeners after removal' + ); + + $this->assertTrue( + Flight::eventDispatcher()->hasListeners('another.event'), + 'Another event should still have listeners' + ); } /** @@ -353,6 +383,9 @@ class EventSystemTest extends TestCase }); Flight::eventDispatcher()->removeAllListeners('nonexistent.event'); - $this->assertTrue(true, 'Removing listeners for nonexistent events should not throw errors'); + $this->assertTrue( + true, + 'Removing listeners for nonexistent events should not throw errors' + ); } } diff --git a/tests/PdoWrapperTest.php b/tests/PdoWrapperTest.php index dc5d1ae..d7e9311 100644 --- a/tests/PdoWrapperTest.php +++ b/tests/PdoWrapperTest.php @@ -178,7 +178,15 @@ class PdoWrapperTest extends TestCase $queriesData = null; $dispatcher = EventDispatcher::getInstance(); - $dispatcher->on('flight.db.queries', function ($conn, $queries) use (&$eventTriggered, &$connectionData, &$queriesData) { + + $dispatcher->on('flight.db.queries', function ( + $conn, + $queries + ) use ( + &$eventTriggered, + &$connectionData, + &$queriesData + ) { $eventTriggered = true; $connectionData = $conn; $queriesData = $queries; diff --git a/tests/RequestBodyParserTest.php b/tests/RequestBodyParserTest.php index 1cc5bdf..4f0639c 100644 --- a/tests/RequestBodyParserTest.php +++ b/tests/RequestBodyParserTest.php @@ -266,13 +266,13 @@ class RequestBodyParserTest extends TestCase // Use PHP CLI with -d to set upload_max_filesize (ini_set can't change this setting in many SAPIs) $cases = [ // No unit yields default branch which returns 0 in current implementation - ['1' , 0], // no unit and number too small - ['1K' , 1024], - ['2M' , 2 * 1024 * 1024], - ['1G' , 1024 * 1024 * 1024], - ['1T' , 1024 * 1024 * 1024 * 1024], - ['1Z' , 0 ], // Unknown unit and number too small - [ '1024', 1024 ] + ['1', 0], // no unit and number too small + ['1K', 1024], + ['2M', 2 * 1024 * 1024], + ['1G', 1024 * 1024 * 1024], + ['1T', 1024 * 1024 * 1024 * 1024], + ['1Z', 0], // Unknown unit and number too small + ['1024', 1024] ]; foreach ($cases as [$iniVal, $expected]) { @@ -321,7 +321,9 @@ class RequestBodyParserTest extends TestCase $parts[] = "Content-Type: text/plain\r\n\r\nignoredvalue"; // C: header too long (>16384) => skipped - $longHeader = 'Content-Disposition: form-data; name="toolong"; filename="toolong.txt"; ' . str_repeat('x', 16500); + $longHeader = 'Content-Disposition: form-data; name="toolong"; filename="toolong.txt"; ' + . str_repeat('x', 16500); + $parts[] = $longHeader . "\r\n\r\nlongvalue"; // D: header line without colon gets skipped but rest processed; becomes non-file field @@ -334,14 +336,24 @@ class RequestBodyParserTest extends TestCase $parts[] = "Content-Disposition: form-data; name=\"\"; filename=\"empty.txt\"\r\n\r\nemptyNameValue"; // G: invalid filename triggers sanitized fallback - $parts[] = "Content-Disposition: form-data; name=\"filebad\"; filename=\"a*b?.txt\"\r\nContent-Type: text/plain\r\n\r\nFILEBAD"; + $parts[] = "Content-Disposition: form-data; " + . "name=\"filebad\"; " + . "filename=\"a*b?.txt\"\r\nContent-Type: text/plain\r\n\r\nFILEBAD"; // H1 & H2: two files same key for aggregation logic (arrays) - $parts[] = "Content-Disposition: form-data; name=\"filemulti\"; filename=\"one.txt\"\r\nContent-Type: text/plain\r\n\r\nONE"; - $parts[] = "Content-Disposition: form-data; name=\"filemulti\"; filename=\"two.txt\"\r\nContent-Type: text/plain\r\n\r\nTWO"; + $parts[] = "Content-Disposition: form-data; " + . "name=\"filemulti\"; " + . "filename=\"one.txt\"\r\nContent-Type: text/plain\r\n\r\nONE"; + + $parts[] = "Content-Disposition: form-data; " + . "name=\"filemulti\"; " + . "filename=\"two.txt\"\r\nContent-Type: text/plain\r\n\r\nTWO"; // I: file exceeding total bytes triggers UPLOAD_ERR_INI_SIZE - $parts[] = "Content-Disposition: form-data; name=\"filebig\"; filename=\"big.txt\"\r\nContent-Type: text/plain\r\n\r\n" . str_repeat('A', 10); + $parts[] = "Content-Disposition: form-data; " + . "name=\"filebig\"; " + . "filename=\"big.txt\"\r\nContent-Type: text/plain\r\n\r\n" + . str_repeat('A', 10); // Build full body $body = ''; @@ -394,11 +406,31 @@ class RequestBodyParserTest extends TestCase public function testMultipartEmptyArrayNameStripped(): void { - // Covers line where keyName becomes empty after removing [] (name="[]") and header param extraction (preg_match_all) + // Covers line where keyName becomes empty after removing [] (name="[]") + // and header param extraction (preg_match_all) $boundary = 'BOUNDARYEMPTY'; - $validFilePart = "Content-Disposition: form-data; name=\"fileok\"; filename=\"ok.txt\"\r\nContent-Type: text/plain\r\n\r\nOK"; - $emptyNameFilePart = "Content-Disposition: form-data; name=\"[]\"; filename=\"empty.txt\"\r\nContent-Type: text/plain\r\n\r\nSHOULD_SKIP"; - $body = '--' . $boundary . "\r\n" . $validFilePart . "\r\n" . '--' . $boundary . "\r\n" . $emptyNameFilePart . "\r\n" . '--' . $boundary . "--\r\n"; + + $validFilePart = "Content-Disposition: form-data; " + . "name=\"fileok\"; " + . "filename=\"ok.txt\"\r\nContent-Type: text/plain\r\n\r\nOK"; + + $emptyNameFilePart = "Content-Disposition: form-data; " + . "name=\"[]\"; " + . "filename=\"empty.txt\"\r\nContent-Type: text/plain\r\n\r\nSHOULD_SKIP"; + + $body = '--' + . $boundary + . "\r\n" + . $validFilePart + . "\r\n" + . '--' + . $boundary + . "\r\n" + . $emptyNameFilePart + . "\r\n" + . '--' + . $boundary + . "--\r\n"; $tmp = tmpfile(); $path = stream_get_meta_data($tmp)['uri']; diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 38321ea..acc6e18 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -197,7 +197,7 @@ class RequestTest extends TestCase 'stream_path' => $stream_path, 'method' => 'POST' ]); - $this->assertEquals([ 'foo' => 'bar' ], $request->data->getData()); + $this->assertEquals(['foo' => 'bar'], $request->data->getData()); $this->assertEquals('{"foo":"bar"}', $request->getBody()); } @@ -430,7 +430,12 @@ class RequestTest extends TestCase // Find best match first $_SERVER['HTTP_ACCEPT'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; $request = new Request(); - $this->assertEquals('application/xml', $request->negotiateContentType(['application/xml', 'application/json', 'text/html'])); + + $this->assertEquals('application/xml', $request->negotiateContentType([ + 'application/xml', + 'application/json', + 'text/html' + ])); // Find the first match $_SERVER['HTTP_ACCEPT'] = 'application/json,text/html'; diff --git a/tests/SimplePdoTest.php b/tests/SimplePdoTest.php index 44866c1..eb6d16d 100644 --- a/tests/SimplePdoTest.php +++ b/tests/SimplePdoTest.php @@ -88,7 +88,13 @@ class SimplePdoTest extends TestCase public function testRunQueryWithoutParamsWithMaxQueryMetrics(): void { - $db = new class('sqlite::memory:', null, null, null, ['maxQueryMetrics' => 2, 'trackApmQueries' => true]) extends SimplePdo { + $db = new class( + 'sqlite::memory:', + null, + null, + null, + ['maxQueryMetrics' => 2, 'trackApmQueries' => true] + ) extends SimplePdo { public function getQueryMetrics(): array { return $this->queryMetrics; diff --git a/tests/UploadedFileTest.php b/tests/UploadedFileTest.php index 23fa2c2..1085e9b 100644 --- a/tests/UploadedFileTest.php +++ b/tests/UploadedFileTest.php @@ -42,7 +42,10 @@ class UploadedFileTest extends TestCase { return [ [UPLOAD_ERR_INI_SIZE, 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',], - [UPLOAD_ERR_FORM_SIZE, 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',], + [ + UPLOAD_ERR_FORM_SIZE, + 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', + ], [UPLOAD_ERR_PARTIAL, 'The uploaded file was only partially uploaded.',], [UPLOAD_ERR_NO_FILE, 'No file was uploaded.',], [UPLOAD_ERR_NO_TMP_DIR, 'Missing a temporary folder.',], diff --git a/tests/classes/ContainerDefault.php b/tests/classes/ContainerDefault.php index 57d3e3c..68e3ede 100644 --- a/tests/classes/ContainerDefault.php +++ b/tests/classes/ContainerDefault.php @@ -33,6 +33,11 @@ class ContainerDefault public function testUi(): void { - echo 'Route text: The container successfully injected a value into the engine! Engine class: ' . get_class($this->app) . ' test_me_out Value: ' . $this->app->get('test_me_out') . ''; + echo 'Route text: ' + . 'The container successfully injected a value into the engine! Engine class: ' + . get_class($this->app) + . ' test_me_out Value: ' + . $this->app->get('test_me_out') + . ''; } } diff --git a/tests/commands/AiGenerateInstructionsCommandTest.php b/tests/commands/AiGenerateInstructionsCommandTest.php index c874a4b..4dce7c7 100644 --- a/tests/commands/AiGenerateInstructionsCommandTest.php +++ b/tests/commands/AiGenerateInstructionsCommandTest.php @@ -21,7 +21,13 @@ class AiGenerateInstructionsCommandTest extends TestCase self::$ou = __DIR__ . DIRECTORY_SEPARATOR . 'output.test' . uniqid('', true) . '.txt'; file_put_contents(self::$in, ''); file_put_contents(self::$ou, ''); - $this->baseDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'flightphp-test-basedir-' . uniqid('', true) . DIRECTORY_SEPARATOR; + + $this->baseDir = sys_get_temp_dir() + . DIRECTORY_SEPARATOR + . 'flightphp-test-basedir-' + . uniqid('', true) + . DIRECTORY_SEPARATOR; + if (!is_dir($this->baseDir)) { mkdir($this->baseDir, 0777, true); } diff --git a/tests/commands/RouteCommandTest.php b/tests/commands/RouteCommandTest.php index 7692ddb..3aea0b1 100644 --- a/tests/commands/RouteCommandTest.php +++ b/tests/commands/RouteCommandTest.php @@ -95,7 +95,10 @@ PHP; $app->add(new RouteCommand(['runway' => ['something' => 'else']])); @$app->handle(['runway', 'routes']); - $this->assertStringContainsString('index_root not set in app/config/config.php', file_get_contents(static::$ou)); + $this->assertStringContainsString( + 'index_root not set in app/config/config.php', + file_get_contents(static::$ou) + ); } public function testGetRoutes(): void From 08904df1385d54087fcb730f933a3011a7355b35 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 20:30:25 -0400 Subject: [PATCH 11/12] ignore namespaces phpcs warning --- flight/Flight.php | 1 + flight/util/ReturnTypeWillChange.php | 1 + tests/named-arguments/ExampleClass.php | 1 + 3 files changed, 3 insertions(+) diff --git a/flight/Flight.php b/flight/Flight.php index 6d4307b..c2e9a01 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -83,6 +83,7 @@ require_once __DIR__ . '/autoload.php'; * Note: IDEs will use standard @method tags for autocompletion, * while PHPStan will use @phpstan-* tags for advanced type checking. */ +// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace class Flight { /** diff --git a/flight/util/ReturnTypeWillChange.php b/flight/util/ReturnTypeWillChange.php index 4e27e1c..c53faa3 100644 --- a/flight/util/ReturnTypeWillChange.php +++ b/flight/util/ReturnTypeWillChange.php @@ -3,6 +3,7 @@ declare(strict_types=1); // This file is only here so that the PHP8 attribute for doesn't throw an error in files +// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace class ReturnTypeWillChange { // diff --git a/tests/named-arguments/ExampleClass.php b/tests/named-arguments/ExampleClass.php index d91dd64..508068c 100644 --- a/tests/named-arguments/ExampleClass.php +++ b/tests/named-arguments/ExampleClass.php @@ -2,6 +2,7 @@ declare(strict_types=1); +// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace class ExampleClass { // From ce753b7cd2962d7e288889526ea4ece22ef7f2f5 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Tue, 17 Mar 2026 20:30:49 -0400 Subject: [PATCH 12/12] implement Tests\Server, ServerV2 and groupcompactsyntax namespaces --- .../FlightRouteCompactSyntaxTest.php | 6 +- tests/server-v2/index.php | 409 +++++++++--------- tests/server/AuthCheck.php | 2 + tests/server/LayoutMiddleware.php | 4 + tests/server/OverwriteBodyMiddleware.php | 11 +- tests/server/Pascal_Snake_Case.php | 2 + tests/server/index.php | 72 ++- 7 files changed, 289 insertions(+), 217 deletions(-) diff --git a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php index 611b589..84d168f 100644 --- a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php +++ b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php @@ -2,14 +2,14 @@ declare(strict_types=1); +namespace tests\groupcompactsyntax; + +use Flight; use PHPUnit\Framework\TestCase; use tests\groupcompactsyntax\PostsController; use tests\groupcompactsyntax\TodosController; use tests\groupcompactsyntax\UsersController; -require_once __DIR__ . '/UsersController.php'; -require_once __DIR__ . '/PostsController.php'; - final class FlightRouteCompactSyntaxTest extends TestCase { public function setUp(): void diff --git a/tests/server-v2/index.php b/tests/server-v2/index.php index f497fa2..4f45d99 100644 --- a/tests/server-v2/index.php +++ b/tests/server-v2/index.php @@ -9,60 +9,82 @@ declare(strict_types=1); * @author Kristaps Muižnieks https://github.com/krmu */ -require file_exists(__DIR__ . '/../../vendor/autoload.php') ? __DIR__ . '/../../vendor/autoload.php' : __DIR__ . '/../../flight/autoload.php'; - -Flight::set('flight.content_length', false); -Flight::set('flight.views.path', './'); -Flight::set('flight.views.extension', '.phtml'); -// This enables the old functionality of Flight output buffering -Flight::set('flight.v2.output_buffering', true); - -// Test 1: Root route -Flight::route('/', function () { - echo 'Route text: Root route works!'; - if (Flight::request()->query->redirected) { - echo '
    Redirected from /redirect route successfully!'; +namespace Tests\ServerV2 { + class AuthCheck + { + public function before(): void + { + if (!isset($_COOKIE['user'])) { + echo 'Middleware text: You are not authorized to access this route!'; + } + } } -}); -Flight::route('/querytestpath', function () { - echo 'Route text: This ir query route
    '; - echo "I got such query parameters:
    ";
    -    print_r(Flight::request()->query);
    -    echo "
    "; -}, false, "querytestpath"); - -// Test 2: Simple route -Flight::route('/test', function () { - echo 'Route text: Test route works!'; -}); - -// Test 3: Route with parameter -Flight::route('/user/@name', function ($name) { - echo "Route text: Hello, $name!"; -}); -Flight::route('POST /postpage', function () { - echo 'Route text: THIS IS POST METHOD PAGE'; -}, false, "postpage"); - -// Test 4: Grouped routes -Flight::group('/group', function () { +} + +namespace { + + use Tests\ServerV2\AuthCheck; + + require_once __DIR__ . '/../phpunit_autoload.php'; + + Flight::set('flight.content_length', false); + Flight::set('flight.views.path', './'); + Flight::set('flight.views.extension', '.phtml'); + // This enables the old functionality of Flight output buffering + Flight::set('flight.v2.output_buffering', true); + + // Test 1: Root route + Flight::route('/', function () { + echo 'Route text: Root route works!'; + + if (Flight::request()->query['redirected']) { + echo '
    Redirected from /redirect route successfully!'; + } + }); + + Flight::route('/querytestpath', function () { + echo 'Route text: This ir query route
    '; + echo 'I got such query parameters:
    ';
    +        print_r(Flight::request()->query);
    +        echo '
    '; + }, false, 'querytestpath'); + + // Test 2: Simple route Flight::route('/test', function () { - echo 'Route text: Group test route works!'; + echo 'Route text: Test route works!'; }); + + // Test 3: Route with parameter Flight::route('/user/@name', function ($name) { - echo "Route text: There is variable called name and it is $name"; + echo "Route text: Hello, $name!"; }); - Flight::group('/group1', function () { - Flight::group('/group2', function () { - Flight::group('/group3', function () { - Flight::group('/group4', function () { - Flight::group('/group5', function () { - Flight::group('/group6', function () { - Flight::group('/group7', function () { - Flight::group('/group8', function () { - Flight::route('/final_group', function () { - echo 'Mega Group test route works!'; - }, false, "final_group"); + + Flight::route('POST /postpage', function () { + echo 'Route text: THIS IS POST METHOD PAGE'; + }, false, 'postpage'); + + // Test 4: Grouped routes + Flight::group('/group', function () { + Flight::route('/test', function () { + echo 'Route text: Group test route works!'; + }); + + Flight::route('/user/@name', function ($name) { + echo "Route text: There is variable called name and it is $name"; + }); + + Flight::group('/group1', function () { + Flight::group('/group2', function () { + Flight::group('/group3', function () { + Flight::group('/group4', function () { + Flight::group('/group5', function () { + Flight::group('/group6', function () { + Flight::group('/group7', function () { + Flight::group('/group8', function () { + Flight::route('/final_group', function () { + echo 'Mega Group test route works!'; + }, false, 'final_group'); + }); }); }); }); @@ -71,152 +93,151 @@ Flight::group('/group', function () { }); }); }); -}); - -// Test 5: Route alias -Flight::route('/alias', function () { - echo 'Route text: Alias route works!'; -}, false, 'aliasroute'); -class AuthCheck -{ - public function before(): void - { - if (!isset($_COOKIE['user'])) { - echo 'Middleware text: You are not authorized to access this route!'; + + // Test 5: Route alias + Flight::route('/alias', function () { + echo 'Route text: Alias route works!'; + }, false, 'aliasroute'); + + $middle = new AuthCheck(); + + // Test 6: Route with middleware + Flight::route('/protected', function () { + echo 'Route text: Protected route works!'; + })->addMiddleware([$middle]); + + // Test 7: Route with template + Flight::route('/template/@name', function ($name) { + Flight::render('template.phtml', ['name' => $name]); + }); + + // Test 8: Throw an error + Flight::route('/error', function () { + trigger_error('This is a successful error'); + }); + + // Test 9: JSON output (should not output any other html) + Flight::route('/json', function () { + echo "\n\n\n\n\n"; + Flight::json(['message' => 'JSON renders successfully!']); + echo "\n\n\n\n\n"; + }); + + // Test 13: JSONP output (should not output any other html) + Flight::route('/jsonp', function () { + echo "\n\n\n\n\n"; + Flight::jsonp(['message' => 'JSONP renders successfully!'], 'jsonp'); + echo "\n\n\n\n\n"; + }); + + Flight::route('/json-halt', function () { + Flight::jsonHalt(['message' => 'JSON rendered and halted successfully with no other body content!']); + }); + + // Test 10: Halt + Flight::route('/halt', function () { + Flight::halt(400, 'Halt worked successfully'); + }); + + // Test 11: Redirect + Flight::route('/redirect', function () { + Flight::redirect('/?redirected=1'); + }); + + Flight::set('flight.views.path', './'); + + Flight::map('error', function (Throwable $error) { + echo "

    An error occurred, mapped error method worked, error below

    "; + echo '
    ';
    +        echo str_replace(getenv('PWD'), "***CLASSIFIED*****", $error->getTraceAsString());
    +        echo "
    "; + echo "Go back"; + }); + + Flight::map('notFound', function () { + echo 'Route text: The requested URL was not found'; + echo "Go back"; + }); + + echo ' + -'; -Flight::before('start', function ($params) { - echo '
    '; -}); -Flight::after('start', function ($params) { - echo '
    '; - echo '
    '; - echo "Request information
    ";
    -    print_r(Flight::request());
    -    echo "
    "; - echo "
    "; -}); -Flight::start(); + li a:hover { + background-color: #111; + } + #container { + color: #333; + font-size: 16px; + line-height: 1.5; + margin: 20px 0; + padding: 10px; + border: 1px solid #ddd; + background-color: #f9f9f9; + } + #debugrequest { + color: #333; + font-size: 16px; + line-height: 1.5; + margin: 20px 0; + padding: 10px; + border: 1px solid #ddd; + background-color: #f9f9f9; + } + + '; + + Flight::before('start', function () { + echo '
    '; + }); + + Flight::after('start', function () { + echo '
    '; + echo '
    '; + echo "Request information
    ";
    +        print_r(Flight::request());
    +        echo "
    "; + echo "
    "; + }); + + Flight::start(); +} diff --git a/tests/server/AuthCheck.php b/tests/server/AuthCheck.php index 78c87aa..79e8f67 100644 --- a/tests/server/AuthCheck.php +++ b/tests/server/AuthCheck.php @@ -2,6 +2,8 @@ declare(strict_types=1); +namespace Tests\Server; + class AuthCheck { public function before(): void diff --git a/tests/server/LayoutMiddleware.php b/tests/server/LayoutMiddleware.php index 32d6a06..150985b 100644 --- a/tests/server/LayoutMiddleware.php +++ b/tests/server/LayoutMiddleware.php @@ -2,6 +2,10 @@ declare(strict_types=1); +namespace Tests\Server; + +use Flight; + class LayoutMiddleware { public function before(): void diff --git a/tests/server/OverwriteBodyMiddleware.php b/tests/server/OverwriteBodyMiddleware.php index f7ada99..98e8468 100644 --- a/tests/server/OverwriteBodyMiddleware.php +++ b/tests/server/OverwriteBodyMiddleware.php @@ -2,11 +2,20 @@ declare(strict_types=1); +namespace Tests\Server; + +use Flight; + class OverwriteBodyMiddleware { public function after(): void { $response = Flight::response(); - $response->write(str_replace('failed', 'successfully works!', $response->getBody()), true); + + $response->write(str_replace( + 'failed', + 'successfully works!', + $response->getBody() + ), true); } } diff --git a/tests/server/Pascal_Snake_Case.php b/tests/server/Pascal_Snake_Case.php index bbba0d2..d80ed41 100644 --- a/tests/server/Pascal_Snake_Case.php +++ b/tests/server/Pascal_Snake_Case.php @@ -2,6 +2,8 @@ declare(strict_types=1); +namespace Tests\Server; + class Pascal_Snake_Case // phpcs:ignore { public function doILoad() // phpcs:ignore diff --git a/tests/server/index.php b/tests/server/index.php index 5fd7a66..6bb9dca 100644 --- a/tests/server/index.php +++ b/tests/server/index.php @@ -2,10 +2,15 @@ declare(strict_types=1); +use Dice\Dice; use flight\core\Loader; use flight\database\PdoWrapper; use tests\classes\Container; use tests\classes\ContainerDefault; +use Tests\Server\AuthCheck; +use Tests\Server\LayoutMiddleware; +use Tests\Server\OverwriteBodyMiddleware; +use Tests\Server\Pascal_Snake_Case; /* * This is the test file where we can open up a quick test server and make @@ -14,7 +19,7 @@ use tests\classes\ContainerDefault; * @author Kristaps Muižnieks https://github.com/krmu */ -require file_exists(__DIR__ . '/../../vendor/autoload.php') ? __DIR__ . '/../../vendor/autoload.php' : __DIR__ . '/../../flight/autoload.php'; +require_once __DIR__ . '/../phpunit_autoload.php'; Flight::set('flight.content_length', false); Flight::set('flight.views.path', './'); @@ -23,20 +28,20 @@ Loader::setV2ClassLoading(false); Flight::path(__DIR__); Flight::group('', function () { - // Test 1: Root route Flight::route('/', function () { echo 'Route text: Root route works!'; - if (Flight::request()->query->redirected) { + if (Flight::request()->query['redirected']) { echo '
    Redirected from /redirect route successfully!'; } }); + Flight::route('/querytestpath', function () { echo 'Route text: This is query route
    '; - echo "Query parameters:
    ";
    +        echo 'Query parameters:
    ';
             print_r(Flight::request()->query);
    -        echo "
    "; - }, false, "querytestpath"); + echo '
    '; + }, false, 'querytestpath'); // Test 2: Simple route Flight::route('/test', function () { @@ -47,18 +52,21 @@ Flight::group('', function () { Flight::route('/user/@name', function ($name) { echo "Route text: Hello, $name!"; }); + Flight::route('POST /postpage', function () { echo 'Route text: THIS IS POST METHOD PAGE'; - }, false, "postpage"); + }, false, 'postpage'); // Test 4: Grouped routes Flight::group('/group', function () { Flight::route('/test', function () { echo 'Route text: Group test route works!'; }); + Flight::route('/user/@name', function ($name) { echo "Route text: There is variable called name and it is $name"; }); + Flight::group('/group1', function () { Flight::group('/group2', function () { Flight::group('/group3', function () { @@ -69,7 +77,7 @@ Flight::group('', function () { Flight::group('/group8', function () { Flight::route('/final_group', function () { echo 'Mega Group test route works!'; - }, false, "final_group"); + }, false, 'final_group'); }); }); }); @@ -86,8 +94,8 @@ Flight::group('', function () { }, false, 'aliasroute'); /** Middleware test */ - include_once 'AuthCheck.php'; $middle = new AuthCheck(); + // Test 6: Route with middleware Flight::route('/protected', function () { echo 'Route text: Protected route works!'; @@ -119,44 +127,68 @@ Flight::group('', function () { // Test 12: Redirect with status code Flight::route('/streamResponse', function () { - echo "Streaming a response"; + echo 'Streaming a response'; + for ($i = 1; $i <= 50; $i++) { echo "."; usleep(50000); ob_flush(); } - echo "is successful!!"; + + echo 'is successful!!'; })->stream(); // Test 12: Redirect with status code Flight::route('/streamWithHeaders', function () { - echo "Streaming a response"; + echo 'Streaming a response'; + for ($i = 1; $i <= 50; $i++) { echo "."; usleep(50000); ob_flush(); } - echo "is successful!!"; + + echo 'is successful!!'; })->streamWithHeaders(['Content-Type' => 'text/html', 'status' => 200]); // Test 14: Overwrite the body with a middleware Flight::route('/overwrite', function () { - echo 'Route text: This route status is that it failed'; + echo <<<'html' + Route text: + This route status is that it + failed + html; })->addMiddleware([new OverwriteBodyMiddleware()]); // Test 15: UTF8 Chars in url Flight::route('/わたしはひとです', function () { - echo 'Route text: This route status is that it succeeded はい!!!'; + echo <<<'html' + Route text: + This route status is that it + succeeded はい!!! + html; }); // Test 16: UTF8 Chars in url with utf8 params Flight::route('/わたしはひとです/@name', function ($name) { - echo 'Route text: This route status is that it ' . ($name === 'ええ' ? 'succeeded' : 'failed') . ' URL Param: ' . $name . ''; + echo 'Route text: This route status is that it ' + . ($name === 'ええ' ? 'succeeded' : 'failed') + . ' URL Param: ' + . $name + . ''; }); // Test 17: Slash in param Flight::route('/redirect/@id', function ($id) { - echo 'Route text: This route status is that it ' . ($id === 'before/after' ? 'succeeded' : 'failed') . ' URL Param: ' . $id . ''; + echo 'Route text: This route status is that it ' + . ($id === 'before/after' ? 'succeeded' : 'failed') + . ' URL Param: ' + . $id + . ''; }); Flight::set('test_me_out', 'You got it boss!'); // used in /no-container route @@ -195,23 +227,25 @@ Flight::map('error', function (Throwable $e) { $e->getCode(), str_replace(getenv('PWD'), '***CONFIDENTIAL***', $e->getTraceAsString()) ); + echo "
    Go back"; }); + Flight::map('notFound', function () { echo 'Route text: The requested URL was not found
    '; echo "Go back"; }); Flight::map('start', function () { - if (Flight::request()->url === '/dice') { - $dice = new \Dice\Dice(); + $dice = new Dice(); $dice = $dice->addRules([ PdoWrapper::class => [ 'shared' => true, 'constructParams' => ['sqlite::memory:'] ] ]); + Flight::registerContainerHandler(function ($class, $params) use ($dice) { return $dice->create($class, $params); });