diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e597fcf..a44d767 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,64 +13,65 @@ on: jobs: tests: name: "Run tests" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-latest" strategy: matrix: php-version: - - "7.4" - - "8.0" - - "8.1" - "8.2" + - "8.3" + - "8.4" + - "8.5" services: mongodb: - image: "mongo:3" + image: "mongo:8" ports: - "27017:27017" steps: - name: "Checkout" - uses: "actions/checkout@v3" + uses: "actions/checkout@v7" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: php-version: "${{ matrix.php-version }}" + extensions: "mongodb" coverage: "none" env: fail-fast: true - name: "Validate composer.json and composer.lock" run: "composer validate --strict --no-interaction --ansi" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v4" - name: "Run tests" run: "make test" coding-standards: name: "Coding standards" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: "actions/checkout@v3" + uses: "actions/checkout@v7" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.1" + php-version: "8.5" coverage: "none" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v4" - name: "Check coding standards" run: "make php-cs-fixer-ci" static-analysis: name: "Static analysis" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: "actions/checkout@v3" + uses: "actions/checkout@v7" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.1" + php-version: "8.5" coverage: "none" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v4" - name: "Run PHPStan" run: "make phpstan" diff --git a/composer.json b/composer.json index eebfdfe..78bfbaf 100644 --- a/composer.json +++ b/composer.json @@ -10,16 +10,16 @@ } ], "require": { - "php": ">=7.2", + "php": "^8.2", "broadway/broadway": "^2.2.1", - "mongodb/mongodb": "^1.0", - "ext-mongodb": "*" + "mongodb/mongodb": "^2.3", + "ext-mongodb": "^2.3" }, "require-dev": { - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.5", "ramsey/uuid": "^4.0", "broadway/coding-standard": "^1.2", - "phpstan/phpstan": "@stable" + "phpstan/phpstan": "^2.0" }, "autoload": { "psr-4": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index de7795d..d90407b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,51 +1,61 @@ parameters: ignoreErrors: - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" - count: 1 + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 4 path: src/MongoDBEventStore.php - - message: "#^Cannot call method getCode\\(\\) on mixed\\.$#" + message: '#^Method Broadway\\EventStore\\MongoDB\\MongoDBEventStore\:\:buildFindByCriteria\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue count: 1 path: src/MongoDBEventStore.php - - message: "#^Cannot cast mixed to string\\.$#" - count: 4 + message: '#^Method Broadway\\EventStore\\MongoDB\\MongoDBEventStore\:\:normalizeDomainMessage\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#1 \\$dateTimeString of static method Broadway\\\\Domain\\\\DateTime\\:\\:fromString\\(\\) expects string, mixed given\\.$#" + message: '#^Parameter \#1 \$dateTimeString of static method Broadway\\Domain\\DateTime\:\:fromString\(\) expects string, mixed given\.$#' + identifier: argument.type count: 1 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#1 \\$event of method Broadway\\\\EventStore\\\\MongoDB\\\\MongoDBEventStore\\:\\:denormalizeDomainMessage\\(\\) expects MongoDB\\\\Model\\\\BSONDocument, array\\|object given\\.$#" + message: '#^Parameter \#1 \$event of method Broadway\\EventStore\\MongoDB\\MongoDBEventStore\:\:denormalizeDomainMessage\(\) expects MongoDB\\Model\\BSONDocument, array\|object\|null given\.$#' + identifier: argument.type count: 3 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, mixed given\\.$#" + message: '#^Parameter \#1 \$json of function json_decode expects string, mixed given\.$#' + identifier: argument.type count: 2 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#1 \\$message of method Broadway\\\\EventStore\\\\MongoDB\\\\MongoDBEventStore\\:\\:normalizeDomainMessage\\(\\) expects Broadway\\\\Domain\\\\DomainMessage, mixed given\\.$#" + message: '#^Parameter \#1 \$message of method Broadway\\EventStore\\MongoDB\\MongoDBEventStore\:\:normalizeDomainMessage\(\) expects Broadway\\Domain\\DomainMessage, mixed given\.$#' + identifier: argument.type count: 1 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#1 \\$serializedObject of method Broadway\\\\Serializer\\\\Serializer\\:\\:deserialize\\(\\) expects array, mixed given\\.$#" + message: '#^Parameter \#1 \$serializedObject of method Broadway\\Serializer\\Serializer\:\:deserialize\(\) expects array, mixed given\.$#' + identifier: argument.type count: 2 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#2 \\$playhead of class Broadway\\\\Domain\\\\DomainMessage constructor expects int, mixed given\\.$#" + message: '#^Parameter \#2 \$playhead of class Broadway\\Domain\\DomainMessage constructor expects int, mixed given\.$#' + identifier: argument.type count: 1 path: src/MongoDBEventStore.php - - message: "#^Parameter \\#3 \\$metadata of class Broadway\\\\Domain\\\\DomainMessage constructor expects Broadway\\\\Domain\\\\Metadata, mixed given\\.$#" + message: '#^Parameter \#3 \$metadata of class Broadway\\Domain\\DomainMessage constructor expects Broadway\\Domain\\Metadata, mixed given\.$#' + identifier: argument.type count: 1 path: src/MongoDBEventStore.php diff --git a/phpstan.neon b/phpstan.neon index 468327a..07a9980 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,2 @@ includes: - phpstan-baseline.neon -parameters: - checkMissingIterableValueType: false diff --git a/src/MongoDBEventStore.php b/src/MongoDBEventStore.php index 3badf48..7503add 100644 --- a/src/MongoDBEventStore.php +++ b/src/MongoDBEventStore.php @@ -51,16 +51,13 @@ class MongoDBEventStore implements EventStore, EventStoreManagement public function __construct( Collection $eventCollection, Serializer $payloadSerializer, - Serializer $metadataSerializer + Serializer $metadataSerializer, ) { $this->eventCollection = $eventCollection; $this->payloadSerializer = $payloadSerializer; $this->metadataSerializer = $metadataSerializer; } - /** - * {@inheritdoc} - */ public function load($id): DomainEventStream { $cursor = $this->eventCollection @@ -81,9 +78,6 @@ public function load($id): DomainEventStream return new DomainEventStream($domainMessages); } - /** - * {@inheritdoc} - */ public function loadFromPlayhead($id, int $playhead): DomainEventStream { $cursor = $this->eventCollection @@ -112,9 +106,6 @@ private function denormalizeDomainMessage(BSONDocument $event): DomainMessage ); } - /** - * {@inheritdoc} - */ public function append($id, DomainEventStream $eventStream): void { // noop to ensure that an error will be thrown early if the ID @@ -130,6 +121,12 @@ public function append($id, DomainEventStream $eventStream): void $messages[] = $this->normalizeDomainMessage($message); } + // mongodb/mongodb 2.x rejects an empty $documents array, while 1.x + // accepted it. Appending an empty stream is a no-op either way. + if ([] === $messages) { + return; + } + try { $this->eventCollection->insertMany($messages); } catch (BulkWriteException $bulkWriteException) { @@ -154,9 +151,6 @@ private function normalizeDomainMessage(DomainMessage $message): array ]; } - /** - * {@inheritdoc} - */ public function visitEvents(Criteria $criteria, EventVisitor $eventVisitor): void { if ($criteria->getAggregateRootTypes()) { diff --git a/test/Management/MongoDBEventStoreManagementTest.php b/test/Management/MongoDBEventStoreManagementTest.php index e2a1ba4..ea31bb5 100644 --- a/test/Management/MongoDBEventStoreManagementTest.php +++ b/test/Management/MongoDBEventStoreManagementTest.php @@ -25,9 +25,6 @@ class MongoDBEventStoreManagementTest extends EventStoreManagementTest /* @var Client $client */ protected $client; - /** - * {@inheritdoc} - */ public function setUp(): void { $this->client = new Client('mongodb://localhost:27017'); @@ -35,9 +32,6 @@ public function setUp(): void parent::setUp(); } - /** - * {@inheritdoc} - */ protected function createEventStore() { $collection = $this->client->selectCollection(self::$databaseName, self::$eventCollectionName); @@ -53,9 +47,6 @@ protected function createEventStore() return $eventStore; } - /** - * {@inheritdoc} - */ protected function tearDown(): void { $this->client->selectDatabase(self::$databaseName)->drop(); diff --git a/test/MongoDBEventStoreTest.php b/test/MongoDBEventStoreTest.php index 7d57fc2..107d7b9 100644 --- a/test/MongoDBEventStoreTest.php +++ b/test/MongoDBEventStoreTest.php @@ -25,9 +25,6 @@ class MongoDBEventStoreTest extends EventStoreTest /* @var Client $client */ protected $client; - /** - * {@inheritdoc} - */ public function setUp(): void { $this->client = new Client('mongodb://localhost:27017'); @@ -44,9 +41,6 @@ public function setUp(): void $this->eventStore->configureCollection(); } - /** - * {@inheritdoc} - */ public function tearDown(): void { $this->client->selectDatabase(self::$databaseName)->drop();