Build/Test Tools: PHPUnit test improvements:

* Switch back to running the PHPUnit test suite against the `src` directory instead of `build`
* Increase the reliability of backing up the `mu-plugins` directory during tests
* Split the PHPUnit tests for PHP versions below 7.0 in half, allowing them to run in parallel and reduce the overall test run duration on GitHub Actions

Merges [50441-50444] to the 5.7 branch.

Fixes #51734, #51735, #52645


git-svn-id: https://develop.svn.wordpress.org/branches/5.7@50464 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
John Blackbourn 2021-03-01 20:21:23 +00:00
parent 7af02944ff
commit cc13009e99
19 changed files with 263 additions and 336 deletions

View File

@ -15,28 +15,20 @@ on:
- cron: '0 0 * * 0'
env:
LOCAL_DIR: build
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: ${{ true }}
COMPOSER_INSTALL: ${{ false }}
# Controls which NPM script to use for running PHPUnit tests. Options ar `php` and `php-composer`.
PHPUNIT_SCRIPT: php
LOCAL_PHP_MEMCACHED: ${{ false }}
SLOW_TESTS: 'external-http,media,restapi'
jobs:
# Sets up WordPress for testing or development use.
# Sets up the workflow for testing.
#
# Performs the following steps:
# - Cancels all previous workflow runs for pull requests that have not completed.
# - Checks out the repository.
# - Logs debug information about the runner container.
# - Installs NodeJS 14.
# - Sets up caching for NPM.
# _ Installs NPM dependencies using install-changed to hash the `package.json` file.
# - Builds WordPress to run from the `build` directory.
# - Creates a ZIP file of compiled WordPress.
# - Uploads ZIP file as an artifact.
setup-wordpress:
name: Setup WordPress
setup-workflow:
name: Setup Workflow
runs-on: ubuntu-latest
if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }}
@ -47,69 +39,16 @@ jobs:
with:
access_token: ${{ github.token }}
- name: Checkout repository
uses: actions/checkout@v2
- name: Log debug information
run: |
echo "$GITHUB_REF"
echo "$GITHUB_EVENT_NAME"
npm --version
node --version
curl --version
git --version
svn --version
php --version
php -i
locale -a
- name: Install NodeJS
uses: actions/setup-node@v2
with:
node-version: 14
- name: Cache NodeJS modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install Dependencies
run: npx install-changed --install-command="npm ci"
- name: Build WordPress
run: npm run build
- name: Create ZIP artifact
uses: thedoctor0/zip-release@0.4.1
with:
filename: built-wp-${{ github.sha }}.zip
exclusions: '*.git* /*node_modules/* packagehash.txt'
- name: Upload build artifact
uses: actions/upload-artifact@v2
with:
name: built-wp-${{ github.sha }}
path: built-wp-${{ github.sha }}.zip
if-no-files-found: error
# Runs the PHPUnit tests for WordPress.
#
# Performs the following steps:
# - Set environment variables.
# - Sets up the environment variables needed for testing with memcached (if desired).
# - Downloads the built WordPress artifact from the previous job.
# - Unzips the artifact.
# - Installs NodeJS 14.
# - Sets up caching for NPM.
# _ Installs NPM dependencies using install-changed to hash the `package.json` file.
# - Installs NPM dependencies
# - Configures caching for Composer.
# _ Installs Composer dependencies (if desired).
# - Installs Composer dependencies (if desired).
# - Logs Docker debug information (about both the Docker installation within the runner).
# - Starts the WordPress Docker container.
# - Starts the memcached server after the Docker network has been created (if desired).
@ -124,16 +63,27 @@ jobs:
# - Submit the test results to the WordPress.org host test results.
# - todo: Configure Slack notifications for failing tests.
test-php:
name: ${{ matrix.php }}${{ matrix.multisite && ' multisite' || '' }}${{ matrix.memcached && ' with memcached' || '' }} on ${{ matrix.os }}
needs: setup-wordpress
name: ${{ matrix.php }}${{ matrix.multisite && ' multisite' || '' }}${{ matrix.split_slow && ' slow tests' || '' }} ${{ matrix.memcached && ' with memcached' || '' }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
php: [ '5.6.20', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0' ]
os: [ ubuntu-latest ]
memcached: [ false ]
split_slow: [ false ]
multisite: [ false, true ]
include:
# Additional "slow" jobs for PHP 5.6.
- php: '5.6.20'
os: ubuntu-latest
memcached: false
multisite: false
split_slow: true
- php: '5.6.20'
os: ubuntu-latest
memcached: false
multisite: true
split_slow: true
# Include jobs for PHP 7.4 with memcached.
- php: '7.4'
os: ubuntu-latest
@ -160,13 +110,8 @@ jobs:
echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV
echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV
- name: Download the built WordPress artifact
uses: actions/download-artifact@v2
with:
name: built-wp-${{ github.sha }}
- name: Unzip built artifact
run: unzip built-wp-${{ github.sha }}.zip
- name: Checkout repository
uses: actions/checkout@v2
- name: Install NodeJS
uses: actions/setup-node@v2
@ -231,7 +176,7 @@ jobs:
- name: Start the Memcached server.
if: ${{ matrix.memcached }}
run: |
cp tests/phpunit/includes/object-cache.php build/wp-content/object-cache.php
cp tests/phpunit/includes/object-cache.php src/wp-content/object-cache.php
docker run --name memcached --net $(basename "$PWD")_wpdevnet -d memcached
- name: General debug information
@ -256,22 +201,37 @@ jobs:
- name: Install WordPress
run: npm run env:install
- name: Run slow PHPUnit tests
if: ${{ matrix.split_slow }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ${{ env.SLOW_TESTS }}
- name: Run PHPUnit tests for single site excluding slow tests
if: ${{ matrix.php < '7.0' && ! matrix.split_slow && ! matrix.multisite }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-required
- name: Run PHPUnit tests for Multisite excluding slow tests
if: ${{ matrix.php < '7.0' && ! matrix.split_slow && matrix.multisite }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-excluded,oembed-headers
- name: Run PHPUnit tests
if: ${{ matrix.php >= '7.0' }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }}
- name: Run AJAX tests
if: ${{ ! matrix.split_slow }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ajax
- name: Run ms-files tests as a multisite install
if: ${{ matrix.multisite }}
if: ${{ matrix.multisite && ! matrix.split_slow }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c tests/phpunit/multisite.xml --group ms-files
- name: Run external HTTP tests
if: ${{ ! matrix.multisite }}
if: ${{ ! matrix.multisite && ! matrix.split_slow }}
run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c phpunit.xml.dist --group external-http
# __fakegroup__ is excluded to force PHPUnit to ignore the <exclude> settings in phpunit.xml.dist.
- name: Run (xDebug) tests
if: ${{ ! matrix.split_slow }}
run: LOCAL_PHP_XDEBUG=true npm run test:${{ env.PHPUNIT_SCRIPT }} -- -v --group xdebug --exclude-group __fakegroup__
- name: Checkout the WordPress Test Reporter
@ -281,14 +241,6 @@ jobs:
repository: 'WordPress/phpunit-test-runner'
path: 'test-runner'
- name: Set up the Git repository
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.ref == 'refs/heads/master' && matrix.report }}
run: |
git init
git remote add origin https://github.com/WordPress/wordpress-develop.git
git fetch
git reset origin/master
- name: Submit test results to the WordPress.org host test results
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.ref == 'refs/heads/master' && matrix.report }}
env:

View File

@ -6,7 +6,6 @@ on:
- cron: '0 0 * * *'
env:
LOCAL_DIR: build
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: ${{ true }}
COMPOSER_INSTALL: ${{ false }}
# Controls which NPM script to use for running PHPUnit tests. Options ar `php` and `php-composer`.
@ -26,7 +25,6 @@ jobs:
# - Installs NodeJS 14.
# - Sets up caching for NPM.
# _ Installs NPM dependencies using install-changed to hash the `package.json` file.
# - Builds WordPress to run from the `build` directory.
# - Logs Docker debug information (about the Docker installation within the runner).
# - Starts the WordPress Docker container.
# - Logs debug general information.
@ -87,9 +85,6 @@ jobs:
- name: Install Dependencies
run: npx install-changed --install-command="npm ci"
- name: Build WordPress
run: npm run build
- name: Docker debug information
run: |
docker -v

View File

@ -7,6 +7,8 @@ var installChanged = require( 'install-changed' );
module.exports = function(grunt) {
var path = require('path'),
fs = require( 'fs' ),
glob = require( 'glob' ),
assert = require( 'assert' ).strict,
spawn = require( 'child_process' ).spawnSync,
SOURCE_DIR = 'src/',
BUILD_DIR = 'build/',
@ -1433,6 +1435,126 @@ module.exports = function(grunt) {
'copy:version',
] );
/**
* Build verification tasks.
*/
grunt.registerTask( 'verify:build', [
'verify:wp-embed',
'verify:old-files',
'verify:source-maps',
] );
/**
* Build assertions for wp-embed.min.js.
*
* @ticket 34698
*/
grunt.registerTask( 'verify:wp-embed', function() {
const file = `${ BUILD_DIR }/wp-includes/js/wp-embed.min.js`;
assert(
fs.existsSync( file ),
'The build/wp-includes/js/wp-embed.min.js file does not exist.'
);
const contents = fs.readFileSync( file, {
encoding: 'utf8',
} );
assert(
contents.length > 0,
'The build/wp-includes/js/wp-embed.min.js file must not be empty.'
);
assert(
false === contents.includes( '&' ),
'The build/wp-includes/js/wp-embed.min.js file must not contain ampersands.'
);
} );
/**
* Build assertions to ensure no project files are inside `$_old_files` in the build directory.
*
* @ticket 36083
*/
grunt.registerTask( 'verify:old-files', function() {
const file = `${ BUILD_DIR }wp-admin/includes/update-core.php`;
assert(
fs.existsSync( file ),
'The build/wp-admin/includes/update-core.php file does not exist.'
);
const contents = fs.readFileSync( file, {
encoding: 'utf8',
} );
assert(
contents.length > 0,
'The build/wp-admin/includes/update-core.php file must not be empty.'
);
const match = contents.match( /\$_old_files = array\(([^\)]+)\);/ );
assert(
match.length > 0,
'The build/wp-admin/includes/update-core.php file does not include an `$_old_files` array.'
);
const files = match[1].split( '\n\t' ).filter( function( file ) {
// Filter out empty lines
if ( '' === file ) {
return false;
}
// Filter out commented out lines
if ( 0 === file.indexOf( '/' ) ) {
return false;
}
return true;
} ).map( function( file ) {
// Strip leading and trailing single quotes and commas
return file.replace( /^\'|\',$/g, '' );
} );
files.forEach(function( file ){
const search = `${ BUILD_DIR }${ file }`;
assert(
false === fs.existsSync( search ),
`${ search } should not be present in the $_old_files array.`
);
});
} );
/**
* Build assertions for the lack of source maps in JavaScript files.
*
* @ticket 24994
* @ticket 46218
*/
grunt.registerTask( 'verify:source-maps', function() {
const path = `${ BUILD_DIR }**/*.js`;
const files = glob.sync( path );
assert(
files.length > 0,
'No JavaScript files found in the build directory.'
);
files.forEach( function( file ) {
const contents = fs.readFileSync( file, {
encoding: 'utf8',
} );
// `data:` URLs are allowed:
const match = contents.match( /sourceMappingURL=((?!data:).)/ );
assert(
match === null,
`The ${ file } file must not contain a sourceMappingURL.`
);
} );
} );
grunt.registerTask( 'build', function() {
if ( grunt.option( 'dev' ) ) {
grunt.task.run( [
@ -1446,7 +1568,8 @@ module.exports = function(grunt) {
'build:css',
'includes:emoji',
'includes:embed',
'replace:emojiBannerText'
'replace:emojiBannerText',
'verify:build'
] );
}
} );

View File

@ -45,7 +45,7 @@ Your WordPress site will accessible at http://localhost:8889. You can see or cha
If you're making changes to WordPress core files, you should start the file watcher in order to build or copy the files as necessary:
```
npm run watch
npm run dev
```
To stop the watcher, press `ctrl+c`.

View File

@ -1293,4 +1293,26 @@ abstract class WP_UnitTestCase_Base extends PHPUnit\Framework\TestCase {
)
);
}
/**
* Touches the given file and its directory if it doesn't already exist.
*
* This can be used to ensure a file that is implictly relied on in a test exists
* without it having to be built.
*
* @param string $file The file name.
*/
public static function touch( $file ) {
if ( file_exists( $file ) ) {
return;
}
$dir = dirname( $file );
if ( ! file_exists( $dir ) ) {
mkdir( $dir, 0777, true );
}
touch( $file );
}
}

View File

@ -4,6 +4,14 @@
* @group admin
*/
class Tests_Admin_includesPlugin extends WP_UnitTestCase {
public static function wpSetUpBeforeClass( $factory ) {
self::_back_up_mu_plugins();
}
public static function wpTearDownAfterClass() {
self::_restore_mu_plugins();
}
function test_get_plugin_data() {
$data = get_plugin_data( DIR_TESTDATA . '/plugins/hello.php' );
@ -369,130 +377,83 @@ class Tests_Admin_includesPlugin extends WP_UnitTestCase {
'list_files_test_plugin/list_files_test_plugin.php',
'list_files_test_plugin/subdir/subfile.php',
);
$this->assertSame( $expected, $plugin_files );
unlink( $sub_dir . '/subfile.php' );
unlink( $plugin[1] );
rmdir( $sub_dir );
rmdir( $plugin_dir );
$this->assertSame( $expected, $plugin_files );
}
/**
* @covers ::get_mu_plugins
*/
public function test_get_mu_plugins_when_mu_plugins_exists_but_is_empty() {
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$exists = true;
$this->_back_up_mu_plugins();
} else {
$exists = false;
mkdir( WPMU_PLUGIN_DIR );
}
mkdir( WPMU_PLUGIN_DIR );
$this->assertSame( array(), get_mu_plugins() );
$mu_plugins = get_mu_plugins();
// Clean up.
if ( $exists ) {
$this->_restore_mu_plugins();
} else {
rmdir( WPMU_PLUGIN_DIR );
}
rmdir( WPMU_PLUGIN_DIR );
$this->assertSame( array(), $mu_plugins );
}
/**
* @covers ::get_mu_plugins
*/
public function test_get_mu_plugins_when_mu_plugins_directory_does_not_exist() {
$exists = false;
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$exists = true;
$this->_back_up_mu_plugins();
rmdir( WPMU_PLUGIN_DIR );
}
$this->assertFileNotExists( WPMU_PLUGIN_DIR );
$this->assertSame( array(), get_mu_plugins() );
// Clean up.
if ( $exists ) {
mkdir( WPMU_PLUGIN_DIR );
$this->_restore_mu_plugins();
}
}
/**
* @covers ::get_mu_plugins
*/
public function test_get_mu_plugins_should_ignore_index_php_containing_silence_is_golden() {
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$exists = true;
$this->_back_up_mu_plugins();
} else {
$exists = false;
mkdir( WPMU_PLUGIN_DIR );
}
mkdir( WPMU_PLUGIN_DIR );
$this->_create_plugin( '<?php\n//Silence is golden.', 'index.php', WPMU_PLUGIN_DIR );
$this->assertSame( array(), get_mu_plugins() );
// Clean up.
$mu_plugins = get_mu_plugins();
unlink( WPMU_PLUGIN_DIR . '/index.php' );
if ( $exists ) {
$this->_restore_mu_plugins();
} else {
rmdir( WPMU_PLUGIN_DIR );
}
rmdir( WPMU_PLUGIN_DIR );
$this->assertSame( array(), $mu_plugins );
}
/**
* @covers ::get_mu_plugins
*/
public function test_get_mu_plugins_should_not_ignore_index_php_containing_something_other_than_silence_is_golden() {
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$exists = true;
$this->_back_up_mu_plugins();
} else {
$exists = false;
mkdir( WPMU_PLUGIN_DIR );
}
mkdir( WPMU_PLUGIN_DIR );
$this->_create_plugin( '<?php\n//Silence is not golden.', 'index.php', WPMU_PLUGIN_DIR );
$found = get_mu_plugins();
$this->assertSame( array( 'index.php' ), array_keys( $found ) );
// Clean up.
unlink( WPMU_PLUGIN_DIR . '/index.php' );
if ( $exists ) {
$this->_restore_mu_plugins();
} else {
rmdir( WPMU_PLUGIN_DIR );
}
rmdir( WPMU_PLUGIN_DIR );
$this->assertSame( array( 'index.php' ), array_keys( $found ) );
}
/**
* @covers ::get_mu_plugins
*/
public function test_get_mu_plugins_should_ignore_files_without_php_extensions() {
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$exists = true;
$this->_back_up_mu_plugins();
} else {
$exists = false;
mkdir( WPMU_PLUGIN_DIR );
}
mkdir( WPMU_PLUGIN_DIR );
$this->_create_plugin( '<?php\n//Test', 'foo.php', WPMU_PLUGIN_DIR );
$this->_create_plugin( '<?php\n//Test 2', 'bar.txt', WPMU_PLUGIN_DIR );
$found = get_mu_plugins();
$this->assertSame( array( 'foo.php' ), array_keys( $found ) );
// Clean up.
unlink( WPMU_PLUGIN_DIR . '/foo.php' );
unlink( WPMU_PLUGIN_DIR . '/bar.txt' );
if ( $exists ) {
$this->_restore_mu_plugins();
} else {
rmdir( WPMU_PLUGIN_DIR );
}
$this->assertSame( array( 'foo.php' ), array_keys( $found ) );
}
/**
@ -651,34 +612,16 @@ class Tests_Admin_includesPlugin extends WP_UnitTestCase {
}
/**
* Move existing mu-plugins to wp-content/mu-plugin/backup.
* Move existing mu-plugins to wp-content/mu-plugin-backup.
*
* @since 4.2.0
*
* @access private
*/
private function _back_up_mu_plugins() {
private static function _back_up_mu_plugins() {
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
$mu_bu_dir = WP_CONTENT_DIR . '/mu-plugin-backup';
if ( ! is_dir( $mu_bu_dir ) ) {
mkdir( $mu_bu_dir );
}
$files_to_move = array();
$mu_plugins = opendir( WPMU_PLUGIN_DIR );
if ( $mu_plugins ) {
while ( false !== $plugin = readdir( $mu_plugins ) ) {
if ( 0 !== strpos( $plugin, '.' ) ) {
$files_to_move[] = $plugin;
}
}
}
closedir( $mu_plugins );
foreach ( $files_to_move as $file_to_move ) {
$f = rename( WPMU_PLUGIN_DIR . '/' . $file_to_move, $mu_bu_dir . '/' . $file_to_move );
}
rename( WPMU_PLUGIN_DIR, $mu_bu_dir );
}
}
@ -689,26 +632,15 @@ class Tests_Admin_includesPlugin extends WP_UnitTestCase {
*
* @access private
*/
private function _restore_mu_plugins() {
$mu_bu_dir = WP_CONTENT_DIR . '/mu-plugin-backup';
$files_to_move = array();
$mu_plugins = @opendir( $mu_bu_dir );
if ( $mu_plugins ) {
while ( false !== $plugin = readdir( $mu_plugins ) ) {
if ( 0 !== strpos( $plugin, '.' ) ) {
$files_to_move[] = $plugin;
}
}
}
private static function _restore_mu_plugins() {
$mu_bu_dir = WP_CONTENT_DIR . '/mu-plugin-backup';
closedir( $mu_plugins );
foreach ( $files_to_move as $file_to_move ) {
rename( $mu_bu_dir . '/' . $file_to_move, WPMU_PLUGIN_DIR . '/' . $file_to_move );
if ( is_dir( WPMU_PLUGIN_DIR ) ) {
rmdir( WPMU_PLUGIN_DIR );
}
if ( is_dir( $mu_bu_dir ) ) {
rmdir( $mu_bu_dir );
rename( $mu_bu_dir, WPMU_PLUGIN_DIR );
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @group admin
* @group upgrade
*/
class Tests_Admin_IncludesUpdateCore extends WP_UnitTestCase {
public function data_old_files() {
global $_old_files;
require_once ABSPATH . 'wp-admin/includes/update-core.php';
$files = $_old_files;
foreach ( $files as &$file ) {
$file = array( $file );
}
return $files;
}
/**
* Ensure no project files are inside `$_old_files` in the build directory.
*
* @ticket 36083
*
* @dataProvider data_old_files
*
* @param string $file File name.
*/
public function test_new_files_are_not_in_old_files_array_compiled( $file ) {
$this->assertFileNotExists( dirname( ABSPATH ) . '/build/' . $file );
}
}

View File

@ -39,13 +39,6 @@ class Tests_Dependencies_jQuery extends WP_UnitTestCase {
}
}
function test_presence_of_jquery_no_conflict() {
$contents = trim( file_get_contents( ABSPATH . WPINC . '/js/jquery/jquery.js' ) );
$noconflict = 'jQuery.noConflict();';
$end = substr( $contents, - strlen( $noconflict ) );
$this->assertSame( $noconflict, $end );
}
/**
* @ticket 22896
*

View File

@ -1,36 +0,0 @@
<?php
/**
* @group dependencies
* @group scripts
*/
class Tests_Dependencies_MediaElementjs extends WP_UnitTestCase {
/**
* Test if the MediaElement.js Flash fallbacks have been re-added.
*
* MediaElement's Flash fallbacks were removed in WordPress 4.9.2 due to limited use cases and
* a history of security vulnerabilities. It's unlikely that there'll ever be a need to
* restore them in the future, and doing so could introduce security vulnerabilities. If you
* want to re-add them, please discuss that with the Security team first.
*
* @since 5.1.0
*
* @ticket 42720
*/
function test_exclusion_of_flash() {
$mejs_folder = ABSPATH . WPINC . '/js/mediaelement';
$js_files = glob( $mejs_folder . '/*.js' );
/*
* The path in $mejs_folder is hardcoded, so this is just a sanity check to make sure the
* correct directory is used, in case it gets renamed in the future.
*/
$this->assertGreaterThan( 0, count( $js_files ) );
$mejs_directory_iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $mejs_folder ) );
$mejs_swf_iterator = new RegexIterator( $mejs_directory_iterator, '/\.swf$/i', RecursiveRegexIterator::GET_MATCH );
// Make sure the Flash files haven't been re-added accidentally.
$this->assertCount( 0, iterator_to_array( $mejs_swf_iterator ) );
}
}

View File

@ -728,7 +728,7 @@ JS;
$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/vendor/wp-polyfill{$suffix}.js' id='wp-polyfill-js'></script>\n";
$expected .= "<script type='text/javascript' id='wp-polyfill-js-after'>\n";
$expected .= "( 'fetch' in window ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-fetch{$suffix}.js\"></scr' + 'ipt>' );( document.contains ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-node-contains{$suffix}.js\"></scr' + 'ipt>' );( window.DOMRect ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-dom-rect{$suffix}.js\"></scr' + 'ipt>' );( window.URL && window.URL.prototype && window.URLSearchParams ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-url{$suffix}.js\"></scr' + 'ipt>' );( window.FormData && window.FormData.prototype.keys ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-formdata{$suffix}.js\"></scr' + 'ipt>' );( Element.prototype.matches && Element.prototype.closest ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-element-closest{$suffix}.js\"></scr' + 'ipt>' );( 'objectFit' in document.documentElement.style ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-object-fit.min.js\"></scr' + 'ipt>' );\n";
$expected .= "( 'fetch' in window ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-fetch{$suffix}.js\"></scr' + 'ipt>' );( document.contains ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-node-contains{$suffix}.js\"></scr' + 'ipt>' );( window.DOMRect ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-dom-rect{$suffix}.js\"></scr' + 'ipt>' );( window.URL && window.URL.prototype && window.URLSearchParams ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-url{$suffix}.js\"></scr' + 'ipt>' );( window.FormData && window.FormData.prototype.keys ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-formdata{$suffix}.js\"></scr' + 'ipt>' );( Element.prototype.matches && Element.prototype.closest ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-element-closest{$suffix}.js\"></scr' + 'ipt>' );( 'objectFit' in document.documentElement.style ) || document.write( '<script src=\"http://example.org/wp-includes/js/dist/vendor/wp-polyfill-object-fit{$suffix}.js\"></scr' + 'ipt>' );\n";
$expected .= "</script>\n";
$expected .= "<script type='text/javascript' src='/wp-includes/js/dist/dom-ready{$suffix}.js' id='wp-dom-ready-js'></script>\n";
$expected .= "<script type='text/javascript' src='/wp-includes/js/dist/hooks{$suffix}.js' id='wp-hooks-js'></script>\n";
@ -1417,18 +1417,6 @@ JS;
);
}
function test_no_source_mapping() {
$all_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( dirname( ABSPATH ) . '/build/' ) );
$js_files = new RegexIterator( $all_files, '/\.js$/' );
foreach ( $js_files as $js_file ) {
$contents = trim( file_get_contents( $js_file ) );
// We allow data: URLs.
$found = preg_match( '/sourceMappingURL=((?!data:).)/', $contents );
$this->assertSame( $found, 0, "sourceMappingURL found in $js_file" );
}
}
/**
* @ticket 52534
* @covers ::wp_localize_script

View File

@ -13,6 +13,8 @@ class Tests_Formatting_Emoji extends WP_UnitTestCase {
* @ticket 36525
*/
public function test_unfiltered_emoji_cdns() {
// `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' );
$output = get_echo( '_print_emoji_detection_script' );
$this->assertContains( wp_json_encode( $this->png_cdn ), $output );
@ -31,6 +33,8 @@ class Tests_Formatting_Emoji extends WP_UnitTestCase {
add_filter( 'emoji_svg_url', array( $this, '_filtered_emoji_svn_cdn' ) );
// `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' );
$output = get_echo( '_print_emoji_detection_script' );
$this->assertContains( wp_json_encode( $this->png_cdn ), $output );
@ -52,6 +56,8 @@ class Tests_Formatting_Emoji extends WP_UnitTestCase {
add_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) );
// `_print_emoji_detection_script()` assumes `wp-includes/js/wp-emoji-loader.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-emoji-loader.js' );
$output = get_echo( '_print_emoji_detection_script' );
$this->assertContains( wp_json_encode( $filtered_png_cdn ), $output );

View File

@ -34,6 +34,9 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
'user_email' => 'administrator@example.com',
)
);
// `get_post_embed_html()` assumes `wp-includes/js/wp-embed.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-embed.js' );
}
public static function wpTearDownAfterClass() {

View File

@ -5,6 +5,13 @@
* @covers ::get_oembed_response_data
*/
class Tests_oEmbed_Response_Data extends WP_UnitTestCase {
public function setUp() {
parent::setUp();
// `get_post_embed_html()` assumes `wp-includes/js/wp-embed.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-embed.js' );
}
function test_get_oembed_response_data_non_existent_post() {
$this->assertFalse( get_oembed_response_data( 0, 100 ) );
}

View File

@ -23,6 +23,9 @@ class Tests_Embed_Template extends WP_UnitTestCase {
$this->assertQueryTrue( 'is_single', 'is_singular', 'is_embed' );
// `print_embed_scripts()` assumes `wp-includes/js/wp-embed-template.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-embed-template.js' );
ob_start();
require ABSPATH . WPINC . '/theme-compat/embed.php';
$actual = ob_get_clean();
@ -290,50 +293,13 @@ class Tests_Embed_Template extends WP_UnitTestCase {
}
/**
* Confirms that no ampersands exist in src/wp-includes/js/wp-embed.js.
*
* See also the `verify:wp-embed` Grunt task for verifying the built file.
*
* @ticket 34698
*/
function test_js_no_ampersands() {
$this->assertNotContains( '&', file_get_contents( ABSPATH . WPINC . '/js/wp-embed.js' ) );
}
/**
* @ticket 34698
*
* @depends test_js_no_ampersands
*
* The previous test confirms that no ampersands exist in src/wp-includes/js/wp-embed.js.
* However, we must also confirm that UglifyJS does not add ampersands during its
* optimizations (which we tweak to avoid, but indirectly -- understandably, there's
* no "don't add ampersands to my JavaScript file" option).
*
* So this test checks for ampersands in build/wp-includes/js/wp-embed.min.js.
* In many cases, this file will not exist; in those cases, we simply skip the test.
*
* So when would it be run? We have Travis CI run `npm run test` which then runs, in order,
* `qunit:compiled` (which runs the build) and then `phpunit`. Thus, this test will at least be
* run during continuous integration.
*
* However, we need to verify that `qunit:compiled` runs before `phpunit`. So this test also
* does a cheap check for a registered Grunt task called `test` that contains both
* `qunit:compiled` and `phpunit`, in that order.
*
* One final failsafe: The Gruntfile.js assertion takes place before checking for the existence
* of wp-embed.min.js. If the Grunt tasks are significantly refactored later, it could indicate
* that wp-embed.min.js doesn't exist anymore. We wouldn't want the test to silently become one
* that is always skipped, and thus useless.
*/
function test_js_no_ampersands_in_compiled() {
$gruntfile = file_get_contents( dirname( ABSPATH ) . '/Gruntfile.js' );
// Confirm this file *should* exist, otherwise this test will always be skipped.
$test = '/grunt.registerTask\(\s*\'test\',.*\'qunit:compiled\'.*\'phpunit\'/';
$this->assertTrue( (bool) preg_match( $test, $gruntfile ) );
$file = dirname( ABSPATH ) . '/build/' . WPINC . '/js/wp-embed.min.js';
if ( ! file_exists( $file ) ) {
return;
}
$this->assertNotContains( '&', file_get_contents( $file ) );
}
}

View File

@ -18,6 +18,9 @@ class Tests_WP_oEmbed extends WP_UnitTestCase {
$this->oembed = _wp_oembed_get_object();
$this->pre_oembed_result_filtered = false;
// `get_post_embed_html()` assumes `wp-includes/js/wp-embed.js` is present:
self::touch( ABSPATH . WPINC . '/js/wp-embed.js' );
}
public function _filter_pre_oembed_result( $result ) {

View File

@ -746,7 +746,7 @@ EOF;
function test_php_and_js_shortcode_attribute_regexes_match() {
$file = file_get_contents( ABSPATH . WPINC . '/js/shortcode.js' );
$file = file_get_contents( ABSPATH . 'js/_enqueues/wp/shortcode.js' );
$matched = preg_match( '|\s+pattern = (\/.+\/)g;|', $file, $matches );
$php = get_shortcode_atts_regex();

View File

@ -152,6 +152,7 @@
<script src="wp-admin/js/dashboard.js"></script>
<script src="wp-includes/js/shortcode.js"></script>
<script src="wp-includes/js/api-request.js"></script>
<script src="wp-includes/js/jquery.js"></script>
<script src="wp-includes/js/wp-api.js"></script>
<script src="wp-admin/js/customize-controls.js"></script>
<script src="wp-admin/js/customize-controls-utils.js"></script>

10
tests/qunit/wp-includes/js/jquery.js vendored Normal file
View File

@ -0,0 +1,10 @@
( function( QUnit ) {
QUnit.module( 'jQuery' );
QUnit.test( 'jQuery is run in noConflict mode', function( assert ) {
assert.expect( 1 );
assert.ok( 'undefined' === typeof window.$ );
} );
} )( window.QUnit );

View File

@ -1,11 +1,7 @@
<?php
/* Path to the WordPress codebase you'd like to test. Add a forward slash in the end. */
if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/build/' );
} else {
define( 'ABSPATH', dirname( __FILE__ ) . '/src/' );
}
define( 'ABSPATH', dirname( __FILE__ ) . '/src/' );
/*
* Path to the theme to test with.