From 9828bac2ecb8af3641ad7803f30a6467a27eba54 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 22 Dec 2025 13:07:31 -0800 Subject: [PATCH 01/19] Issue _doing_it_wrong() when invalid path is provided to registered style --- src/wp-includes/script-loader.php | 27 ++++++++++++++++++++- tests/phpunit/tests/dependencies/styles.php | 19 +++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 56986c3d80a79..5932dde9e7b1e 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -3081,7 +3081,18 @@ function wp_maybe_inline_styles() { $path = $wp_styles->get_data( $handle, 'path' ); if ( $path && $src ) { $size = wp_filesize( $path ); - if ( ! $size ) { + if ( 0 === $size ) { + _doing_it_wrong( + __FUNCTION__, + sprintf( + /* translators: 1: 'path', 2: filesystem path, 3: style handle */ + __( 'Unable to read the "%1$s" key with value "%2$s" for stylesheet "%3$s".' ), + 'path', + esc_html( $path ), + esc_html( $handle ) + ), + '7.0.0' + ); continue; } $styles[] = array( @@ -3120,6 +3131,20 @@ static function ( $a, $b ) { // Get the styles if we don't already have them. $style['css'] = file_get_contents( $style['path'] ); + if ( false === $style['css'] ) { + _doing_it_wrong( + __FUNCTION__, + sprintf( + /* translators: 1: 'path', 2: filesystem path, 3: style handle */ + __( 'Unable to read the "%1$s" key with value "%2$s" for stylesheet "%3$s".' ), + 'path', + esc_html( $style['path'] ), + esc_html( $style['handle'] ) + ), + '7.0.0' + ); + continue; + } /* * Check if the style contains relative URLs that need to be modified. diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 3828c8246e528..f2b5cd03bfc09 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -768,6 +768,25 @@ public function test_wp_maybe_inline_styles_no_path() { $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url ); } + /** + * @ticket 64447 + * + * @covers ::wp_maybe_inline_styles + * @expectedIncorrectUsage wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_bad_path() { + $handle = 'test-handle'; + $inc_path = '/css/ancient-themes.css'; // Does not exist. + $url = '/' . WPINC . $inc_path; + wp_register_style( $handle, $url ); + wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); + wp_enqueue_style( $handle ); + + wp_maybe_inline_styles(); + + $this->assertSame( $GLOBALS['wp_styles']->registered[ $handle ]->src, $url ); + } + /** * @ticket 63887 */ From 9c7273ca6f9f9456513eb9975351c0b2af7b80e9 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 22 Dec 2025 13:13:57 -0800 Subject: [PATCH 02/19] Add test coverage for file read error --- src/wp-includes/script-loader.php | 2 +- tests/phpunit/tests/dependencies/styles.php | 34 ++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 5932dde9e7b1e..c83bc01a26078 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -3130,7 +3130,7 @@ static function ( $a, $b ) { } // Get the styles if we don't already have them. - $style['css'] = file_get_contents( $style['path'] ); + $style['css'] = @file_get_contents( $style['path'] ); if ( false === $style['css'] ) { _doing_it_wrong( __FUNCTION__, diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index f2b5cd03bfc09..acacbb328bee2 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -774,7 +774,39 @@ public function test_wp_maybe_inline_styles_no_path() { * @covers ::wp_maybe_inline_styles * @expectedIncorrectUsage wp_maybe_inline_styles */ - public function test_wp_maybe_inline_styles_bad_path() { + public function test_wp_maybe_inline_styles_bad_path_at_file_size_check() { + $handle = 'test-handle'; + $inc_path = '/css/ancient-themes.css'; // Does not exist. + $url = '/' . WPINC . $inc_path; + wp_register_style( $handle, $url ); + wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); + wp_enqueue_style( $handle ); + + wp_maybe_inline_styles(); + + $this->assertSame( $GLOBALS['wp_styles']->registered[ $handle ]->src, $url ); + } + + /** + * @ticket 64447 + * + * @covers ::wp_maybe_inline_styles + * @expectedIncorrectUsage wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_bad_path_with_file_size_provided() { + // This ensures the initial file size check is bypassed. + add_filter( + 'pre_wp_filesize', + static function ( $size, $path ) { + if ( str_contains( $path, 'ancient-themes.css' ) ) { + $size = 1000; + } + return $size; + }, + 10, + 2 + ); + $handle = 'test-handle'; $inc_path = '/css/ancient-themes.css'; // Does not exist. $url = '/' . WPINC . $inc_path; From 295efccb25a82011ce3f4d8429b07462e0551603 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 22 Dec 2025 13:17:22 -0800 Subject: [PATCH 03/19] Ensure stylesheets of zero size can be inlined --- src/wp-includes/script-loader.php | 2 +- tests/phpunit/tests/dependencies/styles.php | 42 ++++++++++++++++++--- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index c83bc01a26078..650e89e1609d9 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -3081,7 +3081,7 @@ function wp_maybe_inline_styles() { $path = $wp_styles->get_data( $handle, 'path' ); if ( $path && $src ) { $size = wp_filesize( $path ); - if ( 0 === $size ) { + if ( 0 === $size && ! file_exists( $path ) ) { _doing_it_wrong( __FUNCTION__, sprintf( diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index acacbb328bee2..9f7e1173be61b 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -794,11 +794,13 @@ public function test_wp_maybe_inline_styles_bad_path_at_file_size_check() { * @expectedIncorrectUsage wp_maybe_inline_styles */ public function test_wp_maybe_inline_styles_bad_path_with_file_size_provided() { + $inc_path = '/css/ancient-themes.css'; // Does not exist. + // This ensures the initial file size check is bypassed. add_filter( 'pre_wp_filesize', - static function ( $size, $path ) { - if ( str_contains( $path, 'ancient-themes.css' ) ) { + static function ( $size, $path ) use ( $inc_path ) { + if ( str_contains( $path, $inc_path ) ) { $size = 1000; } return $size; @@ -807,9 +809,8 @@ static function ( $size, $path ) { 2 ); - $handle = 'test-handle'; - $inc_path = '/css/ancient-themes.css'; // Does not exist. - $url = '/' . WPINC . $inc_path; + $handle = 'test-handle'; + $url = '/' . WPINC . $inc_path; wp_register_style( $handle, $url ); wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); wp_enqueue_style( $handle ); @@ -819,6 +820,37 @@ static function ( $size, $path ) { $this->assertSame( $GLOBALS['wp_styles']->registered[ $handle ]->src, $url ); } + /** + * @ticket 64447 + * + * @covers ::wp_maybe_inline_styles + */ + public function test_wp_maybe_inline_styles_good_path_with_zero_file_size_provided() { + $inc_path = '/css/classic-themes.css'; + + // This simulates the file having a zero size. + add_filter( + 'pre_wp_filesize', + static function ( $size, $path ) use ( $inc_path ) { + if ( str_contains( $path, $inc_path ) ) { + $size = 0; + } + return $size; + }, + 10, + 2 + ); + + $handle = 'test-handle'; + wp_register_style( $handle, '/' . WPINC . $inc_path ); + wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); + wp_enqueue_style( $handle ); + + wp_maybe_inline_styles(); + + $this->assertFalse( $GLOBALS['wp_styles']->registered[ $handle ]->src ); + } + /** * @ticket 63887 */ From 8cb36ca933edbc4669e1c5c7403233927900036f Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 22 Dec 2025 20:47:46 -0800 Subject: [PATCH 04/19] Remove redundant test and add missing expectedIncorrectUsage tag --- tests/phpunit/tests/dependencies/styles.php | 43 +++++++-------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 9f7e1173be61b..4525af9cac2a5 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -716,10 +716,12 @@ public function test_wp_maybe_inline_styles_multiple_runs() { /** * @ticket 58394 + * @ticket 64447 * * @covers ::wp_maybe_inline_styles + * @expectedIncorrectUsage wp_maybe_inline_styles */ - public function test_test_wp_maybe_inline_styles_missing_file() { + public function test_wp_maybe_inline_styles_missing_file() { $filter = new MockAction(); add_filter( 'pre_wp_filesize', array( $filter, 'filter' ) ); $url = '/' . WPINC . '/css/invalid.css'; @@ -768,25 +770,6 @@ public function test_wp_maybe_inline_styles_no_path() { $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url ); } - /** - * @ticket 64447 - * - * @covers ::wp_maybe_inline_styles - * @expectedIncorrectUsage wp_maybe_inline_styles - */ - public function test_wp_maybe_inline_styles_bad_path_at_file_size_check() { - $handle = 'test-handle'; - $inc_path = '/css/ancient-themes.css'; // Does not exist. - $url = '/' . WPINC . $inc_path; - wp_register_style( $handle, $url ); - wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); - wp_enqueue_style( $handle ); - - wp_maybe_inline_styles(); - - $this->assertSame( $GLOBALS['wp_styles']->registered[ $handle ]->src, $url ); - } - /** * @ticket 64447 * @@ -794,13 +777,13 @@ public function test_wp_maybe_inline_styles_bad_path_at_file_size_check() { * @expectedIncorrectUsage wp_maybe_inline_styles */ public function test_wp_maybe_inline_styles_bad_path_with_file_size_provided() { - $inc_path = '/css/ancient-themes.css'; // Does not exist. + $style_path = '/css/invalid.css'; // Does not exist. // This ensures the initial file size check is bypassed. add_filter( 'pre_wp_filesize', - static function ( $size, $path ) use ( $inc_path ) { - if ( str_contains( $path, $inc_path ) ) { + static function ( $size, $path ) use ( $style_path ) { + if ( str_contains( $path, $style_path ) ) { $size = 1000; } return $size; @@ -810,9 +793,9 @@ static function ( $size, $path ) use ( $inc_path ) { ); $handle = 'test-handle'; - $url = '/' . WPINC . $inc_path; + $url = '/' . WPINC . $style_path; wp_register_style( $handle, $url ); - wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); + wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $style_path ); wp_enqueue_style( $handle ); wp_maybe_inline_styles(); @@ -826,13 +809,13 @@ static function ( $size, $path ) use ( $inc_path ) { * @covers ::wp_maybe_inline_styles */ public function test_wp_maybe_inline_styles_good_path_with_zero_file_size_provided() { - $inc_path = '/css/classic-themes.css'; + $style_path = '/css/classic-themes.css'; // This simulates the file having a zero size. add_filter( 'pre_wp_filesize', - static function ( $size, $path ) use ( $inc_path ) { - if ( str_contains( $path, $inc_path ) ) { + static function ( $size, $path ) use ( $style_path ) { + if ( str_contains( $path, $style_path ) ) { $size = 0; } return $size; @@ -842,8 +825,8 @@ static function ( $size, $path ) use ( $inc_path ) { ); $handle = 'test-handle'; - wp_register_style( $handle, '/' . WPINC . $inc_path ); - wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $inc_path ); + wp_register_style( $handle, '/' . WPINC . $style_path ); + wp_style_add_data( $handle, 'path', ABSPATH . WPINC . $style_path ); wp_enqueue_style( $handle ); wp_maybe_inline_styles(); From ce80e7a99ef95ac89d3c1964ab246ff948954063 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 22 Dec 2025 21:17:00 -0800 Subject: [PATCH 05/19] Ensure built CSS files are present in tests --- tests/phpunit/tests/media.php | 3 +++ tests/phpunit/tests/template.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 1ab836fe856d8..0a232d267a885 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -6677,6 +6677,9 @@ static function () { * @dataProvider data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix */ public function test_wp_enqueue_img_auto_sizes_contain_css_fix( ?Closure $set_up, bool $expected, ?string $expected_deprecated = null ): void { + // This file is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' ); + if ( $set_up ) { $set_up(); } diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index a304fff95f865..ffafa75d14516 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1677,6 +1677,9 @@ function (): void { * @dataProvider data_wp_hoist_late_printed_styles */ public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void { + // This file is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + self::touch( ABSPATH . WPINC . '/css/dist/block-library/theme.css' ); + switch_theme( 'default' ); global $wp_styles; $wp_styles = null; From 8cc52a211ac373f5ca995d63730679feb25b3b62 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 10:01:16 -0800 Subject: [PATCH 06/19] Use is_readable() instead of error suppression Co-authored-by: Jon Surrell --- src/wp-includes/script-loader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 650e89e1609d9..4fbd46d5310e8 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -3130,8 +3130,7 @@ static function ( $a, $b ) { } // Get the styles if we don't already have them. - $style['css'] = @file_get_contents( $style['path'] ); - if ( false === $style['css'] ) { + if ( ! is_readable( $style['path'] ) ) { _doing_it_wrong( __FUNCTION__, sprintf( @@ -3145,6 +3144,7 @@ static function ( $a, $b ) { ); continue; } + $style['css'] = file_get_contents( $style['path'] ); /* * Check if the style contains relative URLs that need to be modified. From 16f8e46e1d9dada1d72d06537dd3ab45097f5bec Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 10:43:26 -0800 Subject: [PATCH 07/19] Touch more styles --- tests/phpunit/tests/media.php | 3 ++- tests/phpunit/tests/template.php | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 0a232d267a885..74e7fe8d448b4 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -6677,7 +6677,8 @@ static function () { * @dataProvider data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix */ public function test_wp_enqueue_img_auto_sizes_contain_css_fix( ?Closure $set_up, bool $expected, ?string $expected_deprecated = null ): void { - // This file is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + // These files is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + self::touch( ABSPATH . WPINC . '/css/dist/block-library/style.css' ); self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' ); if ( $set_up ) { diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index ffafa75d14516..e411e3353651f 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1677,8 +1677,10 @@ function (): void { * @dataProvider data_wp_hoist_late_printed_styles */ public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void { - // This file is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + // These files is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. self::touch( ABSPATH . WPINC . '/css/dist/block-library/theme.css' ); + self::touch( ABSPATH . WPINC . '/css/dist/block-library/style.css' ); + self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' ); switch_theme( 'default' ); global $wp_styles; From 23debdb529d80d49ec24659562108d272f18be82 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 14:28:29 -0800 Subject: [PATCH 08/19] Touch stub CSS files in wp-includes which are created from build process --- tests/phpunit/tests/template.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index e411e3353651f..40ec72e26882f 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1677,11 +1677,6 @@ function (): void { * @dataProvider data_wp_hoist_late_printed_styles */ public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void { - // These files is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. - self::touch( ABSPATH . WPINC . '/css/dist/block-library/theme.css' ); - self::touch( ABSPATH . WPINC . '/css/dist/block-library/style.css' ); - self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' ); - switch_theme( 'default' ); global $wp_styles; $wp_styles = null; @@ -1711,6 +1706,23 @@ static function () { register_core_block_style_handles(); $this->assertTrue( WP_Block_Type_Registry::get_instance()->is_registered( 'core/separator' ), 'Expected the core/separator block to be registered.' ); + // Ensure all registered styles added as part of the build process are present on the disk. .These files are created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + foreach ( wp_styles()->registered as $handle => $dependency ) { + if ( ! is_string( $dependency->src ) ) { + continue; + } + $path = wp_parse_url( $dependency->src, PHP_URL_PATH ); + $position = strpos( $path, WPINC . '/' ); + if ( false === $position ) { + continue; + } + $absolute_path = ABSPATH . substr( $path, $position ); + if ( ! file_exists( $absolute_path ) ) { + self::touch( $absolute_path ); + file_put_contents( $absolute_path, "/* Stub for $handle */" ); + } + } + // Ensure stylesheet files exist on the filesystem since a build may not have been done. $this->ensure_style_asset_file_created( 'wp-block-library', From 15d5bd8599914518533bec3f667c66c848cf575d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 15:57:50 -0800 Subject: [PATCH 09/19] Improve ensuring CSS files are present during tests --- tests/phpunit/tests/template.php | 33 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 40ec72e26882f..379a578fc9540 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1706,30 +1706,18 @@ static function () { register_core_block_style_handles(); $this->assertTrue( WP_Block_Type_Registry::get_instance()->is_registered( 'core/separator' ), 'Expected the core/separator block to be registered.' ); - // Ensure all registered styles added as part of the build process are present on the disk. .These files are created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. - foreach ( wp_styles()->registered as $handle => $dependency ) { - if ( ! is_string( $dependency->src ) ) { - continue; - } - $path = wp_parse_url( $dependency->src, PHP_URL_PATH ); - $position = strpos( $path, WPINC . '/' ); - if ( false === $position ) { - continue; - } - $absolute_path = ABSPATH . substr( $path, $position ); - if ( ! file_exists( $absolute_path ) ) { - self::touch( $absolute_path ); - file_put_contents( $absolute_path, "/* Stub for $handle */" ); - } - } - // Ensure stylesheet files exist on the filesystem since a build may not have been done. $this->ensure_style_asset_file_created( 'wp-block-library', - wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css' + wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css', + wp_should_load_separate_core_block_assets() ); + $dependency = wp_styles()->query( 'wp-block-library' ); + $this->assertTrue( (bool) $dependency, 'Expected wp-block-library stylesheet to be registered.' ); + $this->assertIsString( $dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $dependency ) ); + if ( wp_should_load_separate_core_block_assets() ) { - $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css' ); + $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css', true ); } $this->assertFalse( wp_is_block_theme(), 'Test is not relevant to block themes (only classic themes).' ); @@ -1834,10 +1822,11 @@ static function () { * * @param string $handle Style handle. * @param string $relative_path Relative path to the CSS file in wp-includes. + * @param bool $add_path_data Whether to add the path data. * * @throws Exception If the supplied style handle is not registered as expected. */ - private function ensure_style_asset_file_created( string $handle, string $relative_path ) { + private function ensure_style_asset_file_created( string $handle, string $relative_path, bool $add_path_data = false ) { $dependency = wp_styles()->query( $handle ); if ( ! $dependency ) { throw new Exception( "The stylesheet for $handle is not registered." ); @@ -1851,7 +1840,9 @@ private function ensure_style_asset_file_created( string $handle, string $relati } file_put_contents( $path, "/* CSS for $handle */" ); } - wp_style_add_data( $handle, 'path', $path ); + if ( $add_path_data ) { + wp_style_add_data( $handle, 'path', $path ); + } } public function assertTemplateHierarchy( $url, array $expected, $message = '' ) { From 4ceb527b1d905915ba2bdb2b9a7e370a39670631 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:19:15 -0800 Subject: [PATCH 10/19] Add fail-fast for testing --- .github/workflows/phpunit-tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 63615dfad19f8..23d507feb3d61 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -69,7 +69,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: false + fail-fast: true matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -146,7 +146,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: false + fail-fast: true matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -198,7 +198,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: false + fail-fast: true matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -246,7 +246,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: false + fail-fast: true matrix: php: [ '7.2', '7.4', '8.0', '8.4' ] db-type: [ 'mysql' ] @@ -275,7 +275,7 @@ jobs: secrets: inherit if: ${{ ! startsWith( github.repository, 'WordPress/' ) && github.event_name == 'pull_request' }} strategy: - fail-fast: false + fail-fast: true matrix: php: [ '7.2', '8.4' ] db-version: [ '8.4', '11.8' ] From 5d1ba9f35498dc5aa2f698165dc3c66b5ee6362c Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:22:15 -0800 Subject: [PATCH 11/19] Ensure wp-emoji-loader.js is present for test_wp_hoist_late_printed_styles --- tests/phpunit/tests/template.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 379a578fc9540..e1e97df6adfb1 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1677,6 +1677,9 @@ function (): void { * @dataProvider data_wp_hoist_late_printed_styles */ public function test_wp_hoist_late_printed_styles( ?Closure $set_up, int $inline_size_limit, array $expected_styles ): void { + // `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present: + self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' ); + switch_theme( 'default' ); global $wp_styles; $wp_styles = null; From a7660a9680e916d72a86a2af32001af9d7638bba Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:31:37 -0800 Subject: [PATCH 12/19] Add assertion to ensure wp-block-library was printed --- tests/phpunit/tests/template.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index e1e97df6adfb1..4045b8adada5c 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1744,6 +1744,7 @@ static function () { // Simulate wp_head. $head_output = get_echo( 'wp_head' ); + $this->assertContains( 'wp-block-library', wp_styles()->done, 'Expected wp-block-library to have been added to wp_styles()->done.' ); $this->assertStringContainsString( 'early', $head_output, 'Expected the early-enqueued stylesheet to be present.' ); From 1f8a2f888a6eb50745ba4adf1c5db6ad888910b9 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:31:49 -0800 Subject: [PATCH 13/19] Ensure wp-block-library-theme is created --- tests/phpunit/tests/template.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 4045b8adada5c..1f0770556a7c3 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1715,6 +1715,7 @@ static function () { wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css', wp_should_load_separate_core_block_assets() ); + $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css', true ); $dependency = wp_styles()->query( 'wp-block-library' ); $this->assertTrue( (bool) $dependency, 'Expected wp-block-library stylesheet to be registered.' ); $this->assertIsString( $dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $dependency ) ); From f4694aa09194c3102ab35cce34a5fce87684ab11 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:43:09 -0800 Subject: [PATCH 14/19] Add yet more debug code --- tests/phpunit/tests/template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 1f0770556a7c3..3d84b78acd499 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1716,9 +1716,9 @@ static function () { wp_should_load_separate_core_block_assets() ); $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css', true ); - $dependency = wp_styles()->query( 'wp-block-library' ); - $this->assertTrue( (bool) $dependency, 'Expected wp-block-library stylesheet to be registered.' ); - $this->assertIsString( $dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $dependency ) ); + $block_library_dependency = wp_styles()->query( 'wp-block-library' ); + $this->assertTrue( (bool) $block_library_dependency, 'Expected wp-block-library stylesheet to be registered.' ); + $this->assertIsString( $block_library_dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $block_library_dependency ) ); if ( wp_should_load_separate_core_block_assets() ) { $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css', true ); @@ -1813,7 +1813,7 @@ static function () { $this->assertSame( $expected_styles, $found_subset_styles, - 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) + 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) . "\nAnd wp-block-library: " . json_encode( $block_library_dependency, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "\n And file contents: " . file_get_contents( $block_library_dependency->extra['path'] ) ); } From d3fbff0f72269fff8475d8371f7d82db058da0c5 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 16:55:37 -0800 Subject: [PATCH 15/19] Improve ensuring that wp-block-library is not empty --- tests/phpunit/tests/template.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 3d84b78acd499..8c2a166b95abd 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1719,6 +1719,7 @@ static function () { $block_library_dependency = wp_styles()->query( 'wp-block-library' ); $this->assertTrue( (bool) $block_library_dependency, 'Expected wp-block-library stylesheet to be registered.' ); $this->assertIsString( $block_library_dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $block_library_dependency ) ); + $this->assertNotEmpty( file_get_contents( $block_library_dependency->extra['path'] ), 'Expected wp-block-library file to not be empty.' ); if ( wp_should_load_separate_core_block_assets() ) { $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css', true ); @@ -1838,11 +1839,8 @@ private function ensure_style_asset_file_created( string $handle, string $relati } $dependency->src = includes_url( $relative_path ); $path = ABSPATH . WPINC . '/' . $relative_path; - if ( ! file_exists( $path ) ) { - $dir = dirname( $path ); - if ( ! file_exists( $dir ) ) { - mkdir( $dir, 0777, true ); - } + self::touch( $path ); + if ( 0 === filesize( $path ) ) { file_put_contents( $path, "/* CSS for $handle */" ); } if ( $add_path_data ) { From 5c5912a5b5e3f72609428e83353aa15447066f70 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 17:09:35 -0800 Subject: [PATCH 16/19] Revert "Add fail-fast for testing" This reverts commit 4ceb527b1d905915ba2bdb2b9a7e370a39670631. --- .github/workflows/phpunit-tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 23d507feb3d61..63615dfad19f8 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -69,7 +69,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -146,7 +146,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -198,7 +198,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ ubuntu-24.04 ] php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] @@ -246,7 +246,7 @@ jobs: secrets: inherit if: ${{ startsWith( github.repository, 'WordPress/' ) && ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) }} strategy: - fail-fast: true + fail-fast: false matrix: php: [ '7.2', '7.4', '8.0', '8.4' ] db-type: [ 'mysql' ] @@ -275,7 +275,7 @@ jobs: secrets: inherit if: ${{ ! startsWith( github.repository, 'WordPress/' ) && github.event_name == 'pull_request' }} strategy: - fail-fast: true + fail-fast: false matrix: php: [ '7.2', '8.4' ] db-version: [ '8.4', '11.8' ] From 46afeb707df905f0f160c7031282fc385d3b9ac7 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 17:11:58 -0800 Subject: [PATCH 17/19] Remove debug code --- tests/phpunit/tests/template.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 8c2a166b95abd..0752549048bbb 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1716,10 +1716,6 @@ static function () { wp_should_load_separate_core_block_assets() ); $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css', true ); - $block_library_dependency = wp_styles()->query( 'wp-block-library' ); - $this->assertTrue( (bool) $block_library_dependency, 'Expected wp-block-library stylesheet to be registered.' ); - $this->assertIsString( $block_library_dependency->src, 'Expected wp-block-library to have a string src. Dependency: ' . json_encode( $block_library_dependency ) ); - $this->assertNotEmpty( file_get_contents( $block_library_dependency->extra['path'] ), 'Expected wp-block-library file to not be empty.' ); if ( wp_should_load_separate_core_block_assets() ) { $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css', true ); @@ -1746,7 +1742,6 @@ static function () { // Simulate wp_head. $head_output = get_echo( 'wp_head' ); - $this->assertContains( 'wp-block-library', wp_styles()->done, 'Expected wp-block-library to have been added to wp_styles()->done.' ); $this->assertStringContainsString( 'early', $head_output, 'Expected the early-enqueued stylesheet to be present.' ); @@ -1814,7 +1809,7 @@ static function () { $this->assertSame( $expected_styles, $found_subset_styles, - 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) . "\nAnd wp-block-library: " . json_encode( $block_library_dependency, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "\n And file contents: " . file_get_contents( $block_library_dependency->extra['path'] ) + 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) ) ); } From 7152b33b5d782b8642548f791bae1b78aaeacd70 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 17:17:40 -0800 Subject: [PATCH 18/19] Remove conditional setting of path data --- tests/phpunit/tests/template.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/phpunit/tests/template.php b/tests/phpunit/tests/template.php index 0752549048bbb..a965665360b05 100644 --- a/tests/phpunit/tests/template.php +++ b/tests/phpunit/tests/template.php @@ -1712,13 +1712,12 @@ static function () { // Ensure stylesheet files exist on the filesystem since a build may not have been done. $this->ensure_style_asset_file_created( 'wp-block-library', - wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css', - wp_should_load_separate_core_block_assets() + wp_should_load_separate_core_block_assets() ? 'css/dist/block-library/common.css' : 'css/dist/block-library/style.css' ); - $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css', true ); + $this->ensure_style_asset_file_created( 'wp-block-library-theme', 'css/dist/block-library/theme.css' ); if ( wp_should_load_separate_core_block_assets() ) { - $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css', true ); + $this->ensure_style_asset_file_created( 'wp-block-separator', 'blocks/separator/style.css' ); } $this->assertFalse( wp_is_block_theme(), 'Test is not relevant to block themes (only classic themes).' ); @@ -1809,7 +1808,7 @@ static function () { $this->assertSame( $expected_styles, $found_subset_styles, - 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) ) + 'Expected the same styles. Snapshot: ' . self::get_array_snapshot_export( $found_subset_styles ) ); } @@ -1823,11 +1822,10 @@ static function () { * * @param string $handle Style handle. * @param string $relative_path Relative path to the CSS file in wp-includes. - * @param bool $add_path_data Whether to add the path data. * * @throws Exception If the supplied style handle is not registered as expected. */ - private function ensure_style_asset_file_created( string $handle, string $relative_path, bool $add_path_data = false ) { + private function ensure_style_asset_file_created( string $handle, string $relative_path ) { $dependency = wp_styles()->query( $handle ); if ( ! $dependency ) { throw new Exception( "The stylesheet for $handle is not registered." ); @@ -1838,9 +1836,7 @@ private function ensure_style_asset_file_created( string $handle, string $relati if ( 0 === filesize( $path ) ) { file_put_contents( $path, "/* CSS for $handle */" ); } - if ( $add_path_data ) { - wp_style_add_data( $handle, 'path', $path ); - } + wp_style_add_data( $handle, 'path', $path ); } public function assertTemplateHierarchy( $url, array $expected, $message = '' ) { From 7e0f735ae893ccd014b37e7ae7b820677a9f65d6 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 23 Dec 2025 17:38:49 -0800 Subject: [PATCH 19/19] Fix grammar --- tests/phpunit/tests/media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 74e7fe8d448b4..f6b1e5b2d982b 100644 --- a/tests/phpunit/tests/media.php +++ b/tests/phpunit/tests/media.php @@ -6677,7 +6677,7 @@ static function () { * @dataProvider data_provider_data_provider_to_test_wp_enqueue_img_auto_sizes_contain_css_fix */ public function test_wp_enqueue_img_auto_sizes_contain_css_fix( ?Closure $set_up, bool $expected, ?string $expected_deprecated = null ): void { - // These files is created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. + // These files are created as part of the build process, but the unit tests don't run the build prior to running unit tests on GHA. self::touch( ABSPATH . WPINC . '/css/dist/block-library/style.css' ); self::touch( ABSPATH . WPINC . '/css/dist/block-library/common.css' );