diff --git a/ci/phpstan/baselines/deprecated-methods.neon b/ci/phpstan/baselines/deprecated-methods.neon new file mode 100644 index 00000000..6a9425f8 --- /dev/null +++ b/ci/phpstan/baselines/deprecated-methods.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#Call to deprecated method getName\(\) of class MartinGeorgiev\\Doctrine\\DBAL\\Types\\BaseType#' diff --git a/ci/phpstan/baselines/lexer-constants.neon b/ci/phpstan/baselines/lexer-constants.neon new file mode 100644 index 00000000..7c8abdf1 --- /dev/null +++ b/ci/phpstan/baselines/lexer-constants.neon @@ -0,0 +1,11 @@ +parameters: + ignoreErrors: + - '#Access to undefined constant Doctrine\\ORM\\Query\\Lexer::T_[A-Z_]+#' + - '#Access to constant [A-Z_]+ on an unknown class Doctrine\\ORM\\Query\\TokenType#' + - '#Fetching deprecated class constant T_IDENTIFIER of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_OPEN_PARENTHESIS of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_CLOSE_PARENTHESIS of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_COMMA of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_ORDER of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_AS of class Doctrine\\ORM\\Query\\Lexer#' + - '#Fetching deprecated class constant T_DISTINCT of class Doctrine\\ORM\\Query\\Lexer#' diff --git a/ci/phpstan/baselines/phpstan-identifiers.neon b/ci/phpstan/baselines/phpstan-identifiers.neon new file mode 100644 index 00000000..715b4d17 --- /dev/null +++ b/ci/phpstan/baselines/phpstan-identifiers.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - identifier: missingType.iterableValue diff --git a/ci/phpstan/baselines/type-mismatches.neon b/ci/phpstan/baselines/type-mismatches.neon new file mode 100644 index 00000000..65064191 --- /dev/null +++ b/ci/phpstan/baselines/type-mismatches.neon @@ -0,0 +1,5 @@ +parameters: + ignoreErrors: + - '#Parameter \#1 \$phpArray of method MartinGeorgiev\\Doctrine\\DBAL\\Types\\BaseArray::convertToDatabaseValue\(\) expects array\|null, string given.#' + - '#Parameter \#1 \$postgresArray of method MartinGeorgiev\\Doctrine\\DBAL\\Types\\BaseArray::convertToPHPValue\(\) expects string\|null, int given.#' + - '#Property MartinGeorgiev\\Doctrine\\ORM\\Query\\AST\\Functions\\Cast::\$sourceType \(Doctrine\\ORM\\Query\\AST\\Node\) does not accept Doctrine\\ORM\\Query\\AST\\Node\|string#' diff --git a/ci/phpstan/config.neon b/ci/phpstan/config.neon index 5ffbffea..e7c54625 100644 --- a/ci/phpstan/config.neon +++ b/ci/phpstan/config.neon @@ -1,6 +1,12 @@ includes: - ../../vendor/ekino/phpstan-banned-code/extension.neon + - ../../vendor/phpstan/phpstan-deprecation-rules/rules.neon + - ../../vendor/phpstan/phpstan-doctrine/extension.neon - ../../vendor/phpstan/phpstan-phpunit/extension.neon + - ./baselines/deprecated-methods.neon + - ./baselines/lexer-constants.neon + - ./baselines/phpstan-identifiers.neon + - ./baselines/type-mismatches.neon parameters: level: max @@ -9,13 +15,10 @@ parameters: - ../../src - ../../tests - reportUnmatchedIgnoredErrors: false + tmpDir: ../../var/cache/phpstan + + parallel: + maximumNumberOfProcesses: 4 - ignoreErrors: - - identifier: missingType.iterableValue - - - '#Parameter \#1 \$phpArray of method MartinGeorgiev\\Doctrine\\DBAL\\Types\\BaseArray::convertToDatabaseValue\(\) expects array\|null, string given.#' - - '#Parameter \#1 \$postgresArray of method MartinGeorgiev\\Doctrine\\DBAL\\Types\\BaseArray::convertToPHPValue\(\) expects string\|null, int given.#' - - '#Property MartinGeorgiev\\Doctrine\\ORM\\Query\\AST\\Functions\\Cast::\$sourceType \(Doctrine\\ORM\\Query\\AST\\Node\) does not accept Doctrine\\ORM\\Query\\AST\\Node\|string#' - - '#Access to undefined constant Doctrine\\ORM\\Query\\Lexer::T_[A-Z_]+#' - - '#Access to constant [A-Z_]+ on an unknown class Doctrine\\ORM\\Query\\TokenType#' + errorFormat: table + reportUnmatchedIgnoredErrors: false diff --git a/ci/phpunit/config.xml b/ci/phpunit/config.xml index c4f535df..988fce74 100644 --- a/ci/phpunit/config.xml +++ b/ci/phpunit/config.xml @@ -1,13 +1,29 @@ - - - - ../../tests - - - - - ../../src - - + + + + ../../tests + + + + + + + + + + + ../../src + + diff --git a/ci/rector/config.php b/ci/rector/config.php index 12c0f7b0..f29b9a46 100644 --- a/ci/rector/config.php +++ b/ci/rector/config.php @@ -12,29 +12,36 @@ $basePath = __DIR__.'/../../'; $paths = [ $basePath.'ci', + $basePath.'fixtures', $basePath.'src', $basePath.'tests', ]; $rectorConfig->paths($paths); + $rectorConfig->cacheDirectory($basePath.'var/cache/rector/'); + $rectorConfig->parallel(); $rectorConfig->phpstanConfig($basePath.'ci/phpstan/config.neon'); + + $rectorConfig->sets([ + SetList::CODE_QUALITY, + SetList::DEAD_CODE, + SetList::EARLY_RETURN, + SetList::NAMING, + SetList::PHP_80, + SetList::PHP_81, + SetList::TYPE_DECLARATION, + SetList::PRIVATIZATION, + SetList::CODING_STYLE, + DoctrineSetList::DOCTRINE_ORM_25, + DoctrineSetList::DOCTRINE_CODE_QUALITY, + LevelSetList::UP_TO_PHP_81, + ]); + $rectorConfig->skip([ RenamePropertyToMatchTypeRector::class, ]); - $rectorConfig->importShortClasses(false); - $rectorConfig->importNames(false, false); // @todo Enable once Rector introduces better support for function imports. - - $rectorConfig->import(SetList::CODE_QUALITY); - $rectorConfig->import(SetList::DEAD_CODE); - $rectorConfig->import(SetList::EARLY_RETURN); - $rectorConfig->import(SetList::NAMING); - $rectorConfig->import(SetList::PHP_80); - $rectorConfig->import(SetList::PHP_81); - $rectorConfig->import(SetList::TYPE_DECLARATION); - $rectorConfig->import(DoctrineSetList::DOCTRINE_ORM_25); - $rectorConfig->import(DoctrineSetList::DOCTRINE_CODE_QUALITY); - - $rectorConfig->import(LevelSetList::UP_TO_PHP_81); + $rectorConfig->importShortClasses(false); + $rectorConfig->importNames(false, false); }; diff --git a/composer.json b/composer.json index 3b4d4255..7b0429f0 100644 --- a/composer.json +++ b/composer.json @@ -48,9 +48,11 @@ "ekino/phpstan-banned-code": "^1.0", "friendsofphp/php-cs-fixer": "^3.72.0", "phpstan/phpstan": "^1.12.21", + "phpstan/phpstan-deprecation-rules": "^1.2", + "phpstan/phpstan-doctrine": "^1.5", "phpstan/phpstan-phpunit": "^1.4.2", "phpunit/phpunit": "^10.5.45", - "rector/rector": "^1.2.10", + "rector/rector": "^1.2", "symfony/cache": "^6.4||^7.0" }, "suggest": { diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsArrays.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsArrays.php index bc05f59c..5d476088 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsArrays.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsArrays.php @@ -4,14 +4,15 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsArrays extends Entity { - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] public array $array1; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] public array $array2; } diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDates.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDates.php index 8c0d9121..6c6e25d5 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDates.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDates.php @@ -4,26 +4,27 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsDates extends Entity { - #[ORM\Column(type: 'date_immutable')] + #[ORM\Column(type: Types::DATE_IMMUTABLE)] public \DateTimeImmutable $date1; - #[ORM\Column(type: 'date_immutable')] + #[ORM\Column(type: Types::DATE_IMMUTABLE)] public \DateTimeImmutable $date2; - #[ORM\Column(type: 'datetime_immutable')] + #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public \DateTimeImmutable $datetime1; - #[ORM\Column(type: 'datetime_immutable')] + #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public \DateTimeImmutable $datetime2; - #[ORM\Column(type: 'datetimetz_immutable')] + #[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)] public \DateTimeImmutable $datetimetz1; - #[ORM\Column(type: 'datetimetz_immutable')] + #[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)] public \DateTimeImmutable $datetimetz2; } diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDecimals.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDecimals.php index e3db294e..1c11f49f 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDecimals.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsDecimals.php @@ -4,17 +4,18 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsDecimals extends Entity { - #[ORM\Column(type: 'decimal')] + #[ORM\Column(type: Types::DECIMAL)] public float $decimal1; - #[ORM\Column(type: 'decimal')] + #[ORM\Column(type: Types::DECIMAL)] public float $decimal2; - #[ORM\Column(type: 'decimal')] + #[ORM\Column(type: Types::DECIMAL)] public float $decimal3; } \ No newline at end of file diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsIntegers.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsIntegers.php index 46fbdc26..5ef858df 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsIntegers.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsIntegers.php @@ -4,17 +4,18 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsIntegers extends Entity { - #[ORM\Column(type: 'integer')] + #[ORM\Column(type: Types::INTEGER)] public int $integer1; - #[ORM\Column(type: 'integer')] + #[ORM\Column(type: Types::INTEGER)] public int $integer2; - #[ORM\Column(type: 'integer')] + #[ORM\Column(type: Types::INTEGER)] public int $integer3; } diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsJsons.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsJsons.php index d73c206a..4008c271 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsJsons.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsJsons.php @@ -4,14 +4,15 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsJsons extends Entity { - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] public array $object1; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] public array $object2; } diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php index af7d8da0..e620216c 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php @@ -4,14 +4,15 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity()] class ContainsTexts extends Entity { - #[ORM\Column(type: 'text')] + #[ORM\Column(type: Types::TEXT)] public string $text1; - #[ORM\Column(type: 'text')] + #[ORM\Column(type: Types::TEXT)] public string $text2; } diff --git a/fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php b/fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php index 3d4fc2a7..e0349d3a 100644 --- a/fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php +++ b/fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php @@ -4,19 +4,13 @@ namespace Fixtures\MartinGeorgiev\Doctrine\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; abstract class Entity { - /** - * @ORM\Id - * - * @ORM\Column(type="string") - * - * @ORM\GeneratedValue - */ #[ORM\Id()] - #[ORM\Column(type: 'string')] + #[ORM\Column(type: Types::STRING)] #[ORM\GeneratedValue()] public string $id; } diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseArray.php index 79bf1da3..079051b7 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseArray.php @@ -38,10 +38,11 @@ public function convertToDatabaseValue($phpArray, AbstractPlatform $platform): ? foreach ($phpArray as &$item) { if (!$this->isValidArrayItemForDatabase($item)) { - $exceptionMessage = 'One or more of the items given doesn\'t look valid.'; + $exceptionMessage = "One or more of the items given doesn't look valid."; throw new ConversionException($exceptionMessage); } + $item = $this->transformArrayItemForPostgres($item); } @@ -51,7 +52,7 @@ public function convertToDatabaseValue($phpArray, AbstractPlatform $platform): ? /** * Tests if given PHP array item is from compatible type for PostgreSQL. */ - protected function isValidArrayItemForDatabase(mixed $item): bool + public function isValidArrayItemForDatabase(mixed $item): bool { return true; } @@ -76,6 +77,7 @@ public function convertToPHPValue($postgresArray, AbstractPlatform $platform): ? if ($postgresArray === null) { return null; } + if (!\is_string($postgresArray)) { $exceptionMessage = 'Given PostgreSQL value content type is not PHP string. Instead it is "%s".'; @@ -105,7 +107,7 @@ protected function transformPostgresArrayToPHPArray(string $postgresArray): arra * * @return mixed */ - protected function transformArrayItemForPHP(mixed $item) + public function transformArrayItemForPHP(mixed $item) { return $item; } diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php index 93dcd815..af52a7ba 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php @@ -26,9 +26,11 @@ public function isValidArrayItemForDatabase($item): bool if (!\is_int($item) && !\is_string($item)) { return false; } + if (!(bool) \preg_match('/^-?\d+$/', (string) $item)) { return false; } + if ((string) $item < $this->getMinValue()) { return false; } diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonTransformer.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonTransformer.php index 9ad037dd..0cc23051 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonTransformer.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonTransformer.php @@ -25,7 +25,7 @@ protected function transformToPostgresJson(mixed $phpValue): string try { $postgresValue = \json_encode($phpValue, JSON_THROW_ON_ERROR); } catch (\JsonException) { - throw new ConversionException(\sprintf('Value %s can\'t be resolved to valid JSON', \var_export($phpValue, true))); + throw new ConversionException(\sprintf("Value %s can't be resolved to valid JSON", \var_export($phpValue, true))); } return $postgresValue; diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php index 7c880ea9..99ac932a 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/JsonbArray.php @@ -33,6 +33,7 @@ protected function transformPostgresArrayToPHPArray(string $postgresArray): arra if ($postgresArray === '{}') { return []; } + $trimmedPostgresArray = \mb_substr($postgresArray, 2, -2); $phpArray = \explode('},{', $trimmedPostgresArray); foreach ($phpArray as &$item) { diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php index d9efc19a..15115b4e 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/TextArray.php @@ -41,6 +41,7 @@ protected function transformToPostgresTextArray(array $phpTextArray): string if (!\is_array($phpTextArray)) { throw new \InvalidArgumentException(\sprintf('Value %s is not an array', \var_export($phpTextArray, true))); } + if ($phpTextArray === []) { return '{}'; } diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseOrderableFunction.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseOrderableFunction.php index f8e18956..08579c66 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseOrderableFunction.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseOrderableFunction.php @@ -15,6 +15,7 @@ abstract class BaseOrderableFunction extends BaseFunction { protected Node $expression; + protected ?OrderByClause $orderByClause = null; public function parse(Parser $parser): void diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php index 055c08e0..7bb16b56 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php @@ -23,7 +23,7 @@ abstract class BaseVariadicFunction extends BaseFunction /** * @throws ParserException */ - public function feedParserWithNodes(Parser $parser): void + protected function feedParserWithNodes(Parser $parser): void { $lexer = $parser->getLexer(); @@ -40,6 +40,7 @@ public function feedParserWithNodes(Parser $parser): void $parser->match($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA); $this->nodes[] = $parser->{$this->commonNodeMapping}(); } + $aheadType = $lexer->lookahead->type; } diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Cast.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Cast.php index b8e09369..2b2f7d62 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Cast.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Cast.php @@ -34,6 +34,7 @@ public function parse(Parser $parser): void $parser->match($shouldUseLexer ? Lexer::T_IDENTIFIER : TokenType::T_IDENTIFIER); $parser->match($shouldUseLexer ? Lexer::T_OPEN_PARENTHESIS : TokenType::T_OPEN_PARENTHESIS); + $this->sourceType = $parser->SimpleArithmeticExpression(); $parser->match($shouldUseLexer ? Lexer::T_AS : TokenType::T_AS); $parser->match($shouldUseLexer ? Lexer::T_IDENTIFIER : TokenType::T_IDENTIFIER); @@ -43,6 +44,7 @@ public function parse(Parser $parser): void if (!$token instanceof Token) { return; } + if (!\is_string($token->value)) { return; } @@ -59,6 +61,7 @@ public function parse(Parser $parser): void $parameters[] = $parameter->value; } } + $parser->match($shouldUseLexer ? Lexer::T_CLOSE_PARENTHESIS : TokenType::T_CLOSE_PARENTHESIS); $type .= '('.\implode(', ', $parameters).')'; } diff --git a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php index eaceace1..40572c7d 100644 --- a/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php +++ b/src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php @@ -22,6 +22,7 @@ class StringAgg extends BaseOrderableFunction { private bool $isDistinct = false; + private Node $delimiter; protected function customizeFunction(): void diff --git a/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseArrayTest.php b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseArrayTest.php index 670d59a4..f366463b 100644 --- a/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseArrayTest.php +++ b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseArrayTest.php @@ -100,7 +100,7 @@ public function throws_conversion_exception_when_invalid_array_item_value(): voi $this->expectExceptionMessage("One or more of the items given doesn't look valid."); $this->fixture - ->expects($this->once()) + ->expects(self::once()) ->method('isValidArrayItemForDatabase') ->willReturn(false); diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunctionTestCase.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunctionTestCase.php index c7358df7..64fe3e74 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunctionTestCase.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunctionTestCase.php @@ -33,6 +33,10 @@ public function throws_an_exception_when_lexer_is_not_populated_with_a_lookahead $parser = new Parser($query); $parser->getLexer()->moveNext(); - $this->createFixture()->feedParserWithNodes($parser); + $baseComparisonFunction = $this->createFixture(); + + $reflectionMethod = new \ReflectionMethod($baseComparisonFunction::class, 'feedParserWithNodes'); + $reflectionMethod->setAccessible(true); + $reflectionMethod->invoke($baseComparisonFunction, $parser); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php index 7e6e6c0e..3e7f9f7f 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php @@ -42,7 +42,7 @@ public function throws_exception_when_odd_number_of_arguments_given(): void { $this->expectException(InvalidArgumentForVariadicFunctionException::class); - $dql = \sprintf('SELECT JSON_BUILD_OBJECT(\'key1\', e.value1, \'key2\') FROM %s e', ContainsJsons::class); + $dql = \sprintf("SELECT JSON_BUILD_OBJECT('key1', e.value1, 'key2') FROM %s e", ContainsJsons::class); $this->assertSqlFromDql('', $dql); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php index f484f26e..fa0a64ed 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php @@ -42,7 +42,7 @@ public function throws_exception_when_odd_number_of_arguments_given(): void { $this->expectException(InvalidArgumentForVariadicFunctionException::class); - $dql = \sprintf('SELECT JSONB_BUILD_OBJECT(\'key1\', e.object1, \'key2\') FROM %s e', ContainsJsons::class); + $dql = \sprintf("SELECT JSONB_BUILD_OBJECT('key1', e.object1, 'key2') FROM %s e", ContainsJsons::class); $this->assertSqlFromDql('', $dql); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php index a7d3741b..5484ab4b 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php @@ -43,6 +43,7 @@ private function setConfigurationCache(Configuration $configuration): void return; } + $doctrineArrayCacheClass = '\Doctrine\Common\Cache\ArrayCache'; $useDbalV2 = \class_exists($doctrineArrayCacheClass) && \method_exists($configuration, 'setMetadataCacheImpl') && \method_exists($configuration, 'setQueryCacheImpl'); if ($useDbalV2) { @@ -95,6 +96,7 @@ public function dql_is_transformed_to_valid_sql(): void if (\count($expectedSqls) !== \count($dqls)) { throw new \LogicException(\sprintf('You need ot provide matching expected SQL for every DQL, currently there are %d SQL statements for %d DQL statements', \count($expectedSqls), \count($dqls))); } + foreach ($expectedSqls as $key => $expectedSql) { $this->assertSqlFromDql($expectedSql, $dqls[$key], \sprintf('Assertion failed for expected SQL statement "%s"', $expectedSql)); } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php index d0461c65..a0194678 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php @@ -22,7 +22,7 @@ protected function getExpectedSqlStatements(): array return [ 'SELECT to_tsquery(c0_.text1) AS sclr_0 FROM ContainsTexts c0_', 'SELECT to_tsquery(UPPER(c0_.text1)) AS sclr_0 FROM ContainsTexts c0_', - 'SELECT to_tsquery(\'english\', c0_.text1) AS sclr_0 FROM ContainsTexts c0_', + "SELECT to_tsquery('english', c0_.text1) AS sclr_0 FROM ContainsTexts c0_", ]; } @@ -31,7 +31,7 @@ protected function getDqlStatements(): array return [ \sprintf('SELECT TO_TSQUERY(e.text1) FROM %s e', ContainsTexts::class), \sprintf('SELECT TO_TSQUERY(UPPER(e.text1)) FROM %s e', ContainsTexts::class), - \sprintf('SELECT TO_TSQUERY(\'english\', e.text1) FROM %s e', ContainsTexts::class), + \sprintf("SELECT TO_TSQUERY('english', e.text1) FROM %s e", ContainsTexts::class), ]; } @@ -42,7 +42,7 @@ public function throws_exception_when_too_many_arguments_given(): void { $this->expectException(InvalidArgumentForVariadicFunctionException::class); - $dql = \sprintf('SELECT TO_TSQUERY(\'english\', e.text1, \'extra\') FROM %s e', ContainsTexts::class); + $dql = \sprintf("SELECT TO_TSQUERY('english', e.text1, 'extra') FROM %s e", ContainsTexts::class); $this->assertSqlFromDql('', $dql); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php index a5aed7ba..a7e3be6f 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php @@ -22,7 +22,7 @@ protected function getExpectedSqlStatements(): array return [ 'SELECT to_tsvector(c0_.text1) AS sclr_0 FROM ContainsTexts c0_', 'SELECT to_tsvector(LOWER(c0_.text1)) AS sclr_0 FROM ContainsTexts c0_', - 'SELECT to_tsvector(\'english\', c0_.text1) AS sclr_0 FROM ContainsTexts c0_', + "SELECT to_tsvector('english', c0_.text1) AS sclr_0 FROM ContainsTexts c0_", ]; } @@ -31,7 +31,7 @@ protected function getDqlStatements(): array return [ \sprintf('SELECT TO_TSVECTOR(e.text1) FROM %s e', ContainsTexts::class), \sprintf('SELECT TO_TSVECTOR(LOWER(e.text1)) FROM %s e', ContainsTexts::class), - \sprintf('SELECT TO_TSVECTOR(\'english\', e.text1) FROM %s e', ContainsTexts::class), + \sprintf("SELECT TO_TSVECTOR('english', e.text1) FROM %s e", ContainsTexts::class), ]; } @@ -42,7 +42,7 @@ public function throws_exception_when_too_many_arguments_given(): void { $this->expectException(InvalidArgumentForVariadicFunctionException::class); - $dql = \sprintf('SELECT TO_TSVECTOR(\'english\', e.text1, \'extra\') FROM %s e', ContainsTexts::class); + $dql = \sprintf("SELECT TO_TSVECTOR('english', e.text1, 'extra') FROM %s e", ContainsTexts::class); $this->assertSqlFromDql('', $dql); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php index 50a63515..9261e4b5 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php @@ -21,7 +21,7 @@ protected function getExpectedSqlStatements(): array { return [ 'SELECT unaccent(c0_.text1) AS sclr_0 FROM ContainsTexts c0_', - 'SELECT unaccent(\'unaccent\', c0_.text1) AS sclr_0 FROM ContainsTexts c0_', + "SELECT unaccent('unaccent', c0_.text1) AS sclr_0 FROM ContainsTexts c0_", ]; } @@ -29,7 +29,7 @@ protected function getDqlStatements(): array { return [ \sprintf('SELECT UNACCENT(e.text1) FROM %s e', ContainsTexts::class), - \sprintf('SELECT UNACCENT(\'unaccent\', e.text1) FROM %s e', ContainsTexts::class), + \sprintf("SELECT UNACCENT('unaccent', e.text1) FROM %s e", ContainsTexts::class), ]; } @@ -40,7 +40,7 @@ public function throws_exception_when_too_many_arguments_given(): void { $this->expectException(InvalidArgumentForVariadicFunctionException::class); - $dql = \sprintf('SELECT UNACCENT(\'dict\', e.text1, \'extra\') FROM %s e', ContainsTexts::class); + $dql = \sprintf("SELECT UNACCENT('dict', e.text1, 'extra') FROM %s e", ContainsTexts::class); $this->assertSqlFromDql('', $dql); } }