From 5d267cf21a9d00c0d75104c23243567a055eb31e Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Wed, 26 Mar 2025 23:36:56 +0000 Subject: [PATCH 1/2] chore: test the `BaseType` and `BaseFunction` abstractions --- .../Doctrine/DBAL/Types/BaseTypeTest.php | 96 +++++++++++++++++++ .../Query/AST/Functions/BaseFunctionTest.php | 95 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php create mode 100644 tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php diff --git a/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php new file mode 100644 index 00000000..9a28344e --- /dev/null +++ b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php @@ -0,0 +1,96 @@ +platform = $this->createMock(AbstractPlatform::class); + } + + /** + * @test + */ + public function throws_exception_when_type_name_not_configured(): void + { + $type = new class extends BaseType { + protected const TYPE_NAME = ''; + }; + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('no meaningful value for TYPE_NAME constant'); + + $type->getName(); + } + + /** + * @test + */ + public function throws_exception_when_getting_sql_declaration_with_no_type_name(): void + { + $type = new class extends BaseType { + protected const TYPE_NAME = ''; + }; + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Doctrine type defined in class'); + + $type->getSQLDeclaration([], $this->platform); + } + + /** + * @test + */ + public function returns_correct_type_name(): void + { + $type = new class extends BaseType { + protected const TYPE_NAME = 'custom_type'; + }; + + self::assertEquals('custom_type', $type->getName()); + } + + /** + * @test + */ + public function gets_correct_sql_declaration(): void + { + $type = new class extends BaseType { + protected const TYPE_NAME = 'custom_type'; + }; + + $this->platform + ->expects(self::once()) + ->method('getDoctrineTypeMapping') + ->with('custom_type') + ->willReturn('CUSTOM_SQL_TYPE'); + + $result = $type->getSQLDeclaration([], $this->platform); + self::assertEquals('CUSTOM_SQL_TYPE', $result); + } + + /** + * @test + */ + public function requires_sql_comment_hint_returns_false(): void + { + $type = new class extends BaseType { + protected const TYPE_NAME = 'custom_type'; + }; + + self::assertFalse($type->requiresSQLCommentHint($this->platform)); + } +} diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php new file mode 100644 index 00000000..6ec8fc98 --- /dev/null +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php @@ -0,0 +1,95 @@ +customizeFunction(); + } + + protected function customizeFunction(): void + { + $this->setFunctionPrototype('TEST(%s, %s)'); + } + + /** + * @param list $nodes + */ + public function setNodes(array $nodes): void + { + $this->nodes = $nodes; + } + }; + + $node1 = $this->createMock(Node::class); + $node1->expects($this->once()) + ->method('dispatch') + ->willReturn('arg1'); + + $node2 = $this->createMock(Node::class); + $node2->expects($this->once()) + ->method('dispatch') + ->willReturn('arg2'); + + /** @var list $nodes */ + $nodes = [$node1, $node2]; + $function->setNodes($nodes); + + $sqlWalker = $this->createMock(SqlWalker::class); + + $result = $function->getSql($sqlWalker); + $this->assertEquals('TEST(arg1, arg2)', $result); + } + + /** + * @test + */ + public function get_sql_handles_null_nodes(): void + { + $function = new class('test_function') extends BaseFunction { + public function __construct(string $name) + { + parent::__construct($name); + $this->customizeFunction(); + } + + protected function customizeFunction(): void + { + $this->setFunctionPrototype('TEST(%s)'); + } + + /** + * @param list $nodes + */ + public function setNodes(array $nodes): void + { + $this->nodes = $nodes; + } + }; + + /** @var list $nodes */ + $nodes = [null]; + $function->setNodes($nodes); + + $sqlWalker = $this->createMock(SqlWalker::class); + + $result = $function->getSql($sqlWalker); + $this->assertEquals('TEST(null)', $result); + } +} From eccc921cac1d08c2326a8037f7de2985a489414a Mon Sep 17 00:00:00 2001 From: Martin Georgiev Date: Wed, 26 Mar 2025 23:44:18 +0000 Subject: [PATCH 2/2] suppress phpstan errors that relate to certain Doctrine versions only --- tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php | 1 + .../Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php index 9a28344e..0ef5af3a 100644 --- a/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php +++ b/tests/MartinGeorgiev/Doctrine/DBAL/Types/BaseTypeTest.php @@ -91,6 +91,7 @@ public function requires_sql_comment_hint_returns_false(): void protected const TYPE_NAME = 'custom_type'; }; + // @phpstan-ignore-next-line Not all Doctrine version like this method as it's deprecated. For now, we ignore the deprecation. self::assertFalse($type->requiresSQLCommentHint($this->platform)); } } diff --git a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php index 6ec8fc98..e9de6fd7 100644 --- a/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php +++ b/tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunctionTest.php @@ -17,6 +17,7 @@ class BaseFunctionTest extends TestCase public function get_sql_returns_formatted_function_call(): void { $function = new class('test_function') extends BaseFunction { + // @phpstan-ignore-next-line The type for $name is not string in older Doctrine versions public function __construct(string $name) { parent::__construct($name); @@ -63,6 +64,7 @@ public function setNodes(array $nodes): void public function get_sql_handles_null_nodes(): void { $function = new class('test_function') extends BaseFunction { + // @phpstan-ignore-next-line The type for $name is not string in older Doctrine versions public function __construct(string $name) { parent::__construct($name);