Skip to content

Commit

Permalink
Adding block assertions to strings (#463)
Browse files Browse the repository at this point in the history
* Overhauling the generics of factories to return the proper type

* Adding a global constant to make testing easier

* Include some functionality from core

* Ensure that post factories work in data providers

* Switch to get_comment_delimited_block_content() to compile blocks

* Ensure that a new line is added before/after content

* Adding block assertions for string/content

* Adjust message

* Adjusting to support 1.0-3.0

* Fixing PHPCS
  • Loading branch information
srtfisher authored Nov 14, 2023
1 parent 5c37b70 commit c692556
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 2 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"require-dev": {
"alleyinteractive/alley-coding-standards": "^1.0.1",
"alleyinteractive/wp-match-blocks": "^1.0 || ^2.0 || ^3.0",
"guzzlehttp/guzzle": "^7.7",
"league/flysystem-aws-s3-v3": "^1.0",
"mockery/mockery": "^1.6.6",
Expand Down
26 changes: 26 additions & 0 deletions src/mantle/faker/class-faker-provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@
* Faker Block Provider
*/
class Faker_Provider extends Base {
/**
* Compile a set of blocks.
*
* @param array $blocks Blocks to compile.
* @return string
*/
public static function blocks( array $blocks ): string {
return implode( "\n\n", $blocks );
}

/**
* Build a heading block.
*
* @param int $level Heading level.
* @return string
*/
public static function heading_block( int $level = 2 ): string {
return static::block(
'heading',
sprintf( '<h%d>%s</h%d>', $level, Lorem::sentence(), $level ),
[
'level' => $level,
],
);
}

/**
* Build a paragraph block.
*
Expand Down
3 changes: 2 additions & 1 deletion src/mantle/testing/concerns/trait-assertions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
* Assorted Test_Cast assertions.
*/
trait Assertions {
use Asset_Assertions;
use Asset_Assertions,
Block_Assertions;

/**
* Asserts that the given value is an instance of WP_Error.
Expand Down
156 changes: 156 additions & 0 deletions src/mantle/testing/concerns/trait-block-assertions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
/**
* Block_Assertions trait file
*
* phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_print_r, WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
*
* @package Mantle
*/

namespace Mantle\Testing\Concerns;

use Mantle\Database\Model\Post;
use WP_Post;

use function Alley\WP\match_blocks;
use function Mantle\Support\Helpers\collect;

/**
* Assorted Block assertions
*
* @mixin \PHPUnit\Framework\TestCase
*/
trait Block_Assertions {
/**
* Assert that a string can match a block.
*
* The arguments are passed directly to `match_block()`.
*
* @see \Alley\WP\match_block()
*
* @param string $string The string to check.
* @param array $args The arguments to pass to `match_block()`.
*/
public function assertStringMatchesBlock( string $string, array $args ): void {
$this->assertNotEmpty(
match_blocks( $string, $args ),
'Failed asserting that string matches block with arguments ' . print_r( $args, true ),
);
}

/**
* Assert that a string does not match a block.
*
* The arguments are passed directly to `match_block()`.
*
* @see \Alley\WP\match_block()
*
* @param string $string The string to check.
* @param array $args The arguments to pass to `match_block()`.
*/
public function assertStringNotMatchesBlock( string $string, array $args ): void {
$this->assertEmpty(
match_blocks( $string, $args ),
'Failed asserting that string does not match block with arguments ' . print_r( $args, true ),
);
}

/**
* Assert that a string has a block.
*
* @param string $string The string to check.
* @param string|string[] $block_name The block name(s) to check for. Will attempt to match any of the names.
* @param array $attrs Optional. Attributes to check for.
*/
public function assertStringHasBlock( string $string, string|array $block_name, array $attrs = [] ): void {
$this->assertNotEmpty(
match_blocks(
$string,
[
'attrs' => $this->convert_arguments_for_matching( $attrs ),
'name' => $block_name,
],
),
! empty( $attrs )
? "Failed asserting that string has block [{$block_name}] with attributes " . print_r( $attrs, true )
: "Failed asserting that string has block [{$block_name}]."
);
}

/**
* Assert that a string does not have a block.
*
* @param string $string The string to check.
* @param string|string[] $block_name The block name(s) to check for. Will attempt to match any of the names.
* @param array $attrs Optional. Attributes to check for.
*/
public function assertStringNotHasBlock( string $string, string|array $block_name, array $attrs = [] ): void {
$this->assertEmpty(
match_blocks(
$string,
[
'attrs' => $this->convert_arguments_for_matching( $attrs ),
'name' => $block_name,
],
),
! empty( $attrs )
? "Failed asserting that string does not have block [{$block_name}] with attributes " . print_r( $attrs, true )
: "Failed asserting that string does not have block [{$block_name}]",
);
}

/**
* Assert that a post has a block in its content.
*
* @param Post|WP_Post $post The post to check.
* @param string|string[] $block_name The block name(s) to check for. Will attempt to match any of the names.
* @param array $attrs Optional. Attributes to check for.
*/
public function assertPostHasBlock( Post|WP_Post $post, string|array $block_name, array $attrs = [] ): void {
$this->assertStringHasBlock( $post->post_content, $block_name, $attrs );
}

/**
* Assert that a post does not have a block in its content.
*
* @param Post|WP_Post $post The post to check.
* @param string|string[] $block_name The block name(s) to check for. Will attempt to match any of the names.
* @param array $attrs Optional. Attributes to check for.
*/
public function assertPostNotHasBlock( Post|WP_Post $post, string|array $block_name, array $attrs = [] ): void {
$this->assertStringNotHasBlock( $post->post_content, $block_name, $attrs );
}

/**
* Convert the key/value arguments to an array that can be passed to
* `match_block()`.
*
* @param array $args The arguments to convert.
* @return array
*/
protected function convert_arguments_for_matching( array $args ): array {
// PHPCS is crashing on these lines for some reason. Disabling it for now
// until we've upgrading to WPCS 3.0.

/* phpcs:disable */
return collect( $args )->reduce(
function ( array $carry, $value, $key ) {
// Allow for passing an argument pair directly.
if ( is_array( $value ) && isset( $value['key'], $value['value'] ) ) {
$carry[] = $value;

return $carry;
}

$carry[] = [
$key => $value,
'value' => $value,
];

return $carry;
},
[]
);
/* phpcs:enable */
}
}
7 changes: 6 additions & 1 deletion src/mantle/testing/concerns/trait-with-faker.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Faker\Generator;
use Faker\Factory;
use Mantle\Faker\Faker_Provider;

/**
* This trait sets up a faker instance for use in tests.
Expand Down Expand Up @@ -44,6 +45,10 @@ protected function make_faker(): Generator {
return $this->app->make( Generator::class, [ 'locale' => $locale ] );
}

return Factory::create( $locale );
$generator = Factory::create( $locale );

$generator->addProvider( new Faker_Provider( $generator ) );

return $generator;
}
}
43 changes: 43 additions & 0 deletions tests/testing/concerns/test-block-assertions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
namespace Mantle\Tests\Testing\Concerns;

use Mantle\Testing\Concerns\With_Faker;
use Mantle\Testing\Framework_Test_Case;
use WP_Post;

/**
* @group testing
*/
class Test_Block_Assertions extends Framework_Test_Case {
use With_Faker;

protected WP_Post $post;

public function setUp(): void {
parent::setUp();

$this->post = static::factory()->post->create_and_get( [
'post_content' => $this->faker->blocks( [
$this->faker->paragraph_block,
$this->faker->heading_block( 3 ),
$this->faker->paragraph_block,
$this->faker->heading_block( 4 ),
$this->faker->paragraph_block,
] ),
] );
}

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->assertStringNotHasBlock( $this->post->post_content, 'core/heading', [ 'level' => 5 ] );
}

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->assertPostNotHasBlock( $this->post, 'core/heading', [ 'level' => 5 ] );
}
}

0 comments on commit c692556

Please sign in to comment.