diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 885dd616..1898a021 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,19 +8,12 @@ jobs: strategy: matrix: - php: [8.0, 8.1, 8.2] - symfony: ["4.4.*", "5.4.*", "6.0.*", "6.1.*", "6.2.*", "6.3.*"] - exclude: - - php: 8.0 - symfony: "6.1.*" - - php: 8.0 - symfony: "6.2.*" - - php: 8.0 - symfony: "6.3.*" + php: [8.1, 8.2, 8.3] + symfony: ["5.4.*", "6.4.*"] steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -30,67 +23,35 @@ jobs: extensions: ctype, iconv, intl, json, mbstring, pdo, pdo_sqlite coverage: none - - name: Checkout Symfony 4.4 Sample - if: "matrix.symfony == '4.4.*'" - uses: actions/checkout@v2 - with: - repository: Codeception/symfony-module-tests - path: framework-tests - ref: "4.4_codecept5" - - name: Checkout Symfony 5.4 Sample if: "matrix.symfony == '5.4.*'" - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: Codeception/symfony-module-tests path: framework-tests ref: "5.4_codecept5" - - name: Checkout Symfony 6.0 Sample - if: "matrix.symfony == '6.0.*'" - uses: actions/checkout@v2 + - name: Checkout Symfony 6.4 Sample + if: "matrix.symfony == '6.4.*'" + uses: actions/checkout@v4 with: repository: Codeception/symfony-module-tests path: framework-tests - ref: "6.0" - - - name: Checkout Symfony 6.1 Sample - if: "matrix.symfony == '6.1.*'" - uses: actions/checkout@v2 - with: - repository: Codeception/symfony-module-tests - path: framework-tests - ref: "6.1" - - - name: Checkout Symfony 6.2 Sample - if: "matrix.symfony == '6.2.*'" - uses: actions/checkout@v2 - with: - repository: Codeception/symfony-module-tests - path: framework-tests - ref: "6.2" - - - name: Checkout Symfony 6.3 Sample - if: "matrix.symfony == '6.3.*'" - uses: actions/checkout@v2 - with: - repository: Codeception/symfony-module-tests - path: framework-tests - ref: "6.3" + ref: "6.4" - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache composer dependencies - uses: actions/cache@v2.1.3 + uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} restore-keys: ${{ runner.os }}-${{ matrix.php }}-composer- - - name: Install PHPUnit 9 for Symfony 4.4, 5.4 and 6.0 - if: "matrix.symfony == '4.4.*' || matrix.symfony == '5.4.*' || matrix.symfony == '6.0.*'" + - name: Install PHPUnit 9 for Symfony 5.4 + if: "matrix.symfony == '5.4.*'" run: composer require --dev --no-update "phpunit/phpunit=^9.0" - name: Install dependencies @@ -111,8 +72,8 @@ jobs: run: composer validate working-directory: framework-tests - - name: Install PHPUnit 10 in framework-tests for Symfony 6.1 and 6.2 - if: "matrix.symfony == '6.1.*' || matrix.symfony == '6.2.*' || matrix.symfony == '6.3.*'" + - name: Install PHPUnit 10 in framework-tests for Symfony 6.4 + if: "matrix.symfony == '6.4.*'" run: composer require --dev --no-update "phpunit/phpunit=^10.0" working-directory: framework-tests diff --git a/LICENSE b/LICENSE index 61d82091..624026b5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2011-2020 Michael Bodnarchuk and contributors +Copyright (c) 2011-2024 Michael Bodnarchuk and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index 24d5822d..52a4293b 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ ], "homepage": "https://codeception.com/", "require": { - "php": "^8.0", + "php": "^8.1", "ext-json": "*", "codeception/codeception": "^5.0.8", "codeception/lib-innerbrowser": "^3.1.1 | ^4.0" diff --git a/readme.md b/readme.md index c832d43a..49c9e0ab 100644 --- a/readme.md +++ b/readme.md @@ -9,8 +9,8 @@ A Codeception module for Symfony framework. ## Requirements -* `Symfony` `4.4.x`, `5.4.x`, `6.x` or higher, as per the [Symfony supported versions](https://symfony.com/releases). -* `PHP 8.0` or higher. +* `Symfony` `5.4.x`, `6.4.x` or higher, as per the [Symfony supported versions](https://symfony.com/releases). +* `PHP 8.1` or higher. ## Installation diff --git a/src/Codeception/Lib/Connector/Symfony.php b/src/Codeception/Lib/Connector/Symfony.php index dafcaa5a..684add44 100644 --- a/src/Codeception/Lib/Connector/Symfony.php +++ b/src/Codeception/Lib/Connector/Symfony.php @@ -20,36 +20,29 @@ class Symfony extends HttpKernelBrowser { - private bool $rebootable; - private bool $hasPerformedRequest = false; private ?ContainerInterface $container; - public array $persistentServices = []; - /** * Constructor. * * @param Kernel $kernel A booted HttpKernel instance - * @param array $services An injected services - * @param bool $rebootable + * @param array $persistentServices An injected services */ - public function __construct(Kernel $kernel, array $services = [], bool $rebootable = true) - { + public function __construct( + Kernel $kernel, + public array $persistentServices = [], + private readonly bool $rebootable = true + ) { parent::__construct($kernel); $this->followRedirects(); - $this->rebootable = $rebootable; - $this->persistentServices = $services; $this->container = $this->getContainer(); $this->rebootKernel(); } - /** - * @param Request $request - * @return Response - */ - protected function doRequest($request): Response + /** @param Request $request */ + protected function doRequest(object $request): Response { if ($this->rebootable) { if ($this->hasPerformedRequest) { diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index fc8044ca..bd7b898a 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -43,7 +43,6 @@ use Symfony\Component\VarDumper\Cloner\Data; use function array_keys; use function array_map; -use function array_merge; use function array_search; use function array_unique; use function class_exists; @@ -74,7 +73,7 @@ * * ## Config * - * ### Symfony 5.x or 4.4 + * ### Symfony 5.4 or higher * * * app_path: 'src' - Specify custom path to your app dir, where the kernel interface is located. * * environment: 'local' - Environment used for load kernel @@ -83,8 +82,8 @@ * * debug: true - Turn on/off debug mode * * cache_router: 'false' - Enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire) * * rebootable_client: 'true' - Reboot client's kernel before each request - * * guard: 'false' - Enable custom authentication system with guard (only for 4.x and 5.x versions of the symfony) - * * authenticator: 'false' - Reboot client's kernel before each request (only for 6.x versions of the symfony) + * * guard: 'false' - Enable custom authentication system with guard (only for Symfony 5.4) + * * authenticator: 'false' - Reboot client's kernel before each request (only for Symfony 6.0 or higher) * * #### Example (`functional.suite.yml`) - Symfony 4 Directory Structure * @@ -126,7 +125,7 @@ * browser: firefox * ``` * - * If you're using Symfony with Eloquent ORM (instead of Doctrine), you can load the [`ORM` part of Laravel module](https://codeception.com/docs/modules/Laravel5#Parts) + * If you're using Symfony with Eloquent ORM (instead of Doctrine), you can load the [`ORM` part of Laravel module](https://codeception.com/docs/modules/Laravel#Parts) * in addition to Symfony module. * */ @@ -215,7 +214,7 @@ public function _initialize(): void */ public function _before(TestInterface $test): void { - $this->persistentServices = array_merge($this->persistentServices, $this->permanentServices); + $this->persistentServices = [...$this->persistentServices, ...$this->permanentServices]; $this->client = new SymfonyConnector($this->kernel, $this->persistentServices, $this->config['rebootable_client']); } @@ -322,7 +321,7 @@ protected function getKernelClass(): string $this->requireAdditionalAutoloader(); - $filesRealPath = array_map(function ($file) { + $filesRealPath = array_map(static function ($file) { require_once $file; return $file->getRealPath(); }, $results); @@ -331,7 +330,7 @@ protected function getKernelClass(): string if (class_exists($kernelClass)) { $reflectionClass = new ReflectionClass($kernelClass); - if ($file = array_search($reflectionClass->getFileName(), $filesRealPath)) { + if ($file = array_search($reflectionClass->getFileName(), $filesRealPath, true)) { return $kernelClass; } @@ -355,7 +354,7 @@ protected function getProfile(): ?Profile try { $response = $this->getClient()->getResponse(); return $profiler->loadProfileFromResponse($response); - } catch (BadMethodCallException $e) { + } catch (BadMethodCallException) { $this->fail('You must perform a request before using this method.'); } catch (Exception $e) { $this->fail($e->getMessage()); diff --git a/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php b/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php index 67dc1ddb..001e7ca2 100644 --- a/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/BrowserAssertionsTrait.php @@ -31,7 +31,7 @@ public function rebootClientKernel(): void /** * Verifies that a page is available. - * By default it checks the current page, specify the `$url` parameter to change it. + * By default, it checks the current page, specify the `$url` parameter to change it. * * ```php * seePageRedirectsTo('/admin', '/login'); * ``` - * - * @param string $page - * @param string $redirectsTo */ public function seePageRedirectsTo(string $page, string $redirectsTo): void { diff --git a/src/Codeception/Module/Symfony/EventsAssertionsTrait.php b/src/Codeception/Module/Symfony/EventsAssertionsTrait.php index 0ef1ee4c..8ee296b9 100644 --- a/src/Codeception/Module/Symfony/EventsAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/EventsAssertionsTrait.php @@ -25,7 +25,7 @@ trait EventsAssertionsTrait */ public function dontSeeEvent(array|string $expected = null): void { - $actualEvents = array_merge(array_column($this->getCalledListeners(), 'event')); + $actualEvents = [...array_column($this->getCalledListeners(), 'event')]; $actual = [$this->getOrphanedEvents(), $actualEvents]; $this->assertEventTriggered(false, $expected, $actual); } @@ -110,7 +110,7 @@ public function dontSeeOrphanEvent(array|string $expected = null): void */ public function seeEvent(array|string $expected): void { - $actualEvents = array_merge(array_column($this->getCalledListeners(), 'event')); + $actualEvents = [...array_column($this->getCalledListeners(), 'event')]; $actual = [$this->getOrphanedEvents(), $actualEvents]; $this->assertEventTriggered(true, $expected, $actual); } diff --git a/src/Codeception/Module/Symfony/FormAssertionsTrait.php b/src/Codeception/Module/Symfony/FormAssertionsTrait.php index 31940e15..c6fba53d 100644 --- a/src/Codeception/Module/Symfony/FormAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/FormAssertionsTrait.php @@ -43,7 +43,6 @@ public function dontSeeFormErrors(): void * $I->seeFormErrorMessage('username', 'Username is empty'); * ``` * - * @param string $field * @param string|null $message */ public function seeFormErrorMessage(string $field, string $message = null): void diff --git a/src/Codeception/Module/Symfony/MailerAssertionsTrait.php b/src/Codeception/Module/Symfony/MailerAssertionsTrait.php index 4e61cb2d..f8bb9772 100644 --- a/src/Codeception/Module/Symfony/MailerAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/MailerAssertionsTrait.php @@ -14,8 +14,7 @@ trait MailerAssertionsTrait /** * Checks that no email was sent. * The check is based on `\Symfony\Component\Mailer\EventListener\MessageLoggerListener`, which means: - * If your app performs a HTTP redirect, you need to suppress it using [stopFollowingRedirects()](https://codeception.com/docs/modules/Symfony#stopFollowingRedirects) first; otherwise this check will *always* pass. - * Starting with version 2.0.0, `codeception/module-symfony` requires your app to use [Symfony Mailer](https://symfony.com/doc/current/mailer.html). If your app still uses [Swift Mailer](https://symfony.com/doc/current/email.html), set your version constraint to `^1.6`. + * If your app performs an HTTP redirect, you need to suppress it using [stopFollowingRedirects()](https://codeception.com/docs/modules/Symfony#stopFollowingRedirects) first; otherwise this check will *always* pass. */ public function dontSeeEmailIsSent(): void { @@ -25,8 +24,7 @@ public function dontSeeEmailIsSent(): void /** * Checks if the given number of emails was sent (default `$expectedCount`: 1). * The check is based on `\Symfony\Component\Mailer\EventListener\MessageLoggerListener`, which means: - * If your app performs a HTTP redirect after sending the email, you need to suppress it using [stopFollowingRedirects()](https://codeception.com/docs/modules/Symfony#stopFollowingRedirects) first. - * Starting with version 2.0.0, `codeception/module-symfony` requires your app to use [Symfony Mailer](https://symfony.com/doc/current/mailer.html). If your app still uses [Swift Mailer](https://symfony.com/doc/current/email.html), set your version constraint to `^1.6`. + * If your app performs an HTTP redirect after sending the email, you need to suppress it using [stopFollowingRedirects()](https://codeception.com/docs/modules/Symfony#stopFollowingRedirects) first. * * ```php * getEvents(); } - $this->fail("codeception/module-symfony requires Symfony Mailer https://symfony.com/doc/current/mailer.html to test emails. If your app still uses Swift Mailer, downgrade codeception/module-symfony to ^1.6 - - - Emails can't be tested without Symfony Mailer service."); + $this->fail("Emails can't be tested without Symfony Mailer service."); } } diff --git a/src/Codeception/Module/Symfony/MimeAssertionsTrait.php b/src/Codeception/Module/Symfony/MimeAssertionsTrait.php index 9228602a..12e73cd8 100644 --- a/src/Codeception/Module/Symfony/MimeAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/MimeAssertionsTrait.php @@ -169,9 +169,9 @@ public function assertEmailTextBodyNotContains(string $text, Email $email = null private function verifyEmailObject(?Email $email, string $function): Email { $email = $email ?: $this->grabLastSentEmail(); - $errorMsgFormat = "There is no email to verify. An Email object was not specified when invoking '%s' and the application has not sent one."; + $errorMsgTemplate = "There is no email to verify. An Email object was not specified when invoking '%s' and the application has not sent one."; return $email ?: $this->fail( - sprintf($errorMsgFormat, $function) + sprintf($errorMsgTemplate, $function) ); } } \ No newline at end of file diff --git a/src/Codeception/Module/Symfony/ParameterAssertionsTrait.php b/src/Codeception/Module/Symfony/ParameterAssertionsTrait.php index 63231dd5..61c98ddd 100644 --- a/src/Codeception/Module/Symfony/ParameterAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/ParameterAssertionsTrait.php @@ -5,6 +5,7 @@ namespace Codeception\Module\Symfony; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use UnitEnum; trait ParameterAssertionsTrait { @@ -15,11 +16,8 @@ trait ParameterAssertionsTrait * grabParameter('app.business_name'); * ``` - * - * @param string $parameterName - * @return array|bool|float|int|string|null */ - public function grabParameter(string $parameterName) + public function grabParameter(string $parameterName): array|bool|string|int|float|UnitEnum|null { $parameterBag = $this->grabParameterBagService(); return $parameterBag->get($parameterName); diff --git a/src/Codeception/Module/Symfony/RouterAssertionsTrait.php b/src/Codeception/Module/Symfony/RouterAssertionsTrait.php index e0bdeab0..80501555 100644 --- a/src/Codeception/Module/Symfony/RouterAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/RouterAssertionsTrait.php @@ -5,10 +5,9 @@ namespace Codeception\Module\Symfony; use Symfony\Component\Routing\Exception\ResourceNotFoundException; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouterInterface; use function array_intersect_assoc; -use function array_merge; use function explode; use function sprintf; @@ -23,23 +22,20 @@ trait RouterAssertionsTrait * $I->amOnAction('HomeController'); * $I->amOnAction('ArticleController', ['slug' => 'lorem-ipsum']); * ``` - * - * @param string $action - * @param array $params */ public function amOnAction(string $action, array $params = []): void { $router = $this->grabRouterService(); $routes = $router->getRouteCollection()->getIterator(); + /** @var Route $route */ foreach ($routes as $route) { $controller = $route->getDefault('_controller'); - if (str_ends_with($controller, $action)) { + if (str_ends_with((string) $controller, $action)) { $resource = $router->match($route->getPath()); $url = $router->generate( $resource['_route'], - $params, - UrlGeneratorInterface::ABSOLUTE_PATH + $params ); $this->amOnPage($url); return; @@ -55,9 +51,6 @@ public function amOnAction(string $action, array $params = []): void * $I->amOnRoute('posts.create'); * $I->amOnRoute('posts.show', ['id' => 34]); * ``` - * - * @param string $routeName - * @param array $params */ public function amOnRoute(string $routeName, array $params = []): void { @@ -86,17 +79,16 @@ public function invalidateCachedRouter(): void * $I->seeCurrentActionIs('PostController::index'); * $I->seeCurrentActionIs('HomeController'); * ``` - * - * @param string $action */ public function seeCurrentActionIs(string $action): void { $router = $this->grabRouterService(); $routes = $router->getRouteCollection()->getIterator(); + /** @var Route $route */ foreach ($routes as $route) { $controller = $route->getDefault('_controller'); - if (str_ends_with($controller, $action)) { + if (str_ends_with((string) $controller, $action)) { $request = $this->getClient()->getRequest(); $currentActionFqcn = $request->attributes->get('_controller'); @@ -116,9 +108,6 @@ public function seeCurrentActionIs(string $action): void * $I->seeCurrentRouteIs('posts.index'); * $I->seeCurrentRouteIs('posts.show', ['id' => 8]); * ``` - * - * @param string $routeName - * @param array $params */ public function seeCurrentRouteIs(string $routeName, array $params = []): void { @@ -135,7 +124,7 @@ public function seeCurrentRouteIs(string $routeName, array $params = []): void $this->fail(sprintf('The "%s" url does not match with any route', $uri)); } - $expected = array_merge(['_route' => $routeName], $params); + $expected = ['_route' => $routeName, ...$params]; $intersection = array_intersect_assoc($expected, $match); $this->assertSame($expected, $intersection); @@ -149,8 +138,6 @@ public function seeCurrentRouteIs(string $routeName, array $params = []): void * seeInCurrentRoute('my_blog_pages'); * ``` - * - * @param string $routeName */ public function seeInCurrentRoute(string $routeName): void { diff --git a/src/Codeception/Module/Symfony/SecurityAssertionsTrait.php b/src/Codeception/Module/Symfony/SecurityAssertionsTrait.php index a07e3ab3..b86bd1ff 100644 --- a/src/Codeception/Module/Symfony/SecurityAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/SecurityAssertionsTrait.php @@ -65,7 +65,7 @@ public function seeAuthentication(): void { $security = $this->grabSecurityService(); - if (!$user = $security->getUser()) { + if (!$security->getUser()) { $this->fail('There is no user in session'); } @@ -108,8 +108,6 @@ public function seeRememberedAuthentication(): void * seeUserHasRole('ROLE_ADMIN'); * ``` - * - * @param string $role */ public function seeUserHasRole(string $role): void { diff --git a/src/Codeception/Module/Symfony/SessionAssertionsTrait.php b/src/Codeception/Module/Symfony/SessionAssertionsTrait.php index a8b69afd..7d26314d 100644 --- a/src/Codeception/Module/Symfony/SessionAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/SessionAssertionsTrait.php @@ -178,11 +178,7 @@ protected function getCurrentSession(): SessionInterface { $container = $this->_getContainer(); - if ($this->getSymfonyMajorVersion() < 6) { - return $container->get('session'); - } - - if ($container->has('session')) { + if ($this->getSymfonyMajorVersion() < 6 || $container->has('session')) { return $container->get('session'); } diff --git a/src/Codeception/Module/Symfony/TimeAssertionsTrait.php b/src/Codeception/Module/Symfony/TimeAssertionsTrait.php index 136bef25..a1067f37 100644 --- a/src/Codeception/Module/Symfony/TimeAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/TimeAssertionsTrait.php @@ -13,7 +13,7 @@ trait TimeAssertionsTrait /** * Asserts that the time a request lasted is less than expected. * - * If the page performed a HTTP redirect, only the time of the last request will be taken into account. + * If the page performed an HTTP redirect, only the time of the last request will be taken into account. * You can modify this behavior using [stopFollowingRedirects()](https://codeception.com/docs/modules/Symfony#stopFollowingRedirects) first. * * Also, note that using code coverage can significantly increase the time it takes to resolve a request, diff --git a/src/Codeception/Module/Symfony/TwigAssertionsTrait.php b/src/Codeception/Module/Symfony/TwigAssertionsTrait.php index 52b02d0d..1bfba3ec 100644 --- a/src/Codeception/Module/Symfony/TwigAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/TwigAssertionsTrait.php @@ -21,7 +21,7 @@ public function dontSeeRenderedTemplate(string $template): void { $twigCollector = $this->grabTwigCollector(__FUNCTION__); - $templates = (array)$twigCollector->getTemplates(); + $templates = $twigCollector->getTemplates(); $this->assertArrayNotHasKey( $template, @@ -42,8 +42,8 @@ public function seeCurrentTemplateIs(string $expectedTemplate): void { $twigCollector = $this->grabTwigCollector(__FUNCTION__); - $templates = (array)$twigCollector->getTemplates(); - $actualTemplate = !empty($templates) ? (string) array_key_first($templates) : 'N/A'; + $templates = $twigCollector->getTemplates(); + $actualTemplate = empty($templates) ? 'N/A' : (string) array_key_first($templates); $this->assertSame( $expectedTemplate, @@ -66,7 +66,7 @@ public function seeRenderedTemplate(string $template): void { $twigCollector = $this->grabTwigCollector(__FUNCTION__); - $templates = (array)$twigCollector->getTemplates(); + $templates = $twigCollector->getTemplates(); $this->assertArrayHasKey( $template, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy