diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 091e30743cc..9e0c588532a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -8,7 +8,7 @@ array<string, array<string, array<string, array<string, array<string, string>>>>> - + DoctrinePersistentCollection @@ -25,4 +25,19 @@ array_merge(array_flip($keys), $this->elements) + + + + __toString + + + null + + + + + + $resource + + diff --git a/psalm.xml b/psalm.xml index 12d2090d114..db67872c997 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,5 +1,5 @@ - + @@ -14,5 +14,8 @@ + + + diff --git a/src/Action/SearchAction.php b/src/Action/SearchAction.php index 14dacfd0a63..5a8415e29fc 100644 --- a/src/Action/SearchAction.php +++ b/src/Action/SearchAction.php @@ -13,7 +13,6 @@ namespace Sonata\AdminBundle\Action; -use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\AdminBundle\Admin\BreadcrumbsBuilderInterface; use Sonata\AdminBundle\Admin\Pool; use Sonata\AdminBundle\Search\SearchHandler; @@ -87,11 +86,7 @@ public function __invoke(Request $request): Response try { $admin = $this->pool->getAdminByAdminCode($request->get('admin')); } catch (ServiceNotFoundException $e) { - throw new \RuntimeException('Unable to find the Admin instance', $e->getCode(), $e); - } - - if (!$admin instanceof AdminInterface) { - throw new \RuntimeException('The requested service is not an Admin instance'); + throw new \RuntimeException('Unable to find the Admin instance', (int) $e->getCode(), $e); } $results = []; @@ -113,7 +108,7 @@ public function __invoke(Request $request): Response 'id' => $admin->id($result), ]; } - $page = (int) $pager->getPage(); + $page = $pager->getPage(); $total = $pager->countResults(); } diff --git a/src/Action/SetObjectFieldValueAction.php b/src/Action/SetObjectFieldValueAction.php index 015df673c71..7a03ea17e2c 100644 --- a/src/Action/SetObjectFieldValueAction.php +++ b/src/Action/SetObjectFieldValueAction.php @@ -95,8 +95,7 @@ public function __invoke(Request $request): JsonResponse ), Response::HTTP_METHOD_NOT_ALLOWED); } - $rootObject = $object = $admin->getObject($objectId); - + $object = $admin->getObject($objectId); if (!$object) { return new JsonResponse('Object does not exist', Response::HTTP_NOT_FOUND); } @@ -121,10 +120,13 @@ public function __invoke(Request $request): JsonResponse } $propertyPath = new PropertyPath($field); + $rootObject = $object; // If property path has more than 1 element, take the last object in order to validate it if ($propertyPath->getLength() > 1) { - $object = $this->propertyAccessor->getValue($object, $propertyPath->getParent()); + $parent = $propertyPath->getParent(); + \assert(null !== $parent); + $object = $this->propertyAccessor->getValue($object, $parent); $elements = $propertyPath->getElements(); $field = end($elements); diff --git a/src/Admin/AbstractAdmin.php b/src/Admin/AbstractAdmin.php index 9c9106f89dc..beb26a9236c 100644 --- a/src/Admin/AbstractAdmin.php +++ b/src/Admin/AbstractAdmin.php @@ -571,7 +571,7 @@ final public function getBaseRoutePattern(): string if ($this->isChild()) { // the admin class is a child, prefix it with the parent route pattern $baseRoutePattern = $this->baseRoutePattern; - if (!$this->baseRoutePattern) { + if (!$baseRoutePattern) { preg_match(self::CLASS_REGEX, $this->class, $matches); if (!$matches) { @@ -625,7 +625,7 @@ final public function getBaseRouteName(): string if ($this->isChild()) { // the admin class is a child, prefix it with the parent route name $baseRouteName = $this->baseRouteName; - if (!$this->baseRouteName) { + if (!$baseRouteName) { preg_match(self::CLASS_REGEX, $this->class, $matches); if (!$matches) { @@ -675,6 +675,7 @@ final public function getClass(): string } $subClass = $this->getRequest()->query->get('subclass'); + \assert(\is_string($subClass)); if (!$this->hasSubClass($subClass)) { throw new \LogicException(sprintf('Subclass "%s" is not defined.', $subClass)); @@ -713,7 +714,7 @@ final public function hasSubClass(string $name): bool final public function hasActiveSubClass(): bool { if (\count($this->subClasses) > 0 && $this->hasRequest()) { - return null !== $this->getRequest()->query->get('subclass'); + return \is_string($this->getRequest()->query->get('subclass')); } return false; @@ -741,6 +742,7 @@ final public function getActiveSubclassCode(): string } $subClass = $this->getRequest()->query->get('subclass'); + \assert(\is_string($subClass)); if (!$this->hasSubClass($subClass)) { throw new \LogicException(sprintf( @@ -786,7 +788,7 @@ final public function getBatchActions(): array final public function getRoutes(): RouteCollectionInterface { $this->buildRoutes(); - \assert($this->routes !== null); + \assert(null !== $this->routes); return $this->routes; } @@ -1003,7 +1005,7 @@ final public function getSideMenu(string $action, ?AdminInterface $childAdmin = } $this->buildTabMenu($action, $childAdmin); - \assert($this->menu !== null); + \assert(null !== $this->menu); return $this->menu; } @@ -1127,7 +1129,7 @@ final public function getParentFieldDescription(): FieldDescriptionInterface static::class )); } - \assert($this->parentFieldDescription !== null); + \assert(null !== $this->parentFieldDescription); return $this->parentFieldDescription; } @@ -1159,7 +1161,7 @@ final public function getSubject(): object static::class )); } - \assert($this->subject !== null); + \assert(null !== $this->subject); return $this->subject; } @@ -1598,7 +1600,7 @@ final public function createObjectSecurity(object $object): void final public function isGranted($name, ?object $object = null): bool { - $objectRef = $object ? sprintf('/%s#%s', spl_object_hash($object), $this->id($object)) : ''; + $objectRef = $object ? sprintf('/%s#%s', spl_object_hash($object), $this->id($object) ?? '') : ''; $key = md5(json_encode($name).$objectRef); if (!\array_key_exists($key, $this->cacheIsGranted)) { @@ -1626,7 +1628,7 @@ public function id(object $model): ?string final public function getShow(): FieldDescriptionCollection { $this->buildShow(); - \assert($this->show !== null); + \assert(null !== $this->show); return $this->show; } @@ -1693,10 +1695,12 @@ public function getPerPageOptions(): array /** * Returns true if the per page value is allowed, false otherwise. + * + * @param mixed $perPage */ - final public function determinedPerPageValue(int $perPage): bool + final public function determinedPerPageValue($perPage): bool { - return \in_array($perPage, $this->getPerPageOptions(), true); + return \is_int($perPage) && \in_array($perPage, $this->getPerPageOptions(), true); } final public function isAclEnabled(): bool @@ -1917,7 +1921,7 @@ final public function getTemplateRegistry(): MutableTemplateRegistryInterface if (false === $this->hasTemplateRegistry()) { throw new \LogicException(sprintf('Unable to find the template registry for admin `%s`.', static::class)); } - \assert($this->templateRegistry !== null); + \assert(null !== $this->templateRegistry); return $this->templateRegistry; } diff --git a/src/Block/AdminSearchBlockService.php b/src/Block/AdminSearchBlockService.php index 3892e8414d7..9a724169923 100644 --- a/src/Block/AdminSearchBlockService.php +++ b/src/Block/AdminSearchBlockService.php @@ -13,7 +13,6 @@ namespace Sonata\AdminBundle\Block; -use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\AdminBundle\Admin\Pool; use Sonata\AdminBundle\Search\SearchHandler; use Sonata\AdminBundle\Templating\TemplateRegistryInterface; @@ -72,11 +71,7 @@ public function execute(BlockContextInterface $blockContext, ?Response $response try { $admin = $this->pool->getAdminByAdminCode($blockContext->getSetting('admin_code')); } catch (ServiceNotFoundException $e) { - throw new \RuntimeException('Unable to find the Admin instance', $e->getCode(), $e); - } - - if (!$admin instanceof AdminInterface) { - throw new \RuntimeException('The requested service is not an Admin instance'); + throw new \RuntimeException('Unable to find the Admin instance', (int) $e->getCode(), $e); } $admin->checkAccess('list'); diff --git a/src/Controller/CRUDController.php b/src/Controller/CRUDController.php index 07cba52651e..282b410bb70 100644 --- a/src/Controller/CRUDController.php +++ b/src/Controller/CRUDController.php @@ -23,7 +23,6 @@ use Sonata\AdminBundle\Datagrid\ProxyQueryInterface; use Sonata\AdminBundle\Exception\LockException; use Sonata\AdminBundle\Exception\ModelManagerException; -use Sonata\AdminBundle\FieldDescription\FieldDescriptionCollection; use Sonata\AdminBundle\Model\AuditManagerInterface; use Sonata\AdminBundle\Templating\TemplateRegistryInterface; use Sonata\AdminBundle\Util\AdminAclUserManagerInterface; @@ -390,7 +389,7 @@ public function batchAction(Request $request): Response $allElements = $forwardedRequest->request->getBoolean('all_elements'); $forwardedRequest->request->set('idx', $idx); - $forwardedRequest->request->set('all_elements', $allElements); + $forwardedRequest->request->set('all_elements', (string) $allElements); $data = $forwardedRequest->request->all(); $data['all_elements'] = $allElements; @@ -618,7 +617,6 @@ public function showAction(Request $request): Response $this->admin->setSubject($object); $fields = $this->admin->getShow(); - \assert($fields instanceof FieldDescriptionCollection); $template = $this->templateRegistry->getTemplate('show'); @@ -1201,7 +1199,7 @@ protected function validateCsrfToken(string $intention): void */ protected function escapeHtml(string $s): string { - return htmlspecialchars((string) $s, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'); + return htmlspecialchars($s, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'); } /** diff --git a/src/DependencyInjection/Admin/AbstractTaggedAdmin.php b/src/DependencyInjection/Admin/AbstractTaggedAdmin.php index 91b240002de..afc58cc47d1 100644 --- a/src/DependencyInjection/Admin/AbstractTaggedAdmin.php +++ b/src/DependencyInjection/Admin/AbstractTaggedAdmin.php @@ -270,7 +270,7 @@ final public function getFilterPersister(): FilterPersisterInterface if (!$this->hasFilterPersister()) { throw new \LogicException(sprintf('Admin "%s" has no filter persister.', static::class)); } - \assert($this->filterPersister !== null); + \assert(null !== $this->filterPersister); return $this->filterPersister; } diff --git a/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php b/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php index baa9c10c37d..6301753d88b 100644 --- a/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php +++ b/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php @@ -192,8 +192,11 @@ public function process(ContainerBuilder $container): void $groups[$resolvedGroupName]['roles'] = $groupDefaults[$resolvedGroupName]['roles']; } - if (isset($groups[$resolvedGroupName]['on_top']) && !empty($group['on_top']) && $group['on_top'] - && (\count($groups[$resolvedGroupName]['items']) > 1)) { + if ( + isset($groups[$resolvedGroupName]['on_top']) + && !empty($group['on_top']) + && (\count($groups[$resolvedGroupName]['items']) > 1) + ) { throw new \RuntimeException('You can\'t use "on_top" option with multiple same name groups.'); } if (empty($group['on_top'])) { diff --git a/src/EventListener/AssetsInstallCommandListener.php b/src/EventListener/AssetsInstallCommandListener.php index 246028e1b82..4bf35f42759 100644 --- a/src/EventListener/AssetsInstallCommandListener.php +++ b/src/EventListener/AssetsInstallCommandListener.php @@ -19,11 +19,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Filesystem\Exception\IOException; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; -use Symfony\Component\HttpKernel\KernelInterface; /** * This listener extends `assets:install` command when SonataCoreBundle will be not register. Files from `Resources/private/SonataCoreBundleAssets` @@ -74,15 +72,12 @@ public function copySonataCoreBundleAssets(ConsoleTerminateEvent $event): void private function execute(InputInterface $input, OutputInterface $output, FrameworkApplication $application): int { - /** - * @var KernelInterface - */ $kernel = $application->getKernel(); $targetArg = rtrim($input->getArgument('target') ?? '', '/'); if (!$targetArg) { - $targetArg = $this->getPublicDirectory($kernel->getContainer()); + $targetArg = $this->getPublicDirectory(); } if (!is_dir($targetArg)) { @@ -168,7 +163,6 @@ private function execute(InputInterface $input, OutputInterface $output, Framewo case 'warning': $io->$ioMethod('All deprecated SonataCoreBundle assets from SonataAdminBundle were successfully installed.'); break; - case 'error': default: $io->$ioMethod('No deprecated SonataCoreBundle assets from SonataAdminBundle were provided by any bundle.'); break; @@ -245,15 +239,10 @@ private function hardCopy(string $originDir, string $targetDir): string return self::METHOD_COPY; } - private function getPublicDirectory(ContainerInterface $container): string + private function getPublicDirectory(): string { $defaultPublicDir = 'public'; - - if (null === $this->projectDir && !$container->hasParameter('kernel.project_dir')) { - return $defaultPublicDir; - } - - $composerFilePath = ($this->projectDir ?? $container->getParameter('kernel.project_dir')).'/composer.json'; + $composerFilePath = $this->projectDir.'/composer.json'; if (!file_exists($composerFilePath)) { return $defaultPublicDir; diff --git a/src/FieldDescription/BaseFieldDescription.php b/src/FieldDescription/BaseFieldDescription.php index 1a643cf5de3..55e3c5a2dda 100644 --- a/src/FieldDescription/BaseFieldDescription.php +++ b/src/FieldDescription/BaseFieldDescription.php @@ -434,7 +434,7 @@ protected function getFieldValue(?object $object, ?string $fieldName) } catch (ExceptionInterface $exception) { throw new NoValueException( sprintf('Cannot access property "%s" in class "%s".', $this->getName(), \get_class($object)), - $exception->getCode(), + (int) $exception->getCode(), $exception ); } diff --git a/src/Mapper/BaseGroupedMapper.php b/src/Mapper/BaseGroupedMapper.php index 73e0d5065f7..4fb8c310d99 100644 --- a/src/Mapper/BaseGroupedMapper.php +++ b/src/Mapper/BaseGroupedMapper.php @@ -131,6 +131,7 @@ public function with(string $name, array $options = []): self 'translation_domain' => $options['translation_domain'] ?? null, ]); // add new tab automatically } + \assert(null !== $this->currentTab); // if no tab is selected, we go the the main one named '_' .. if ('default' !== $this->currentTab) { @@ -372,7 +373,7 @@ protected function getCurrentGroupName(): string ]); } } - \assert($this->currentGroup !== null); + \assert(null !== $this->currentGroup); return $this->currentGroup; } diff --git a/src/Route/RouteGeneratorInterface.php b/src/Route/RouteGeneratorInterface.php index dca3dac52e2..b37422972f9 100644 --- a/src/Route/RouteGeneratorInterface.php +++ b/src/Route/RouteGeneratorInterface.php @@ -33,7 +33,7 @@ public function generateUrl(AdminInterface $admin, string $name, array $paramete * * @return array * - * @phpstan-return array{route: string, routeParameters: array, routeAbsolute: bool} + * @phpstan-return array{route: string, routeParameters: array, routeAbsolute: bool} */ public function generateMenuUrl(AdminInterface $admin, string $name, array $parameters = [], int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): array; diff --git a/src/Security/Handler/AclSecurityHandlerInterface.php b/src/Security/Handler/AclSecurityHandlerInterface.php index ab1b03cda60..0e4e7bfdfe0 100644 --- a/src/Security/Handler/AclSecurityHandlerInterface.php +++ b/src/Security/Handler/AclSecurityHandlerInterface.php @@ -98,14 +98,14 @@ public function deleteAcl(ObjectIdentityInterface $objectIdentity): void; /** * Helper method to find the index of a class ACE for a role. * - * @return string|int|false index if found, FALSE if not found + * @return int|false index if found, FALSE if not found */ public function findClassAceIndexByRole(MutableAclInterface $acl, string $role); /** * Helper method to find the index of a class ACE for a username. * - * @return string|int|false index if found, FALSE if not found + * @return int|false index if found, FALSE if not found */ public function findClassAceIndexByUsername(MutableAclInterface $acl, string $username); } diff --git a/tests/App/Model/ModelManager.php b/tests/App/Model/ModelManager.php index eefc7858858..893ffcecc30 100644 --- a/tests/App/Model/ModelManager.php +++ b/tests/App/Model/ModelManager.php @@ -55,6 +55,8 @@ public function findOneBy(string $class, array $criteria = []): ?object /** * @return Foo|null + * + * @psalm-suppress ImplementedReturnTypeMismatch */ public function find(string $class, $id): ?object { diff --git a/tests/Controller/CRUDControllerTest.php b/tests/Controller/CRUDControllerTest.php index fce5264f012..dad17318e38 100644 --- a/tests/Controller/CRUDControllerTest.php +++ b/tests/Controller/CRUDControllerTest.php @@ -147,7 +147,7 @@ class CRUDControllerTest extends TestCase private $translator; /** - * @var LoggerInterface|MockObject + * @var LoggerInterface&MockObject */ private $logger; @@ -166,9 +166,6 @@ class CRUDControllerTest extends TestCase */ private $parameterBag; - /** - * {@inheritdoc} - */ protected function setUp(): void { $this->httpMethodParameterOverride = Request::getHttpMethodParameterOverride(); diff --git a/tests/Datagrid/DatagridMapperTest.php b/tests/Datagrid/DatagridMapperTest.php index 75a4fa77c16..adbd3a70e72 100644 --- a/tests/Datagrid/DatagridMapperTest.php +++ b/tests/Datagrid/DatagridMapperTest.php @@ -225,6 +225,9 @@ public function testAddRemove(): void $this->assertSame('fooFilterName', $fieldDescription->getOption('field_name')); } + /** + * @psalm-suppress InvalidScalarArgument + */ public function testAddException(): void { $this->expectException(\TypeError::class); diff --git a/tests/Datagrid/DatagridTest.php b/tests/Datagrid/DatagridTest.php index db5fe47184e..23fa2240c1f 100644 --- a/tests/Datagrid/DatagridTest.php +++ b/tests/Datagrid/DatagridTest.php @@ -88,7 +88,7 @@ protected function setUp(): void $this->formBuilder ->method('add') - ->willReturnCallback(function (?string $name, string $type, array $options): void { + ->willReturnCallback(function (string $name, string $type, array $options): void { $this->formTypes[$name] = new FormBuilder( $name, TestEntity::class, diff --git a/tests/Datagrid/ListMapperTest.php b/tests/Datagrid/ListMapperTest.php index 0b97f8c9e1a..7ed64b93f75 100644 --- a/tests/Datagrid/ListMapperTest.php +++ b/tests/Datagrid/ListMapperTest.php @@ -210,6 +210,9 @@ public function testAddDuplicateNameException(): void $this->listMapper->add('fooName'); } + /** + * @psalm-suppress InvalidScalarArgument + */ public function testAddWrongTypeException(): void { $this->expectException(\TypeError::class); @@ -228,7 +231,7 @@ public function testAutoAddVirtualOption(): void foreach ($this->fieldDescriptionCollection->getElements() as $field) { $this->assertTrue( $field->getOption('virtual_field', false), - sprintf('Failed asserting that FieldDescription with type "%s" is tagged with virtual flag.', $field->getType()) + sprintf('Failed asserting that FieldDescription with name "%s" is tagged with virtual flag.', $field->getName()) ); } } diff --git a/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php b/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php index d8aacb02082..78fa0baf239 100644 --- a/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php +++ b/tests/DependencyInjection/Compiler/AddDependencyCallsCompilerPassTest.php @@ -18,6 +18,7 @@ use Knp\Menu\Provider\MenuProviderInterface; use PHPUnit\Framework\TestCase; use Sonata\AdminBundle\Admin\AbstractAdmin; +use Sonata\AdminBundle\Admin\Pool; use Sonata\AdminBundle\DependencyInjection\Compiler\AddDependencyCallsCompilerPass; use Sonata\AdminBundle\DependencyInjection\SonataAdminExtension; use Sonata\AdminBundle\Route\RoutesCache; @@ -100,7 +101,7 @@ public function testProcessParsingFullValidConfig(): void $this->assertTrue($container->hasParameter('sonata.admin.configuration.dashboard_groups')); $dashboardGroupsSettings = $container->getParameter('sonata.admin.configuration.dashboard_groups'); - + $this->assertIsArray($dashboardGroupsSettings); $this->assertArrayHasKey('sonata_group_one', $dashboardGroupsSettings); $this->assertArrayHasKey('label', $dashboardGroupsSettings['sonata_group_one']); @@ -161,6 +162,7 @@ public function testProcessResultingConfig(): void $this->assertTrue($container->hasDefinition('sonata_news_admin')); $pool = $container->get('sonata.admin.pool'); + $this->assertInstanceOf(Pool::class, $pool); $adminServiceIds = $pool->getAdminServiceIds(); $adminGroups = $pool->getAdminGroups(); $adminClasses = $pool->getAdminClasses(); @@ -255,8 +257,10 @@ public function testProcessSortAdmins(): void $compilerPass->process($container); $container->compile(); + $pool = $container->get('sonata.admin.pool'); + $this->assertInstanceOf(Pool::class, $pool); // use array_values to check groups position - $adminGroups = array_values($container->get('sonata.admin.pool')->getAdminGroups()); + $adminGroups = array_values($pool->getAdminGroups()); $this->assertSame('sonata_group_one', $adminGroups['0']['label'], 'second group in configuration, first in list'); $this->assertSame('1 Entry', $adminGroups[0]['items'][0]['label'], 'second entry for group in configuration, first in list'); @@ -281,7 +285,9 @@ public function testProcessGroupNameAsParameter(): void $compilerPass->process($container); $container->compile(); - $adminGroups = $container->get('sonata.admin.pool')->getAdminGroups(); + $pool = $container->get('sonata.admin.pool'); + $this->assertInstanceOf(Pool::class, $pool); + $adminGroups = $pool->getAdminGroups(); $this->assertArrayHasKey('resolved_group_name', $adminGroups); $this->assertArrayNotHasKey('%sonata.admin.parameter.groupname%', $adminGroups); @@ -549,6 +555,7 @@ public function testProcessAbstractAdminServiceInServiceDefinition(): void $container->compile(); $pool = $container->get('sonata.admin.pool'); + $this->assertInstanceOf(Pool::class, $pool); $adminServiceIds = $pool->getAdminServiceIds(); $this->assertContains('sonata_post_one_admin', $adminServiceIds); diff --git a/tests/DependencyInjection/Compiler/ExtensionCompilerPassTest.php b/tests/DependencyInjection/Compiler/ExtensionCompilerPassTest.php index a47d6feff56..073fa4faa45 100644 --- a/tests/DependencyInjection/Compiler/ExtensionCompilerPassTest.php +++ b/tests/DependencyInjection/Compiler/ExtensionCompilerPassTest.php @@ -19,6 +19,7 @@ use PHPUnit\Framework\TestCase; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Admin\AdminExtensionInterface; +use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\AdminBundle\DependencyInjection\Compiler\ExtensionCompilerPass; use Sonata\AdminBundle\DependencyInjection\SonataAdminExtension; use Sonata\AdminBundle\Tests\Fixtures\DependencyInjection\TimestampableTrait; @@ -260,6 +261,8 @@ public function testProcess(): void $filterExtension = $container->get('sonata_extension_filter'); $def = $container->get('sonata_post_admin'); + $this->assertInstanceOf(AdminInterface::class, $def); + $extensions = $def->getExtensions(); $this->assertCount(5, $extensions); @@ -269,6 +272,8 @@ public function testProcess(): void $this->assertSame($globalExtension, $extensions[4]); $def = $container->get('sonata_article_admin'); + $this->assertInstanceOf(AdminInterface::class, $def); + $extensions = $def->getExtensions(); $this->assertCount(6, $extensions); @@ -279,8 +284,11 @@ public function testProcess(): void $this->assertSame($globalExtension, $extensions[5]); $def = $container->get('sonata_news_admin'); + $this->assertInstanceOf(AdminInterface::class, $def); + $extensions = $def->getExtensions(); $this->assertCount(6, $extensions); + $this->assertSame($historyExtension, $extensions[0]); $this->assertSame($securityExtension, $extensions[2]); $this->assertSame($filterExtension, $extensions[3]); diff --git a/tests/DependencyInjection/SonataAdminExtensionTest.php b/tests/DependencyInjection/SonataAdminExtensionTest.php index 6d6d1e99b9f..7890172e663 100644 --- a/tests/DependencyInjection/SonataAdminExtensionTest.php +++ b/tests/DependencyInjection/SonataAdminExtensionTest.php @@ -276,10 +276,14 @@ public function testDefaultTemplates(): void public function testLoadIntlTemplate(): void { - $bundlesWithSonataIntlBundle = array_merge($this->container->getParameter('kernel.bundles'), ['SonataIntlBundle' => true]); - $this->container->setParameter('kernel.bundles', $bundlesWithSonataIntlBundle); + $bundles = $this->container->getParameter('kernel.bundles'); + $this->assertIsArray($bundles); + + $this->container->setParameter('kernel.bundles', array_merge($bundles, ['SonataIntlBundle' => true])); $this->load(); + $templates = $this->container->getParameter('sonata.admin.configuration.templates'); + $this->assertIsArray($templates); $this->assertSame('@SonataIntl/CRUD/history_revision_timestamp.html.twig', $templates['history_revision_timestamp']); } diff --git a/tests/Filter/Persister/SessionFilterPersisterTest.php b/tests/Filter/Persister/SessionFilterPersisterTest.php index 4cbf1f88df4..e13dd292706 100644 --- a/tests/Filter/Persister/SessionFilterPersisterTest.php +++ b/tests/Filter/Persister/SessionFilterPersisterTest.php @@ -21,7 +21,7 @@ class SessionFilterPersisterTest extends TestCase { /** - * @var SessionInterface|MockObject + * @var SessionInterface&MockObject */ private $session; diff --git a/tests/Form/Widget/BaseWidgetTest.php b/tests/Form/Widget/BaseWidgetTest.php index a80b753bce4..4a9a4a3876f 100644 --- a/tests/Form/Widget/BaseWidgetTest.php +++ b/tests/Form/Widget/BaseWidgetTest.php @@ -53,9 +53,6 @@ abstract class BaseWidgetTest extends AbstractWidgetTestCase ], ]; - /** - * {@inheritdoc} - */ protected function getEnvironment(): Environment { $environment = parent::getEnvironment(); @@ -69,10 +66,7 @@ protected function getEnvironment(): Environment return $environment; } - /** - * {@inheritdoc} - */ - protected function getRenderingEngine(?Environment $environment = null): TwigRendererEngine + protected function getRenderingEngine(Environment $environment): TwigRendererEngine { if (!\in_array($this->type, ['form', 'filter'], true)) { throw new \Exception( @@ -86,17 +80,11 @@ protected function getRenderingEngine(?Environment $environment = null): TwigRen ); } - /** - * {@inheritdoc} - */ protected function getSonataAdmin() { return $this->sonataAdmin; } - /** - * {@inheritdoc} - */ protected function getTemplatePaths(): array { $twigPaths = array_filter([ diff --git a/tests/Manipulator/ServicesManipulatorTest.php b/tests/Manipulator/ServicesManipulatorTest.php index daa51dc6580..f46167a35d2 100644 --- a/tests/Manipulator/ServicesManipulatorTest.php +++ b/tests/Manipulator/ServicesManipulatorTest.php @@ -21,24 +21,22 @@ */ class ServicesManipulatorTest extends TestCase { - /** @var ServicesManipulator */ + /** + * @var ServicesManipulator + */ private $servicesManipulator; - /** @var string */ - private $file; - /** - * {@inheritdoc} + * @var string */ + private $file; + protected function setUp(): void { $this->file = sprintf('%s/%s.yml', sys_get_temp_dir(), lcg_value()); $this->servicesManipulator = new ServicesManipulator($this->file); } - /** - * {@inheritdoc} - */ protected function tearDown(): void { @unlink($this->file); diff --git a/tests/Menu/Integration/BaseMenuTest.php b/tests/Menu/Integration/BaseMenuTest.php index bbccf69ab27..011ce545a0b 100644 --- a/tests/Menu/Integration/BaseMenuTest.php +++ b/tests/Menu/Integration/BaseMenuTest.php @@ -28,11 +28,11 @@ */ abstract class BaseMenuTest extends TestCase { - private $environment; - /** - * {@inheritdoc} + * @var Environment */ + private $environment; + protected function setUp(): void { // Adapt to both bundle and project-wide test strategy diff --git a/tests/Menu/Matcher/Voter/ActiveVoterTest.php b/tests/Menu/Matcher/Voter/ActiveVoterTest.php index 8c7c13226bb..58283ad3353 100644 --- a/tests/Menu/Matcher/Voter/ActiveVoterTest.php +++ b/tests/Menu/Matcher/Voter/ActiveVoterTest.php @@ -19,17 +19,11 @@ class ActiveVoterTest extends AbstractVoterTest { - /** - * {@inheritdoc} - */ public function createVoter($dataVoter, $route): VoterInterface { return new ActiveVoter(); } - /** - * {@inheritdoc} - */ public function provideData(): array { return [ diff --git a/tests/Menu/Matcher/Voter/AdminVoterTest.php b/tests/Menu/Matcher/Voter/AdminVoterTest.php index bd0f389f1ca..a90b50b32e8 100644 --- a/tests/Menu/Matcher/Voter/AdminVoterTest.php +++ b/tests/Menu/Matcher/Voter/AdminVoterTest.php @@ -22,9 +22,6 @@ class AdminVoterTest extends AbstractVoterTest { - /** - * {@inheritdoc} - */ public function provideData(): array { return [ @@ -42,9 +39,6 @@ public function provideData(): array ]; } - /** - * {@inheritdoc} - */ protected function createVoter($dataVoter, $route): VoterInterface { $request = new Request(); @@ -57,9 +51,6 @@ protected function createVoter($dataVoter, $route): VoterInterface return new AdminVoter($requestStack); } - /** - * {@inheritdoc} - */ protected function createItem($data): ItemInterface { $item = $this->getMockForAbstractClass(ItemInterface::class); @@ -74,9 +65,6 @@ protected function createItem($data): ItemInterface return $item; } - /** - * {@inheritdoc} - */ private function getAdmin(string $code, bool $list = false, bool $granted = false): AdminInterface { $admin = $this->createMock(AdminInterface::class); @@ -98,9 +86,6 @@ private function getAdmin(string $code, bool $list = false, bool $granted = fals return $admin; } - /** - * {@inheritdoc} - */ private function getChildAdmin( string $parentCode, string $childCode, diff --git a/tests/Show/ShowMapperTest.php b/tests/Show/ShowMapperTest.php index d5cea770d25..79f9f224288 100644 --- a/tests/Show/ShowMapperTest.php +++ b/tests/Show/ShowMapperTest.php @@ -380,6 +380,9 @@ public function testAddRemove(): void $this->assertFalse($this->showMapper->has('fooName')); } + /** + * @psalm-suppress InvalidScalarArgument + */ public function testAddException(): void { $this->expectException(\TypeError::class); diff --git a/tests/Twig/Extension/CanonicalizeExtensionTest.php b/tests/Twig/Extension/CanonicalizeExtensionTest.php index ad5a6e53346..239e68762ce 100644 --- a/tests/Twig/Extension/CanonicalizeExtensionTest.php +++ b/tests/Twig/Extension/CanonicalizeExtensionTest.php @@ -242,6 +242,9 @@ public function select2LocalesProvider() private function changeLocale(string $locale): void { - $this->requestStack->getCurrentRequest()->setLocale($locale); + $request = $this->requestStack->getCurrentRequest(); + \assert(null !== $request); + + $request->setLocale($locale); } } diff --git a/tests/Util/ObjectAclManipulatorTest.php b/tests/Util/ObjectAclManipulatorTest.php index ca0e8ef5a03..b6c6cc44707 100644 --- a/tests/Util/ObjectAclManipulatorTest.php +++ b/tests/Util/ObjectAclManipulatorTest.php @@ -29,12 +29,12 @@ class ObjectAclManipulatorTest extends TestCase { /** - * @var MockObject|OutputInterface + * @var MockObject&OutputInterface */ private $output; /** - * @var MockObject|AdminInterface + * @var MockObject&AdminInterface */ private $admin; @@ -82,7 +82,7 @@ public function testConfigureAclsIgnoresNonAclSecurityHandlers(): void public function testConfigureAcls(): void { $securityHandler = $this->createMock(AclSecurityHandlerInterface::class); - $acls = $this->createMock('SplObjectStorage'); + $acls = $this->createMock(\SplObjectStorage::class); $acls->expects($this->atLeastOnce())->method('contains')->with($this->isInstanceOf(ObjectIdentityInterface::class)) ->willReturn(false, true); $acl = $this->createStub(MutableAclInterface::class);