From f9d052c5a8a3ea2e0c0394ff92e3a4e1dec5a404 Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Mon, 16 Sep 2024 21:08:01 -0400 Subject: [PATCH] Small qol improvements (#583) * Ensure you can pass blocks as arguments to block factory * Change return type of dd() methods to never * Make hookable call register_hooks() on construct * Allow returning falsy * Add a test to validate an edge case facing elsewhere --- CHANGELOG.md | 1 + src/mantle/database/query/class-builder.php | 2 +- src/mantle/http-client/class-request.php | 2 +- src/mantle/http-client/class-response.php | 2 +- src/mantle/support/class-collection.php | 8 ++++ src/mantle/support/class-stringable.php | 2 +- src/mantle/support/interface-enumerable.php | 3 +- .../traits/trait-enumerates-values.php | 2 +- src/mantle/support/traits/trait-hookable.php | 7 +++ src/mantle/testing/class-block-factory.php | 12 ++++- tests/Support/CollectionTest.php | 46 ++++++++++++------- tests/Testing/BlockFactoryTest.php | 37 +++++++++++++++ .../Testing/Concerns/BlockAssertionsTest.php | 9 ++++ 13 files changed, 107 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d11befc16..8fdd5b839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Dropped support for Redis as a cache backend in favor of the default object cache drop-in. +- Allow returning falsey from `Collection::map_to_dictionary()`. ## v1.1.3 - 2024-08-14 diff --git a/src/mantle/database/query/class-builder.php b/src/mantle/database/query/class-builder.php index a37a55bc1..c71daa389 100644 --- a/src/mantle/database/query/class-builder.php +++ b/src/mantle/database/query/class-builder.php @@ -935,7 +935,7 @@ public function dump(): static { /** * Dump the query variables being passed to WP_Query and die. */ - public function dd(): void { + public function dd(): never { $this->dump(); die; } diff --git a/src/mantle/http-client/class-request.php b/src/mantle/http-client/class-request.php index 92a7deb5b..66ffceb0a 100644 --- a/src/mantle/http-client/class-request.php +++ b/src/mantle/http-client/class-request.php @@ -142,7 +142,7 @@ public function dump() { /** * Dump the request to the screen and die. */ - public function dd(): void { + public function dd(): never { $this->dump(); exit( 1 ); } diff --git a/src/mantle/http-client/class-response.php b/src/mantle/http-client/class-response.php index b0aefb742..c27798945 100644 --- a/src/mantle/http-client/class-response.php +++ b/src/mantle/http-client/class-response.php @@ -344,7 +344,7 @@ public function dump() { /** * Dump the response to the screen and exit. */ - public function dd(): void { + public function dd(): never { $this->dump(); exit( 1 ); } diff --git a/src/mantle/support/class-collection.php b/src/mantle/support/class-collection.php index f59b158b2..149231cf5 100644 --- a/src/mantle/support/class-collection.php +++ b/src/mantle/support/class-collection.php @@ -755,6 +755,10 @@ public function map_to_dictionary( callable $callback ) { foreach ( $this->items as $key => $item ) { $pair = $callback( $item, $key ); + if ( ! $pair || ! is_array( $pair ) ) { + continue; + } + $key = key( $pair ); $value = reset( $pair ); @@ -786,6 +790,10 @@ public function map_with_keys( callable $callback ) { foreach ( $this->items as $key => $value ) { $assoc = $callback( $value, $key ); + if ( ! is_array( $assoc ) ) { + continue; + } + foreach ( $assoc as $map_key => $map_value ) { $result[ $map_key ] = $map_value; } diff --git a/src/mantle/support/class-stringable.php b/src/mantle/support/class-stringable.php index 934d36e0b..52f55cf82 100644 --- a/src/mantle/support/class-stringable.php +++ b/src/mantle/support/class-stringable.php @@ -1068,7 +1068,7 @@ public function dump() { /** * Dump the string and end the script. */ - public function dd(): void { + public function dd(): never { $this->dump(); exit( 1 ); diff --git a/src/mantle/support/interface-enumerable.php b/src/mantle/support/interface-enumerable.php index 97f16d592..670d59c99 100644 --- a/src/mantle/support/interface-enumerable.php +++ b/src/mantle/support/interface-enumerable.php @@ -147,9 +147,8 @@ public function contains( $key, $operator = null, $value = null ); * Dump the collection and end the script. * * @param mixed ...$args - * @return void */ - public function dd( ...$args ); + public function dd( ...$args ): never; /** * Dump the collection. diff --git a/src/mantle/support/traits/trait-enumerates-values.php b/src/mantle/support/traits/trait-enumerates-values.php index a038d7c70..480ab7a7a 100644 --- a/src/mantle/support/traits/trait-enumerates-values.php +++ b/src/mantle/support/traits/trait-enumerates-values.php @@ -185,7 +185,7 @@ public function contains_strict( $key, $value = null ) { * * @param mixed ...$args */ - public function dd( ...$args ): void { + public function dd( ...$args ): never { $this->dump( ...$args ); exit( 1 ); diff --git a/src/mantle/support/traits/trait-hookable.php b/src/mantle/support/traits/trait-hookable.php index b31f746c8..f8eb27dba 100644 --- a/src/mantle/support/traits/trait-hookable.php +++ b/src/mantle/support/traits/trait-hookable.php @@ -24,6 +24,13 @@ * the respective WordPress hooks. */ trait Hookable { + /** + * Constructor (can be overridden by the trait user). + */ + public function __construct() { + $this->register_hooks(); + } + /** * Boot all actions and attribute methods on the service provider. * diff --git a/src/mantle/testing/class-block-factory.php b/src/mantle/testing/class-block-factory.php index 58a504df2..e2cf9f3e8 100644 --- a/src/mantle/testing/class-block-factory.php +++ b/src/mantle/testing/class-block-factory.php @@ -107,9 +107,17 @@ public function __call( string $name, array $arguments ): string { /** * Generate a collection of blocks. * - * @param array $blocks Blocks to generate. + * Blocks can be passed as an array or as individual arguments. + * + * @param array|string ...$blocks Blocks to generate. */ - public function blocks( array $blocks ): string { + public function blocks( array|string ...$blocks ): string { + $blocks = isset( $blocks[0] ) && is_array( $blocks[0] ) ? $blocks[0] : $blocks; + + if ( ! is_array( $blocks ) ) { + $blocks = [ $blocks ]; + } + return collect( $blocks ) ->map( fn ( $block ) => is_array( $block ) ? serialize_blocks( $block ) : $block ) ->implode( "\n\n" ); diff --git a/tests/Support/CollectionTest.php b/tests/Support/CollectionTest.php index 78874877f..1873398c9 100644 --- a/tests/Support/CollectionTest.php +++ b/tests/Support/CollectionTest.php @@ -2343,23 +2343,35 @@ public function testFlatMap($collection) * @dataProvider collectionClassProvider */ #[DataProvider( 'collectionClassProvider' )] -// public function testMapToDictionary($collection) -// { -// $data = new $collection([ -// ['id' => 1, 'name' => 'A'], -// ['id' => 2, 'name' => 'B'], -// ['id' => 3, 'name' => 'C'], -// ['id' => 4, 'name' => 'B'], -// ]); -// -// $groups = $data->map_to_dictionary(function ($item, $key) { -// return [$item['name'] => $item['id']]; -// }); -// -// $this->assertInstanceOf($collection, $groups); -// $this->assertEquals(['A' => [1], 'B' => [2, 4], 'C' => [3]], $groups->to_array()); -// $this->assertIsArray($groups->get('A')); -// } + public function testMapToDictionary($collection) + { + $data = new $collection([ + ['id' => 1, 'name' => 'A'], + ['id' => 2, 'name' => 'B'], + ['id' => 3, 'name' => 'C'], + ['id' => 4, 'name' => 'B'], + ]); + + $groups = $data->map_to_dictionary(function ($item, $key) { + return [$item['name'] => $item['id']]; + }); + + $this->assertInstanceOf($collection, $groups); + $this->assertEquals(['A' => [1], 'B' => [2, 4], 'C' => [3]], $groups->to_array()); + $this->assertIsArray($groups->get('A')); + } + + public function testMapToDictionaryReturnFalsy() { + $groups = ( new Collection([1, 2, 3, 4, 5]) )->map_to_dictionary(function ($item, $key) { + if (2 === $item) { + return null; + } + + return ['key' => $item]; + }); + + $this->assertEquals(['key' => [1, 3, 4, 5]], $groups->to_array()); + } /** * @dataProvider collectionClassProvider diff --git a/tests/Testing/BlockFactoryTest.php b/tests/Testing/BlockFactoryTest.php index 78adcdb5e..01f07dacf 100644 --- a/tests/Testing/BlockFactoryTest.php +++ b/tests/Testing/BlockFactoryTest.php @@ -23,6 +23,43 @@ public function test_it_can_generate_blocks() { "\n
\n", block_factory()->image( 'https://picsum.photos/353/580' ), ); + + $this->assertEquals( + ' +

Heading Here

+ + + +

Paragraph here.

+', + block_factory()->blocks( [ + block_factory()->heading( 'Heading Here' ), + block_factory()->paragraph( 'Paragraph here.' ), + ] ), + ); + + $this->assertEquals( + ' +

Heading Here

+', + block_factory()->blocks( + block_factory()->heading( 'Heading Here' ), + ), + ); + + $this->assertEquals( + ' +

Heading Here

+ + + +

Paragraph here.

+', + block_factory()->blocks( + block_factory()->heading( 'Heading Here' ), + block_factory()->paragraph( 'Paragraph here.' ), + ), + ); } public function test_it_throws_an_exception_for_invalid_blocks() { diff --git a/tests/Testing/Concerns/BlockAssertionsTest.php b/tests/Testing/Concerns/BlockAssertionsTest.php index c9b267af2..3879fe433 100644 --- a/tests/Testing/Concerns/BlockAssertionsTest.php +++ b/tests/Testing/Concerns/BlockAssertionsTest.php @@ -25,6 +25,13 @@ public function setUp(): void { $this->faker->paragraph_block, $this->faker->heading_block( 4 ), $this->faker->paragraph_block, + $this->faker->block( + 'vendor/example-name', + '', + [ + 'moduleId' => 1234, + ] + ), ] ), ] ); } @@ -33,6 +40,7 @@ public function test_string_has_content() { $this->assertStringHasBlock( $this->post->post_content, 'core/paragraph' ); $this->assertStringHasBlock( $this->post->post_content, 'core/heading' ); $this->assertStringHasBlock( $this->post->post_content, 'core/heading', [ 'level' => 3 ] ); + $this->assertStringHasBlock( $this->post->post_content, 'vendor/example-name', [ 'moduleId' => 1234 ] ); $this->assertStringNotHasBlock( $this->post->post_content, 'core/heading', [ 'level' => 5 ] ); } @@ -40,6 +48,7 @@ public function test_post_has_content() { $this->assertPostHasBlock( $this->post, 'core/paragraph' ); $this->assertPostHasBlock( $this->post, 'core/heading' ); $this->assertPostHasBlock( $this->post, 'core/heading', [ 'level' => 3 ] ); + $this->assertPostHasBlock( $this->post, 'vendor/example-name', [ 'moduleId' => 1234 ] ); $this->assertPostNotHasBlock( $this->post, 'core/heading', [ 'level' => 5 ] ); } }