Skip to content

Commit

Permalink
Add phpunit test infrastructure and tests
Browse files Browse the repository at this point in the history
Pulled from #181
  • Loading branch information
ryelle committed Apr 3, 2023
1 parent 2b9149d commit 1730ec9
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ phpcs.xml.dist
/source/wp-content/mu-plugins/*

# ...except the actual source of this project.
!/source/wp-content/tests
!/source/wp-content/themes
!/source/wp-content/themes/wporg-main-2022
!/source/wp-content/mu-plugins
Expand Down
11 changes: 11 additions & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,16 @@
"wp-content/mu-plugins": "./source/wp-content/mu-plugins",
"wp-content/mu-plugins/0-sandbox.php": "./env/0-sandbox.php",
"wp-cli.yml": "./wp-cli.yml"
},
"env": {
"tests": {
"config": {
"WP_ENVIRONMENT_TYPE": false
},
"mappings": {
"wp-content/tests": "./source/wp-content/tests",
"vendor": "./vendor"
}
}
}
}
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
"wpackagist-plugin/wordpress-importer": "*",
"wporg/wporg-repo-tools": "dev-trunk",
"wporg/wporg-mu-plugins": "dev-build",
"wporg/wporg-parent-2021": "dev-build"
"wporg/wporg-parent-2021": "dev-build",
"yoast/phpunit-polyfills": "^1.0"
},
"scripts": {
"format": "phpcbf -p",
Expand Down
70 changes: 65 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

141 changes: 141 additions & 0 deletions env/export-content/tests/block-parser-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?php
/**
* Test the BlockParser class and related functions.
*/

use WordPress_org\Main_2022\ExportToPatterns\BlockParser;
use function WordPress_org\Main_2022\ExportToPatterns\replace_with_i18n;

require dirname( __DIR__ ) . '/includes/parser.php';

class BlockParser_Test extends WP_UnitTestCase {
/**
* Data provider for valid block content, and the expected strings when parsed.
*
* @return array
*/
public function data_block_content_strings() {
return [
[
// Two plain paragraphs.
"<!-- wp:paragraph -->\n<p>One.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Two.</p>\n<!-- /wp:paragraph -->",
[ 'One.', 'Two.' ],
],
[
// A paragraph with nested HTML.
"<!-- wp:paragraph -->\n<p>A paragraph with <strong>bold</strong> text.</p>\n<!-- /wp:paragraph -->",
[ 'A paragraph with <strong>bold</strong> text.' ],
],
[
// A paragraph with a nested link.
"<!-- wp:paragraph -->\n<p>A paragraph with <a href=\"#\">a link</strong>.</p>\n<!-- /wp:paragraph -->",
[ 'A paragraph with <a href="#">a link</strong>.' ],
],
[
// Empty paragraph.
"<!-- wp:paragraph -->\n<p></p>\n<!-- /wp:paragraph -->\n",
[],
],
[
// Buttons.
"<!-- wp:buttons -->\n<div class=\"wp-block-buttons\"><!-- wp:button -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"#\">Button 1</a></div>\n<!-- /wp:button -->\n\n<!-- wp:button -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"#\">Button 2</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->",
[ 'Button 1', 'Button 2' ],
],
[
// Column with a list, list-items.
"<!-- wp:column {\"verticalAlignment\":\"center\",\"width\":\"50%\",\"style\":{\"spacing\":{\"padding\":{\"right\":\"60px\"}}}} -->\n<div class=\"wp-block-column is-vertically-aligned-center\" style=\"padding-right:60px;flex-basis:50%\"><!-- wp:list {\"className\":\"is-style-features\"} -->\n<ul class=\"is-style-features\"><!-- wp:list-item -->\n<li>Simple</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Intuitive</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Extendable</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Free</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Open</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list --></div>\n<!-- /wp:column -->",
[ 'Simple', 'Intuitive', 'Extendable', 'Free', 'Open' ],
],
[
// Image block with an alt.
"<!-- wp:image {\"width\":150,\"height\":45,\"linkDestination\":\"custom\"} -->\n<figure class=\"wp-block-image is-resized\"><a href=\"#\"><img src=\"./badge-apple.png\" alt=\"Download on the Apple App Store\" width=\"150\" height=\"45\" /></a></figure>\n<!-- /wp:image -->",
[ 'Download on the Apple App Store' ],
],
[
// Navigation with custom navigation links.
"<!-- wp:navigation {\"textColor\":\"blueberry-1\",\"overlayMenu\":\"never\",\"className\":\"is-style-dots\",\"style\":{\"spacing\":{\"blockGap\":\"0px\"}},\"fontSize\":\"small\"} -->\n<!-- wp:navigation-link {\"label\":\"Releases\",\"url\":\"https://wordpress.org/download/releases/\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n\n<!-- wp:navigation-link {\"label\":\"Nightly\",\"url\":\"https://wordpress.org/download/beta-nightly/\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n\n<!-- wp:navigation-link {\"label\":\"Counter\",\"url\":\"https://wordpress.org/download/counter/\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n\n<!-- wp:navigation-link {\"label\":\"Source\",\"url\":\"https://wordpress.org/download/source/\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n<!-- /wp:navigation -->",
[ 'Releases', 'Nightly', 'Counter', 'Source' ],
],
[
// Cover with background image (with alt), and nested paragraph.
"<!-- wp:cover {\"url\":\"http://localhost:8878/wp-content/uploads/2022/10/kerstin-wrba-zeInZepl_Hw-unsplash-scaled.jpg\",\"id\":7,\"dimRatio\":50,\"overlayColor\":\"tertiary\",\"isDark\":false} -->\n<div class=\"wp-block-cover is-light\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-tertiary-background-color has-background-dim\"></span><img class=\"wp-block-cover__image-background wp-image-7\" alt=\"Some alt.\" src=\"http://localhost:8878/wp-content/uploads/2022/10/kerstin-wrba-zeInZepl_Hw-unsplash-scaled.jpg\" data-object-fit=\"cover\"/><div class=\"wp-block-cover__inner-container\"><!-- wp:paragraph {\"align\":\"center\",\"fontSize\":\"large\"} -->\n<p class=\"has-text-align-center has-large-font-size\">Testing a Cover</p>\n<!-- /wp:paragraph --></div></div>\n<!-- /wp:cover -->",
[ 'Some alt.', 'Testing a Cover' ],
],
[
// Social links.
"<!-- wp:social-links {\"className\":\"is-style-logos-only\"} -->\n<ul class=\"wp-block-social-links is-style-logos-only\">\n<!-- wp:social-link {\"url\":\"https://www.facebook.com/WordPress/\",\"service\":\"facebook\",\"label\":\"Visit our Facebook page\"} /-->\n<!-- wp:social-link {\"url\":\"https://twitter.com/WordPress\",\"service\":\"twitter\",\"label\":\"Visit our Twitter account\"} /-->\n</ul>\n<!-- /wp:social-links -->",
[ 'Visit our Facebook page', 'Visit our Twitter account' ],
],
[
// List with links
"<!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li><a href=\"#\">Fonts API</a></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Interactivity <a href=\"#\">Link</a> API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><a href=\"\">Block API</a></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->",
[ 'Fonts API', 'Interactivity <a href="#">Link</a> API', 'Block API' ],
],
[
// List of lists
"<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>APIs:<!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li>Fonts API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Interactivity API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Block API</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list --></li>\n<!-- /wp:list-item -->\n</ul>\n<!-- /wp:list -->",
[ 'APIs:', 'Fonts API', 'Interactivity API', 'Block API' ],
],
];
}

/**
* Test string parsing from valid block content.
*
* @dataProvider data_block_content_strings
*/
public function test_strings_parser( $block_content, $expected ) {
$parser = new BlockParser( $block_content );
$strings = $parser->to_strings();
$this->assertSame( $expected, $strings );
}

/**
* Data provider for valid block content and the i18n-ized results.
*
* @return array
*/
public function data_block_content_i18n() {
return [
[
// Two plain paragraphs.
"<!-- wp:paragraph -->\n<p>One.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>Two.</p>\n<!-- /wp:paragraph -->",
"<!-- wp:paragraph -->\n<p><?php _e( 'One.', 'wporg' ); ?></p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p><?php _e( 'Two.', 'wporg' ); ?></p>\n<!-- /wp:paragraph -->",
],
[
// Image block with an alt.
"<!-- wp:image {\"width\":150,\"height\":45,\"linkDestination\":\"custom\"} -->\n<figure class=\"wp-block-image is-resized\"><a href=\"#\"><img src=\"./badge-apple.png\" alt=\"Download on the Apple App Store\" width=\"150\" height=\"45\" /></a></figure>\n<!-- /wp:image -->",
"<!-- wp:image {\"width\":150,\"height\":45,\"linkDestination\":\"custom\"} -->\n<figure class=\"wp-block-image is-resized\"><a href=\"#\"><img src=\"./badge-apple.png\" alt=\"<?php _e( 'Download on the Apple App Store', 'wporg' ); ?>\" width=\"150\" height=\"45\" /></a></figure>\n<!-- /wp:image -->",
],
[
// Navigation with custom navigation links.
"<!-- wp:navigation {\"textColor\":\"blueberry-1\",\"overlayMenu\":\"never\",\"className\":\"is-style-dots\",\"style\":{\"spacing\":{\"blockGap\":\"0px\"}},\"fontSize\":\"small\"} -->\n<!-- wp:navigation-link {\"label\":\"Releases\",\"url\":\"#\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n<!-- /wp:navigation -->",
"<!-- wp:navigation {\"textColor\":\"blueberry-1\",\"overlayMenu\":\"never\",\"className\":\"is-style-dots\",\"style\":{\"spacing\":{\"blockGap\":\"0px\"}},\"fontSize\":\"small\"} -->\n<!-- wp:navigation-link {\"label\":\"<?php _e( 'Releases', 'wporg' ); ?>\",\"url\":\"#\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->\n<!-- /wp:navigation -->",
],
[
// List with links
"<!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li><a href=\"#\">Fonts API</a></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Interactivity <a href=\"#\">Link</a> API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><a href=\"\">Block API</a></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->",
"<!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li><a href=\"#\"><?php _e( 'Fonts API', 'wporg' ); ?></a></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><?php _e( 'Interactivity <a href=\"#\">Link</a> API', 'wporg' ); ?></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><a href=\"\"><?php _e( 'Block API', 'wporg' ); ?></a></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->",
],
[
// List of lists
"<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>APIs:<!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li>Fonts API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Interactivity API</li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li>Block API</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list --></li>\n<!-- /wp:list-item -->\n</ul>\n<!-- /wp:list -->\n",
"<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li><?php _e( 'APIs:', 'wporg' ); ?><!-- wp:list -->\n<ul>\n<!-- wp:list-item -->\n<li><?php _e( 'Fonts API', 'wporg' ); ?></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><?php _e( 'Interactivity API', 'wporg' ); ?></li>\n<!-- /wp:list-item -->\n<!-- wp:list-item -->\n<li><?php _e( 'Block API', 'wporg' ); ?></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list --></li>\n<!-- /wp:list-item -->\n</ul>\n<!-- /wp:list -->\n",
],
[
"<!-- wp:quote -->\n<blockquote class=\"wp-block-quote\"><!-- wp:paragraph -->\m<p>I'm interested in running the open-source WordPress &lt;https://wordpress.org/&gt; web software and I was wondering if my account supported the following:</p>\n<!-- /wp:paragraph --></blockquote>\n<!-- /wp:quote -->",
"<!-- wp:quote -->\n<blockquote class=\"wp-block-quote\"><!-- wp:paragraph -->\m<p><?php _e( 'I&#039;m interested in running the open-source WordPress &lt;https://wordpress.org/&gt; web software and I was wondering if my account supported the following:', 'wporg' ); ?></p>\n<!-- /wp:paragraph --></blockquote>\n<!-- /wp:quote -->",
],
];
}

/**
* Test the i18n replacement.
*
* @dataProvider data_block_content_i18n
*/
public function test_i18n_replacement( $block_content, $expected ) {
$content_with_i18n = replace_with_i18n( $block_content );
$this->assertSame( $expected, $content_with_i18n );
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"build:theme": "yarn workspace wporg-main-2022-theme build",
"lint:frontend": "yarn workspace wporg-main-2022-theme lint:css && yarn workspace wporg-main-2022-theme lint:js",
"lint:php": "composer run lint source/wp-content/themes/wporg-main-2022 source/wp-content/mu-plugins/theme-switcher.php env",
"start:theme": "yarn workspace wporg-main-2022-theme start"
"start:theme": "yarn workspace wporg-main-2022-theme start",
"test:php": "wp-env run phpunit 'WP_MULTISITE=1 phpunit -c /var/www/html/wp-content/tests/phpunit/phpunit.xml --verbose'"
},
"workspaces": [
"source/wp-content/themes/wporg-main-2022"
Expand Down
44 changes: 44 additions & 0 deletions source/wp-content/tests/phpunit/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* PHPUnit bootstrap file
*/

// Require composer dependencies.
require_once __DIR__ . '/../../../vendor/autoload.php';

// Detect where to load the WordPress tests environment from.
if ( false !== getenv( 'WP_TESTS_DIR' ) ) {
$_test_root = getenv( 'WP_TESTS_DIR' );
} else {
$_test_root = __DIR__ . '/../../../vendor/wp-phpunit/wp-phpunit';
}

// Give access to tests_add_filter() function.
require_once $_test_root . '/includes/functions.php';

/**
* Adds a wp_die handler for use during tests.
*
* If bootstrap.php triggers wp_die, it will not cause the script to fail. This
* means that tests will look like they passed even though they should have
* failed. So we throw an exception if WordPress dies during test setup. This
* way the failure is observable.
*
* @param string|WP_Error $message The error message.
*
* @throws Exception When a `wp_die()` occurs.
*/
function fail_if_died( $message ) {
if ( is_wp_error( $message ) ) {
$message = $message->get_error_message();
}

throw new Exception( 'WordPress died: ' . $message );
}
tests_add_filter( 'wp_die_handler', 'fail_if_died' );

// Start up the WP testing environment.
require_once $_test_root . '/includes/bootstrap.php';

// Use existing behavior for wp_die during actual test execution.
remove_filter( 'wp_die_handler', 'fail_if_died' );
14 changes: 14 additions & 0 deletions source/wp-content/tests/phpunit/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<phpunit
bootstrap="./bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="export-content">
<directory suffix="-test.php">../../../env/export-content/tests</directory>
</testsuite>
</testsuites>
</phpunit>

0 comments on commit 1730ec9

Please sign in to comment.