From be6339f96030e7fe76a9dc82a72d327c8702c747 Mon Sep 17 00:00:00 2001 From: Stefano Arlandini Date: Fri, 17 Sep 2021 18:15:50 +0200 Subject: [PATCH] Improve the compatibility layer for Doctrine DBAL to avoid side-effects of polyfilling (#553) * Improve the compatibility layer for Doctrine DBAL to avoid deprecations * Update the CHANGELOG file * Mark the `TracingDriver*` and `TracingStatement*` classes as `@internal` --- CHANGELOG.md | 1 + phpstan-baseline.neon | 85 ------ phpstan.neon | 2 + psalm-baseline.xml | 10 +- .../ExceptionConverterDriverInterface.php | 12 - src/Tracing/Doctrine/DBAL/TracingDriver.php | 140 --------- .../Doctrine/DBAL/TracingDriverForV2.php | 114 ++++++++ .../Doctrine/DBAL/TracingDriverForV3.php | 92 ++++++ .../Doctrine/DBAL/TracingStatementForV2.php | 2 + .../Doctrine/DBAL/TracingStatementForV3.php | 3 + src/aliases.php | 14 +- .../Doctrine/DBAL/TracingDriverForV2Test.php | 192 ++++++++++++ .../Doctrine/DBAL/TracingDriverForV3Test.php | 134 +++++++++ .../DBAL/TracingDriverMiddlewareTest.php | 4 +- .../Doctrine/DBAL/TracingDriverTest.php | 273 ------------------ 15 files changed, 557 insertions(+), 521 deletions(-) delete mode 100644 src/Tracing/Doctrine/DBAL/Compatibility/ExceptionConverterDriverInterface.php delete mode 100644 src/Tracing/Doctrine/DBAL/TracingDriver.php create mode 100644 src/Tracing/Doctrine/DBAL/TracingDriverForV2.php create mode 100644 src/Tracing/Doctrine/DBAL/TracingDriverForV3.php create mode 100644 tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php create mode 100644 tests/Tracing/Doctrine/DBAL/TracingDriverForV3Test.php delete mode 100644 tests/Tracing/Doctrine/DBAL/TracingDriverTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c2baa8..92bc9080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix: Test if `TracingStatement` exists before attempting to create the class alias, otherwise it breaks when opcache is enabled. (#552) - Fix: Pass logger from `logger` config option to `TransportFactory` (#555) +- Improve the compatibility layer with Doctrine DBAL to avoid deprecations notices (#553) ## 4.2.2 (2021-08-30) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1e060e0c..fc8b646e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15,56 +15,6 @@ parameters: count: 1 path: src/EventListener/ErrorListener.php - - - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Driver\\|Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\Compatibility\\\\ExceptionConverterDriverInterface\\:\\:connect\\(\\)\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Driver\\|Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\Compatibility\\\\ExceptionConverterDriverInterface\\:\\:getDatabasePlatform\\(\\)\\.$#" - count: 2 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Driver\\|Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\Compatibility\\\\ExceptionConverterDriverInterface\\:\\:getSchemaManager\\(\\)\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Call to an undefined method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\Compatibility\\\\ExceptionConverterDriverInterface\\:\\:convertException\\(\\)\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:connect\\(\\) has parameter \\$driverOptions with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:connect\\(\\) has parameter \\$password with no typehint specified\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:connect\\(\\) has parameter \\$username with no typehint specified\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:convertException\\(\\) has parameter \\$message with no typehint specified\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\DriverException given\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - - - message: "#^Parameter \\$exception of method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:convertException\\(\\) has invalid typehint type Doctrine\\\\DBAL\\\\Driver\\\\DriverException\\.$#" - count: 1 - path: src/Tracing/Doctrine/DBAL/TracingDriver.php - - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Driver\\\\Connection\\:\\:errorCode\\(\\)\\.$#" count: 1 @@ -220,41 +170,6 @@ parameters: count: 1 path: tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php - - - message: "#^Class Doctrine\\\\DBAL\\\\Driver\\\\DriverException not found\\.$#" - count: 3 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Parameter \\#1 \\$driverException of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Driver\\\\Exception, string given\\.$#" - count: 1 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Parameter \\#1 \\$originalClassName of method PHPUnit\\\\Framework\\\\TestCase\\:\\:createMock\\(\\) expects class\\-string\\, string given\\.$#" - count: 2 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\DriverException&PHPUnit\\\\Framework\\\\MockObject\\\\MockObject given\\.$#" - count: 1 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Trying to mock an undefined method convertException\\(\\) on class Sentry\\\\SentryBundle\\\\Tests\\\\Tracing\\\\Doctrine\\\\DBAL\\\\StubExceptionConverterDriverInterface\\.$#" - count: 1 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Trying to mock an undefined method getDatabase\\(\\) on class Doctrine\\\\DBAL\\\\Driver\\.$#" - count: 1 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - - - message: "#^Trying to mock an undefined method getName\\(\\) on class Doctrine\\\\DBAL\\\\Driver\\.$#" - count: 1 - path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php - - message: "#^Trying to mock an undefined method closeCursor\\(\\) on class Doctrine\\\\DBAL\\\\Driver\\\\Statement\\.$#" count: 1 diff --git a/phpstan.neon b/phpstan.neon index ff77da37..cabfaeda 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,9 @@ parameters: excludePaths: - src/aliases.php - src/Tracing/Doctrine/DBAL/TracingStatementForV2.php + - src/Tracing/Doctrine/DBAL/TracingDriverForV2.php - tests/End2End/App + - tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php dynamicConstantNames: - Symfony\Component\HttpKernel\Kernel::VERSION - Symfony\Component\HttpKernel\Kernel::VERSION_ID diff --git a/psalm-baseline.xml b/psalm-baseline.xml index fa32acb6..2052cea0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + ConsoleListener @@ -8,6 +8,11 @@ public function __construct(HubInterface $hub, bool $captureErrors = true) + + + ExceptionConverterDriver + + $this->decoratedStatement @@ -33,6 +38,9 @@ + + TracingDriverForV2 + FilterControllerEvent FilterResponseEvent diff --git a/src/Tracing/Doctrine/DBAL/Compatibility/ExceptionConverterDriverInterface.php b/src/Tracing/Doctrine/DBAL/Compatibility/ExceptionConverterDriverInterface.php deleted file mode 100644 index dde6b971..00000000 --- a/src/Tracing/Doctrine/DBAL/Compatibility/ExceptionConverterDriverInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -= 2.13. - * - * @internal - */ -final class TracingDriver implements DriverInterface, VersionAwarePlatformDriverInterface, ExceptionConverterDriverInterface -{ - /** - * @var HubInterface The current hub - */ - private $hub; - - /** - * @var DriverInterface|VersionAwarePlatformDriverInterface|ExceptionConverterDriverInterface The instance of the decorated driver - */ - private $decoratedDriver; - - /** - * @param HubInterface $hub The current hub - * @param DriverInterface $decoratedDriver The instance of the driver to decorate - */ - public function __construct(HubInterface $hub, DriverInterface $decoratedDriver) - { - $this->hub = $hub; - $this->decoratedDriver = $decoratedDriver; - } - - /** - * {@inheritdoc} - */ - public function connect(array $params, $username = null, $password = null, array $driverOptions = []) - { - return new TracingDriverConnection( - $this->hub, - $this->decoratedDriver->connect($params, $username, $password, $driverOptions), - $this->decoratedDriver->getDatabasePlatform()->getName(), - $params - ); - } - - /** - * {@inheritdoc} - */ - public function getDatabasePlatform() - { - return $this->decoratedDriver->getDatabasePlatform(); - } - - /** - * {@inheritdoc} - */ - public function getSchemaManager(Connection $conn, ?AbstractPlatform $platform = null) - { - return $this->decoratedDriver->getSchemaManager($conn, $platform); - } - - /** - * {@inheritdoc} - */ - public function getExceptionConverter(): ExceptionConverter - { - if (method_exists($this->decoratedDriver, 'getExceptionConverter')) { - return $this->decoratedDriver->getExceptionConverter(); - } - - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 2.x.', __METHOD__)); - } - - /** - * {@inheritdoc} - */ - public function getName(): string - { - if (method_exists($this->decoratedDriver, 'getName')) { - return $this->decoratedDriver->getName(); - } - - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); - } - - /** - * {@inheritdoc} - */ - public function getDatabase(Connection $conn): ?string - { - if (method_exists($this->decoratedDriver, 'getDatabase')) { - return $this->decoratedDriver->getDatabase($conn); - } - - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); - } - - /** - * {@inheritdoc} - */ - public function createDatabasePlatformForVersion($version): AbstractPlatform - { - if ($this->decoratedDriver instanceof VersionAwarePlatformDriverInterface) { - return $this->decoratedDriver->createDatabasePlatformForVersion($version); - } - - return $this->getDatabasePlatform(); - } - - /** - * {@inheritdoc} - */ - public function convertException($message, LegacyDriverExceptionInterface $exception): DBALDriverException - { - if (!interface_exists(ResultStatement::class)) { - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); - } - - if ($this->decoratedDriver instanceof ExceptionConverterDriverInterface) { - return $this->decoratedDriver->convertException($message, $exception); - } - - return new DBALDriverException($message, $exception); - } -} diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverForV2.php b/src/Tracing/Doctrine/DBAL/TracingDriverForV2.php new file mode 100644 index 00000000..85dfa7d5 --- /dev/null +++ b/src/Tracing/Doctrine/DBAL/TracingDriverForV2.php @@ -0,0 +1,114 @@ +hub = $hub; + $this->decoratedDriver = $decoratedDriver; + } + + /** + * {@inheritdoc} + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = []): TracingDriverConnection + { + return new TracingDriverConnection( + $this->hub, + $this->decoratedDriver->connect($params, $username, $password, $driverOptions), + $this->decoratedDriver->getDatabasePlatform()->getName(), + $params + ); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform(): AbstractPlatform + { + return $this->decoratedDriver->getDatabasePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn, ?AbstractPlatform $platform = null): AbstractSchemaManager + { + return $this->decoratedDriver->getSchemaManager($conn, $platform); + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return $this->decoratedDriver->getName(); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn): ?string + { + return $this->decoratedDriver->getDatabase($conn); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version): AbstractPlatform + { + if ($this->decoratedDriver instanceof VersionAwarePlatformDriver) { + return $this->decoratedDriver->createDatabasePlatformForVersion($version); + } + + return $this->getDatabasePlatform(); + } + + /** + * {@inheritdoc} + */ + public function convertException($message, DriverException $exception): DBALDriverException + { + if ($this->decoratedDriver instanceof ExceptionConverterDriver) { + return $this->decoratedDriver->convertException($message, $exception); + } + + return new DBALDriverException($message, $exception); + } +} diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php b/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php new file mode 100644 index 00000000..c6fa7b65 --- /dev/null +++ b/src/Tracing/Doctrine/DBAL/TracingDriverForV3.php @@ -0,0 +1,92 @@ += 3.0. + * + * @internal + */ +final class TracingDriverForV3 implements Driver, VersionAwarePlatformDriver +{ + /** + * @var HubInterface The current hub + */ + private $hub; + + /** + * @var Driver|VersionAwarePlatformDriver The instance of the decorated driver + */ + private $decoratedDriver; + + /** + * @param HubInterface $hub The current hub + * @param Driver $decoratedDriver The instance of the driver to decorate + */ + public function __construct(HubInterface $hub, Driver $decoratedDriver) + { + $this->hub = $hub; + $this->decoratedDriver = $decoratedDriver; + } + + /** + * {@inheritdoc} + */ + public function connect(array $params): TracingDriverConnection + { + return new TracingDriverConnection( + $this->hub, + $this->decoratedDriver->connect($params), + $this->decoratedDriver->getDatabasePlatform()->getName(), + $params + ); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform(): AbstractPlatform + { + return $this->decoratedDriver->getDatabasePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn, AbstractPlatform $platform): AbstractSchemaManager + { + return $this->decoratedDriver->getSchemaManager($conn, $platform); + } + + /** + * {@inheritdoc} + */ + public function getExceptionConverter(): ExceptionConverter + { + return $this->decoratedDriver->getExceptionConverter(); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version): AbstractPlatform + { + if ($this->decoratedDriver instanceof VersionAwarePlatformDriver) { + return $this->decoratedDriver->createDatabasePlatformForVersion($version); + } + + return $this->getDatabasePlatform(); + } +} diff --git a/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php b/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php index ffaaf7cb..7803d415 100644 --- a/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php +++ b/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php @@ -9,6 +9,8 @@ use Sentry\Tracing\SpanContext; /** + * @internal + * * @phpstan-implements \IteratorAggregate */ final class TracingStatementForV2 extends AbstractTracingStatement implements \IteratorAggregate, Statement diff --git a/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php b/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php index fdc78715..2ef5b3b1 100644 --- a/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php +++ b/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php @@ -9,6 +9,9 @@ use Doctrine\DBAL\ParameterType; use Sentry\Tracing\SpanContext; +/** + * @internal + */ final class TracingStatementForV3 extends AbstractTracingStatement implements Statement { /** diff --git a/src/aliases.php b/src/aliases.php index 89eddab1..56f4f8b6 100644 --- a/src/aliases.php +++ b/src/aliases.php @@ -4,7 +4,6 @@ namespace Sentry\SentryBundle; -use Doctrine\DBAL\Driver\ExceptionConverterDriver as LegacyExceptionConverterDriverInterface; use Doctrine\DBAL\Driver\Middleware as DoctrineMiddlewareInterface; use Doctrine\DBAL\Result; use Sentry\SentryBundle\EventListener\ErrorListenerExceptionEvent; @@ -13,8 +12,9 @@ use Sentry\SentryBundle\EventListener\RequestListenerResponseEvent; use Sentry\SentryBundle\EventListener\RequestListenerTerminateEvent; use Sentry\SentryBundle\EventListener\SubRequestListenerRequestEvent; -use Sentry\SentryBundle\Tracing\Doctrine\DBAL\Compatibility\ExceptionConverterDriverInterface; use Sentry\SentryBundle\Tracing\Doctrine\DBAL\Compatibility\MiddlewareInterface; +use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverForV2; +use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverForV3; use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingStatementForV2; use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingStatementForV3; use Symfony\Component\HttpKernel\Event\ControllerEvent; @@ -83,14 +83,12 @@ class_alias(GetResponseEvent::class, SubRequestListenerRequestEvent::class); class_alias(MiddlewareInterface::class, DoctrineMiddlewareInterface::class); } -if (!interface_exists(LegacyExceptionConverterDriverInterface::class)) { - class_alias(ExceptionConverterDriverInterface::class, LegacyExceptionConverterDriverInterface::class); -} - if (!class_exists('Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingStatement')) { if (class_exists(Result::class)) { - class_alias(TracingStatementForV3::class, 'Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingStatement'); + class_alias(TracingStatementForV3::class, 'Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingStatement'); + class_alias(TracingDriverForV3::class, 'Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver'); } elseif (interface_exists(Result::class)) { - class_alias(TracingStatementForV2::class, 'Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingStatement'); + class_alias(TracingStatementForV2::class, 'Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingStatement'); + class_alias(TracingDriverForV2::class, 'Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver'); } } diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php b/tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php new file mode 100644 index 00000000..75c94ee9 --- /dev/null +++ b/tests/Tracing/Doctrine/DBAL/TracingDriverForV2Test.php @@ -0,0 +1,192 @@ +hub = $this->createMock(HubInterface::class); + } + + public static function setUpBeforeClass(): void + { + if (!self::isDoctrineDBALVersion2Installed()) { + self::markTestSkipped(); + } + } + + public function testConnect(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + $databasePlatform->expects($this->once()) + ->method('getName') + ->willReturn('foo'); + + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('connect') + ->with(['host' => 'localhost'], 'username', 'password', ['foo' => 'bar']) + ->willReturn($this->createMock(DriverConnectionInterface::class)); + + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertInstanceOf(TracingDriverConnection::class, $driver->connect(['host' => 'localhost'], 'username', 'password', ['foo' => 'bar'])); + } + + public function testGetDatabasePlatform(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->getDatabasePlatform()); + } + + public function testGetSchemaManager(): void + { + $connection = $this->createMock(Connection::class); + $databasePlatform = $this->createMock(AbstractPlatform::class); + $schemaManager = $this->createMock(AbstractSchemaManager::class); + + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('getSchemaManager') + ->with($connection, $databasePlatform) + ->willReturn($schemaManager); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame($schemaManager, $driver->getSchemaManager($connection, $databasePlatform)); + } + + public function testGetName(): void + { + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('getName') + ->willReturn('foo'); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame('foo', $driver->getName()); + } + + public function testGetDatabase(): void + { + $connection = $this->createMock(Connection::class); + + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('getDatabase') + ->with($connection) + ->willReturn('foo'); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame('foo', $driver->getDatabase($connection)); + } + + public function testCreateDatabasePlatformForVersion(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(StubVersionAwarePlatformDriver::class); + $decoratedDriver->expects($this->once()) + ->method('createDatabasePlatformForVersion') + ->with('5.7') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); + } + + public function testCreateDatabasePlatformForVersionWhenDriverDoesNotImplementInterface(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(Driver::class); + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); + } + + public function testConvertException(): void + { + $exception = $this->createMock(DriverException::class); + $convertedException = new DBALDriverException('foo', $exception); + + $decoratedDriver = $this->createMock(StubExceptionConverterDriver::class); + $decoratedDriver->expects($this->once()) + ->method('convertException') + ->with('foo', $exception) + ->willReturn($convertedException); + + $driver = new TracingDriverForV2($this->hub, $decoratedDriver); + + $this->assertSame($convertedException, $driver->convertException('foo', $exception)); + } + + public function testConvertExceptionWhenDriverDoesNotImplementInterface(): void + { + $exception = $this->createMock(DriverException::class); + $driver = new TracingDriverForV2($this->hub, $this->createMock(Driver::class)); + + $this->assertEquals( + new DBALDriverException('foo', $exception), + $driver->convertException('foo', $exception) + ); + } +} + +if (interface_exists(Driver::class)) { + interface StubVersionAwarePlatformDriver extends Driver, VersionAwarePlatformDriver + { + } + + if (interface_exists(ExceptionConverterDriver::class)) { + interface StubExceptionConverterDriver extends Driver, ExceptionConverterDriver + { + } + } else { + interface StubExceptionConverterDriver extends Driver + { + } + } +} diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverForV3Test.php b/tests/Tracing/Doctrine/DBAL/TracingDriverForV3Test.php new file mode 100644 index 00000000..ebd0b96b --- /dev/null +++ b/tests/Tracing/Doctrine/DBAL/TracingDriverForV3Test.php @@ -0,0 +1,134 @@ += 3.0.'); + } + } + + protected function setUp(): void + { + $this->hub = $this->createMock(HubInterface::class); + } + + public function testConnect(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + $databasePlatform->expects($this->once()) + ->method('getName') + ->willReturn('foo'); + + $decoratedDriver = $this->createMock(DriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('connect') + ->with(['host' => 'localhost']) + ->willReturn($this->createMock(DriverConnectionInterface::class)); + + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertInstanceOf(TracingDriverConnection::class, $driver->connect(['host' => 'localhost'])); + } + + public function testGetDatabasePlatform(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(DriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->getDatabasePlatform()); + } + + public function testGetSchemaManager(): void + { + $connection = $this->createMock(Connection::class); + $databasePlatform = $this->createMock(AbstractPlatform::class); + $schemaManager = $this->createMock(AbstractSchemaManager::class); + + $decoratedDriver = $this->createMock(DriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('getSchemaManager') + ->with($connection, $databasePlatform) + ->willReturn($schemaManager); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertSame($schemaManager, $driver->getSchemaManager($connection, $databasePlatform)); + } + + public function testGetExceptionConverter(): void + { + $exceptionConverter = $this->createMock(ExceptionConverter::class); + + $decoratedDriver = $this->createMock(DriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('getExceptionConverter') + ->willReturn($exceptionConverter); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertSame($exceptionConverter, $driver->getExceptionConverter()); + } + + public function testCreateDatabasePlatformForVersion(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(VersionAwarePlatformDriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('createDatabasePlatformForVersion') + ->with('5.7') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); + } + + public function testCreateDatabasePlatformForVersionWhenDriverDoesNotImplementInterface(): void + { + $databasePlatform = $this->createMock(AbstractPlatform::class); + + $decoratedDriver = $this->createMock(DriverInterface::class); + $decoratedDriver->expects($this->once()) + ->method('getDatabasePlatform') + ->willReturn($databasePlatform); + + $driver = new TracingDriverForV3($this->hub, $decoratedDriver); + + $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); + } +} diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php b/tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php index e0c8d541..84d9fd25 100644 --- a/tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php +++ b/tests/Tracing/Doctrine/DBAL/TracingDriverMiddlewareTest.php @@ -25,8 +25,8 @@ final class TracingDriverMiddlewareTest extends DoctrineTestCase public static function setUpBeforeClass(): void { - if (!self::isDoctrineDBALVersion3Installed()) { - self::markTestSkipped(); + if (!self::isDoctrineDBALInstalled()) { + self::markTestSkipped('This test requires the "doctrine/dbal" Composer package.'); } } diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverTest.php b/tests/Tracing/Doctrine/DBAL/TracingDriverTest.php deleted file mode 100644 index c43590c1..00000000 --- a/tests/Tracing/Doctrine/DBAL/TracingDriverTest.php +++ /dev/null @@ -1,273 +0,0 @@ -hub = $this->createMock(HubInterface::class); - } - - public static function setUpBeforeClass(): void - { - if (!self::isDoctrineBundlePackageInstalled()) { - self::markTestSkipped(); - } - } - - public function testConnect(): void - { - $databasePlatform = $this->createMock(AbstractPlatform::class); - $databasePlatform->expects($this->once()) - ->method('getName') - ->willReturn('foo'); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('connect') - ->with(['host' => 'localhost'], 'username', 'password', ['foo' => 'bar']) - ->willReturn($this->createMock(DriverConnectionInterface::class)); - - $decoratedDriver->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($databasePlatform); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertInstanceOf(TracingDriverConnection::class, $driver->connect(['host' => 'localhost'], 'username', 'password', ['foo' => 'bar'])); - } - - public function testGetDatabasePlatform(): void - { - $databasePlatform = $this->createMock(AbstractPlatform::class); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($databasePlatform); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($databasePlatform, $driver->getDatabasePlatform()); - } - - public function testGetSchemaManager(): void - { - $connection = $this->createMock(Connection::class); - $databasePlatform = $this->createMock(AbstractPlatform::class); - $schemaManager = $this->createMock(AbstractSchemaManager::class); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getSchemaManager') - ->with($connection, $databasePlatform) - ->willReturn($schemaManager); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($schemaManager, $driver->getSchemaManager($connection, $databasePlatform)); - } - - public function testGetExceptionConverter(): void - { - if (!self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be >= 3.0.'); - } - - $exceptionConverter = $this->createMock(ExceptionConverter::class); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getExceptionConverter') - ->willReturn($exceptionConverter); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($exceptionConverter, $driver->getExceptionConverter()); - } - - public function testGetExceptionConverterThrowsIfDoctrineDBALVersionIsLowerThan30(): void - { - if (self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be < 3.0.'); - } - - $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage('The Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver::getExceptionConverter() method is not supported on Doctrine DBAL 2.x.'); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $driver->getExceptionConverter(); - } - - public function testGetNameIfDoctrineDBALVersionIsLowerThan30(): void - { - if (self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be < 3.0.'); - } - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getName') - ->willReturn('foo'); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame('foo', $driver->getName()); - } - - public function testGetNameThrowsIfDoctrineDBALVersionIsAtLeast30(): void - { - if (!self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be >= 3.0.'); - } - - $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage('The Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver::getName() method is not supported on Doctrine DBAL 3.0.'); - - $driver = new TracingDriver($this->hub, $this->createMock(DriverInterface::class)); - $driver->getName(); - } - - public function testGetDatabaseIfDoctrineDBALVersionIsLowerThan30(): void - { - if (self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be < 3.0.'); - } - - $connection = $this->createMock(Connection::class); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getDatabase') - ->with($connection) - ->willReturn('foo'); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame('foo', $driver->getDatabase($connection)); - } - - public function testGetDatabaseThrowsIfDoctrineDBALVersionIsAtLeast30(): void - { - if (!self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be >= 3.0.'); - } - - $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage('The Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver::getDatabase() method is not supported on Doctrine DBAL 3.0.'); - - $driver = new TracingDriver($this->hub, $this->createMock(DriverInterface::class)); - $driver->getDatabase($this->createMock(Connection::class)); - } - - public function testCreateDatabasePlatformForVersion(): void - { - $databasePlatform = $this->createMock(AbstractPlatform::class); - - $decoratedDriver = $this->createMock(StubVersionAwarePlatformDriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('createDatabasePlatformForVersion') - ->with('5.7') - ->willReturn($databasePlatform); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); - } - - public function testCreateDatabasePlatformForVersionWhenDriverDoesNotImplementInterface(): void - { - $databasePlatform = $this->createMock(AbstractPlatform::class); - - $decoratedDriver = $this->createMock(DriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('getDatabasePlatform') - ->willReturn($databasePlatform); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($databasePlatform, $driver->createDatabasePlatformForVersion('5.7')); - } - - public function testConvertException(): void - { - if (!self::isDoctrineDBALVersion2Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be ^2.13.'); - } - - $exception = $this->createMock(DriverExceptionInterface::class); - $convertedException = new DBALDriverException('foo', $exception); - - $decoratedDriver = $this->createMock(StubExceptionConverterDriverInterface::class); - $decoratedDriver->expects($this->once()) - ->method('convertException') - ->with('foo', $exception) - ->willReturn($convertedException); - - $driver = new TracingDriver($this->hub, $decoratedDriver); - - $this->assertSame($convertedException, $driver->convertException('foo', $exception)); - } - - public function testConvertExceptionThrowsIfDoctrineDBALVersionIsAtLeast30(): void - { - if (!self::isDoctrineDBALVersion3Installed()) { - $this->markTestSkipped('This test requires the version of the "doctrine/dbal" Composer package to be >= 3.0.'); - } - - $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage('The Sentry\\SentryBundle\\Tracing\\Doctrine\\DBAL\\TracingDriver::convertException() method is not supported on Doctrine DBAL 3.0.'); - - $driver = new TracingDriver($this->hub, $this->createMock(StubExceptionConverterDriverInterface::class)); - $driver->convertException('foo', $this->createMock(DriverExceptionInterface::class)); - } -} - -if (interface_exists(DriverInterface::class)) { - if (interface_exists(VersionAwarePlatformDriverInterface::class)) { - interface StubVersionAwarePlatformDriverInterface extends DriverInterface, VersionAwarePlatformDriverInterface - { - } - } - - if (interface_exists(ExceptionConverterDriverInterface::class)) { - interface StubExceptionConverterDriverInterface extends ExceptionConverterDriverInterface, DriverInterface - { - } - } else { - interface StubExceptionConverterDriverInterface extends DriverInterface - { - } - } - - if (!interface_exists(DriverExceptionInterface::class)) { - class_alias(Exception::class, DriverExceptionInterface::class); - } -}