wordpress-develop/tests/phpunit/tests/blocks/render.php
Sergey Biryukov b0419afba6 Build/Test Tools: Ignore EOL differences in tests using multiline string assertions.
Unix vs. Windows EOL style mismatches can cause misleading failures in tests using the heredoc syntax (`<<<`) or multiline strings as the expected result.

Fixes #31432. See #42594, #47411.

git-svn-id: https://develop.svn.wordpress.org/trunk@46612 602fd350-edb4-49c9-b593-d223f7449a82
2019-10-29 14:26:41 +00:00

486 lines
12 KiB
PHP

<?php
/**
* Block rendering tests.
*
* @package WordPress
* @subpackage Blocks
* @since 5.0.0
*/
/**
* Tests for block rendering functions
*
* @since 5.0.0
*
* @group blocks
*/
class WP_Test_Block_Render extends WP_UnitTestCase {
/**
* The location of the fixtures to test with.
*
* @since 5.0.0
* @var string
*/
protected static $fixtures_dir;
/**
* Test block instance number.
*
* @since 5.0.0
*
* @var int
*/
protected $test_block_instance_number = 0;
/**
* Tear down after each test.
*
* @since 5.0.0
*/
public function tearDown() {
parent::tearDown();
$this->test_block_instance_number = 0;
$registry = WP_Block_Type_Registry::get_instance();
if ( $registry->is_registered( 'core/test' ) ) {
$registry->unregister( 'core/test' );
}
if ( $registry->is_registered( 'core/dynamic' ) ) {
$registry->unregister( 'core/dynamic' );
}
}
/**
* @ticket 45109
*/
public function test_do_blocks_removes_comments() {
$original_html = file_get_contents( DIR_TESTDATA . '/blocks/do-blocks-original.html' );
$expected_html = file_get_contents( DIR_TESTDATA . '/blocks/do-blocks-expected.html' );
$actual_html = do_blocks( $original_html );
$this->assertEqualsIgnoreEOL( $expected_html, $actual_html );
}
/**
* @ticket 45109
*/
public function test_the_content() {
add_shortcode( 'someshortcode', array( $this, 'handle_shortcode' ) );
$classic_content = "Foo\n\n[someshortcode]\n\nBar\n\n[/someshortcode]\n\nBaz";
$block_content = "<!-- wp:core/paragraph -->\n<p>Foo</p>\n<!-- /wp:core/paragraph -->\n\n<!-- wp:core/shortcode -->[someshortcode]\n\nBar\n\n[/someshortcode]<!-- /wp:core/shortcode -->\n\n<!-- wp:core/paragraph -->\n<p>Baz</p>\n<!-- /wp:core/paragraph -->";
$classic_filtered_content = apply_filters( 'the_content', $classic_content );
$block_filtered_content = apply_filters( 'the_content', $block_content );
// Block rendering add some extra blank lines, but we're not worried about them.
$block_filtered_content = preg_replace( "/\n{2,}/", "\n", $block_filtered_content );
remove_shortcode( 'someshortcode' );
$this->assertEquals( trim( $classic_filtered_content ), trim( $block_filtered_content ) );
}
function handle_shortcode( $atts, $content ) {
return $content;
}
/**
* @ticket 45495
*/
function test_nested_calls_to_the_content() {
register_block_type(
'core/test',
array(
'render_callback' => array(
$this,
'dynamic_the_content_call',
),
)
);
$content = "foo\n\nbar";
$the_content = apply_filters( 'the_content', '<!-- wp:core/test -->' . $content . '<!-- /wp:core/test -->' );
$this->assertSame( $content, $the_content );
}
function dynamic_the_content_call( $attrs, $content ) {
apply_filters( 'the_content', '' );
return $content;
}
public function test_can_nest_at_least_so_deep() {
$minimum_depth = 99;
$content = 'deep inside';
for ( $i = 0; $i < $minimum_depth; $i++ ) {
$content = '<!-- wp:core/test -->' . $content . '<!-- /wp:core/test -->';
}
$this->assertEquals( 'deep inside', do_blocks( $content ) );
}
public function test_can_nest_at_least_so_deep_with_dynamic_blocks() {
$minimum_depth = 99;
$content = '0';
for ( $i = 0; $i < $minimum_depth; $i++ ) {
$content = '<!-- wp:core/test -->' . $content . '<!-- /wp:core/test -->';
}
register_block_type(
'core/test',
array(
'render_callback' => array(
$this,
'render_dynamic_incrementer',
),
)
);
$this->assertEquals( $minimum_depth, (int) do_blocks( $content ) );
}
public function render_dynamic_incrementer( $attrs, $content ) {
return (string) ( 1 + (int) $content );
}
/**
* @ticket 45290
*/
public function test_blocks_arent_autopeed() {
$expected_content = 'test';
$test_content = "<!-- wp:fake/block -->\n$expected_content\n<!-- /wp:fake/block -->";
$current_priority = has_action( 'the_content', 'wpautop' );
$filtered_content = trim( apply_filters( 'the_content', $test_content ) );
$this->assertEquals( $expected_content, $filtered_content );
// Check that wpautop() is still defined in the same place.
$this->assertSame( $current_priority, has_action( 'the_content', 'wpautop' ) );
// ... and that the restore function has removed itself.
$this->assertFalse( has_action( 'the_content', '_restore_wpautop_hook' ) );
$test_content = 'test';
$expected_content = "<p>$test_content</p>";
$current_priority = has_action( 'the_content', 'wpautop' );
$filtered_content = trim( apply_filters( 'the_content', $test_content ) );
$this->assertEquals( $expected_content, $filtered_content );
$this->assertSame( $current_priority, has_action( 'the_content', 'wpautop' ) );
$this->assertFalse( has_action( 'the_content', '_restore_wpautop_hook' ) );
}
/**
* @ticket 45109
*/
public function data_do_block_test_filenames() {
self::$fixtures_dir = DIR_TESTDATA . '/blocks/fixtures';
$fixture_filenames = array_merge(
glob( self::$fixtures_dir . '/*.json' ),
glob( self::$fixtures_dir . '/*.html' )
);
$fixture_filenames = array_values(
array_unique(
array_map(
array( $this, 'clean_fixture_filename' ),
$fixture_filenames
)
)
);
return array_map(
array( $this, 'pass_parser_fixture_filenames' ),
$fixture_filenames
); }
/**
* @dataProvider data_do_block_test_filenames
* @ticket 45109
*/
public function test_do_block_output( $html_filename, $server_html_filename ) {
$html_path = self::$fixtures_dir . '/' . $html_filename;
$server_html_path = self::$fixtures_dir . '/' . $server_html_filename;
foreach ( array( $html_path, $server_html_path ) as $filename ) {
if ( ! file_exists( $filename ) ) {
throw new Exception( "Missing fixture file: '$filename'" );
}
}
$html = do_blocks( self::strip_r( file_get_contents( $html_path ) ) );
$expected_html = self::strip_r( file_get_contents( $server_html_path ) );
$this->assertEquals(
$expected_html,
$html,
"File '$html_path' does not match expected value"
);
}
/**
* @ticket 45109
*/
public function test_dynamic_block_rendering() {
$settings = array(
'render_callback' => array(
$this,
'render_test_block',
),
);
register_block_type( 'core/test', $settings );
// The duplicated dynamic blocks below are there to ensure that do_blocks() replaces each one-by-one.
$post_content =
'before' .
'<!-- wp:core/test {"value":"b1"} --><!-- /wp:core/test -->' .
'<!-- wp:core/test {"value":"b1"} --><!-- /wp:core/test -->' .
'between' .
'<!-- wp:core/test {"value":"b2"} /-->' .
'<!-- wp:core/test {"value":"b2"} /-->' .
'after';
$updated_post_content = do_blocks( $post_content );
$this->assertEquals(
$updated_post_content,
'before' .
'1:b1' .
'2:b1' .
'between' .
'3:b2' .
'4:b2' .
'after'
);
}
/**
* @ticket 45109
*/
public function test_global_post_persistence() {
global $post;
register_block_type(
'core/test',
array(
'render_callback' => array(
$this,
'render_test_block_wp_query',
),
)
);
$posts = self::factory()->post->create_many( 5 );
$post = get_post( end( $posts ) );
$global_post = $post;
do_blocks( '<!-- wp:core/test /-->' );
$this->assertEquals( $global_post, $post );
}
/**
* @ticket 45109
*/
public function test_dynamic_block_renders_string() {
$settings = array(
'render_callback' => array(
$this,
'render_test_block_numeric',
),
);
register_block_type( 'core/test', $settings );
$block_type = new WP_Block_Type( 'core/test', $settings );
$rendered = $block_type->render();
$this->assertSame( '10', $rendered );
$this->assertInternalType( 'string', $rendered );
}
public function test_dynamic_block_gets_inner_html() {
register_block_type(
'core/dynamic',
array(
'render_callback' => array(
$this,
'render_serialize_dynamic_block',
),
)
);
$output = do_blocks( '<!-- wp:dynamic -->inner<!-- /wp:dynamic -->' );
$data = unserialize( base64_decode( $output ) );
$this->assertEquals( 'inner', $data[1] );
}
public function test_dynamic_block_gets_rendered_inner_blocks() {
register_block_type(
'core/test',
array(
'render_callback' => array(
$this,
'render_test_block_numeric',
),
)
);
register_block_type(
'core/dynamic',
array(
'render_callback' => array(
$this,
'render_serialize_dynamic_block',
),
)
);
$output = do_blocks( '<!-- wp:dynamic -->before<!-- wp:test /-->after<!-- /wp:dynamic -->' );
$data = unserialize( base64_decode( $output ) );
$this->assertEquals( 'before10after', $data[1] );
}
public function test_dynamic_block_gets_rendered_inner_dynamic_blocks() {
register_block_type(
'core/dynamic',
array(
'render_callback' => array(
$this,
'render_serialize_dynamic_block',
),
)
);
$output = do_blocks( '<!-- wp:dynamic -->before<!-- wp:dynamic -->deep inner<!-- /wp:dynamic -->after<!-- /wp:dynamic -->' );
$data = unserialize( base64_decode( $output ) );
$inner = $this->render_serialize_dynamic_block( array(), 'deep inner' );
$this->assertEquals( $data[1], 'before' . $inner . 'after' );
}
/**
* Helper function to remove relative paths and extension from a filename, leaving just the fixture name.
*
* @since 5.0.0
*
* @param string $filename The filename to clean.
* @return string The cleaned fixture name.
*/
protected function clean_fixture_filename( $filename ) {
$filename = wp_basename( $filename );
$filename = preg_replace( '/\..+$/', '', $filename );
return $filename;
}
/**
* Helper function to return the filenames needed to test the parser output.
*
* @since 5.0.0
*
* @param string $filename The cleaned fixture name.
* @return array The input and expected output filenames for that fixture.
*/
protected function pass_parser_fixture_filenames( $filename ) {
return array(
"$filename.html",
"$filename.server.html",
);
}
/**
* Helper function to remove '\r' characters from a string.
*
* @since 5.0.0
*
* @param string $input The string to remove '\r' from.
* @return string The input string, with '\r' characters removed.
*/
protected function strip_r( $input ) {
return str_replace( "\r", '', $input );
}
/**
* Test block rendering function.
*
* @since 5.0.0
*
* @param array $attributes Block attributes.
* @return string Block output.
*/
public function render_test_block( $attributes ) {
$this->test_block_instance_number += 1;
return $this->test_block_instance_number . ':' . $attributes['value'];
}
/**
* Test block rendering function, returning numeric value.
*
* @since 5.0.0
*
* @return int Block output.
*/
public function render_test_block_numeric() {
return 10;
}
/**
* Test block rendering function, returning base64 encoded serialised value.
*
* @since 5.0.0
*
* @return string Block output.
*/
public function render_serialize_dynamic_block( $attributes, $content ) {
return base64_encode( serialize( array( $attributes, $content ) ) );
}
/**
* Test block rendering function, creating a new WP_Query instance.
*
* @since 5.0.0
*
* @return string Block output.
*/
public function render_test_block_wp_query() {
$content = '';
$recent = new WP_Query(
array(
'numberposts' => 10,
'orderby' => 'ID',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'draft, publish, future, pending, private',
'suppress_filters' => true,
)
);
while ( $recent->have_posts() ) {
$recent->the_post();
$content .= get_the_title();
}
wp_reset_postdata();
return $content;
}
}