Skip to content

Commit

Permalink
Fix & improve tests (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
seferov authored Jun 5, 2024
1 parent af23a49 commit 2ee2ae1
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 242 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
"vimeo/psalm": "^5.24"
},
"require-dev": {
"symfony/form": "^5.0 || ^6.0 || ^7.0",
"doctrine/annotations": "^1.8|^2",
"doctrine/orm": "^2.9",
"phpunit/phpunit": "~7.5 || ~9.5",
"symfony/cache-contracts": "^1.0 || ^2.0",
"symfony/console": "*",
"symfony/form": "^5.0 || ^6.0 || ^7.0",
"symfony/messenger": "^5.0 || ^6.0 || ^7.0",
"symfony/security-guard": "*",
"symfony/security-core": "*",
"symfony/serializer": "^5.0 || ^6.0 || ^7.0",
"symfony/validator": "*",
"twig/twig": "^2.10 || ^3.0",
Expand Down
40 changes: 20 additions & 20 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
*/
class Plugin implements PluginEntryPointInterface
{
public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config = null): void
public function __invoke(RegistrationInterface $registration, ?\SimpleXMLElement $config = null): void
{
require_once __DIR__.'/Handler/HeaderBagHandler.php';
require_once __DIR__.'/Handler/ContainerHandler.php';
Expand All @@ -39,13 +39,13 @@ public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config
require_once __DIR__.'/Handler/DoctrineQueryBuilderHandler.php';
require_once __DIR__.'/Provider/FormGetErrorsReturnTypeProvider.php';

$api->registerHooksFromClass(HeaderBagHandler::class);
$api->registerHooksFromClass(ConsoleHandler::class);
$api->registerHooksFromClass(ContainerDependencyHandler::class);
$api->registerHooksFromClass(RequiredSetterHandler::class);
$registration->registerHooksFromClass(HeaderBagHandler::class);
$registration->registerHooksFromClass(ConsoleHandler::class);
$registration->registerHooksFromClass(ContainerDependencyHandler::class);
$registration->registerHooksFromClass(RequiredSetterHandler::class);

if (class_exists(\Doctrine\ORM\QueryBuilder::class)) {
$api->registerHooksFromClass(DoctrineQueryBuilderHandler::class);
$registration->registerHooksFromClass(DoctrineQueryBuilderHandler::class);
}

if (class_exists(AnnotationRegistry::class)) {
Expand All @@ -54,10 +54,10 @@ public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config
/** @psalm-suppress DeprecatedMethod */
AnnotationRegistry::registerLoader('class_exists');
}
$api->registerHooksFromClass(DoctrineRepositoryHandler::class);
$registration->registerHooksFromClass(DoctrineRepositoryHandler::class);

require_once __DIR__.'/Handler/AnnotationHandler.php';
$api->registerHooksFromClass(AnnotationHandler::class);
$registration->registerHooksFromClass(AnnotationHandler::class);
}

if (isset($config->containerXml)) {
Expand All @@ -83,14 +83,14 @@ public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config

require_once __DIR__.'/Handler/ParameterBagHandler.php';
ParameterBagHandler::init($containerMeta);
$api->registerHooksFromClass(ParameterBagHandler::class);
$registration->registerHooksFromClass(ParameterBagHandler::class);
}

$api->registerHooksFromClass(ContainerHandler::class);
$registration->registerHooksFromClass(ContainerHandler::class);

$this->addStubs($api, __DIR__.'/Stubs/common');
$this->addStubs($api, __DIR__.'/Stubs/'.Kernel::MAJOR_VERSION);
$this->addStubs($api, __DIR__.'/Stubs/php');
$this->addStubs($registration, __DIR__.'/Stubs/common');
$this->addStubs($registration, __DIR__.'/Stubs/'.Kernel::MAJOR_VERSION);
$this->addStubs($registration, __DIR__.'/Stubs/php');

if (isset($config->twigCachePath)) {
$twig_cache_path = getcwd().DIRECTORY_SEPARATOR.ltrim((string) $config->twigCachePath, DIRECTORY_SEPARATOR);
Expand All @@ -99,15 +99,15 @@ public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config
}

require_once __DIR__.'/Twig/CachedTemplatesTainter.php';
$api->registerHooksFromClass(CachedTemplatesTainter::class);
$registration->registerHooksFromClass(CachedTemplatesTainter::class);

require_once __DIR__.'/Twig/CachedTemplatesMapping.php';
$api->registerHooksFromClass(CachedTemplatesMapping::class);
$registration->registerHooksFromClass(CachedTemplatesMapping::class);
CachedTemplatesMapping::setCachePath($twig_cache_path);
}

require_once __DIR__.'/Twig/AnalyzedTemplatesTainter.php';
$api->registerHooksFromClass(AnalyzedTemplatesTainter::class);
$registration->registerHooksFromClass(AnalyzedTemplatesTainter::class);

if (isset($config->twigRootPath)) {
$twig_root_path = trim((string) $config->twigRootPath, DIRECTORY_SEPARATOR);
Expand All @@ -119,20 +119,20 @@ public function __invoke(RegistrationInterface $api, ?\SimpleXMLElement $config
TemplateFileAnalyzer::setTemplateRootPath($twig_root_path);
}

$api->registerHooksFromClass(FormGetErrorsReturnTypeProvider::class);
$registration->registerHooksFromClass(FormGetErrorsReturnTypeProvider::class);
}

private function addStubs(RegistrationInterface $api, string $path): void
private function addStubs(RegistrationInterface $registration, string $path): void
{
if (!is_dir($path)) {
// e.g. looking for stubs for version 3, but there aren't any at time of writing, so don't try and load them.
// e.g., looking for stubs for version 3, but there aren't any at time of writing, so don't try and load them.
return;
}

$a = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
foreach ($a as $file) {
if (!$file->isDir()) {
$api->addStubFile($file->getPathname());
$registration->addStubFile($file->getPathname());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ interface PropertyAccessorInterface
* @psalm-param mixed $value
* @psalm-param-out T $objectOrArray
*/
public function setValue(&$objectOrArray, $propertyPath, $value);
public function setValue(object|array &$objectOrArray, string|PropertyPathInterface $propertyPath, mixed $value);

/**
* @param object|array $objectOrArray
* @param string|PropertyPathInterface $propertyPath
*
* @return mixed
*/
public function getValue($objectOrArray, $propertyPath);
public function getValue(object|array $objectOrArray, string|PropertyPathInterface $propertyPath): mixed;

/**
* @param object|array $objectOrArray
* @param string|PropertyPathInterface $propertyPath
*
* @return bool
*/
public function isWritable($objectOrArray, $propertyPath);
public function isWritable(object|array $objectOrArray, string|PropertyPathInterface $propertyPath): bool;

/**
* @param object|array $objectOrArray
* @param string|PropertyPathInterface $propertyPath
*
* @return bool
*/
public function isReadable($objectOrArray, $propertyPath);
public function isReadable(object|array $objectOrArray, string|PropertyPathInterface $propertyPath): bool;
}

This file was deleted.

47 changes: 20 additions & 27 deletions tests/acceptance/acceptance/ContainerService.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,26 @@ Feature: Container service

Background:
Given I have Symfony plugin enabled

Scenario: Asserting psalm recognizes return type of service got via 'ContainerInterface::get()'
Given I have the following code
And I have the following code preamble
"""
<?php
use \Symfony\Component\DependencyInjection\ContainerInterface;
class SomeService
{
public function do(): void {}
}
"""

class SomeController
Scenario: Asserting psalm recognizes return type of service got via 'ContainerInterface::get()'
Given I have the following code
"""
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
public function __invoke(ContainerInterface $container): void
{
$this->container->get(SomeService::class)->do();
$container->get(SomeService::class)->do();
}
}
"""
Expand All @@ -30,19 +33,11 @@ Feature: Container service
Scenario: Asserting psalm recognizes return type of service got via 'ContainerInterface::get()'.
Given I have the following code
"""
<?php
class SomeService
{
public function do(): void {}
}
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
public function __invoke(ContainerInterface $container): void
{
$this->container->get(SomeService::class)->nosuchmethod();
$container->get(SomeService::class)->nosuchmethod();
}
}
"""
Expand All @@ -55,18 +50,16 @@ Feature: Container service
Scenario: Container get(self::class) should not crash
Given I have the following code
"""
<?php
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index()
public function index(ContainerInterface $container): void
{
$this->container->get(self::class)->index();
$container->get(self::class)->index();
}
}
"""
When I run Psalm
Then I see these errors
| Type | Message |
| MissingReturnType | Method SomeController::index does not have a return type, expecting void |
| Type | Message |
| MixedMethodCall | Cannot determine the type of the object on the left hand side of this expression |
And I see no other errors
51 changes: 20 additions & 31 deletions tests/acceptance/acceptance/ContainerXml.feature
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@ Feature: Container XML config
"""
<containerXml>../../tests/acceptance/container.xml</containerXml>
"""
And I have the following code preamble
"""
<?php
use \Symfony\Component\DependencyInjection\ContainerInterface;
use \Symfony\Component\HttpKernel\HttpKernelInterface;
"""

Scenario: Asserting psalm recognizes return type of service got via 'ContainerInterface::get() using service ID'
Given I have the following code
"""
<?php
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): bool
public function __invoke(ContainerInterface $container): bool
{
return $this->container->get('service_container')->has('lorem');
return $container->get('service_container')->has('lorem');
}
}
"""
Expand All @@ -29,15 +32,11 @@ Feature: Container XML config
Scenario: Psalm emits when service ID not found in container'
Given I have the following code
"""
<?php
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
public function __invoke(ContainerInterface $container): void
{
$this->container->get('not_a_service')->has('lorem');
$container->get('not_a_service')->has('lorem');
}
}
"""
Expand All @@ -49,18 +48,12 @@ Feature: Container XML config
Scenario: Using service both via alias and class const
Given I have the following code
"""
<?php
use Symfony\Component\HttpKernel\HttpKernelInterface;
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
public function __invoke(ContainerInterface $container): void
{
$this->container->get('http_kernel');
$this->container->get(HttpKernelInterface::class);
$container->get('http_kernel');
$container->get(HttpKernelInterface::class);
}
}
"""
Expand All @@ -70,15 +63,11 @@ Feature: Container XML config
Scenario: Using private service
Given I have the following code
"""
<?php
class SomeController
class App
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
public function __invoke(ContainerInterface $container): void
{
$this->container->get('private_service');
$container->get('private_service');
}
}
"""
Expand Down
Loading

0 comments on commit 2ee2ae1

Please sign in to comment.