diff options
-rw-r--r-- | src/wp-admin/includes/class-wp-list-table.php | 4 | ||||
-rw-r--r-- | src/wp-includes/capabilities.php | 59 | ||||
-rw-r--r-- | src/wp-includes/class-wp-comment-query.php | 4 | ||||
-rw-r--r-- | src/wp-includes/class-wp-customize-widgets.php | 2 | ||||
-rw-r--r-- | src/wp-includes/post.php | 9 | ||||
-rw-r--r-- | src/wp-includes/user.php | 7 | ||||
-rw-r--r-- | tests/phpunit/includes/abstract-testcase.php | 40 | ||||
-rw-r--r-- | tests/phpunit/includes/build-visual-html-tree.php | 304 | ||||
-rw-r--r-- | tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php | 5 | ||||
-rw-r--r-- | tests/phpunit/tests/build-visual-html-tree.php | 144 | ||||
-rw-r--r-- | tests/phpunit/tests/dependencies/scripts.php | 435 | ||||
-rw-r--r-- | tools/local-env/scripts/install.js | 1 |
12 files changed, 774 insertions, 240 deletions
diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index 5a7fa0db8e..cdf31db597 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -72,10 +72,10 @@ class WP_List_Table { protected $modes = array(); /** - * Stores the value returned by ->get_column_info(). + * Stores the value returned by ::get_column_info(). * * @since 4.1.0 - * @var array + * @var array|null */ protected $_column_headers; diff --git a/src/wp-includes/capabilities.php b/src/wp-includes/capabilities.php index d6c340c95e..48586e093c 100644 --- a/src/wp-includes/capabilities.php +++ b/src/wp-includes/capabilities.php @@ -470,7 +470,7 @@ function map_meta_cap( $cap, $user_id, ...$args ) { if ( $meta_key ) { $allowed = ! is_protected_meta( $meta_key, $object_type ); - if ( ! empty( $object_subtype ) && has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { + if ( has_filter( "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) { /** * Filters whether the user is allowed to edit a specific meta key of a specific object type and subtype. @@ -512,36 +512,33 @@ function map_meta_cap( $cap, $user_id, ...$args ) { $allowed = apply_filters( "auth_{$object_type}_meta_{$meta_key}", $allowed, $meta_key, $object_id, $user_id, $cap, $caps ); } - if ( ! empty( $object_subtype ) ) { - - /** - * Filters whether the user is allowed to edit meta for specific object types/subtypes. - * - * Return true to have the mapped meta caps from `edit_{$object_type}` apply. - * - * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. - * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered. - * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). - * - * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`. - * @since 4.7.0 Renamed from `auth_post_{$post_type}_meta_{$meta_key}` to - * `auth_{$object_type}_{$object_subtype}_meta_{$meta_key}`. - * @deprecated 4.9.8 Use {@see 'auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}'} instead. - * - * @param bool $allowed Whether the user can add the object meta. Default false. - * @param string $meta_key The meta key. - * @param int $object_id Object ID. - * @param int $user_id User ID. - * @param string $cap Capability name. - * @param string[] $caps Array of the user's capabilities. - */ - $allowed = apply_filters_deprecated( - "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", - array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ), - '4.9.8', - "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" - ); - } + /** + * Filters whether the user is allowed to edit meta for specific object types/subtypes. + * + * Return true to have the mapped meta caps from `edit_{$object_type}` apply. + * + * The dynamic portion of the hook name, `$object_type` refers to the object type being filtered. + * The dynamic portion of the hook name, `$object_subtype` refers to the object subtype being filtered. + * The dynamic portion of the hook name, `$meta_key`, refers to the meta key passed to map_meta_cap(). + * + * @since 4.6.0 As `auth_post_{$post_type}_meta_{$meta_key}`. + * @since 4.7.0 Renamed from `auth_post_{$post_type}_meta_{$meta_key}` to + * `auth_{$object_type}_{$object_subtype}_meta_{$meta_key}`. + * @deprecated 4.9.8 Use {@see 'auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}'} instead. + * + * @param bool $allowed Whether the user can add the object meta. Default false. + * @param string $meta_key The meta key. + * @param int $object_id Object ID. + * @param int $user_id User ID. + * @param string $cap Capability name. + * @param string[] $caps Array of the user's capabilities. + */ + $allowed = apply_filters_deprecated( + "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", + array( $allowed, $meta_key, $object_id, $user_id, $cap, $caps ), + '4.9.8', + "auth_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" + ); if ( ! $allowed ) { $caps[] = $cap; diff --git a/src/wp-includes/class-wp-comment-query.php b/src/wp-includes/class-wp-comment-query.php index 6a72c0d209..03d3479b6c 100644 --- a/src/wp-includes/class-wp-comment-query.php +++ b/src/wp-includes/class-wp-comment-query.php @@ -579,9 +579,7 @@ class WP_Comment_Query { } } - if ( ! empty( $status_clauses ) ) { - $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; - } + $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; } // User IDs or emails whose unapproved comments are included, regardless of $status. diff --git a/src/wp-includes/class-wp-customize-widgets.php b/src/wp-includes/class-wp-customize-widgets.php index 2a7915224b..b24a9c8b47 100644 --- a/src/wp-includes/class-wp-customize-widgets.php +++ b/src/wp-includes/class-wp-customize-widgets.php @@ -923,7 +923,7 @@ final class WP_Customize_Widgets { <span class="customize-action"> <?php $panel = $this->manager->get_panel( 'widgets' ); - $panel_title = $panel && isset( $panel->title ) ? $panel->title : __( 'Widgets' ); + $panel_title = isset( $panel->title ) ? $panel->title : __( 'Widgets' ); /* translators: ▸ is the unicode right-pointing triangle. %s: Section title in the Customizer. */ printf( __( 'Customizing ▸ %s' ), esc_html( $panel_title ) ); ?> diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index bd749b2f82..ae711eebb8 100644 --- a/src/wp-includes/post.php +++ b/src/wp-includes/post.php @@ -4874,6 +4874,15 @@ function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true ) } } + /** + * Fires immediately before a new post is inserted in the database. + * + * @since 6.9.0 + * + * @param array $data Array of unslashed post data. + */ + do_action( 'pre_post_insert', $data ); + if ( false === $wpdb->insert( $wpdb->posts, $data ) ) { if ( $wp_error ) { if ( 'attachment' === $post_type ) { diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index c3df9229bf..4dacf58628 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -637,7 +637,7 @@ function count_user_posts( $userid, $post_type = 'post', $public_only = false ) * @since 4.1.0 Added `$post_type` argument. * @since 4.3.1 Added `$public_only` argument. * - * @param int $count The user's post count. + * @param string $count The user's post count as a numeric string. * @param int $userid User ID. * @param string|array $post_type Single post type or array of post types to count the number of posts for. * @param bool $public_only Whether to limit counted posts to public posts. @@ -2286,7 +2286,10 @@ function wp_insert_user( $userdata ) { */ $user_nicename = apply_filters( 'pre_user_nicename', $user_nicename ); - if ( mb_strlen( $user_nicename ) > 50 ) { + // Check if the sanitized nicename is empty. + if ( empty( $user_nicename ) ) { + return new WP_Error( 'empty_user_nicename', __( 'Cannot create a user with an empty nicename.' ) ); + } elseif ( mb_strlen( $user_nicename ) > 50 ) { return new WP_Error( 'user_nicename_too_long', __( 'Nicename may not be longer than 50 characters.' ) ); } diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index f665bdafb1..6750df13c7 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -1,5 +1,6 @@ <?php +require_once __DIR__ . '/build-visual-html-tree.php'; require_once __DIR__ . '/factory.php'; require_once __DIR__ . '/trac.php'; @@ -13,7 +14,6 @@ require_once __DIR__ . '/trac.php'; * All WordPress unit tests should inherit from this class. */ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { - protected static $forced_tickets = array(); protected $expected_deprecated = array(); protected $caught_deprecated = array(); @@ -1181,6 +1181,44 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase { } /** + * Check HTML markup (including blocks) for semantic equivalence. + * + * Given two markup strings, assert that they translate to the same semantic HTML tree, + * normalizing tag names, attribute names, and attribute order. Furthermore, attributes + * and class names are sorted and deduplicated, and whitespace in style attributes + * is normalized. Finally, block delimiter comments are recognized and normalized, + * applying the same principles. + * + * @since 6.9.0 + * + * @param string $expected The expected HTML. + * @param string $actual The actual HTML. + * @param string|null $fragment_context Optional. The fragment context, for example "<td>" expected HTML + * must occur within "<table><tr>" fragment context. Default "<body>". + * Only "<body>" or `null` are supported at this time. + * Set to `null` to parse a full HTML document. + * @param string|null $message Optional. The assertion error message. + */ + public function assertEqualHTML( string $expected, string $actual, ?string $fragment_context = '<body>', $message = 'HTML markup was not equivalent.' ): void { + try { + $tree_expected = build_visual_html_tree( $expected, $fragment_context ); + $tree_actual = build_visual_html_tree( $actual, $fragment_context ); + } catch ( Exception $e ) { + // For PHP 8.4+, we can retry, using the built-in DOM\HTMLDocument parser. + if ( class_exists( 'DOM\HtmlDocument' ) ) { + $dom_expected = DOM\HtmlDocument::createFromString( $expected, LIBXML_NOERROR ); + $tree_expected = build_visual_html_tree( $dom_expected->saveHtml(), $fragment_context ); + $dom_actual = DOM\HtmlDocument::createFromString( $actual, LIBXML_NOERROR ); + $tree_actual = build_visual_html_tree( $dom_actual->saveHtml(), $fragment_context ); + } else { + throw $e; + } + } + + $this->assertSame( $tree_expected, $tree_actual, $message ); + } + + /** * Helper function to convert a single-level array containing text strings to a named data provider. * * The value of the data set will also be used as the name of the data set. diff --git a/tests/phpunit/includes/build-visual-html-tree.php b/tests/phpunit/includes/build-visual-html-tree.php new file mode 100644 index 0000000000..e0f6c3ac3d --- /dev/null +++ b/tests/phpunit/includes/build-visual-html-tree.php @@ -0,0 +1,304 @@ +<?php + +/* phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped */ + +/** + * Generates representation of the semantic HTML tree structure. + * + * This is inspired by the representation used by the HTML5lib tests. It's been extended here for + * blocks to render the semantic structure of blocks and their attributes. + * The order of attributes and class names is normalized both for HTML tags and blocks, + * as is the whitespace in HTML tags' style attribute. + * + * For example, consider the following block markup: + * + * <!-- wp:separator {"className":"is-style-default has-custom-classname","style":{"spacing":{"margin":{"top":"50px","bottom":"50px"}}},"backgroundColor":"accent-1"} --> + * <hr class="wp-block-separator is-style-default has-custom-classname" style="margin-top: 50px; margin-bottom: 50px" /> + * <!-- /wp:separator --> + * + * This will be represented as: + * + * BLOCK["core/separator"] + * { + * "backgroundColor": "accent-1", + * "className": "has-custom-classname is-style-default", + * "style": { + * "spacing": { + * "margin": { + * "top": "50px", + * "bottom": "50px" + * } + * } + * } + * } + * <hr> + * class="has-custom-classname is-style-default wp-block-separator" + * style="margin-top:50px;margin-bottom:50px;" + * + * + * @see https://github.com/WordPress/wordpress-develop/blob/trunk/tests/phpunit/data/html5lib-tests/tree-construction/README.md + * + * @since 6.9.0 + * + * @throws WP_HTML_Unsupported_Exception|Error If the markup could not be parsed. + * + * @param string $html Given test HTML. + * @param string|null $fragment_context Context element in which to parse HTML, such as BODY or SVG. + * @return string Tree structure of parsed HTML, if supported. + */ +function build_visual_html_tree( string $html, ?string $fragment_context ): string { + $processor = $fragment_context + ? WP_HTML_Processor::create_fragment( $html, $fragment_context ) + : WP_HTML_Processor::create_full_parser( $html ); + if ( null === $processor ) { + throw new Error( 'Could not create a parser.' ); + } + $tree_indent = ' '; + + $output = ''; + $indent_level = 0; + $was_text = null; + $text_node = ''; + + $block_context = array(); + + while ( $processor->next_token() ) { + if ( null !== $processor->get_last_error() ) { + break; + } + + $token_name = $processor->get_token_name(); + $token_type = $processor->get_token_type(); + $is_closer = $processor->is_tag_closer(); + + if ( $was_text && '#text' !== $token_name ) { + if ( '' !== $text_node ) { + $output .= "{$text_node}\"\n"; + } + $was_text = false; + $text_node = ''; + } + + switch ( $token_type ) { + case '#doctype': + $doctype = $processor->get_doctype_info(); + $output .= "<!DOCTYPE {$doctype->name}"; + if ( null !== $doctype->public_identifier || null !== $doctype->system_identifier ) { + $output .= " \"{$doctype->public_identifier}\" \"{$doctype->system_identifier}\""; + } + $output .= ">\n"; + break; + + case '#tag': + $namespace = $processor->get_namespace(); + $tag_name = 'html' === $namespace + ? strtolower( $processor->get_tag() ) + : "{$namespace} {$processor->get_qualified_tag_name()}"; + + if ( $is_closer ) { + --$indent_level; + + if ( 'html' === $namespace && 'TEMPLATE' === $token_name ) { + --$indent_level; + } + + break; + } + + $tag_indent = $indent_level; + + if ( $processor->expects_closer() ) { + ++$indent_level; + } + + $output .= str_repeat( $tree_indent, $tag_indent ) . "<{$tag_name}>\n"; + + $attribute_names = $processor->get_attribute_names_with_prefix( '' ); + if ( $attribute_names ) { + $sorted_attributes = array(); + foreach ( $attribute_names as $attribute_name ) { + $sorted_attributes[ $attribute_name ] = $processor->get_qualified_attribute_name( $attribute_name ); + } + + /* + * Sorts attributes to match html5lib sort order. + * + * - First comes normal HTML attributes. + * - Then come adjusted foreign attributes; these have spaces in their names. + * - Finally come non-adjusted foreign attributes; these have a colon in their names. + * + * Example: + * + * From: <math xlink:author definitionurl xlink:title xlink:show> + * Sorted: 'definitionURL', 'xlink show', 'xlink title', 'xlink:author' + */ + uasort( + $sorted_attributes, + static function ( $a, $b ) { + $a_has_ns = str_contains( $a, ':' ); + $b_has_ns = str_contains( $b, ':' ); + + // Attributes with `:` should follow all other attributes. + if ( $a_has_ns !== $b_has_ns ) { + return $a_has_ns ? 1 : -1; + } + + $a_has_sp = str_contains( $a, ' ' ); + $b_has_sp = str_contains( $b, ' ' ); + + // Attributes with a namespace ' ' should come after those without. + if ( $a_has_sp !== $b_has_sp ) { + return $a_has_sp ? 1 : -1; + } + + return $a <=> $b; + } + ); + + foreach ( $sorted_attributes as $attribute_name => $display_name ) { + $val = $processor->get_attribute( $attribute_name ); + /* + * Attributes with no value are `true` with the HTML API, + * we use the empty string value in the tree structure. + */ + if ( true === $val ) { + $val = ''; + } elseif ( 'class' === $attribute_name ) { + $class_names = iterator_to_array( $processor->class_list() ); + sort( $class_names, SORT_STRING ); + $val = implode( ' ', $class_names ); + } elseif ( 'style' === $attribute_name ) { + $normalized_style = ''; + foreach ( explode( ';', $val ) as $style ) { + if ( empty( trim( $style ) ) ) { + continue; + } + list( $style_key, $style_val ) = explode( ':', $style ); + + $style_key = trim( $style_key ); + $style_val = trim( $style_val ); + + $normalized_style .= "{$style_key}:{$style_val};"; + } + $val = $normalized_style; + } + $output .= str_repeat( $tree_indent, $tag_indent + 1 ) . "{$display_name}=\"{$val}\"\n"; + } + } + + // Self-contained tags contain their inner contents as modifiable text. + $modifiable_text = $processor->get_modifiable_text(); + if ( '' !== $modifiable_text ) { + $output .= str_repeat( $tree_indent, $tag_indent + 1 ) . "\"{$modifiable_text}\"\n"; + } + + if ( 'html' === $namespace && 'TEMPLATE' === $token_name ) { + $output .= str_repeat( $tree_indent, $indent_level ) . "content\n"; + ++$indent_level; + } + + break; + + case '#cdata-section': + case '#text': + $text_content = $processor->get_modifiable_text(); + if ( '' === trim( $text_content, " \f\t\r\n" ) ) { + break; + } + $was_text = true; + if ( '' === $text_node ) { + $text_node .= str_repeat( $tree_indent, $indent_level ) . '"'; + } + $text_node .= $text_content; + break; + + case '#funky-comment': + // Comments must be "<" then "!-- " then the data then " -->". + $output .= str_repeat( $tree_indent, $indent_level ) . "<!-- {$processor->get_modifiable_text()} -->\n"; + break; + + case '#comment': + // Comments must be "<" then "!--" then the data then "-->". + $comment = "<!--{$processor->get_full_comment_text()}-->"; + + // Maybe the comment is a block delimiter. + $parser = new WP_Block_Parser(); + $parser->document = $comment; + $parser->offset = 0; + list( $delimiter_type, $block_name, $block_attrs, $start_offset, $token_length ) = $parser->next_token(); + + switch ( $delimiter_type ) { + case 'block-opener': + case 'void-block': + $output .= str_repeat( $tree_indent, $indent_level ) . "BLOCK[\"{$block_name}\"]\n"; + + if ( 'block-opener' === $delimiter_type ) { + $block_context[] = $block_name; + ++$indent_level; + } + + // If they're no attributes, we're done here. + if ( empty( $block_attrs ) ) { + break; + } + + // Normalize attribute order. + ksort( $block_attrs, SORT_STRING ); + + if ( isset( $block_attrs['className'] ) ) { + // Normalize class name order (and de-duplicate), as we need to be tolerant of different orders. + // (Style attributes don't need this treatment, as they are parsed into a nested array.) + $block_class_processor = new WP_HTML_Tag_Processor( '<div>' ); + $block_class_processor->next_token(); + $block_class_processor->set_attribute( 'class', $block_attrs['className'] ); + $class_names = iterator_to_array( $block_class_processor->class_list() ); + sort( $class_names, SORT_STRING ); + $block_attrs['className'] = implode( ' ', $class_names ); + } + + $block_attrs = json_encode( $block_attrs, JSON_PRETTY_PRINT ); + // Fix indentation by "halving" it (2 spaces instead of 4). + // Additionally, we need to indent each line by the current indentation level. + $block_attrs = preg_replace( '/^( +)\1/m', str_repeat( $tree_indent, $indent_level ) . '$1', $block_attrs ); + // Finally, indent the first line, and the last line (with the closing curly brace). + $output .= str_repeat( $tree_indent, $indent_level ) . substr( $block_attrs, 0, -1 ) . str_repeat( $tree_indent, $indent_level ) . "}\n"; + break; + case 'block-closer': + // Is this a closer for the currently open block? + if ( ! empty( $block_context ) && end( $block_context ) === $block_name ) { + // If it's a closer, we don't add it to the output. + // Instead, we decrease indentation and remove the block from block context stack. + --$indent_level; + array_pop( $block_context ); + } + break; + default: // Not a block delimiter. + $output .= str_repeat( $tree_indent, $indent_level ) . $comment . "\n"; + break; + } + break; + default: + // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export + $serialized_token_type = var_export( $processor->get_token_type(), true ); + throw new Error( "Unhandled token type for tree construction: {$serialized_token_type}" ); + } + } + + if ( null !== $processor->get_unsupported_exception() ) { + throw $processor->get_unsupported_exception(); + } + + if ( null !== $processor->get_last_error() ) { + throw new Error( "Parser error: {$processor->get_last_error()}" ); + } + + if ( $processor->paused_at_incomplete_token() ) { + throw new Error( 'Paused at incomplete token.' ); + } + + if ( '' !== $text_node ) { + $output .= "{$text_node}\"\n"; + } + + return $output; +} diff --git a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php index 262c6c4640..2c1872795f 100644 --- a/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php +++ b/tests/phpunit/includes/factory/class-wp-unittest-factory-for-attachment.php @@ -50,12 +50,13 @@ class WP_UnitTest_Factory_For_Attachment extends WP_UnitTest_Factory_For_Post { } /** - * Saves an attachment. + * Saves a file as an attachment. * * @since 4.4.0 * @since 6.2.0 Returns a WP_Error object on failure. * - * @param string $file The file name to create attachment object for. + * @param string $file Full path to the file to create an attachment object for. + * The name of the file will be used as the attachment name. * @param int $parent_post_id ID of the post to attach the file to. * * @return int|WP_Error The attachment ID on success, WP_Error object on failure. diff --git a/tests/phpunit/tests/build-visual-html-tree.php b/tests/phpunit/tests/build-visual-html-tree.php new file mode 100644 index 0000000000..42e35c5b74 --- /dev/null +++ b/tests/phpunit/tests/build-visual-html-tree.php @@ -0,0 +1,144 @@ +<?php + +/** + * Tests for build_visual_html_tree(). + * + * @package WordPress + * + * @group testsuite + */ +class Tests_Build_Equivalent_HTML_Semantic_Tree extends WP_UnitTestCase { + public function data_build_equivalent_html_semantic_tree() { + $block_markup = <<<END + <!-- wp:separator {"className":"is-style-default has-custom-classname","style":{"spacing":{"margin":{"top":"50px","bottom":"50px"}}},"backgroundColor":"accent-1"} --> + <hr class="wp-block-separator is-style-default has-custom-classname" style="margin-top: 50px; margin-bottom: 50px" /> + <!-- /wp:separator --> +END; + + $tree_structure = <<<END +BLOCK["core/separator"] + { + "backgroundColor": "accent-1", + "className": "has-custom-classname is-style-default", + "style": { + "spacing": { + "margin": { + "top": "50px", + "bottom": "50px" + } + } + } + } + <hr> + class="has-custom-classname is-style-default wp-block-separator" + style="margin-top:50px;margin-bottom:50px;" + +END; + + return array( + 'Block delimiter' => array( $block_markup, $tree_structure ), + ); + } + + /** + * @ticket 63527 + * + * @covers ::build_visual_html_tree + * + * @dataProvider data_build_equivalent_html_semantic_tree + */ + public function test_build_equivalent_html_semantic_tree( $markup, $expected ) { + $actual = build_visual_html_tree( $markup, '<body>' ); + $this->assertSame( $expected, $actual ); + } + + public function data_build_equivalent_html_semantic_tree_with_equivalent_html() { + return array( + 'Different attribute order' => array( + '<img src="wp.png" alt="The WordPress logo">', + '<img alt="The WordPress logo" src="wp.png">', + ), + 'Different class name order' => array( + '<hr class="wp-block-separator is-style-default">', + '<hr class="is-style-default wp-block-separator">', + ), + 'Differences in style attribute whitespace and trailing semicolon' => array( + '<hr style="margin-top: 50px; margin-bottom: 50px;">', + '<hr style="margin-top:50px;margin-bottom: 50px">', + ), + 'Different block attribute order' => array( + '<!-- wp:separator {"className":"is-style-default","backgroundColor":"accent-1"} -->', + '<!-- wp:separator {"backgroundColor":"accent-1","className":"is-style-default"} -->', + ), + 'Different block class name order' => array( + '<!-- wp:separator {"className":"is-style-default has-custom-classname"} -->', + '<!-- wp:separator {"className":"has-custom-classname is-style-default"} -->', + ), + 'Different whitespace in block class name' => array( + '<!-- wp:separator {"className":"wp-block-separator is-style-default"} -->', + '<!-- wp:separator {"className":"wp-block-separator is-style-default "} -->', + ), + 'Duplicated block class names' => array( + '<!-- wp:separator {"className":"wp-block-separator is-style-default"} -->', + '<!-- wp:separator {"className":"wp-block-separator is-style-default wp-block-separator"} -->', + ), + 'Different Capitalization of tag' => array( + '<IMG src="wp.png" alt="The WordPress logo">', + '<img src="wp.png" alt="The WordPress logo">', + ), + ); + } + + /** + * @ticket 63527 + * + * @covers ::build_visual_html_tree + * + * @dataProvider data_build_equivalent_html_semantic_tree_with_equivalent_html + */ + public function test_build_equivalent_html_semantic_tree_with_equivalent_html( $expected, $actual ) { + $tree_expected = build_visual_html_tree( $expected, '<body>' ); + $tree_actual = build_visual_html_tree( $actual, '<body>' ); + + $this->assertSame( $tree_expected, $tree_actual ); + } + + public function data_build_equivalent_html_semantic_tree_with_non_equivalent_html() { + return array( + 'Different attributes' => array( + '<img src="wp.png" alt="The WordPress logo">', + '<img alt="The WordPress logo" src="wp.png" title="WordPress">', + ), + 'Different class names' => array( + '<hr class="wp-block-separator is-style-default">', + '<hr class="is-style-default wp-block-hairline">', + ), + 'Different styles' => array( + '<hr style="margin-top: 50px; margin-bottom: 50px;">', + '<hr style="margin-top: 50px; margin-bottom: 100px">', + ), + 'Different comments' => array( + '<!-- abc -->', + '<!-- xyz -->', + ), + 'Semantically relevant whitespace' => array( + '<div style="color: rgb(50 139 31)">Test</div>', + '<div style="color:rgb(5013931)">Test</div>', + ), + ); + } + + /** + * @ticket 63527 + * + * @covers ::build_visual_html_tree + * + * @dataProvider data_build_equivalent_html_semantic_tree_with_non_equivalent_html + */ + public function test_build_equivalent_html_semantic_tree_with_non_equivalent_html( $expected, $actual ) { + $tree_expected = build_visual_html_tree( $expected, '<body>' ); + $tree_actual = build_visual_html_tree( $actual, '<body>' ); + + $this->assertNotSame( $tree_expected, $tree_actual ); + } +} diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 89bfb4ef92..d00c77b5a1 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -79,7 +79,7 @@ JS; $expected .= "<script type='text/javascript' src='http://example.com?ver=1.2' id='empty-deps-version-js'></script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='empty-deps-null-version-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. $this->assertSame( '', get_echo( 'wp_print_scripts' ) ); @@ -125,7 +125,7 @@ JS; 'id' => 'ms-isa-1-js-after', ) ); - $this->assertEqualMarkup( $expected, $output, 'Inline scripts in the "after" position, that are attached to a deferred main script, are failing to print/execute.' ); + $this->assertEqualHTML( $expected, $output, '<body>', 'Inline scripts in the "after" position, that are attached to a deferred main script, are failing to print/execute.' ); } /** @@ -154,7 +154,7 @@ JS; ) ); - $this->assertEqualMarkup( $expected, $output, 'Inline scripts in the "after" position, that are attached to a blocking main script, are failing to print/execute.' ); + $this->assertEqualHTML( $expected, $output, '<body>', 'Inline scripts in the "after" position, that are attached to a blocking main script, are failing to print/execute.' ); } /** @@ -187,9 +187,9 @@ JS; 'id' => 'ds-i1-1-js-before', ) ); - $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-1.js' id='ds-i1-1-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; - $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-2.js' id='ds-i1-2-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; - $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-3.js' id='ds-i1-3-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; + $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-1.js' id='ds-i1-1-js' {$strategy}='{$strategy}' data-wp-strategy='{$strategy}'></script>\n"; + $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-2.js' id='ds-i1-2-js' {$strategy}='{$strategy}' data-wp-strategy='{$strategy}'></script>\n"; + $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-3.js' id='ds-i1-3-js' {$strategy}='{$strategy}' data-wp-strategy='{$strategy}'></script>\n"; $expected .= wp_get_inline_script_tag( 'console.log("before last");', array( @@ -197,9 +197,9 @@ JS; 'type' => 'text/javascript', ) ); - $expected .= "<script type='text/javascript' src='http://example.org/ms-i1-1.js' id='ms-i1-1-js' {$strategy} data-wp-strategy='{$strategy}'></script>\n"; + $expected .= "<script type='text/javascript' src='http://example.org/ms-i1-1.js' id='ms-i1-1-js' {$strategy}='{$strategy}' data-wp-strategy='{$strategy}'></script>\n"; - $this->assertEqualMarkup( $expected, $output, 'Inline scripts in the "before" position, that are attached to a deferred main script, are failing to print/execute.' ); + $this->assertEqualHTML( $expected, $output, '<body>', 'Inline scripts in the "before" position, that are attached to a deferred main script, are failing to print/execute.' ); } /** @@ -216,8 +216,8 @@ JS; // No dependents, No dependencies then async. wp_enqueue_script( 'main-script-a1', '/main-script-a1.js', array(), null, array( 'strategy' => 'async' ) ); $output = get_echo( 'wp_print_scripts' ); - $expected = "<script type='text/javascript' src='/main-script-a1.js' id='main-script-a1-js' async data-wp-strategy='async'></script>\n"; - $this->assertEqualMarkup( $expected, $output, 'Scripts enqueued with an async loading strategy are failing to have the async attribute applied to the script handle when being printed.' ); + $expected = "<script type='text/javascript' src='/main-script-a1.js' id='main-script-a1-js' async='async' data-wp-strategy='async'></script>\n"; + $this->assertEqualHTML( $expected, $output, '<body>', 'Scripts enqueued with an async loading strategy are failing to have the async attribute applied to the script handle when being printed.' ); } /** @@ -238,9 +238,9 @@ JS; wp_enqueue_script( 'dependency-script-a2', '/dependency-script-a2.js', array(), null ); wp_enqueue_script( 'main-script-a2', '/main-script-a2.js', array( 'dependency-script-a2' ), null, compact( 'strategy' ) ); $output = get_echo( 'wp_print_scripts' ); - $expected = "<script id='dependency-script-a2-js' src='/dependency-script-a2.js'></script>\n"; - $expected .= "<script type='text/javascript' src='/main-script-a2.js' id='main-script-a2-js' {$strategy} data-wp-strategy='{$strategy}'></script>"; - $this->assertEqualMarkup( $expected, $output, 'Dependents of a blocking dependency are free to have any strategy.' ); + $expected = "<script id='dependency-script-a2-js' src='/dependency-script-a2.js' type='text/javascript'></script>\n"; + $expected .= "<script type='text/javascript' src='/main-script-a2.js' id='main-script-a2-js' {$strategy}='{$strategy}' data-wp-strategy='{$strategy}'></script>"; + $this->assertEqualHTML( $expected, $output, '<body>', 'Dependents of a blocking dependency are free to have any strategy.' ); } /** @@ -264,7 +264,7 @@ JS; <script type='text/javascript' src='/main-script-a3.js' id='main-script-a3-js' data-wp-strategy='{$strategy}'></script> <script id="dependent-script-a3-js" src="/dependent-script-a3.js" type="text/javascript"></script> JS; - $this->assertEqualMarkup( $expected, $output, 'Blocking dependents must force delayed dependencies to become blocking.' ); + $this->assertEqualHTML( $expected, $output, '<body>', 'Blocking dependents must force delayed dependencies to become blocking.' ); } /** @@ -511,18 +511,26 @@ JS; }, 'expected_markup' => <<<HTML <script id="blocking-not-async-without-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-not-async-without-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-not-async-without-dependency:%20script' id='blocking-not-async-without-dependency-js'></script> <script id="blocking-not-async-without-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-not-async-without-dependency: after inline" ) +/* ]]> */ </script> <script id="async-with-blocking-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-blocking-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-blocking-dependency:%20script' id='async-with-blocking-dependency-js' data-wp-strategy='async'></script> <script id="async-with-blocking-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-blocking-dependency: after inline" ) +/* ]]> */ </script> HTML , @@ -548,25 +556,37 @@ HTML }, 'expected_markup' => <<<HTML <script id="async-no-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-no-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-no-dependency:%20script' id='async-no-dependency-js' data-wp-strategy='async'></script> <script id="async-no-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-no-dependency: after inline" ) +/* ]]> */ </script> <script id="async-one-async-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-one-async-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-one-async-dependency:%20script' id='async-one-async-dependency-js' data-wp-strategy='async'></script> <script id="async-one-async-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-one-async-dependency: after inline" ) +/* ]]> */ </script> <script id="async-two-async-dependencies-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-two-async-dependencies: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-two-async-dependencies:%20script' id='async-two-async-dependencies-js' data-wp-strategy='async'></script> <script id="async-two-async-dependencies-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-two-async-dependencies: after inline" ) +/* ]]> */ </script> HTML , @@ -584,18 +604,26 @@ HTML }, 'expected_markup' => <<<HTML <script id="async-with-blocking-dependent-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-blocking-dependent: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-blocking-dependent:%20script' id='async-with-blocking-dependent-js' data-wp-strategy='async'></script> <script id="async-with-blocking-dependent-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-blocking-dependent: after inline" ) +/* ]]> */ </script> <script id="blocking-dependent-of-async-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependent-of-async: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependent-of-async:%20script' id='blocking-dependent-of-async-js'></script> <script id="blocking-dependent-of-async-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependent-of-async: after inline" ) +/* ]]> */ </script> HTML , @@ -613,18 +641,26 @@ HTML }, 'expected_markup' => <<<HTML <script id="async-with-defer-dependent-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-defer-dependent: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-defer-dependent:%20script' id='async-with-defer-dependent-js' data-wp-strategy='async'></script> <script id="async-with-defer-dependent-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-with-defer-dependent: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-async-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-async: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-async:%20script' id='defer-dependent-of-async-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-async-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-async: after inline" ) +/* ]]> */ </script> HTML , @@ -645,17 +681,25 @@ HTML }, 'expected_markup' => <<<HTML <script id="blocking-bundle-of-none-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-of-none: before inline" ) +/* ]]> */ </script> <script id="blocking-bundle-of-none-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-of-none: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-blocking-bundle-of-none-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-none: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-bundle-of-none:%20script' id='defer-dependent-of-blocking-bundle-of-none-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-blocking-bundle-of-none-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-none: after inline" ) +/* ]]> */ </script> HTML , @@ -679,25 +723,37 @@ HTML }, 'expected_markup' => <<<HTML <script id="blocking-bundle-member-one-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-member-one: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-bundle-member-one:%20script' id='blocking-bundle-member-one-js'></script> <script id="blocking-bundle-member-one-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-member-one: after inline" ) +/* ]]> */ </script> <script id="blocking-bundle-member-two-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-member-two: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-bundle-member-two:%20script' id='blocking-bundle-member-two-js'></script> <script id="blocking-bundle-member-two-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-bundle-member-two: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-blocking-bundle-of-two-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-two: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-bundle-of-two:%20script' id='defer-dependent-of-blocking-bundle-of-two-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-blocking-bundle-of-two-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-two: after inline" ) +/* ]]> */ </script> HTML , @@ -720,17 +776,25 @@ HTML }, 'expected_markup' => <<<HTML <script id="defer-bundle-of-none-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-bundle-of-none: before inline" ) +/* ]]> */ </script> <script id="defer-bundle-of-none-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-bundle-of-none: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-defer-bundle-of-none-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-defer-bundle-of-none: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-defer-bundle-of-none:%20script' id='defer-dependent-of-defer-bundle-of-none-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-defer-bundle-of-none-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-defer-bundle-of-none: after inline" ) +/* ]]> */ </script> HTML , @@ -751,25 +815,37 @@ HTML }, 'expected_markup' => <<<HTML <script id="blocking-dependency-with-defer-following-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependency-with-defer-following-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependency-with-defer-following-dependency:%20script' id='blocking-dependency-with-defer-following-dependency-js'></script> <script id="blocking-dependency-with-defer-following-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependency-with-defer-following-dependency: after inline" ) +/* ]]> */ </script> <script id="defer-dependency-with-blocking-preceding-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependency-with-blocking-preceding-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependency-with-blocking-preceding-dependency:%20script' id='defer-dependency-with-blocking-preceding-dependency-js' data-wp-strategy='defer'></script> <script id="defer-dependency-with-blocking-preceding-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependency-with-blocking-preceding-dependency: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-blocking-and-defer-dependencies-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-and-defer-dependencies: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-and-defer-dependencies:%20script' id='defer-dependent-of-blocking-and-defer-dependencies-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-blocking-and-defer-dependencies-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-blocking-and-defer-dependencies: after inline" ) +/* ]]> */ </script> HTML , @@ -790,25 +866,37 @@ HTML }, 'expected_markup' => <<<HTML <script id="defer-dependency-with-blocking-following-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependency-with-blocking-following-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependency-with-blocking-following-dependency:%20script' id='defer-dependency-with-blocking-following-dependency-js' data-wp-strategy='defer'></script> <script id="defer-dependency-with-blocking-following-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependency-with-blocking-following-dependency: after inline" ) +/* ]]> */ </script> <script id="blocking-dependency-with-defer-preceding-dependency-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependency-with-defer-preceding-dependency: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependency-with-defer-preceding-dependency:%20script' id='blocking-dependency-with-defer-preceding-dependency-js'></script> <script id="blocking-dependency-with-defer-preceding-dependency-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "blocking-dependency-with-defer-preceding-dependency: after inline" ) +/* ]]> */ </script> <script id="defer-dependent-of-defer-and-blocking-dependencies-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-defer-and-blocking-dependencies: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-defer-and-blocking-dependencies:%20script' id='defer-dependent-of-defer-and-blocking-dependencies-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-defer-and-blocking-dependencies-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-defer-and-blocking-dependencies: after inline" ) +/* ]]> */ </script> HTML , @@ -826,18 +914,26 @@ HTML }, 'expected_markup' => <<<HTML <script id="defer-with-async-dependent-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-with-async-dependent: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-async-dependent:%20script' id='defer-with-async-dependent-js' data-wp-strategy='defer'></script> <script id="defer-with-async-dependent-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-with-async-dependent: after inline" ) +/* ]]> */ </script> <script id="async-dependent-of-defer-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-dependent-of-defer: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-dependent-of-defer:%20script' id='async-dependent-of-defer-js' data-wp-strategy='async'></script> <script id="async-dependent-of-defer-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "async-dependent-of-defer: after inline" ) +/* ]]> */ </script> HTML , @@ -851,9 +947,11 @@ HTML }, 'expected_markup' => <<<HTML <script id="defer-with-before-inline-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-with-before-inline: before inline" ) +/* ]]> */ </script> -<script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-before-inline:%20script' id='defer-with-before-inline-js' defer data-wp-strategy='defer'></script> +<script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-before-inline:%20script' id='defer-with-before-inline-js' defer='defer' data-wp-strategy='defer'></script> HTML , ), @@ -867,7 +965,9 @@ HTML 'expected_markup' => <<<HTML <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-after-inline:%20script' id='defer-with-after-inline-js' data-wp-strategy='defer'></script> <script id="defer-with-after-inline-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-with-after-inline: after inline" ) +/* ]]> */ </script> HTML , @@ -883,9 +983,9 @@ HTML wp_enqueue_script( 'theme-functions', 'https://example.com/theme-functions.js', array( 'jquery' ), null, array( 'strategy' => 'defer' ) ); }, 'expected_markup' => <<<HTML -<script type='text/javascript' src='http://$wp_tests_domain/wp-includes/js/jquery/jquery.js' id='jquery-core-js' defer data-wp-strategy='defer'></script> -<script type='text/javascript' src='http://$wp_tests_domain/wp-includes/js/jquery/jquery-migrate.js' id='jquery-migrate-js' defer data-wp-strategy='defer'></script> -<script type='text/javascript' src='https://example.com/theme-functions.js' id='theme-functions-js' defer data-wp-strategy='defer'></script> +<script type='text/javascript' src='http://$wp_tests_domain/wp-includes/js/jquery/jquery.js' id='jquery-core-js' defer='defer' data-wp-strategy='defer'></script> +<script type='text/javascript' src='http://$wp_tests_domain/wp-includes/js/jquery/jquery-migrate.js' id='jquery-migrate-js' defer='defer' data-wp-strategy='defer'></script> +<script type='text/javascript' src='https://example.com/theme-functions.js' id='theme-functions-js' defer='defer' data-wp-strategy='defer'></script> HTML , ), @@ -912,11 +1012,15 @@ HTML <script type='text/javascript' src='https://example.com/external.js?script_event_log=inner-bundle-member-two:%20script' id='inner-bundle-member-two-js' data-wp-strategy='defer'></script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=outer-bundle-leaf-member:%20script' id='outer-bundle-leaf-member-js'></script> <script id="defer-dependent-of-nested-aliases-js-before" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-nested-aliases: before inline" ) +/* ]]> */ </script> <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-nested-aliases:%20script' id='defer-dependent-of-nested-aliases-js' data-wp-strategy='defer'></script> <script id="defer-dependent-of-nested-aliases-js-after" type="text/javascript"> +/* <![CDATA[ */ scriptEventLog.push( "defer-dependent-of-nested-aliases: after inline" ) +/* ]]> */ </script> HTML , @@ -935,9 +1039,9 @@ HTML $this->enqueue_test_script( 'defer-dependent-of-async-aliases', 'defer', array( $alias_handle ) ); }, 'expected_markup' => <<<HTML -<script type='text/javascript' src='https://example.com/external.js?script_event_log=async1:%20script' id='async1-js' defer data-wp-strategy='async'></script> -<script type='text/javascript' src='https://example.com/external.js?script_event_log=async2:%20script' id='async2-js' defer data-wp-strategy='async'></script> -<script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-async-aliases:%20script' id='defer-dependent-of-async-aliases-js' defer data-wp-strategy='defer'></script> +<script type='text/javascript' src='https://example.com/external.js?script_event_log=async1:%20script' id='async1-js' defer='defer' data-wp-strategy='async'></script> +<script type='text/javascript' src='https://example.com/external.js?script_event_log=async2:%20script' id='async2-js' defer='defer' data-wp-strategy='async'></script> +<script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-async-aliases:%20script' id='defer-dependent-of-async-aliases-js' defer='defer' data-wp-strategy='defer'></script> HTML , ), @@ -960,7 +1064,7 @@ HTML public function test_various_strategy_dependency_chains( $set_up, $expected_markup ) { $set_up(); $actual_markup = get_echo( 'wp_print_scripts' ); - $this->assertEqualMarkup( trim( $expected_markup ), trim( $actual_markup ), "Actual markup:\n{$actual_markup}" ); + $this->assertEqualHTML( trim( $expected_markup ), trim( $actual_markup ), '<body>', "Actual markup:\n{$actual_markup}" ); } /** @@ -1036,12 +1140,12 @@ HTML wp_enqueue_script( 'dependent-script-d4-2', '/dependent-script-d4-2.js', array( 'dependent-script-d4-1' ), null, array( 'strategy' => 'async' ) ); wp_enqueue_script( 'dependent-script-d4-3', '/dependent-script-d4-3.js', array( 'dependent-script-d4-2' ), null, array( 'strategy' => 'defer' ) ); $output = get_echo( 'wp_print_scripts' ); - $expected = "<script type='text/javascript' src='/main-script-d4.js' id='main-script-d4-js' defer data-wp-strategy='defer'></script>\n"; - $expected .= "<script type='text/javascript' src='/dependent-script-d4-1.js' id='dependent-script-d4-1-js' defer data-wp-strategy='defer'></script>\n"; - $expected .= "<script type='text/javascript' src='/dependent-script-d4-2.js' id='dependent-script-d4-2-js' defer data-wp-strategy='async'></script>\n"; - $expected .= "<script type='text/javascript' src='/dependent-script-d4-3.js' id='dependent-script-d4-3-js' defer data-wp-strategy='defer'></script>\n"; + $expected = "<script type='text/javascript' src='/main-script-d4.js' id='main-script-d4-js' defer='defer' data-wp-strategy='defer'></script>\n"; + $expected .= "<script type='text/javascript' src='/dependent-script-d4-1.js' id='dependent-script-d4-1-js' defer='defer' data-wp-strategy='defer'></script>\n"; + $expected .= "<script type='text/javascript' src='/dependent-script-d4-2.js' id='dependent-script-d4-2-js' defer='defer' data-wp-strategy='async'></script>\n"; + $expected .= "<script type='text/javascript' src='/dependent-script-d4-3.js' id='dependent-script-d4-3-js' defer='defer' data-wp-strategy='defer'></script>\n"; - $this->assertEqualMarkup( $expected, $output, 'Scripts registered as defer but that have dependents that are async are expected to have said dependents deferred.' ); + $this->assertEqualHTML( $expected, $output, '<body>', 'Scripts registered as defer but that have dependents that are async are expected to have said dependents deferred.' ); } /** @@ -1113,7 +1217,7 @@ HTML $expected_header .= "<script type='text/javascript' src='/enqueue-header-old.js' id='enqueue-header-old-js'></script>\n"; $expected_header .= "<script type='text/javascript' src='/enqueue-header-new.js' id='enqueue-header-new-js'></script>\n"; - $this->assertEqualMarkup( $expected_header, $actual_header, 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); + $this->assertEqualHTML( $expected_header, $actual_header, '<body>', 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); $this->assertEmpty( $actual_footer, 'Expected footer to be empty since all scripts were for head.' ); } @@ -1141,7 +1245,7 @@ HTML $expected_footer .= "<script type='text/javascript' src='/enqueue-footer-new.js' id='enqueue-footer-new-js'></script>\n"; $this->assertEmpty( $actual_header, 'Expected header to be empty since all scripts targeted footer.' ); - $this->assertEqualMarkup( $expected_footer, $actual_footer, 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); + $this->assertEqualHTML( $expected_footer, $actual_footer, '<body>', 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); } /** @@ -1260,7 +1364,7 @@ HTML wp_register_script( 'invalid-strategy', '/defaults.js', array(), null, array( 'strategy' => 'random-strategy' ) ); wp_enqueue_script( 'invalid-strategy' ); - $this->assertEqualMarkup( + $this->assertEqualHTML( "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", get_echo( 'wp_print_scripts' ) ); @@ -1285,7 +1389,7 @@ HTML wp_script_add_data( 'invalid-strategy', 'strategy', 'random-strategy' ); wp_enqueue_script( 'invalid-strategy' ); - $this->assertEqualMarkup( + $this->assertEqualHTML( "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", get_echo( 'wp_print_scripts' ) ); @@ -1306,7 +1410,7 @@ HTML public function test_script_strategy_doing_it_wrong_via_enqueue() { wp_enqueue_script( 'invalid-strategy', '/defaults.js', array(), null, array( 'strategy' => 'random-strategy' ) ); - $this->assertEqualMarkup( + $this->assertEqualHTML( "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", get_echo( 'wp_print_scripts' ) ); @@ -1342,9 +1446,9 @@ HTML $concatenate_scripts = $old_value; $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep,two-concat-dep,three-concat-dep&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' src='/main-script.js' id='main-defer-script-js' defer data-wp-strategy='defer'></script>\n"; + $expected .= "<script type='text/javascript' src='/main-script.js' id='main-defer-script-js' defer='defer' data-wp-strategy='defer'></script>\n"; - $this->assertEqualMarkup( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered with a "defer" loading strategy. Deferred scripts should not be part of the script concat loading query.' ); + $this->assertEqualHTML( $expected, $print_scripts, '<body>', 'Scripts are being incorrectly concatenated when a main script is registered with a "defer" loading strategy. Deferred scripts should not be part of the script concat loading query.' ); } /** @@ -1377,9 +1481,9 @@ HTML $concatenate_scripts = $old_value; $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep-1,two-concat-dep-1,three-concat-dep-1&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' src='/main-script.js' id='main-async-script-1-js' async data-wp-strategy='async'></script>\n"; + $expected .= "<script type='text/javascript' src='/main-script.js' id='main-async-script-1-js' async='async' data-wp-strategy='async'></script>\n"; - $this->assertEqualMarkup( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered with an "async" loading strategy. Async scripts should not be part of the script concat loading query.' ); + $this->assertEqualHTML( $expected, $print_scripts, '<body>', 'Scripts are being incorrectly concatenated when a main script is registered with an "async" loading strategy. Async scripts should not be part of the script concat loading query.' ); } /** @@ -1416,9 +1520,9 @@ HTML $concatenate_scripts = $old_value; $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep-2,two-concat-dep-2,three-concat-dep-2,four-concat-dep-2,five-concat-dep-2,six-concat-dep-2&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' src='/main-script.js' id='deferred-script-2-js' defer data-wp-strategy='defer'></script>\n"; + $expected .= "<script type='text/javascript' src='/main-script.js' id='deferred-script-2-js' defer='defer' data-wp-strategy='defer'></script>\n"; - $this->assertEqualMarkup( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered as deferred after other blocking scripts are registered. Deferred scripts should not be part of the script concat loader query string. ' ); + $this->assertEqualHTML( $expected, $print_scripts, '<body>', 'Scripts are being incorrectly concatenated when a main script is registered as deferred after other blocking scripts are registered. Deferred scripts should not be part of the script concat loader query string. ' ); } /** @@ -1427,6 +1531,8 @@ HTML public function test_wp_enqueue_script_with_html5_support_does_not_contain_type_attribute() { global $wp_version; + $this->add_html5_script_theme_support(); + $GLOBALS['wp_scripts'] = new WP_Scripts(); $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' ); @@ -1434,7 +1540,7 @@ HTML $expected = "<script src='http://example.com?ver={$wp_version}' id='empty-deps-no-version-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1473,7 +1579,7 @@ HTML $expected .= "<script type='text/javascript' src='{$wp_scripts->base_url}ftp://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver={$wp_version}' id='jquery-ftp-js'></script>\n"; // Go! - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. $this->assertSame( '', get_echo( 'wp_print_scripts' ) ); @@ -1516,7 +1622,7 @@ HTML $expected .= "<script type='text/javascript' src='http://example.com' id='test-only-data-js'></script>\n"; // Go! - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. $this->assertSame( '', get_echo( 'wp_print_scripts' ) ); @@ -1531,10 +1637,10 @@ HTML // Enqueue and add conditional comments. wp_enqueue_script( 'test-only-conditional', 'example.com', array(), null ); wp_script_add_data( 'test-only-conditional', 'conditional', 'gt IE 7' ); - $expected = "<!--[if gt IE 7]>\n<script type='text/javascript' src='http://example.com' id='test-only-conditional-js'></script>\n<![endif]-->\n"; + $expected = "<!--[if gt IE 7]>\n<script type=\"text/javascript\" src=\"http://example.com\" id=\"test-only-conditional-js\"></script>\n<![endif]-->\n"; // Go! - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. $this->assertSame( '', get_echo( 'wp_print_scripts' ) ); @@ -1555,7 +1661,7 @@ HTML $expected = str_replace( "'", '"', $expected ); // Go! - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. $this->assertSame( '', get_echo( 'wp_print_scripts' ) ); @@ -1573,10 +1679,10 @@ HTML $expected = "<script type='text/javascript' src='http://example.com' id='test-invalid-js'></script>\n"; // Go! - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); // No scripts left to print. - $this->assertEqualMarkup( '', get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( '', get_echo( 'wp_print_scripts' ) ); } /** @@ -1602,7 +1708,7 @@ HTML wp_enqueue_script( 'handle-three' ); - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1690,8 +1796,8 @@ HTML $expected_header .= "<script type='text/javascript' src='/child-head.js' id='child-head-js'></script>\n"; $expected_footer = "<script type='text/javascript' src='/parent.js' id='parent-js'></script>\n"; - $this->assertEqualMarkup( $expected_header, $header, 'Expected same header markup.' ); - $this->assertEqualMarkup( $expected_footer, $footer, 'Expected same footer markup.' ); + $this->assertEqualHTML( $expected_header, $header, '<body>', 'Expected same header markup.' ); + $this->assertEqualHTML( $expected_footer, $footer, '<body>', 'Expected same footer markup.' ); } /** @@ -1711,8 +1817,8 @@ HTML $expected_footer = "<script type='text/javascript' src='/child-footer.js' id='child-footer-js'></script>\n"; $expected_footer .= "<script type='text/javascript' src='/parent.js' id='parent-js'></script>\n"; - $this->assertEqualMarkup( $expected_header, $header, 'Expected same header markup.' ); - $this->assertEqualMarkup( $expected_footer, $footer, 'Expected same footer markup.' ); + $this->assertEqualHTML( $expected_header, $header, '<body>', 'Expected same header markup.' ); + $this->assertEqualHTML( $expected_footer, $footer, '<body>', 'Expected same footer markup.' ); } /** @@ -1742,8 +1848,8 @@ HTML $expected_footer .= "<script type='text/javascript' src='/child2-footer.js' id='child2-footer-js'></script>\n"; $expected_footer .= "<script type='text/javascript' src='/parent-footer.js' id='parent-footer-js'></script>\n"; - $this->assertEqualMarkup( $expected_header, $header, 'Expected same header markup.' ); - $this->assertEqualMarkup( $expected_footer, $footer, 'Expected same footer markup.' ); + $this->assertEqualHTML( $expected_header, $header, '<body>', 'Expected same header markup.' ); + $this->assertEqualHTML( $expected_footer, $footer, '<body>', 'Expected same footer markup.' ); } /** @@ -1770,10 +1876,16 @@ HTML wp_enqueue_script( 'test-example', 'example.com', array(), null ); wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); - $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected = <<<HTML +<script type='text/javascript' id='test-example-js-before'> +/* <![CDATA[ */ +console.log("before"); +/* ]]> */ +</script> +HTML; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1784,9 +1896,15 @@ HTML wp_add_inline_script( 'test-example', 'console.log("after");' ); $expected = "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= <<<HTML +<script type='text/javascript' id='test-example-js-after'> +/* <![CDATA[ */ +console.log("after"); +/* ]]> */ +</script> +HTML; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1797,11 +1915,11 @@ HTML wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected = "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1812,9 +1930,9 @@ HTML wp_enqueue_script( 'test-example' ); wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); - $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected = "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1825,9 +1943,9 @@ HTML wp_enqueue_script( 'test-example' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected = "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1839,10 +1957,10 @@ HTML wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected = "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1855,11 +1973,11 @@ HTML wp_add_inline_script( 'test-example', 'console.log("after");' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\nconsole.log(\"before\");\n</script>\n"; + $expected = "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1872,11 +1990,11 @@ HTML wp_add_inline_script( 'test-example', 'console.log("after");' ); $expected = "<script type='text/javascript' id='test-example-js-extra'>\n/* <![CDATA[ */\nvar testExample = {\"foo\":\"bar\"};\n/* ]]> */\n</script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1895,13 +2013,13 @@ HTML wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); wp_add_inline_script( 'two', 'console.log("before two");', 'before' ); - $expected = "<script type='text/javascript' id='one-js-before'>\nconsole.log(\"before one\");\n</script>\n"; + $expected = "<script type='text/javascript' id='one-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before one\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}one.js?ver={$wp_version}' id='one-js'></script>\n"; - $expected .= "<script type='text/javascript' id='two-js-before'>\nconsole.log(\"before two\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='two-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before two\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1919,12 +2037,12 @@ HTML wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); - $expected = "<script type='text/javascript' id='one-js-before'>\nconsole.log(\"before one\");\n</script>\n"; + $expected = "<script type='text/javascript' id='one-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before one\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}one.js?ver={$wp_version}' id='one-js'></script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1946,12 +2064,12 @@ HTML $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one&ver={$wp_version}'></script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; - $expected .= "<script type='text/javascript' id='two-js-after'>\nconsole.log(\"after two\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='two-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after two\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; - $expected .= "<script type='text/javascript' id='three-js-after'>\nconsole.log(\"after three\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='three-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after three\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}four.js?ver={$wp_version}' id='four-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -1969,9 +2087,9 @@ HTML $expected_localized = str_replace( "'", '"', $expected_localized ); $expected = "<!--[if gte IE 9]>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; $expected .= "<![endif]-->\n"; $expected = str_replace( "'", '"', $expected ); @@ -1982,7 +2100,7 @@ HTML wp_script_add_data( 'test-example', 'conditional', 'gte IE 9' ); $this->assertSame( $expected_localized, get_echo( 'wp_print_scripts' ) ); - $this->assertEqualMarkup( $expected, $wp_scripts->print_html ); + $this->assertEqualHTML( $expected, $wp_scripts->print_html ); $this->assertTrue( $wp_scripts->do_concat ); } @@ -1999,7 +2117,7 @@ HTML $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); wp_add_inline_script( 'test-example', 'console.log("after");' ); @@ -2007,7 +2125,7 @@ HTML wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); - $this->assertEqualMarkup( $expected, $print_scripts ); + $this->assertEqualHTML( $expected, $print_scripts ); } /** @@ -2023,8 +2141,8 @@ HTML $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; $expected .= "<!--[if gte IE 9]>\n"; - $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type=\"text/javascript\" src=\"http://example.com\" id=\"test-example-js\"></script>\n"; + $expected .= "<script type=\"text/javascript\" id=\"test-example-js-after\">\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; $expected .= "<![endif]-->\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); @@ -2034,7 +2152,7 @@ HTML wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); - $this->assertEqualMarkup( $expected, $print_scripts ); + $this->assertEqualHTML( $expected, $print_scripts ); } /** @@ -2050,7 +2168,7 @@ HTML $wp_scripts->do_concat = true; $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); @@ -2059,7 +2177,7 @@ HTML wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); - $this->assertEqualMarkup( $expected, $print_scripts ); + $this->assertEqualHTML( $expected, $print_scripts ); } /** @@ -2075,15 +2193,17 @@ HTML $wp_scripts->do_concat = true; $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate,wp-dom-ready,wp-hooks&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/dist/i18n.min.js' id='wp-i18n-js'></script>\n"; $expected .= "<script type='text/javascript' id='wp-i18n-js-after'>\n"; + $expected .= "/* <![CDATA[ */\n"; $expected .= "wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );\n"; + $expected .= "/* ]]> */\n"; $expected .= "</script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/dist/a11y.min.js' id='wp-a11y-js'></script>\n"; $expected .= "<script type='text/javascript' src='http://example2.com' id='test-example2-js'></script>\n"; - $expected .= "<script type='text/javascript' id='test-example2-js-after'>\nconsole.log(\"after\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='test-example2-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after\");\n/* ]]> */\n</script>\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); @@ -2109,7 +2229,7 @@ HTML $print_scripts // Printed scripts. ); - $this->assertEqualMarkup( $expected, $print_scripts ); + $this->assertEqualHTML( $expected, $print_scripts ); } /** @@ -2126,7 +2246,9 @@ HTML $expected_tail = "<script type='text/javascript' src='/customize-dependency.js' id='customize-dependency-js'></script>\n"; $expected_tail .= "<script type='text/javascript' id='customize-dependency-js-after'>\n"; + $expected_tail .= "/* <![CDATA[ */\n"; $expected_tail .= "tryCustomizeDependency()\n"; + $expected_tail .= "/* ]]> */\n"; $expected_tail .= "</script>\n"; $handle = 'customize-dependency'; @@ -2142,7 +2264,7 @@ HTML $tail = substr( $print_scripts, strrpos( $print_scripts, '<script type="text/javascript" src="/customize-dependency.js" id="customize-dependency-js">' ) ); - $this->assertEqualMarkup( $expected_tail, $tail ); + $this->assertEqualHTML( $expected_tail, $tail ); } /** @@ -2161,12 +2283,12 @@ HTML wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); $expected = "<script type='text/javascript' src='/wp-includes/js/script.js?ver={$wp_version}' id='one-js'></script>\n"; - $expected .= "<script type='text/javascript' id='one-js-after'>\nconsole.log(\"after one\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='one-js-after'>\n/* <![CDATA[ */\nconsole.log(\"after one\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script2.js?ver={$wp_version}' id='two-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$wp_version}' id='three-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$wp_version}' id='four-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2185,11 +2307,11 @@ HTML wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one,two&ver={$wp_version}'></script>\n"; - $expected .= "<script type='text/javascript' id='three-js-before'>\nconsole.log(\"before three\");\n</script>\n"; + $expected .= "<script type='text/javascript' id='three-js-before'>\n/* <![CDATA[ */\nconsole.log(\"before three\");\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$wp_version}' id='three-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$wp_version}' id='four-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2206,7 +2328,7 @@ HTML ), 'delayed' => false, 'expected_data' => '/*before foo 1*/', - 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/*before foo 1*/\n</script>\n", + 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/* <![CDATA[ */\n/*before foo 1*/\n/* ]]> */\n</script>\n", ), 'after-blocking' => array( 'position' => 'after', @@ -2216,7 +2338,7 @@ HTML ), 'delayed' => false, 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", - 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/*after foo 1*/\n/*after foo 2*/\n</script>\n", + 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/* <![CDATA[ */\n/*after foo 1*/\n/*after foo 2*/\n/* ]]> */\n</script>\n", ), 'before-delayed' => array( 'position' => 'before', @@ -2225,7 +2347,7 @@ HTML ), 'delayed' => true, 'expected_data' => '/*before foo 1*/', - 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/*before foo 1*/\n</script>\n", + 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/* <![CDATA[ */\n/*before foo 1*/\n/* ]]> */\n</script>\n", ), 'after-delayed' => array( 'position' => 'after', @@ -2235,7 +2357,7 @@ HTML ), 'delayed' => true, 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", - 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/*after foo 1*/\n/*after foo 2*/\n</script>\n", + 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/* <![CDATA[ */\n/*after foo 1*/\n/*after foo 2*/\n/* ]]> */\n</script>\n", ), ); } @@ -2287,13 +2409,13 @@ HTML $this->assertSame( $expected_data, $wp_scripts->get_inline_script_data( $handle, $position ) ); $this->assertSame( $expected_data, $wp_scripts->print_inline_script( $handle, $position, false ) ); - $this->assertEqualMarkup( + $this->assertEqualHTML( $expected_tag, $wp_scripts->get_inline_script_tag( $handle, $position ) ); ob_start(); $output = $wp_scripts->print_inline_script( $handle, $position, true ); - $this->assertEqualMarkup( $expected_tag, ob_get_clean() ); + $this->assertEqualHTML( $expected_tag, ob_get_clean() ); $this->assertEquals( $expected_data, $output ); } @@ -2321,7 +2443,7 @@ HTML ); $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2348,7 +2470,7 @@ HTML ); $expected .= "<script type='text/javascript' src='/wp-content/plugins/my-plugin/js/script.js' id='plugin-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2375,7 +2497,7 @@ HTML ); $expected .= "<script type='text/javascript' src='/wp-content/themes/my-theme/js/script.js' id='theme-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2402,7 +2524,7 @@ HTML ); $expected .= "<script type='text/javascript' src='/wp-admin/js/script.js' id='script-handle-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2432,7 +2554,7 @@ HTML $expected = "<script type='text/javascript' src='/wp-includes/js/dist/wp-i18n.js' id='wp-i18n-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-admin/js/script.js' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2461,7 +2583,7 @@ HTML ); $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2491,7 +2613,7 @@ HTML $expected .= "<script type='text/javascript' src='/wp-includes/js/script.js' id='test-dependency-js'></script>\n"; $expected .= "<script type='text/javascript' src='/wp-includes/js/script2.js' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2880,7 +3002,7 @@ HTML $expected = "<script type='text/javascript' id='test-example-js-extra'>\n/* <![CDATA[ */\nvar testExample = {$expected};\n/* ]]> */\n</script>\n"; $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; - $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } /** @@ -2945,7 +3067,7 @@ HTML $expected .= "<script type='text/javascript' src='/plugins/wp-i18n.js' id='wp-i18n-js'></script>\n"; $expected .= "<script type='text/javascript' src='/default/common.js' id='common-js'></script>\n"; - $this->assertEqualMarkup( $expected, $print_scripts ); + $this->assertEqualHTML( $expected, $print_scripts ); } /** @@ -2981,87 +3103,6 @@ HTML } /** - * Parse an HTML markup fragment. - * - * @param string $markup Markup. - * @return DOMDocument Document containing the normalized markup fragment. - */ - protected function parse_markup_fragment( $markup ) { - $dom = new DOMDocument(); - $dom->loadHTML( - "<!DOCTYPE html><html><head><meta charset=utf8></head><body>{$markup}</body></html>" - ); - - /** @var DOMElement $body */ - $body = $dom->getElementsByTagName( 'body' )->item( 0 ); - - // Trim whitespace nodes added before/after which can be added when parsing. - foreach ( array( $body->firstChild, $body->lastChild ) as $node ) { - if ( $node instanceof DOMText && '' === trim( $node->data ) ) { - $body->removeChild( $node ); - } - } - - // Normalize other whitespace nodes. - $xpath = new DOMXPath( $dom ); - foreach ( $xpath->query( '//text()' ) as $node ) { - /** @var DOMText $node */ - if ( preg_match( '/^\s+$/', $node->nodeValue ) ) { - $node->nodeValue = ' '; - } - } - - return $dom; - } - - /** - * Assert markup is equal after normalizing script tags. - * - * @param string $expected Expected markup. - * @param string $actual Actual markup. - * @param string $message Message. - */ - protected function assertEqualMarkup( $expected, $actual, $message = '' ) { - $expected_dom = $this->parse_markup_fragment( $expected ); - $actual_dom = $this->parse_markup_fragment( $actual ); - foreach ( array( $expected_dom, $actual_dom ) as $dom ) { - $xpath = new DOMXPath( $dom ); - /** @var DOMElement $script */ - - // Normalize type attribute. When missing, it defaults to text/javascript. - foreach ( $xpath->query( '//script[ not( @type ) ]' ) as $script ) { - $script->setAttribute( 'type', 'text/javascript' ); - } - - // Normalize script contents to remove CDATA wrapper. - foreach ( $xpath->query( '//script[ contains( text(), "<![CDATA[" ) ]' ) as $script ) { - $script->textContent = str_replace( - array( - "/* <![CDATA[ */\n", - "\n/* ]]> */", - ), - '', - $script->textContent - ); - } - - // Normalize XHTML-compatible boolean attributes to HTML5 ones. - foreach ( array( 'async', 'defer' ) as $attribute ) { - foreach ( iterator_to_array( $xpath->query( "//script[ @{$attribute} = '{$attribute}' ]" ) ) as $script ) { - $script->removeAttribute( $attribute ); - $script->setAttributeNode( $dom->createAttribute( $attribute ) ); - } - } - } - - $this->assertEquals( - $expected_dom->getElementsByTagName( 'body' )->item( 0 ), - $actual_dom->getElementsByTagName( 'body' )->item( 0 ), - $message - ); - } - - /** * Adds html5 script theme support. */ protected function add_html5_script_theme_support() { @@ -3100,8 +3141,8 @@ HTML wp_scripts()->do_footer_items(); $footer = ob_get_clean(); - $this->assertEqualMarkup( $expected_header, $header, 'Expected header script markup to match.' ); - $this->assertEqualMarkup( $expected_footer, $footer, 'Expected footer script markup to match.' ); + $this->assertEqualHTML( $expected_header, $header, '<body>', 'Expected header script markup to match.' ); + $this->assertEqualHTML( $expected_footer, $footer, '<body>', 'Expected footer script markup to match.' ); $this->assertEqualSets( $expected_in_footer, wp_scripts()->in_footer, 'Expected to have the same handles for in_footer.' ); $this->assertEquals( $expected_groups, wp_scripts()->groups, 'Expected groups to match.' ); } diff --git a/tools/local-env/scripts/install.js b/tools/local-env/scripts/install.js index ad75da48c4..3bbc30d4d8 100644 --- a/tools/local-env/scripts/install.js +++ b/tools/local-env/scripts/install.js @@ -3,7 +3,6 @@ const dotenvExpand = require( 'dotenv-expand' ); const wait_on = require( 'wait-on' ); const { execSync } = require( 'child_process' ); const { renameSync, readFileSync, writeFileSync } = require( 'fs' ); -const { utils } = require( './utils.js' ); const local_env_utils = require( './utils' ); dotenvExpand.expand( dotenv.config() ); |