diff --git a/composer.json b/composer.json index 43d7590..35c8acc 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,8 @@ "symfony/filesystem": "^6.3", "symfony/framework-bundle": "^6.3", "symfony/phpunit-bridge": "^6.3", - "phpstan/phpstan": "1.11.x-dev" + "phpstan/phpstan": "^1.10.39" }, - "minimum-stability": "dev", "autoload": { "psr-4": { "Symfonycasts\\MicroMapper\\": "src" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 64d0c83..de18d88 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,6 +16,7 @@ + diff --git a/src/MapperInterface.php b/src/MapperInterface.php index 484b2b3..6e6c558 100644 --- a/src/MapperInterface.php +++ b/src/MapperInterface.php @@ -14,9 +14,6 @@ * * Also add #[AsMapper(from: Foo:class, to: Bar:class)] to each mapper class. * - * @template TFrom of object - * @template TTo of object - * * @author Ryan Weaver */ interface MapperInterface @@ -27,7 +24,8 @@ interface MapperInterface * This method should load (e.g. from the database) or instantiate the "to object". * Avoid populating any properties except for an identifier. * - * @param TFrom $from + * @template TTo of object + * * @param class-string $toClass * * @return TTo @@ -39,8 +37,9 @@ public function load(object $from, string $toClass, array $context): object; * * Receives the "to object" returned from load(). * - * @param TFrom $from - * @param TTo $to + * @template TTo of object + * + * @param TTo $to * * @return TTo */ diff --git a/src/MicroMapperInterface.php b/src/MicroMapperInterface.php index 03eadf3..af3418c 100644 --- a/src/MicroMapperInterface.php +++ b/src/MicroMapperInterface.php @@ -11,16 +11,14 @@ /** * Maps one object to another using the configured mappers. - * - * @template TFrom of object - * @template TTo of object */ interface MicroMapperInterface { public const MAX_DEPTH = 'max_depth'; /** - * @param TFrom $from + * @template TTo of object + * * @param class-string $toClass * * @return TTo diff --git a/tests/IntegrationTest.php b/tests/Functional/IntegrationTest.php similarity index 96% rename from tests/IntegrationTest.php rename to tests/Functional/IntegrationTest.php index 830b4a8..4a19fc9 100644 --- a/tests/IntegrationTest.php +++ b/tests/Functional/IntegrationTest.php @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -namespace Symfonycasts\MicroMapper\Tests; +namespace Symfonycasts\MicroMapper\Tests\Functional; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfonycasts\MicroMapper\MicroMapperInterface; diff --git a/tests/PHPStan/MicroMapperTest.php b/tests/PHPStan/MicroMapperTest.php new file mode 100644 index 0000000..6edcdc8 --- /dev/null +++ b/tests/PHPStan/MicroMapperTest.php @@ -0,0 +1,35 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfonycasts\MicroMapper\Tests\PHPStan; + +use PHPStan\Testing\TypeInferenceTestCase; + +final class MicroMapperTest extends TypeInferenceTestCase +{ + /** @return array */ + public static function dataFileAsserts(): iterable + { + yield from self::gatherAssertTypes(__DIR__.'/data/micro_mapper.php'); + yield from self::gatherAssertTypes(__DIR__.'/data/mapper.php'); + } + + /** + * @dataProvider dataFileAsserts + */ + public function testFileAsserts( + string $assertType, + string $file, + mixed ...$args, + ): void { + $this->assertFileAsserts($assertType, $file, ...$args); + } +} diff --git a/tests/PHPStan/data/mapper.php b/tests/PHPStan/data/mapper.php new file mode 100644 index 0000000..9d473fe --- /dev/null +++ b/tests/PHPStan/data/mapper.php @@ -0,0 +1,25 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfonycasts\MicroMapper\MapperInterface; +use Symfonycasts\MicroMapper\Tests\fixtures\DinosaurDto; + +use function PHPStan\Testing\assertType; + +function doMapperInterfaceLoad(MapperInterface $microMapper): void +{ + assertType(DinosaurDto::class, $microMapper->load(new \stdClass(), DinosaurDto::class)); +} + +function doMapperInterfacePopulate(MapperInterface $microMapper, DinosaurDto $dto): void +{ + assertType(DinosaurDto::class, $microMapper->populate(new \stdClass(), $dto)); +} diff --git a/tests/PHPStan/data/micro_mapper.php b/tests/PHPStan/data/micro_mapper.php new file mode 100644 index 0000000..91c4755 --- /dev/null +++ b/tests/PHPStan/data/micro_mapper.php @@ -0,0 +1,26 @@ + + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfonycasts\MicroMapper\MicroMapper; +use Symfonycasts\MicroMapper\MicroMapperInterface; +use Symfonycasts\MicroMapper\Tests\fixtures\DinosaurDto; + +use function PHPStan\Testing\assertType; + +function doMicroMapperInterfaceMap(MicroMapperInterface $microMapper): void +{ + assertType(DinosaurDto::class, $microMapper->map(new \stdClass(), DinosaurDto::class)); +} + +function doMicroMapperImplementationMap(MicroMapper $microMapper): void +{ + assertType(DinosaurDto::class, $microMapper->map(new \stdClass(), DinosaurDto::class)); +} diff --git a/tests/MapperConfigTest.php b/tests/Unit/MapperConfigTest.php similarity index 96% rename from tests/MapperConfigTest.php rename to tests/Unit/MapperConfigTest.php index 435fec6..f5185ca 100644 --- a/tests/MapperConfigTest.php +++ b/tests/Unit/MapperConfigTest.php @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -namespace Symfonycasts\MicroMapper\Tests; +namespace Symfonycasts\MicroMapper\Tests\Unit; use PHPUnit\Framework\TestCase; use Symfonycasts\MicroMapper\MapperConfig; diff --git a/tests/MicroMapperTest.php b/tests/Unit/MicroMapperTest.php similarity index 98% rename from tests/MicroMapperTest.php rename to tests/Unit/MicroMapperTest.php index adb1e7d..8c59fa0 100644 --- a/tests/MicroMapperTest.php +++ b/tests/Unit/MicroMapperTest.php @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -namespace Symfonycasts\MicroMapper\Tests; +namespace Symfonycasts\MicroMapper\Tests\Unit; use PHPUnit\Framework\TestCase; use Symfonycasts\MicroMapper\MapperConfig; diff --git a/tests/deprecations-ignored b/tests/deprecations-ignored new file mode 100644 index 0000000..bb4211e --- /dev/null +++ b/tests/deprecations-ignored @@ -0,0 +1,11 @@ +%_PHPStan_d5c599c96% +%^Method "PhpParser\\NodeVisitor\:\:leaveNode\(\)" might add "int\|Node\|array\|null" as a native return type declaration in the future\. Do the same in implementation "PHPStan\\BetterReflection\\SourceLocator\\SourceStubber\\PhpStormStubs\\CachingVisitor" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "PhpParser\\NodeVisitor\:\:enterNode\(\)" might add "int\|Node\|null" as a native return type declaration in the future\. Do the same in implementation "PhpParser\\NodeVisitorAbstract@anonymous" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "PhpParser\\NodeVisitor\:\:leaveNode\(\)" might add "int\|Node\|array\|null" as a native return type declaration in the future\. Do the same in implementation "PhpParser\\NodeVisitorAbstract@anonymous" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionFunction\:\:invokeArgs\(\)" might add "mixed" as a native return type declaration in the future\. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionFunction" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getFileName\(\)" might add "string\|false" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getStartLine\(\)" might add "int\|false" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getEndLine\(\)" might add "int\|false" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getDocComment\(\)" might add "string\|false" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getStaticPropertyValue\(\)" might add "mixed" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$% +%^Method "ReflectionClass\:\:getExtensionName\(\)" might add "string\|false" as a native return type declaration in the future. Do the same in child class "PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass" now to avoid errors or add an explicit @return annotation to suppress this message\.$%