From 55008b09e9c1e73fc6567c67169ec1444d2c997f Mon Sep 17 00:00:00 2001 From: matt Date: Sat, 17 Feb 2024 22:52:21 +0000 Subject: [PATCH 1/3] Always set max_string_length on `ConfigLoader::load()`` --- src/Psalm/ConfigLoader.php | 19 ++++++++++--------- test/Psalm/ConfigLoaderTest.php | 6 ++---- test/Psalm/ConfigLoaderTrait.php | 7 +------ 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/Psalm/ConfigLoader.php b/src/Psalm/ConfigLoader.php index bf0c8e5..4dad481 100644 --- a/src/Psalm/ConfigLoader.php +++ b/src/Psalm/ConfigLoader.php @@ -15,23 +15,25 @@ final class ConfigLoader { + public const DEFAULT_STRING_LENGTH = 1000; + private static bool $loaded = false; public static function load(?int $maxStringLength = null): void { if (self::$loaded) { - return; - } + $config = Config::getInstance(); + } else { + self::hackPsalmCli(); + self::setPsalmVersion(); - self::hackPsalmCli(); - self::setPsalmVersion(); + $config = Config::getConfigForPath(__DIR__, getcwd()); + self::$loaded = true; + } - $config = Config::getConfigForPath(__DIR__, getcwd()); if ($maxStringLength !== null) { $config->max_string_length = $maxStringLength; } - - self::$loaded = true; } /** @@ -39,10 +41,9 @@ public static function load(?int $maxStringLength = null): void */ private static function hackPsalmCli(): void { - // phpcs:disable Squiz.PHP.GlobalKeyword.NotAllowed + // phpcs:ignore Squiz.PHP.GlobalKeyword.NotAllowed global $argv; $argv = []; - // phpcs:enable } private static function setPsalmVersion(): void diff --git a/test/Psalm/ConfigLoaderTest.php b/test/Psalm/ConfigLoaderTest.php index bf59458..9274949 100644 --- a/test/Psalm/ConfigLoaderTest.php +++ b/test/Psalm/ConfigLoaderTest.php @@ -14,16 +14,14 @@ final class ConfigLoaderTest extends TestCase { use ConfigLoaderTrait; - protected function setUp(): void + protected function tearDown(): void { - parent::setUp(); - self::tearDownConfig(); } public function testLoadDefaultsMaxStringLength(): void { - $expected = 1000; + $expected = ConfigLoader::DEFAULT_STRING_LENGTH; ConfigLoader::load(); $actual = Config::getInstance()->max_string_length; diff --git a/test/Psalm/ConfigLoaderTrait.php b/test/Psalm/ConfigLoaderTrait.php index 19e63ed..4bce7c8 100644 --- a/test/Psalm/ConfigLoaderTrait.php +++ b/test/Psalm/ConfigLoaderTrait.php @@ -13,14 +13,9 @@ */ trait ConfigLoaderTrait { - protected static function reloadConfig(int $maxStringLength = 500): void - { - self::tearDownConfig(); - ConfigLoader::load($maxStringLength); - } - protected static function tearDownConfig(): void { + ConfigLoader::load(ConfigLoader::DEFAULT_STRING_LENGTH); $loaderReflection = new ReflectionClass(ConfigLoader::class); $loaderReflection->setStaticPropertyValue('loaded', false); } From 5bef5bbc70e9882f36b234a0fbf93ff2b22c7ada Mon Sep 17 00:00:00 2001 From: matt Date: Sat, 17 Feb 2024 23:00:09 +0000 Subject: [PATCH 2/3] Add failing test for #13 --- test/Psalm/ConfigLoaderTrait.php | 3 --- test/Psalm/TypeUtilTest.php | 26 ++++++++++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/test/Psalm/ConfigLoaderTrait.php b/test/Psalm/ConfigLoaderTrait.php index 4bce7c8..0947163 100644 --- a/test/Psalm/ConfigLoaderTrait.php +++ b/test/Psalm/ConfigLoaderTrait.php @@ -6,7 +6,6 @@ use Kynx\Laminas\FormShape\Psalm\ConfigLoader; use PHPUnit\Framework\TestCase; -use ReflectionClass; /** * @psalm-require-extends TestCase @@ -16,7 +15,5 @@ trait ConfigLoaderTrait protected static function tearDownConfig(): void { ConfigLoader::load(ConfigLoader::DEFAULT_STRING_LENGTH); - $loaderReflection = new ReflectionClass(ConfigLoader::class); - $loaderReflection->setStaticPropertyValue('loaded', false); } } diff --git a/test/Psalm/TypeUtilTest.php b/test/Psalm/TypeUtilTest.php index 0520ad6..88fea7b 100644 --- a/test/Psalm/TypeUtilTest.php +++ b/test/Psalm/TypeUtilTest.php @@ -42,6 +42,15 @@ #[CoversClass(TypeUtil::class)] final class TypeUtilTest extends TestCase { + use ConfigLoaderTrait; + + protected function tearDown(): void + { + parent::tearDown(); + + $this->tearDownConfig(); + } + #[DataProvider('filterProvider')] public function testFilter(Union $union, Union $filter, Union $expected): void { @@ -94,7 +103,7 @@ public function testNarrow(Union $search, Union $replace, Union $expected): void public static function narrowProvider(): array { - ConfigLoader::load(500); + ConfigLoader::load(); return [ 'uses replace type' => [ @@ -213,15 +222,15 @@ public static function replaceTypeProvider(): array ]; } - #[DataProvider('toLaxUnion')] - public function testToLaxUnion(mixed $value, array $expected): void + #[DataProvider('toLooseUnionProvider')] + public function testToLooseUnion(mixed $value, array $expected): void { $union = TypeUtil::toLooseUnion($value); $actual = array_values($union->getAtomicTypes()); self::assertEquals($expected, $actual); } - public static function toLaxUnion(): array + public static function toLooseUnionProvider(): array { ConfigLoader::load(500); @@ -294,6 +303,15 @@ public static function toLaxUnion(): array ]; } + public function testToLooseUnionWithLongLiteralStringReturnsNonEmptyString(): void + { + $expected = [new TNonEmptyString()]; + ConfigLoader::load(1); + $union = TypeUtil::toLooseUnion('abc'); + $actual = array_values($union->getAtomicTypes()); + self::assertEquals($expected, $actual); + } + #[DataProvider('toStrictUnionProvider')] public function testToStrictUnion(mixed $value, Atomic $expected): void { From cf97a474afbbd1fb65b1760d924285368fbbef83 Mon Sep 17 00:00:00 2001 From: matt Date: Sat, 17 Feb 2024 23:43:17 +0000 Subject: [PATCH 3/3] Replace calls to TLiteralString::make() with TypeUtil::getAtomicStringFromLiteral() (thanks Rector :) --- psalm-baseline.xml | 7 +--- src/Filter/BooleanVisitor.php | 9 ++--- src/Filter/ToNullVisitor.php | 31 +++++++++++++--- src/Psalm/TypeUtil.php | 31 +++++++++++++--- src/Validator/NotEmptyVisitor.php | 5 +-- test/Decorator/PrettyPrinterTest.php | 11 +++--- test/Filter/AllowListVisitorTest.php | 4 +- test/Filter/BooleanVisitorTest.php | 6 +-- test/Filter/ToNullVisitorTest.php | 4 +- test/Psalm/ConfigLoaderTest.php | 7 +++- test/Psalm/ConfigLoaderTrait.php | 2 +- test/Psalm/TypeComparatorTest.php | 20 +++++----- test/Psalm/TypeUtilTest.php | 51 +++++++++++++++----------- test/Validator/InArrayVisitorTest.php | 12 +++--- test/Validator/NotEmptyVisitorTest.php | 10 ++--- 15 files changed, 128 insertions(+), 82 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index e8b9e50..0c4e4b1 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -96,11 +96,6 @@ - - - - - @@ -112,7 +107,7 @@ - + diff --git a/src/Filter/BooleanVisitor.php b/src/Filter/BooleanVisitor.php index 365cec3..3cb5fc4 100644 --- a/src/Filter/BooleanVisitor.php +++ b/src/Filter/BooleanVisitor.php @@ -12,7 +12,6 @@ use Psalm\Type\Atomic\TBool; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Union; @@ -32,8 +31,8 @@ public function visit(FilterInterface $filter, Union $previous): Union $remove = []; if ($type & Boolean::TYPE_FALSE_STRING) { - $remove[] = TLiteralString::make('false'); - $remove[] = TLiteralString::make('true'); + $remove[] = TypeUtil::getAtomicStringFromLiteral('false'); + $remove[] = TypeUtil::getAtomicStringFromLiteral('true'); } if ($type & Boolean::TYPE_NULL) { @@ -45,8 +44,8 @@ public function visit(FilterInterface $filter, Union $previous): Union } if ($type & Boolean::TYPE_ZERO_STRING) { - $remove[] = TLiteralString::make('0'); - $remove[] = TLiteralString::make('1'); + $remove[] = TypeUtil::getAtomicStringFromLiteral('0'); + $remove[] = TypeUtil::getAtomicStringFromLiteral('1'); } if ($type & Boolean::TYPE_FLOAT) { diff --git a/src/Filter/ToNullVisitor.php b/src/Filter/ToNullVisitor.php index 6dad58c..b3c0607 100644 --- a/src/Filter/ToNullVisitor.php +++ b/src/Filter/ToNullVisitor.php @@ -14,7 +14,6 @@ use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNonEmptyArray; use Psalm\Type\Atomic\TNonEmptyString; use Psalm\Type\Atomic\TNull; @@ -39,15 +38,27 @@ public function visit(FilterInterface $filter, Union $previous): Union $visited = $previous; if ($type & ToNull::TYPE_FLOAT) { - $visited = TypeUtil::replaceType($visited, new TLiteralFloat(0.0), new Union([new TFloat()])); + $visited = TypeUtil::replaceType( + $visited, + new TLiteralFloat(0.0), + new Union([new TFloat()]) + ); } if ($type & ToNull::TYPE_ZERO_STRING) { - $visited = TypeUtil::replaceType($visited, TLiteralString::make('0'), new Union([new TString()])); + $visited = TypeUtil::replaceType( + $visited, + TypeUtil::getAtomicStringFromLiteral('0'), + new Union([new TString()]) + ); } if ($type & ToNull::TYPE_STRING) { - $visited = TypeUtil::replaceType($visited, new TString(), new Union([new TNonEmptyString()])); + $visited = TypeUtil::replaceType( + $visited, + new TString(), + new Union([new TNonEmptyString()]) + ); } if ($type & ToNull::TYPE_EMPTY_ARRAY) { @@ -59,11 +70,19 @@ public function visit(FilterInterface $filter, Union $previous): Union } if ($type & ToNull::TYPE_INTEGER) { - $visited = TypeUtil::replaceType($visited, new TLiteralInt(0), new Union([new TInt()])); + $visited = TypeUtil::replaceType( + $visited, + new TLiteralInt(0), + new Union([new TInt()]) + ); } if ($type & ToNull::TYPE_BOOLEAN) { - $visited = TypeUtil::replaceType($visited, new TBool(), new Union([new TTrue()])); + $visited = TypeUtil::replaceType( + $visited, + new TBool(), + new Union([new TTrue()]) + ); } return $visited === $previous ? $previous : TypeUtil::widen($visited, new Union([new TNull()])); diff --git a/src/Psalm/TypeUtil.php b/src/Psalm/TypeUtil.php index 41e5cd9..f8e5152 100644 --- a/src/Psalm/TypeUtil.php +++ b/src/Psalm/TypeUtil.php @@ -4,6 +4,7 @@ namespace Kynx\Laminas\FormShape\Psalm; +use Psalm\Config; use Psalm\Type; use Psalm\Type\Atomic; use Psalm\Type\Atomic\TArray; @@ -19,6 +20,7 @@ use Psalm\Type\Atomic\TMixed; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyString; +use Psalm\Type\Atomic\TNonFalsyString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TResource; @@ -41,6 +43,7 @@ use function is_resource; use function is_string; use function str_contains; +use function strlen; final readonly class TypeUtil { @@ -157,7 +160,7 @@ public static function toStrictUnion(mixed $value): Union is_float($value) => new Union([new TLiteralFloat($value)]), is_int($value) => new Union([new TLiteralInt($value)]), is_object($value) => new Union([new TNamedObject($value::class)]), - is_string($value) => new Union([TLiteralString::make($value)]), + is_string($value) => new Union([self::getAtomicStringFromLiteral($value)]), is_resource($value) => new Union([new TResource()]), $value === null => new Union([new TNull()]), default => new Union([new TMixed()]), @@ -189,6 +192,24 @@ public static function getEmptyUnion(): Union return $builder->freeze(); } + /** + * Safely return a string atomic + * + * @see Type::getAtomicStringFromLiteral() - does the same but without involving (internal) ProjectAnalyzer + */ + public static function getAtomicStringFromLiteral(string $value, bool $fromDocblock = false): TString + { + $config = Config::getInstance(); + + if ($value === '' || strlen($value) < $config->max_string_length) { + return TLiteralString::make($value, $fromDocblock); + } elseif ($value === '0') { + return new TNonEmptyString($fromDocblock); + } + + return new TNonFalsyString($fromDocblock); + } + /** * @param array $narrowest */ @@ -280,7 +301,7 @@ private static function toLooseBool(bool $value): Union return Type::combineUnionTypes(self::toStrictUnion($value), new Union([ new TEmptyNumeric(), - TLiteralString::make(""), + self::getAtomicStringFromLiteral(""), new TNull(), ])); } @@ -293,7 +314,7 @@ private static function toLooseFloat(float $value): Union $types = [ new TLiteralFloat($value), - TLiteralString::make("$value"), + self::getAtomicStringFromLiteral("$value"), ]; if ((string) $value === (int) $value . "") { $types[] = new TLiteralInt((int) $value); @@ -311,7 +332,7 @@ private static function toLooseInt(int $value): Union return new Union([ new TLiteralInt($value), // new TLiteralFloat($value), // this would output 'float' - TLiteralString::make("$value"), + self::getAtomicStringFromLiteral("$value"), ]); } @@ -322,7 +343,7 @@ private static function toLooseString(string $value): Union } $types = [ - TLiteralString::make($value), + self::getAtomicStringFromLiteral($value), ]; if ($value === (int) $value . "") { $types[] = new TLiteralInt((int) $value); diff --git a/src/Validator/NotEmptyVisitor.php b/src/Validator/NotEmptyVisitor.php index 4962947..6953404 100644 --- a/src/Validator/NotEmptyVisitor.php +++ b/src/Validator/NotEmptyVisitor.php @@ -14,7 +14,6 @@ use Psalm\Type\Atomic\TIntRange; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyArray; use Psalm\Type\Atomic\TNonEmptyString; @@ -54,7 +53,7 @@ public function visit(ValidatorInterface $validator, Union $previous): Union $remove[] = new TObject(); } if ($type & NotEmpty::SPACE) { - $remove[] = TLiteralString::make(' '); + $remove[] = TypeUtil::getAtomicStringFromLiteral(' '); } if ($type & NotEmpty::NULL) { $remove[] = new TNull(); @@ -63,7 +62,7 @@ public function visit(ValidatorInterface $validator, Union $previous): Union $narrow[] = new TNonEmptyArray([Type::getArrayKey(), Type::getMixed()]); } if ($type & NotEmpty::ZERO) { - $remove[] = TLiteralString::make('0'); + $remove[] = TypeUtil::getAtomicStringFromLiteral('0'); } if ($type & NotEmpty::STRING) { $narrow[] = new TNonEmptyString(); diff --git a/test/Decorator/PrettyPrinterTest.php b/test/Decorator/PrettyPrinterTest.php index f41f20f..acce046 100644 --- a/test/Decorator/PrettyPrinterTest.php +++ b/test/Decorator/PrettyPrinterTest.php @@ -25,7 +25,6 @@ use Psalm\Type\Atomic\TKeyedArray; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyString; use Psalm\Type\Atomic\TNull; @@ -127,8 +126,8 @@ public function testDecorateSortsTypes(): void new TNull(), new TLiteralFloat(1.23), new TLiteralInt(1), - TLiteralString::make('b'), - TLiteralString::make('1'), + TypeUtil::getAtomicStringFromLiteral('b'), + TypeUtil::getAtomicStringFromLiteral('1'), ]); $actual = $this->decorator->decorate($union); @@ -184,8 +183,8 @@ public static function combineTypesProvider(): array 'int, int range' => [[new TInt(), new TIntRange(1, null)], 'int'], 'literal float, float' => [[new TLiteralFloat(1.23), new TFloat()], 'float'], 'float, literal float' => [[new TFloat(), new TLiteralFloat(1.23)], 'float'], - 'literal string, string' => [[TLiteralString::make('foo'), new TString()], 'string'], - 'string, literal string' => [[new TString(), TLiteralString::make('foo')], 'string'], + 'literal string, string' => [[TypeUtil::getAtomicStringFromLiteral('foo'), new TString()], 'string'], + 'string, literal string' => [[new TString(), TypeUtil::getAtomicStringFromLiteral('foo')], 'string'], 'numeric-string, string' => [[new TNumericString(), new TString()], 'string'], 'string, numeric-string' => [[new TString(), new TNumericString()], 'string'], @@ -200,7 +199,7 @@ public function testDecorateLimitsLiterals(): void { $expected = 'string'; $types = array_map( - static fn (int $i): TLiteralString => TLiteralString::make((string) $i), + static fn (int $i): TString => TypeUtil::getAtomicStringFromLiteral((string) $i), range(1, 4) ); $union = new Union($types); diff --git a/test/Filter/AllowListVisitorTest.php b/test/Filter/AllowListVisitorTest.php index b612f80..55d8aa8 100644 --- a/test/Filter/AllowListVisitorTest.php +++ b/test/Filter/AllowListVisitorTest.php @@ -6,13 +6,13 @@ use Kynx\Laminas\FormShape\Filter\AllowListVisitor; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use Laminas\Filter\AllowList; use Laminas\Filter\Boolean; use PHPUnit\Framework\Attributes\CoversClass; use Psalm\Type\Atomic\TBool; use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNonEmptyString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumericString; @@ -46,7 +46,7 @@ public static function visitProvider(): array 'lax list' => [ new AllowList(['list' => [123], 'strict' => false]), [new TString()], - [TLiteralString::make('123'), new TNull()], + [TypeUtil::getAtomicStringFromLiteral('123'), new TNull()], ], 'strict narrows previous' => [ new AllowList(['list' => ['foo', 123], 'strict' => true]), diff --git a/test/Filter/BooleanVisitorTest.php b/test/Filter/BooleanVisitorTest.php index 0222b1b..dfd0185 100644 --- a/test/Filter/BooleanVisitorTest.php +++ b/test/Filter/BooleanVisitorTest.php @@ -6,6 +6,7 @@ use Kynx\Laminas\FormShape\Filter\BooleanVisitor; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use Laminas\Filter\AllowList; use Laminas\Filter\Boolean; use PHPUnit\Framework\Attributes\CoversClass; @@ -14,7 +15,6 @@ use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TString; @@ -38,7 +38,7 @@ public static function visitProvider(): array ], 'false string' => [ new Boolean(['casting' => false, 'type' => Boolean::TYPE_FALSE_STRING]), - [TLiteralString::make('false'), TLiteralString::make('true')], + [TypeUtil::getAtomicStringFromLiteral('false'), TypeUtil::getAtomicStringFromLiteral('true')], [new TBool()], ], 'null' => [ @@ -53,7 +53,7 @@ public static function visitProvider(): array ], 'zero string' => [ new Boolean(['casting' => false, 'type' => Boolean::TYPE_ZERO_STRING]), - [TLiteralString::make('0'), TLiteralString::make('1')], + [TypeUtil::getAtomicStringFromLiteral('0'), TypeUtil::getAtomicStringFromLiteral('1')], [new TBool()], ], 'float' => [ diff --git a/test/Filter/ToNullVisitorTest.php b/test/Filter/ToNullVisitorTest.php index 7a93de2..2e26ef0 100644 --- a/test/Filter/ToNullVisitorTest.php +++ b/test/Filter/ToNullVisitorTest.php @@ -6,6 +6,7 @@ use Kynx\Laminas\FormShape\Filter\ToNullVisitor; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use Laminas\Filter\Boolean; use Laminas\Filter\ToNull; use PHPUnit\Framework\Attributes\CoversClass; @@ -15,7 +16,6 @@ use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNonEmptyArray; use Psalm\Type\Atomic\TNonEmptyString; use Psalm\Type\Atomic\TNull; @@ -52,7 +52,7 @@ public static function visitProvider(): array ], 'zero string' => [ new ToNull(['type' => ToNull::TYPE_ZERO_STRING]), - [TLiteralString::make('0')], + [TypeUtil::getAtomicStringFromLiteral('0')], [new TString(), new TNull()], ], 'string' => [ diff --git a/test/Psalm/ConfigLoaderTest.php b/test/Psalm/ConfigLoaderTest.php index 9274949..19aded8 100644 --- a/test/Psalm/ConfigLoaderTest.php +++ b/test/Psalm/ConfigLoaderTest.php @@ -14,9 +14,14 @@ final class ConfigLoaderTest extends TestCase { use ConfigLoaderTrait; + protected function setUp(): void + { + self::resetConfig(); + } + protected function tearDown(): void { - self::tearDownConfig(); + self::resetConfig(); } public function testLoadDefaultsMaxStringLength(): void diff --git a/test/Psalm/ConfigLoaderTrait.php b/test/Psalm/ConfigLoaderTrait.php index 0947163..0374ae7 100644 --- a/test/Psalm/ConfigLoaderTrait.php +++ b/test/Psalm/ConfigLoaderTrait.php @@ -12,7 +12,7 @@ */ trait ConfigLoaderTrait { - protected static function tearDownConfig(): void + protected static function resetConfig(): void { ConfigLoader::load(ConfigLoader::DEFAULT_STRING_LENGTH); } diff --git a/test/Psalm/TypeComparatorTest.php b/test/Psalm/TypeComparatorTest.php index 3cc0c4c..7a4989e 100644 --- a/test/Psalm/TypeComparatorTest.php +++ b/test/Psalm/TypeComparatorTest.php @@ -7,6 +7,7 @@ use Iterator; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; use Kynx\Laminas\FormShape\Psalm\TypeComparator; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; @@ -23,7 +24,6 @@ use Psalm\Type\Atomic\TKeyedArray; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TMixed; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyArray; @@ -65,8 +65,8 @@ public static function isContainedByTrueProvider(): array new TLiteralInt(123), ], 'literal string contained by literal string' => [ - TLiteralString::make('abc'), - TLiteralString::make('abc'), + TypeUtil::getAtomicStringFromLiteral('abc'), + TypeUtil::getAtomicStringFromLiteral('abc'), ], 'int range contained by int range' => [ new TIntRange(2, 3), @@ -81,11 +81,11 @@ public static function isContainedByTrueProvider(): array new TString(), ], 'literal string contained by non empty string' => [ - TLiteralString::make('a'), + TypeUtil::getAtomicStringFromLiteral('a'), new TNonEmptyString(), ], 'literal string contained by numeric string' => [ - TLiteralString::make('123'), + TypeUtil::getAtomicStringFromLiteral('123'), new TNumericString(), ], 'numeric string contained by non empty string' => [ @@ -105,7 +105,7 @@ public static function isContainedByTrueProvider(): array new TArrayKey(), ], 'literal string contained by non empty scalar' => [ - TLiteralString::make('a'), + TypeUtil::getAtomicStringFromLiteral('a'), new TNonEmptyScalar(), ], 'negative int contained by non empty scalar' => [ @@ -251,7 +251,7 @@ public static function isContainedByFalseProvider(): array ], 'string contained by literal string' => [ new TString(), - TLiteralString::make('abc'), + TypeUtil::getAtomicStringFromLiteral('abc'), ], 'int range contained by min bound' => [ new TIntRange(1, 4), @@ -262,11 +262,11 @@ public static function isContainedByFalseProvider(): array new TIntRange(null, 3), ], 'empty literal string contained by non empty string' => [ - TLiteralString::make(''), + TypeUtil::getAtomicStringFromLiteral(''), new TNonEmptyString(), ], 'alpha literal string contained by numeric string' => [ - TLiteralString::make('abc'), + TypeUtil::getAtomicStringFromLiteral('abc'), new TNumericString(), ], 'string contained by non empty string' => [ @@ -278,7 +278,7 @@ public static function isContainedByFalseProvider(): array new TNumericString(), ], 'empty literal string contained by non empty scalar' => [ - TLiteralString::make(''), + TypeUtil::getAtomicStringFromLiteral(''), new TNonEmptyScalar(), ], 'int range contained by non empty scalar' => [ diff --git a/test/Psalm/TypeUtilTest.php b/test/Psalm/TypeUtilTest.php index 88fea7b..aeb8266 100644 --- a/test/Psalm/TypeUtilTest.php +++ b/test/Psalm/TypeUtilTest.php @@ -21,10 +21,10 @@ use Psalm\Type\Atomic\TKeyedArray; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TMixed; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyString; +use Psalm\Type\Atomic\TNonFalsyString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TNumeric; use Psalm\Type\Atomic\TNumericString; @@ -48,7 +48,7 @@ protected function tearDown(): void { parent::tearDown(); - $this->tearDownConfig(); + $this->resetConfig(); } #[DataProvider('filterProvider')] @@ -128,8 +128,8 @@ public static function narrowProvider(): array ], 'replaces narrowest' => [ new Union([new TString()]), - new Union([new TNonEmptyString(), TLiteralString::make('a')]), - new Union([TLiteralString::make('a')]), + new Union([new TNonEmptyString(), TypeUtil::getAtomicStringFromLiteral('a')]), + new Union([TypeUtil::getAtomicStringFromLiteral('a')]), ], 'replaces multiple' => [ new Union([new TScalar()]), @@ -158,8 +158,8 @@ public static function narrowProvider(): array ], 'replaces string literals order independent' => [ new Union([new TString()]), - new Union([TLiteralString::make('a'), new TNonEmptyString()]), - new Union([TLiteralString::make('a')]), + new Union([TypeUtil::getAtomicStringFromLiteral('a'), new TNonEmptyString()]), + new Union([TypeUtil::getAtomicStringFromLiteral('a')]), ], ]; } @@ -238,7 +238,11 @@ public static function toLooseUnionProvider(): array return [ 'array' => [ ['a' => 123], - [new TKeyedArray(['a' => new Union([new TLiteralInt(123), TLiteralString::make('123')])])], + [ + new TKeyedArray([ + 'a' => new Union([new TLiteralInt(123), TypeUtil::getAtomicStringFromLiteral('123')]), + ]), + ], ], 'empty array' => [ [], @@ -246,11 +250,16 @@ public static function toLooseUnionProvider(): array ], 'list' => [ ['a', 'b'], - [Type::getNonEmptyListAtomic(new Union([TLiteralString::make('a'), TLiteralString::make('b')]))], + [ + Type::getNonEmptyListAtomic(new Union([ + TypeUtil::getAtomicStringFromLiteral('a'), + TypeUtil::getAtomicStringFromLiteral('b'), + ])), + ], ], 'false' => [ false, - [TLiteralString::make(''), new TFalse(), new TEmptyNumeric(), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TFalse(), new TEmptyNumeric(), new TNull()], ], 'true' => [ true, @@ -258,27 +267,27 @@ public static function toLooseUnionProvider(): array ], 'zero float' => [ 0.0, - [TLiteralString::make(''), new TFalse(), new TEmptyNumeric(), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TFalse(), new TEmptyNumeric(), new TNull()], ], 'float' => [ 1.23, - [new TLiteralFloat(1.23), TLiteralString::make('1.23')], + [new TLiteralFloat(1.23), TypeUtil::getAtomicStringFromLiteral('1.23')], ], 'int float' => [ 1.0, - [new TLiteralFloat(1.0), TLiteralString::make('1'), new TLiteralInt(1)], + [new TLiteralFloat(1.0), TypeUtil::getAtomicStringFromLiteral('1'), new TLiteralInt(1)], ], 'zero int' => [ 0, - [TLiteralString::make(''), new TFalse(), new TEmptyNumeric(), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TFalse(), new TEmptyNumeric(), new TNull()], ], 'int' => [ 123, - [new TLiteralInt(123), TLiteralString::make('123')], + [new TLiteralInt(123), TypeUtil::getAtomicStringFromLiteral('123')], ], 'null' => [ null, - [TLiteralString::make(''), new TFalse(), new TEmptyNumeric(), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TFalse(), new TEmptyNumeric(), new TNull()], ], 'object' => [ new stdClass(), @@ -290,22 +299,22 @@ public static function toLooseUnionProvider(): array ], 'empty string' => [ '', - [TLiteralString::make(''), new TFalse(), new TEmptyNumeric(), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TFalse(), new TEmptyNumeric(), new TNull()], ], 'int string' => [ '123', - [TLiteralString::make('123'), new TLiteralInt(123)], + [TypeUtil::getAtomicStringFromLiteral('123'), new TLiteralInt(123)], ], 'non-empty-string' => [ 'abc', - [TLiteralString::make('abc')], + [TypeUtil::getAtomicStringFromLiteral('abc')], ], ]; } - public function testToLooseUnionWithLongLiteralStringReturnsNonEmptyString(): void + public function testToLooseUnionWithLongLiteralStringReturnsNonFalsyString(): void { - $expected = [new TNonEmptyString()]; + $expected = [new TNonFalsyString()]; ConfigLoader::load(1); $union = TypeUtil::toLooseUnion('abc'); $actual = array_values($union->getAtomicTypes()); @@ -370,7 +379,7 @@ public static function toStrictUnionProvider(): array ], 'string' => [ 'abc', - TLiteralString::make('abc'), + TypeUtil::getAtomicStringFromLiteral('abc'), ], ]; } diff --git a/test/Validator/InArrayVisitorTest.php b/test/Validator/InArrayVisitorTest.php index 8469c5b..aca6c8a 100644 --- a/test/Validator/InArrayVisitorTest.php +++ b/test/Validator/InArrayVisitorTest.php @@ -5,6 +5,7 @@ namespace KynxTest\Laminas\FormShape\Validator; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use Kynx\Laminas\FormShape\Validator\InArrayVisitor; use Kynx\Laminas\FormShape\ValidatorVisitorInterface; use Laminas\Validator\InArray; @@ -14,7 +15,6 @@ use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TLiteralFloat; use Psalm\Type\Atomic\TLiteralInt; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNull; use Psalm\Type\Atomic\TString; use Psalm\Type\Union; @@ -40,18 +40,18 @@ public static function visitProvider(): array 'loose null' => [ new InArray(['haystack' => [null], 'strict' => false]), [new TString(), new TNull()], - [TLiteralString::make(''), new TNull()], + [TypeUtil::getAtomicStringFromLiteral(''), new TNull()], ], 'literal string' => [ new InArray(['haystack' => ['foo'], 'strict' => true]), [new TString()], - [TLiteralString::make("foo")], + [TypeUtil::getAtomicStringFromLiteral("foo")], ], 'loose string' => [ new InArray(['haystack' => ['foo'], 'strict' => false]), [new TString()], - [TLiteralString::make('foo')], + [TypeUtil::getAtomicStringFromLiteral('foo')], ], 'strict int' => [ new InArray(['haystack' => [123], 'strict' => true]), @@ -62,7 +62,7 @@ public static function visitProvider(): array => [ new InArray(['haystack' => [123], 'strict' => false]), [new TInt(), new TString()], - [new TLiteralInt(123), TLiteralString::make("123")], + [new TLiteralInt(123), TypeUtil::getAtomicStringFromLiteral("123")], ], 'strict float' => [ new InArray(['haystack' => [1.23], 'strict' => true]), @@ -73,7 +73,7 @@ public static function visitProvider(): array => [ new InArray(['haystack' => [1.23], 'strict' => false]), [new TFloat(), new TString()], - [new TLiteralFloat(1.23), TLiteralString::make('1.23')], + [new TLiteralFloat(1.23), TypeUtil::getAtomicStringFromLiteral('1.23')], ], ]; } diff --git a/test/Validator/NotEmptyVisitorTest.php b/test/Validator/NotEmptyVisitorTest.php index 5cd23fa..9dffd7f 100644 --- a/test/Validator/NotEmptyVisitorTest.php +++ b/test/Validator/NotEmptyVisitorTest.php @@ -6,6 +6,7 @@ use Countable; use Kynx\Laminas\FormShape\Psalm\ConfigLoader; +use Kynx\Laminas\FormShape\Psalm\TypeUtil; use Kynx\Laminas\FormShape\Validator\NotEmptyVisitor; use Kynx\Laminas\FormShape\ValidatorVisitorInterface; use Laminas\Validator\NotEmpty; @@ -15,7 +16,6 @@ use Psalm\Type\Atomic\TBool; use Psalm\Type\Atomic\TInt; use Psalm\Type\Atomic\TIntRange; -use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TNonEmptyArray; use Psalm\Type\Atomic\TNull; @@ -55,7 +55,7 @@ public static function visitProvider(): array ], 'space' => [ new NotEmpty(NotEmpty::SPACE), - [TLiteralString::make(' '), new TInt()], + [TypeUtil::getAtomicStringFromLiteral(' '), new TInt()], [new TInt()], ], 'null' => [ @@ -70,13 +70,13 @@ public static function visitProvider(): array ], 'zero' => [ new NotEmpty(NotEmpty::ZERO), - [TLiteralString::make('0'), new TInt()], + [TypeUtil::getAtomicStringFromLiteral('0'), new TInt()], [new TInt()], ], 'string' => [ new NotEmpty(NotEmpty::STRING), - [TLiteralString::make(''), TLiteralString::make('a')], - [TLiteralString::make('a')], + [TypeUtil::getAtomicStringFromLiteral(''), TypeUtil::getAtomicStringFromLiteral('a')], + [TypeUtil::getAtomicStringFromLiteral('a')], ], 'float' => [ new NotEmpty(NotEmpty::FLOAT),