From 8cfed4717432f0c90bb6a3c4f33f81467ee0e005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 17 Sep 2024 16:14:04 +0200 Subject: [PATCH 1/6] Remove symfony/phpunit-bridge --- composer.json | 2 +- tests/GridFS/BucketFunctionalTest.php | 6 ------ tests/SpecTests/DocumentsMatchConstraint.php | 13 +++++-------- .../UnifiedSpecTests/Constraint/IsBsonType.php | 7 ++----- tests/UnifiedSpecTests/Constraint/Matches.php | 17 +++++------------ 5 files changed, 13 insertions(+), 32 deletions(-) diff --git a/composer.json b/composer.json index a856f4e84..105b1924f 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,9 @@ }, "require-dev": { "doctrine/coding-standard": "^12.0", + "phpunit/phpunit": "^9.6", "rector/rector": "^1.1", "squizlabs/php_codesniffer": "^3.7", - "symfony/phpunit-bridge": "^7.1", "vimeo/psalm": "^5.13" }, "replace": { diff --git a/tests/GridFS/BucketFunctionalTest.php b/tests/GridFS/BucketFunctionalTest.php index 3456951a9..ccbe6bf02 100644 --- a/tests/GridFS/BucketFunctionalTest.php +++ b/tests/GridFS/BucketFunctionalTest.php @@ -871,7 +871,6 @@ public function testDanglingOpenWritableStream(): void } $code = <<<'PHP' - require '%s'; require '%s'; $client = MongoDB\Tests\FunctionalTestCase::createTestClient(); $database = $client->selectDatabase(getenv('MONGODB_DATABASE') ?: 'phplib_test'); @@ -888,8 +887,6 @@ public function testDanglingOpenWritableStream(): void sprintf( $code, __DIR__ . '/../../vendor/autoload.php', - // Include the PHPUnit autoload file to ensure PHPUnit classes can be loaded - __DIR__ . '/../../vendor/bin/.phpunit/phpunit/vendor/autoload.php', ), ), '2>&1', @@ -914,7 +911,6 @@ public function testDanglingOpenWritableStreamWithGlobalStreamWrapperAlias(): vo } $code = <<<'PHP' - require '%s'; require '%s'; $client = MongoDB\Tests\FunctionalTestCase::createTestClient(); $database = $client->selectDatabase(getenv('MONGODB_DATABASE') ?: 'phplib_test'); @@ -931,8 +927,6 @@ public function testDanglingOpenWritableStreamWithGlobalStreamWrapperAlias(): vo sprintf( $code, __DIR__ . '/../../vendor/autoload.php', - // Include the PHPUnit autoload file to ensure PHPUnit classes can be loaded - __DIR__ . '/../../vendor/bin/.phpunit/phpunit/vendor/autoload.php', ), ), '2>&1', diff --git a/tests/SpecTests/DocumentsMatchConstraint.php b/tests/SpecTests/DocumentsMatchConstraint.php index 16e7914a6..03f905bd3 100644 --- a/tests/SpecTests/DocumentsMatchConstraint.php +++ b/tests/SpecTests/DocumentsMatchConstraint.php @@ -13,7 +13,6 @@ use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; use stdClass; -use Symfony\Bridge\PhpUnit\ConstraintTrait; use function array_values; use function get_debug_type; @@ -36,8 +35,6 @@ */ class DocumentsMatchConstraint extends Constraint { - use ConstraintTrait; - /** * TODO: This is not currently used, but was preserved from the design of * TestCase::assertMatchesDocument(), which would sort keys and then compare @@ -65,7 +62,7 @@ public function __construct(array|object $value, private bool $ignoreExtraKeysIn $this->comparatorFactory = Factory::getInstance(); } - private function doEvaluate($other, $description = '', $returnResult = false) + public function evaluate($other, string $description = '', bool $returnResult = false): ?bool { /* TODO: If ignoreExtraKeys and sortKeys are both false, then we may be * able to skip preparation, convert both documents to extended JSON, @@ -198,7 +195,7 @@ private function assertEquals(ArrayObject $expected, ArrayObject $actual, bool $ } } - private function doAdditionalFailureDescription($other) + protected function additionalFailureDescription($other): string { if ($this->lastFailure === null) { return ''; @@ -207,12 +204,12 @@ private function doAdditionalFailureDescription($other) return $this->lastFailure->getMessage(); } - private function doFailureDescription($other) + protected function failureDescription($other): string { return 'two BSON objects are equal'; } - private function doMatches($other) + protected function matches($other): bool { /* TODO: If ignoreExtraKeys and sortKeys are both false, then we may be * able to skip preparation, convert both documents to extended JSON, @@ -232,7 +229,7 @@ private function doMatches($other) return true; } - private function doToString() + public function toString(): string { return 'matches ' . $this->exporter()->export($this->value); } diff --git a/tests/UnifiedSpecTests/Constraint/IsBsonType.php b/tests/UnifiedSpecTests/Constraint/IsBsonType.php index 7d17a9af7..e81ccb2a3 100644 --- a/tests/UnifiedSpecTests/Constraint/IsBsonType.php +++ b/tests/UnifiedSpecTests/Constraint/IsBsonType.php @@ -23,7 +23,6 @@ use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\LogicalOr; use RuntimeException; -use Symfony\Bridge\PhpUnit\ConstraintTrait; use function array_keys; use function array_map; @@ -40,8 +39,6 @@ final class IsBsonType extends Constraint { - use ConstraintTrait; - private static array $types = [ 'double', 'string', @@ -88,7 +85,7 @@ public static function anyOf(string ...$types): Constraint return LogicalOr::fromConstraints(...array_map(fn ($type) => new self($type), $types)); } - private function doMatches($other): bool + protected function matches($other): bool { return match ($this->type) { 'double' => is_float($other), @@ -118,7 +115,7 @@ private function doMatches($other): bool }; } - private function doToString(): string + public function toString(): string { return sprintf('is of BSON type "%s"', $this->type); } diff --git a/tests/UnifiedSpecTests/Constraint/Matches.php b/tests/UnifiedSpecTests/Constraint/Matches.php index 2a80357fd..eb963aca9 100644 --- a/tests/UnifiedSpecTests/Constraint/Matches.php +++ b/tests/UnifiedSpecTests/Constraint/Matches.php @@ -13,7 +13,6 @@ use RuntimeException; use SebastianBergmann\Comparator\ComparisonFailure; use SebastianBergmann\Comparator\Factory; -use Symfony\Bridge\PhpUnit\ConstraintTrait; use function array_keys; use function count; @@ -49,8 +48,6 @@ */ class Matches extends Constraint { - use ConstraintTrait; - private mixed $value; private bool $allowExtraRootKeys; @@ -69,7 +66,7 @@ public function __construct($value, private ?EntityMap $entityMap = null, $allow $this->comparatorFactory = Factory::getInstance(); } - private function doEvaluate($other, $description = '', $returnResult = false) + public function evaluate($other, $description = '', $returnResult = false): ?bool { $other = self::prepare($other); $success = false; @@ -321,8 +318,7 @@ private function assertMatchesOperator(BSONDocument $operator, $actual, string $ throw new LogicException('unsupported operator: ' . $name); } - /** @see ConstraintTrait */ - private function doAdditionalFailureDescription($other) + protected function additionalFailureDescription($other): string { if ($this->lastFailure === null) { return ''; @@ -331,14 +327,12 @@ private function doAdditionalFailureDescription($other) return $this->lastFailure->getMessage(); } - /** @see ConstraintTrait */ - private function doFailureDescription($other) + protected function failureDescription($other): string { return 'expected value matches actual value'; } - /** @see ConstraintTrait */ - private function doMatches($other) + protected function matches($other): bool { $other = self::prepare($other); @@ -351,8 +345,7 @@ private function doMatches($other) return true; } - /** @see ConstraintTrait */ - private function doToString() + public function toString(): string { return 'matches ' . $this->exporter()->export($this->value); } From 227e0e551725e0afae2937455424a3fa470b55cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 17 Sep 2024 16:17:10 +0200 Subject: [PATCH 2/6] Run phpunit directly --- .evergreen/run-tests.sh | 14 +++++++------- .github/workflows/tests.yml | 2 +- CONTRIBUTING.md | 6 ++---- composer.json | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index 4ff744cd9..abf6aacb1 100755 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -83,30 +83,30 @@ export MONGODB_MULTI_MONGOS_LB_URI="${MONGODB_MULTI_MONGOS_LB_URI}" # Run the tests, and store the results in a junit result file case "$TESTS" in atlas) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group atlas + php vendor/bin/phpunit $PHPUNIT_OPTS --group atlas ;; atlas-data-lake) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group atlas-data-lake + php vendor/bin/phpunit $PHPUNIT_OPTS --group atlas-data-lake ;; csfle) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group csfle + php vendor/bin/phpunit $PHPUNIT_OPTS --group csfle ;; csfle-without-aws-creds) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group csfle-without-aws-creds + php vendor/bin/phpunit $PHPUNIT_OPTS --group csfle-without-aws-creds ;; versioned-api) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group versioned-api + php vendor/bin/phpunit $PHPUNIT_OPTS --group versioned-api ;; serverless) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS --group serverless + php vendor/bin/phpunit $PHPUNIT_OPTS --group serverless ;; *) - php vendor/bin/simple-phpunit $PHPUNIT_OPTS + php vendor/bin/phpunit $PHPUNIT_OPTS ;; esac diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5e7497813..803eb476d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -77,7 +77,7 @@ jobs: php-ini-values: "zend.assertions=1" - name: "Run PHPUnit" - run: "vendor/bin/simple-phpunit -v" + run: "vendor/bin/phpunit -v" env: SYMFONY_DEPRECATIONS_HELPER: 999999 MONGODB_URI: ${{ steps.setup-mongodb.outputs.cluster-uri }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ee5ee3a3e..0fb70ba3b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,12 +43,10 @@ credentials in the connection string (i.e. `MONGODB_URI`) or set the Note that `MONGODB_USERNAME` and `MONGODB_PASSWORD` will override any credentials present in the connection string. -By default, the `simple-phpunit` binary chooses the correct PHPUnit version for -the PHP version you are running. To run tests against a specific PHPUnit -version, use the `SYMFONY_PHPUNIT_VERSION` environment variable: +To run tests use the `phpunit` executable installed by Composer: ```console -$ SYMFONY_PHPUNIT_VERSION=8.5 vendor/bin/simple-phpunit +$ vendor/bin/phpunit ``` ### Environment Variables diff --git a/composer.json b/composer.json index 105b1924f..3ac90068c 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "fix:cs": "phpcbf", "fix:psalm:baseline": "psalm --set-baseline=psalm-baseline.xml", "fix:rector": "rector process --ansi", - "test": "simple-phpunit" + "test": "phpunit" }, "extra": { "branch-alias": { From 7a1bdddf42204ce69deb4029b545ddf13e32dca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 17 Sep 2024 16:20:32 +0200 Subject: [PATCH 3/6] Return null when expected --- tests/SpecTests/DocumentsMatchConstraint.php | 2 ++ tests/UnifiedSpecTests/Constraint/Matches.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/SpecTests/DocumentsMatchConstraint.php b/tests/SpecTests/DocumentsMatchConstraint.php index 03f905bd3..e8d4d0de0 100644 --- a/tests/SpecTests/DocumentsMatchConstraint.php +++ b/tests/SpecTests/DocumentsMatchConstraint.php @@ -97,6 +97,8 @@ public function evaluate($other, string $description = '', bool $returnResult = if (! $success) { $this->fail($other, $description, $this->lastFailure); } + + return null; } /** @param string|BSONArray[] $expectedType */ diff --git a/tests/UnifiedSpecTests/Constraint/Matches.php b/tests/UnifiedSpecTests/Constraint/Matches.php index eb963aca9..4346b6dc8 100644 --- a/tests/UnifiedSpecTests/Constraint/Matches.php +++ b/tests/UnifiedSpecTests/Constraint/Matches.php @@ -101,6 +101,8 @@ public function evaluate($other, $description = '', $returnResult = false): ?boo if (! $success) { $this->fail($other, $description, $this->lastFailure); } + + return null; } private function assertEquals($expected, $actual, string $keyPath): void From cd78a47f9608e40dea72a4b4f824a3f9f0ed9792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 17 Sep 2024 22:02:01 +0200 Subject: [PATCH 4/6] Hide deprecation message from examples output --- tests/ExamplesTest.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/ExamplesTest.php b/tests/ExamplesTest.php index 7946622f4..7053e29f9 100644 --- a/tests/ExamplesTest.php +++ b/tests/ExamplesTest.php @@ -5,11 +5,15 @@ use Generator; use function bin2hex; +use function error_reporting; use function getenv; use function putenv; use function random_bytes; use function sprintf; +use const E_ALL; +use const E_DEPRECATED; + /** @runTestsInSeparateProcesses */ final class ExamplesTest extends FunctionalTestCase { @@ -304,7 +308,14 @@ public function testWithTransaction(): void private function assertExampleOutput(string $file, string $expectedOutput): void { - require $file; + // Hide deprecation messages + $level = error_reporting(E_ALL ^ E_DEPRECATED); + + try { + require $file; + } finally { + error_reporting($level); + } $this->assertStringMatchesFormat($expectedOutput, $this->getActualOutputForAssertion()); } From 3ce4d6ab58daa9537ea898e7ca088a9667c3e364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 18 Sep 2024 22:48:49 +0200 Subject: [PATCH 5/6] Revert hidding warnings in examples --- CONTRIBUTING.md | 6 ------ tests/ExamplesTest.php | 13 +------------ 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0fb70ba3b..fe387e26d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,12 +43,6 @@ credentials in the connection string (i.e. `MONGODB_URI`) or set the Note that `MONGODB_USERNAME` and `MONGODB_PASSWORD` will override any credentials present in the connection string. -To run tests use the `phpunit` executable installed by Composer: - -```console -$ vendor/bin/phpunit -``` - ### Environment Variables The test suite references the following environment variables: diff --git a/tests/ExamplesTest.php b/tests/ExamplesTest.php index 7053e29f9..7946622f4 100644 --- a/tests/ExamplesTest.php +++ b/tests/ExamplesTest.php @@ -5,15 +5,11 @@ use Generator; use function bin2hex; -use function error_reporting; use function getenv; use function putenv; use function random_bytes; use function sprintf; -use const E_ALL; -use const E_DEPRECATED; - /** @runTestsInSeparateProcesses */ final class ExamplesTest extends FunctionalTestCase { @@ -308,14 +304,7 @@ public function testWithTransaction(): void private function assertExampleOutput(string $file, string $expectedOutput): void { - // Hide deprecation messages - $level = error_reporting(E_ALL ^ E_DEPRECATED); - - try { - require $file; - } finally { - error_reporting($level); - } + require $file; $this->assertStringMatchesFormat($expectedOutput, $this->getActualOutputForAssertion()); } From a8ace60dd46bc6d91dc218dd03ffad8f503564b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Thu, 19 Sep 2024 08:55:37 +0200 Subject: [PATCH 6/6] Fix cursor Id deprecation --- tests/Model/CodecCursorFunctionalTest.php | 7 +++++-- tests/Operation/WatchFunctionalTest.php | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/Model/CodecCursorFunctionalTest.php b/tests/Model/CodecCursorFunctionalTest.php index 432d71732..48fd2cb59 100644 --- a/tests/Model/CodecCursorFunctionalTest.php +++ b/tests/Model/CodecCursorFunctionalTest.php @@ -55,12 +55,15 @@ function (...$args) use (&$previousErrorHandler, &$deprecations) { E_USER_DEPRECATED | E_DEPRECATED, ); - $cursorId = $codecCursor->getId(); + $cursorId = $codecCursor->getId(true); } finally { restore_error_handler(); } - self::assertInstanceOf(CursorId::class, $cursorId); + self::logicalOr( + self::isInstanceOf(Int64::class), + self::isInstanceOf(CursorId::class), + )->matches($cursorId); // Expect 2 deprecations: 1 from CodecCursor, one from Cursor self::assertCount(2, $deprecations); diff --git a/tests/Operation/WatchFunctionalTest.php b/tests/Operation/WatchFunctionalTest.php index 562192f1b..639199471 100644 --- a/tests/Operation/WatchFunctionalTest.php +++ b/tests/Operation/WatchFunctionalTest.php @@ -720,7 +720,7 @@ public function testInitialCursorIsNotClosed(): void * reports the cursor as alive. While the cursor ID is accessed through * ChangeStream, we'll need to use reflection to access the internal * Cursor and call isDead(). */ - $this->assertNotEquals('0', (string) $changeStream->getCursorId()); + $this->assertNotEquals('0', (string) $changeStream->getCursorId(true)); $rc = new ReflectionClass(ChangeStream::class); $rp = $rc->getProperty('iterator'); @@ -1370,11 +1370,11 @@ public function testOriginalReadPreferenceIsPreservedOnResume(): void } $changeStream = $operation->execute($secondary); - $previousCursorId = $changeStream->getCursorId(); + $previousCursorId = $changeStream->getCursorId(true); $this->forceChangeStreamResume(); $changeStream->next(); - $this->assertNotSame($previousCursorId, $changeStream->getCursorId()); + $this->assertNotSame($previousCursorId, $changeStream->getCursorId(true)); $getCursor = Closure::bind( fn () => $this->iterator->getInnerIterator(),