From 0e387470d00f8ca429917cb57912087c06400fa6 Mon Sep 17 00:00:00 2001 From: Pavel Buchnev Date: Mon, 10 Jan 2022 19:41:20 +0300 Subject: [PATCH] Fix driver cloning (#44) --- src/Driver/Driver.php | 16 +++-- .../Unit/Driver/AbstractDriverTest.php | 72 ++++++++++++++++++- tests/Database/Unit/Driver/TestDriver.php | 15 ++++ 3 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/Driver/Driver.php b/src/Driver/Driver.php index 277cd709..a7a94c1d 100644 --- a/src/Driver/Driver.php +++ b/src/Driver/Driver.php @@ -145,6 +145,12 @@ public function __call(string $name, array $arguments): mixed }; } + public function __clone() + { + $this->schemaHandler = $this->schemaHandler->withDriver($this); + $this->queryBuilder = $this->queryBuilder->withDriver($this); + } + /** * Get driver source database or file name. * @@ -273,6 +279,11 @@ public function lastInsertID(string $sequence = null) return $result; } + public function getTransactionLevel(): int + { + return $this->transactionLevel; + } + /** * Start SQL transaction with specified isolation level (not all DBMS support it). Nested * transactions are processed using savepoints. @@ -636,9 +647,4 @@ protected function defineLoggerContext(float $queryStart, ?PDOStatement $stateme return $context; } - - public function getTransactionLevel(): int - { - return $this->transactionLevel; - } } diff --git a/tests/Database/Unit/Driver/AbstractDriverTest.php b/tests/Database/Unit/Driver/AbstractDriverTest.php index ac83926c..c2058281 100644 --- a/tests/Database/Unit/Driver/AbstractDriverTest.php +++ b/tests/Database/Unit/Driver/AbstractDriverTest.php @@ -6,11 +6,17 @@ use Cycle\Database\Config\SQLiteDriverConfig; use Cycle\Database\Driver\Driver; +use Cycle\Database\Driver\DriverInterface; +use Cycle\Database\Driver\HandlerInterface; +use Cycle\Database\Query\BuilderInterface; +use Mockery as m; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; class AbstractDriverTest extends TestCase { + use m\Adapter\Phpunit\MockeryPHPUnitIntegration; + private Driver $driver; protected function setUp(): void @@ -22,11 +28,71 @@ protected function setUp(): void public function testLoggerShouldBeSet() { - $logger = $this->createMock(LoggerInterface::class); - $logger->expects($this->once()) - ->method('debug')->with('Insert ID: 0', []); + $logger = m::mock(LoggerInterface::class); + $logger->shouldReceive('debug') + ->once()->with('Insert ID: 0'); $this->driver->setLogger($logger); $this->driver->lastInsertID(); } + + public function testGetNotSetNameShouldThrowAnException() + { + $this->expectException(\RuntimeException::class); + $this->expectErrorMessage('Driver name is not defined.'); + $this->driver->getName(); + } + + public function testWithName() + { + $handler = m::mock(HandlerInterface::class); + $builder = m::mock(BuilderInterface::class); + + $handler->shouldReceive('withDriver')->once(); + $builder->shouldReceive('withDriver')->once(); + + $driver = TestDriver::createWith( + new SQLiteDriverConfig(), + $handler, + $builder + ); + + $driver->getSchemaHandler()->shouldReceive('withDriver')->once(); + $driver->getQueryBuilder()->shouldReceive('withDriver')->once(); + + $newDriver = $driver->withName('test'); + $this->assertSame('test', $newDriver->getName()); + + $this->checkImmutability($driver, $newDriver); + } + + public function testClone() + { + $handler = m::mock(HandlerInterface::class); + $builder = m::mock(BuilderInterface::class); + + $handler->shouldReceive('withDriver')->once(); + $builder->shouldReceive('withDriver')->once(); + + $driver = TestDriver::createWith( + new SQLiteDriverConfig(), + $handler, + $builder + ); + + $driver->getSchemaHandler()->shouldReceive('withDriver')->once(); + $driver->getQueryBuilder()->shouldReceive('withDriver')->once(); + + $newDriver = clone $driver; + + $this->checkImmutability($driver, $newDriver); + } + + private function checkImmutability(DriverInterface $driver, DriverInterface $newDriver): void + { + // Immutability + $this->assertNotSame($driver, $newDriver); + $this->assertNotSame($driver->getSchemaHandler(), $newDriver->getSchemaHandler()); + $this->assertNotSame($driver->getQueryBuilder(), $newDriver->getQueryBuilder()); + } } diff --git a/tests/Database/Unit/Driver/TestDriver.php b/tests/Database/Unit/Driver/TestDriver.php index 69820a76..26487a08 100644 --- a/tests/Database/Unit/Driver/TestDriver.php +++ b/tests/Database/Unit/Driver/TestDriver.php @@ -6,9 +6,11 @@ use Cycle\Database\Config\DriverConfig; use Cycle\Database\Driver\Driver; +use Cycle\Database\Driver\HandlerInterface; use Cycle\Database\Driver\SQLite\SQLiteCompiler; use Cycle\Database\Driver\SQLite\SQLiteHandler; use Cycle\Database\Exception\StatementException; +use Cycle\Database\Query\BuilderInterface; use Cycle\Database\Query\QueryBuilder; class TestDriver extends Driver @@ -32,4 +34,17 @@ public static function create(DriverConfig $config): Driver QueryBuilder::defaultBuilder() ); } + + public static function createWith( + DriverConfig $config, + HandlerInterface $handler, + BuilderInterface $builder + ): Driver { + return new self( + $config, + $handler, + new SQLiteCompiler('""'), + $builder + ); + } }