From a8bd3170dbe087890a53a4fc32bdd7e7da921374 Mon Sep 17 00:00:00 2001 From: Stefan Teunissen Date: Thu, 2 Apr 2026 15:25:59 +0200 Subject: [PATCH 1/2] fix(database-mysql): Added missing QueryBuilderFactoryInterface implementation --- packages/database-mysql/module.php | 3 +++ .../src/Query/MySqlQueryBuilderFactory.php | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php diff --git a/packages/database-mysql/module.php b/packages/database-mysql/module.php index c32f98d5..6b2e9ea1 100644 --- a/packages/database-mysql/module.php +++ b/packages/database-mysql/module.php @@ -10,7 +10,9 @@ use Marko\Database\MySql\Connection\MySqlConnection; use Marko\Database\MySql\Introspection\MySqlIntrospector; use Marko\Database\MySql\Query\MySqlQueryBuilder; +use Marko\Database\MySql\Query\MySqlQueryBuilderFactory; use Marko\Database\MySql\Sql\MySqlGenerator; +use Marko\Database\Query\QueryBuilderFactoryInterface; use Marko\Database\Query\QueryBuilderInterface; // Marko-specific configuration for this module. @@ -29,5 +31,6 @@ }, SqlGeneratorInterface::class => MySqlGenerator::class, QueryBuilderInterface::class => MySqlQueryBuilder::class, + QueryBuilderFactoryInterface::class => MySqlQueryBuilderFactory::class, ], ]; diff --git a/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php b/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php new file mode 100644 index 00000000..378b1dae --- /dev/null +++ b/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php @@ -0,0 +1,24 @@ +connection, + ); + } +} From 76b03958cdfc51ea22b981d2f294078d64895d06 Mon Sep 17 00:00:00 2001 From: Mark Shust Date: Sat, 4 Apr 2026 23:48:56 -0400 Subject: [PATCH 2/2] fix(database-mysql): add tests and remove unnecessary self-namespace import Add unit tests for MySqlQueryBuilderFactory (creation, independence, interface compliance) and a module binding test for the new QueryBuilderFactoryInterface entry. Remove unnecessary self-namespace import in the factory class. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/Query/MySqlQueryBuilderFactory.php | 1 - .../tests/Module/ModuleBindingsTest.php | 10 ++++ .../Query/MySqlQueryBuilderFactoryTest.php | 50 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/database-mysql/tests/Query/MySqlQueryBuilderFactoryTest.php diff --git a/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php b/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php index 378b1dae..c0853253 100644 --- a/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php +++ b/packages/database-mysql/src/Query/MySqlQueryBuilderFactory.php @@ -5,7 +5,6 @@ namespace Marko\Database\MySql\Query; use Marko\Database\Connection\ConnectionInterface; -use Marko\Database\MySql\Query\MySqlQueryBuilder; use Marko\Database\Query\QueryBuilderFactoryInterface; use Marko\Database\Query\QueryBuilderInterface; diff --git a/packages/database-mysql/tests/Module/ModuleBindingsTest.php b/packages/database-mysql/tests/Module/ModuleBindingsTest.php index 84c09bda..0191e34a 100644 --- a/packages/database-mysql/tests/Module/ModuleBindingsTest.php +++ b/packages/database-mysql/tests/Module/ModuleBindingsTest.php @@ -12,7 +12,9 @@ use Marko\Database\Exceptions\ConfigurationException; use Marko\Database\Introspection\IntrospectorInterface; use Marko\Database\MySql\Connection\MySqlConnection; +use Marko\Database\MySql\Query\MySqlQueryBuilderFactory; use Marko\Database\MySql\Sql\MySqlGenerator; +use Marko\Database\Query\QueryBuilderFactoryInterface; describe('MySQL module.php bindings', function (): void { it('binds ConnectionInterface to MySqlConnection class', function (): void { @@ -42,6 +44,14 @@ ->and($moduleConfig['bindings'][IntrospectorInterface::class])->toBeInstanceOf(Closure::class); }); + it('binds QueryBuilderFactoryInterface to MySqlQueryBuilderFactory class', function (): void { + $modulePath = dirname(__DIR__, 2); + $moduleConfig = require $modulePath . '/module.php'; + + expect($moduleConfig['bindings'])->toHaveKey(QueryBuilderFactoryInterface::class) + ->and($moduleConfig['bindings'][QueryBuilderFactoryInterface::class])->toBe(MySqlQueryBuilderFactory::class); + }); + it('throws ConfigurationException when config file missing', function (): void { // Create temp directory WITHOUT config $tempDir = sys_get_temp_dir() . '/marko_mysql_noconfig_' . uniqid(); diff --git a/packages/database-mysql/tests/Query/MySqlQueryBuilderFactoryTest.php b/packages/database-mysql/tests/Query/MySqlQueryBuilderFactoryTest.php new file mode 100644 index 00000000..498ec94b --- /dev/null +++ b/packages/database-mysql/tests/Query/MySqlQueryBuilderFactoryTest.php @@ -0,0 +1,50 @@ +implementsInterface(QueryBuilderFactoryInterface::class))->toBeTrue(); + }); + + it('accepts ConnectionInterface via constructor', function (): void { + $reflection = new ReflectionClass(MySqlQueryBuilderFactory::class); + $constructor = $reflection->getConstructor(); + $params = $constructor->getParameters(); + + expect($params)->toHaveCount(1) + ->and($params[0]->getName())->toBe('connection') + ->and($params[0]->getType()->getName())->toBe(ConnectionInterface::class); + }); + + it('creates MySqlQueryBuilder instances', function (): void { + $connection = $this->createMock(ConnectionInterface::class); + $factory = new MySqlQueryBuilderFactory($connection); + + $builder = $factory->create(); + + expect($builder)->toBeInstanceOf(QueryBuilderInterface::class) + ->and($builder)->toBeInstanceOf(MySqlQueryBuilder::class); + }); + + it('creates a new instance on each call', function (): void { + $connection = $this->createMock(ConnectionInterface::class); + $factory = new MySqlQueryBuilderFactory($connection); + + $builder1 = $factory->create(); + $builder2 = $factory->create(); + + expect($builder1)->not->toBe($builder2); + }); +});