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\.$%