Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup server side unit tests #617

Merged
merged 9 commits into from
May 5, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 67 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
language: node_js
node_js:
- "node"
sudo: false

language: php

notifications:
email:
on_success: never
on_failure: change

branches:
only:
- master

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above 3 lines will need to be removed won't they if we want Travis to run against each PR?

cache:
directories:
- vendor
- $HOME/.composer/cache

env:
- TRAVIS_NODE_VERSION="7"

install:
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION

matrix:
include:
- php: 7.1
env: WP_VERSION=latest
- php: 5.6
env: WP_VERSION=latest
- php: 5.2
env: WP_VERSION=latest
- php: 5.6
env: TRAVISCI=phpcs
- php: 5.6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use the latest PHP 7.1 for this (WP Core uses the latest for its JS only job)

env: TRAVISCI=js

before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- |
if [[ ! -z "$WP_VERSION" ]] ; then
bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then
composer global require "phpunit/phpunit=4.8.*"
else
composer global require "phpunit/phpunit=5.7.*"
fi
fi
- |
if [[ "$TRAVISCI" == "phpcs" ]] ; then
composer global require wp-coding-standards/wpcs
phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs
fi

script:
- "npm run ci"
- |
if [[ ! -z "$WP_VERSION" ]] ; then
phpunit
WP_MULTISITE=1 phpunit
fi
- |
if [[ "$TRAVISCI" == "phpcs" ]] ; then
phpcs --standard=phpcs.ruleset.xml $(find . -name '*.php')
fi
- |
if [[ "$TRAVISCI" == "js" ]] ; then
npm run ci
fi
127 changes: 127 additions & 0 deletions bin/install-wp-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env bash

if [ $# -lt 3 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
exit 1
fi

DB_NAME=$1
DB_USER=$2
DB_PASS=$3
DB_HOST=${4-localhost}
WP_VERSION=${5-latest}
SKIP_DB_CREATE=${6-false}

WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}

download() {
if [ `which curl` ]; then
curl -s "$1" > "$2";
elif [ `which wget` ]; then
wget -nv -O "$2" "$1"
fi
}

if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
WP_TESTS_TAG="tags/$WP_VERSION"
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
WP_TESTS_TAG="trunk"
else
# http serves a single offer, whereas https serves multiple. we only want one
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
if [[ -z "$LATEST_VERSION" ]]; then
echo "Latest WordPress version could not be found"
exit 1
fi
WP_TESTS_TAG="tags/$LATEST_VERSION"
fi

set -ex

install_wp() {

if [ -d $WP_CORE_DIR ]; then
return;
fi

mkdir -p $WP_CORE_DIR

if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
mkdir -p /tmp/wordpress-nightly
download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
else
if [ $WP_VERSION == 'latest' ]; then
local ARCHIVE_NAME='latest'
else
local ARCHIVE_NAME="wordpress-$WP_VERSION"
fi
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
fi

download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
}

install_test_suite() {
# portable in-place argument for both GNU sed and Mac OSX sed
if [[ $(uname -s) == 'Darwin' ]]; then
local ioption='-i .bak'
else
local ioption='-i'
fi

# set up testing suite if it doesn't yet exist
if [ ! -d $WP_TESTS_DIR ]; then
# set up testing suite
mkdir -p $WP_TESTS_DIR
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
fi

if [ ! -f wp-tests-config.php ]; then
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
# remove all forward slashes in the end
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
fi

}

install_db() {

if [ ${SKIP_DB_CREATE} = "true" ]; then
return 0
fi

# parse DB_HOST for port or socket references
local PARTS=(${DB_HOST//\:/ })
local DB_HOSTNAME=${PARTS[0]};
local DB_SOCK_OR_PORT=${PARTS[1]};
local EXTRA=""

if ! [ -z $DB_HOSTNAME ] ; then
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
EXTRA=" --socket=$DB_SOCK_OR_PORT"
elif ! [ -z $DB_HOSTNAME ] ; then
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
fi
fi

# create database
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
}

install_wp
install_test_suite
install_db
21 changes: 18 additions & 3 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ function register_block( $slug, $settings ) {
}

if ( isset( $registered_blocks[ $slug ] ) ) {
$message = sprintf( __( 'Block "%s" is already registered.' ), $slug );
_doing_it_wrong( __FUNCTION__, $message, '0.1.0' );
return;
}

Expand All @@ -66,6 +64,23 @@ function register_block( $slug, $settings ) {
return $settings;
}

/**
* Unregisters a block.
*
* @param string slug Block slug
* @return array The previous block value, if it has been
* successfully unregistered; otherwise `null`.
*/
function unregister_block( $slug ) {
global $registered_blocks;
if ( ! isset( $registered_blocks[ $slug ] ) ) {
$message = sprintf( __( 'Block "%s" is not registered.' ), $slug );
_doing_it_wrong( __FUNCTION__, $message, '0.1.0' );
return;
}
unset( $registered_blocks[ $slug ] );
}

/**
* Extract the block attributes from the block's attributes string
*
Expand Down Expand Up @@ -99,7 +114,7 @@ function do_blocks( $content ) {
global $registered_blocks;

// Extract the blocks from the post content
$open_matcher = '/<!--\s*wp:([a-z](?:[a-z0-9\/]+)*)\s+((?:(?!-->).)*)-->.*<!--\s*\/wp:\g1\s+-->/';
$open_matcher = '/<!--\s*wp:([a-z](?:[a-z0-9\/]+)*)\s+((?:(?!-->).)*)-->.*?<!--\s*\/wp:\g1\s+-->/';
preg_match_all( $open_matcher, $content, $matches, PREG_OFFSET_CAPTURE );

$new_content = $content;
Expand Down
10 changes: 10 additions & 0 deletions phpcs.ruleset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<ruleset name="WordPress Coding Standards for Plugins">
<description>Generally-applicable sniffs for WordPress plugins</description>

<rule ref="WordPress-Core" />
<rule ref="WordPress-Docs" />

<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
</ruleset>
14 changes: 14 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<phpunit
bootstrap="phpunit/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite>
<directory prefix="test-" suffix=".php">./phpunit/</directory>
</testsuite>
</testsuites>
</phpunit>
25 changes: 25 additions & 0 deletions phpunit/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* PHPUnit bootstrap file
*
* @package Gutenberg
*/

$_tests_dir = getenv( 'WP_TESTS_DIR' );
if ( ! $_tests_dir ) {
$_tests_dir = '/tmp/wordpress-tests-lib';
}

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

/**
* Manually load the plugin being tested.
*/
function _manually_load_plugin() {
require dirname( dirname( __FILE__ ) ) . '/index.php';
}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );

// Start up the WP testing environment.
require $_tests_dir . '/includes/bootstrap.php';
42 changes: 42 additions & 0 deletions phpunit/test-dynamic-blocks-render.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

class DynamicBlocksRenderTest extends WP_UnitTestCase {
/**
* @expectedIncorrectUsage register_block
*/
function test_invalid_non_string_slugs() {
register_block( 1, array() );
}

/**
* @expectedIncorrectUsage register_block
*/
function test_invalid_slugs_without_namespace() {
register_block( 'text', array() );
}

function render_dummy_block( $attributes ) {
return $attributes[ 'value' ];
}

function test_register_block() {
$settings = array( 'render' => [ $this, 'render_dummy_block' ] );
register_block( 'core/dummy', $settings );
$post_content =
'before' .
'<!-- wp:core/dummy value:b1 --><!-- /wp:core/dummy -->' .
'between' .
'<!-- wp:core/dummy value:b2 --><!-- /wp:core/dummy -->' .
'after';

$updated_post_content = do_blocks( $post_content );
unregister_block( 'core/dummy' );
$this->assertEquals( $updated_post_content,
'before' .
'b1' .
'between' .
'b2' .
'after'
);
}
}
27 changes: 27 additions & 0 deletions phpunit/test-registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

class RegistrationTest extends WP_UnitTestCase {
/**
* @expectedIncorrectUsage register_block
*/
function test_invalid_non_string_slugs() {
register_block( 1, array() );
}

/**
* @expectedIncorrectUsage register_block
*/
function test_invalid_slugs_without_namespace() {
register_block( 'text', array() );
}

function test_register_block() {
$settings = array( 'icon' => 'text' );
$updated_settings = register_block( 'core/text', $settings );
$this->assertEquals( $updated_settings, array(
'icon' => 'text',
'slug' => 'core/text'
) );
unregister_block( 'core/text' );
}
}