From 7a10dacf7aaa16cd07fc5fa16ede14b84942c7f8 Mon Sep 17 00:00:00 2001 From: Steve Bauman Date: Fri, 24 Jul 2026 12:29:52 -0400 Subject: [PATCH] Improve fake index assertions --- src/Testing/Fakes/FakeIndexManager.php | 75 ++++++++++++++++++-- tests/Unit/Indices/FakeIndexManagerTest.php | 76 ++++++++++++++++++++- 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/src/Testing/Fakes/FakeIndexManager.php b/src/Testing/Fakes/FakeIndexManager.php index a122104..c6ccdb6 100644 --- a/src/Testing/Fakes/FakeIndexManager.php +++ b/src/Testing/Fakes/FakeIndexManager.php @@ -272,10 +272,29 @@ public function assertChecked(string $index): static /** * Assert that the given index was created. + * + * @param (callable(IndexBlueprint): bool)|null $callback */ - public function assertCreated(IndexBlueprint $index): static + public function assertCreated(IndexBlueprint|string $index, ?callable $callback = null): static { - PHPUnit::assertContainsEquals($index, $this->created); + if ($index instanceof IndexBlueprint) { + PHPUnit::assertContainsEquals($index, $this->created); + + return $this; + } + + $created = array_filter( + $this->created, + fn (IndexBlueprint $created): bool => ( + $created->name() === $index + && (! isset($callback) || $callback($created)) + ) + ); + + PHPUnit::assertNotEmpty( + $created, + "The expected index [{$index}] was not created." + ); return $this; } @@ -294,20 +313,64 @@ public function assertNotCreated(string $index): static /** * Assert that the given index mapping was updated. + * + * @param Mapping|(callable(Mapping): bool)|null $assertion */ - public function assertMappingPut(string $index, Mapping $mapping): static + public function assertMappingPut(string $index, Mapping|callable|null $assertion = null): static { - PHPUnit::assertContainsEquals(compact('index', 'mapping'), $this->mappings); + if ($assertion instanceof Mapping) { + PHPUnit::assertContainsEquals([ + 'index' => $index, + 'mapping' => $assertion, + ], $this->mappings); + + return $this; + } + + $mappings = array_filter( + $this->mappings, + fn (array $operation): bool => ( + $operation['index'] === $index + && (! isset($assertion) || $assertion($operation['mapping'])) + ) + ); + + PHPUnit::assertNotEmpty( + $mappings, + "The expected mapping for index [{$index}] was not updated." + ); return $this; } /** * Assert that the given index settings were updated. + * + * @param Settings|(callable(Settings): bool)|null $assertion */ - public function assertSettingsPut(string $index, Settings $settings): static + public function assertSettingsPut(string $index, Settings|callable|null $assertion = null): static { - PHPUnit::assertContainsEquals(compact('index', 'settings'), $this->settings); + if ($assertion instanceof Settings) { + PHPUnit::assertContainsEquals([ + 'index' => $index, + 'settings' => $assertion, + ], $this->settings); + + return $this; + } + + $settings = array_filter( + $this->settings, + fn (array $operation): bool => ( + $operation['index'] === $index + && (! isset($assertion) || $assertion($operation['settings'])) + ) + ); + + PHPUnit::assertNotEmpty( + $settings, + "The expected settings for index [{$index}] were not updated." + ); return $this; } diff --git a/tests/Unit/Indices/FakeIndexManagerTest.php b/tests/Unit/Indices/FakeIndexManagerTest.php index 6be137c..1255418 100644 --- a/tests/Unit/Indices/FakeIndexManagerTest.php +++ b/tests/Unit/Indices/FakeIndexManagerTest.php @@ -7,6 +7,7 @@ use DirectoryTree\OpenSearchAdapter\Indices\Mapping; use DirectoryTree\OpenSearchAdapter\Indices\Settings; use DirectoryTree\OpenSearchAdapter\Testing\Fakes\FakeIndexManager; +use PHPUnit\Framework\ExpectationFailedException; it('implements the index manager contract', function () { expect(new FakeIndexManager)->toBeInstanceOf(IndexManagerInterface::class); @@ -38,12 +39,66 @@ expect($indices->exists('posts'))->toBeTrue(); }); +it('asserts created indices by name', function () { + $indices = new FakeIndexManager; + + $indices->create(new IndexBlueprint( + 'posts', + (new Mapping)->text('title'), + (new Settings)->index(['number_of_replicas' => 0]) + )); + + $indices + ->assertCreated('posts') + ->assertCreated('posts', fn (IndexBlueprint $index): bool => ( + $index->mapping()?->toArray() === [ + 'properties' => [ + 'title' => ['type' => 'text'], + ], + ] + && $index->settings()?->toArray() === [ + 'index' => ['number_of_replicas' => 0], + ] + )); +}); + +it('fails when no created index satisfies the assertion', function () { + $indices = new FakeIndexManager; + + $indices->create(new IndexBlueprint('posts')); + + expect(fn () => $indices->assertCreated('comments')) + ->toThrow(ExpectationFailedException::class); + + expect(fn () => $indices->assertCreated('posts', fn (): bool => false)) + ->toThrow(ExpectationFailedException::class); +}); + it('records mapping updates', function () { $indices = new FakeIndexManager; $indices->putMapping('posts', $mapping = (new Mapping)->keyword('status')); - $indices->assertMappingPut('posts', $mapping); + $indices + ->assertMappingPut('posts', $mapping) + ->assertMappingPut('posts') + ->assertMappingPut('posts', fn (Mapping $mapping): bool => $mapping->toArray() === [ + 'properties' => [ + 'status' => ['type' => 'keyword'], + ], + ]); +}); + +it('fails when no mapping update satisfies the assertion', function () { + $indices = new FakeIndexManager; + + $indices->putMapping('posts', (new Mapping)->keyword('status')); + + expect(fn () => $indices->assertMappingPut('comments')) + ->toThrow(ExpectationFailedException::class); + + expect(fn () => $indices->assertMappingPut('posts', fn (): bool => false)) + ->toThrow(ExpectationFailedException::class); }); it('records settings updates', function () { @@ -51,7 +106,24 @@ $indices->putSettings('posts', $settings = (new Settings)->index(['refresh_interval' => -1])); - $indices->assertSettingsPut('posts', $settings); + $indices + ->assertSettingsPut('posts', $settings) + ->assertSettingsPut('posts') + ->assertSettingsPut('posts', fn (Settings $settings): bool => $settings->toArray() === [ + 'index' => ['refresh_interval' => -1], + ]); +}); + +it('fails when no settings update satisfies the assertion', function () { + $indices = new FakeIndexManager; + + $indices->putSettings('posts', (new Settings)->index(['refresh_interval' => -1])); + + expect(fn () => $indices->assertSettingsPut('comments')) + ->toThrow(ExpectationFailedException::class); + + expect(fn () => $indices->assertSettingsPut('posts', fn (): bool => false)) + ->toThrow(ExpectationFailedException::class); }); it('records open and close operations', function () {