diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index 98b3456935716..a55b2e48aa2ed 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -75,6 +75,20 @@ public static function set_up_before_class() { $class = get_called_class(); + /* + * Record the contents of the uploads directory before any class fixtures + * are created, so that `remove_added_uploads()` can tell pre-existing + * files apart from files added by the tests. + * + * This must happen before `wpSetUpBeforeClass()` runs. Capturing it later + * would treat files uploaded by the first class's fixtures as + * pre-existing, permanently exempting them from cleanup and leaving them + * on disk for the rest of the run. + */ + if ( null === self::$ignore_files ) { + self::$ignore_files = self::scan_user_uploads(); + } + if ( method_exists( $class, 'wpSetUpBeforeClass' ) ) { call_user_func( array( $class, 'wpSetUpBeforeClass' ), static::factory() ); } @@ -112,16 +126,22 @@ public function set_up() { $this->factory = static::factory(); - if ( ! self::$ignore_files ) { - self::$ignore_files = $this->scan_user_uploads(); - } - if ( ! self::$hooks_saved ) { $this->_backup_hooks(); } $this->clean_up_global_scope(); + /* + * Reset the metadata lazyload queue before each test. + * + * `tear_down()` resets the queue after every test, but fixtures created + * in `wpSetUpBeforeClass()` run outside of any test's `tear_down()`. + * Without this reset, anything queued while building class fixtures + * leaks into the first test of the class. + */ + $this->reset_lazyload_queue(); + /* * When running core tests, ensure that post types and taxonomies * are reset for each test. We skip this step for non-core tests, @@ -207,7 +227,7 @@ public function tear_down() { } // Reset comment globals. - $comment_globals = array( 'comment_alt', 'comment_depth', 'comment_thread_alt' ); + $comment_globals = array( 'comment', 'comment_alt', 'comment_depth', 'comment_thread_alt' ); foreach ( $comment_globals as $global ) { $GLOBALS[ $global ] = null; } @@ -230,6 +250,18 @@ public function tear_down() { $this->_restore_hooks(); wp_set_current_user( 0 ); + /* + * When running core tests, reset `$_SERVER` after each test. + * + * `set_up()` performs the same reset before each test, but class fixtures + * created in `wpSetUpBeforeClass()` run before the first `set_up()` of a + * class. Without this reset, `$_SERVER` values left behind by a previous + * class are still in place while those fixtures are created. + */ + if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) { + $this->reset__SERVER(); + } + $this->reset_lazyload_queue(); WP_Style_Engine_CSS_Rules_Store::remove_all_stores(); @@ -1530,9 +1562,10 @@ public function rmdir( $path ) { /** * Deletes files added to the `uploads` directory during tests. * - * This method works in tandem with the `set_up()` and `rmdir()` methods: - * - `set_up()` scans the `uploads` directory before every test, and stores - * its contents inside of the `$ignore_files` property. + * This method works in tandem with the `set_up_before_class()` and `rmdir()` methods: + * - `set_up_before_class()` scans the `uploads` directory once, before any + * test or class fixture has run, and stores its contents inside of the + * `$ignore_files` property. * - `rmdir()` and its helper methods only delete files that are not listed * in the `$ignore_files` property. If called during `tear_down()` in tests, * this will only delete files added during the previously run test. @@ -1550,7 +1583,7 @@ public function remove_added_uploads() { * @param string $dir Path to the directory to scan. * @return string[] List of file paths. */ - public function files_in_dir( $dir ) { + public static function files_in_dir( $dir ) { $files = array(); $iterator = new RecursiveDirectoryIterator( $dir ); @@ -1571,14 +1604,14 @@ public function files_in_dir( $dir ) { * * @return string[] List of file paths. */ - public function scan_user_uploads() { + public static function scan_user_uploads() { static $files = array(); if ( ! empty( $files ) ) { return $files; } $uploads = wp_upload_dir(); - $files = $this->files_in_dir( $uploads['basedir'] ); + $files = self::files_in_dir( $uploads['basedir'] ); return $files; }