start unit test implementation
This commit is contained in:
parent
b054dfaba2
commit
2cb4b62df3
@ -1,13 +1,16 @@
|
||||
/.git
|
||||
/.github
|
||||
/assets
|
||||
/bin
|
||||
/node_modules
|
||||
/tests
|
||||
/vendor
|
||||
/.distignore
|
||||
/.drone.yml
|
||||
/.eslintrc.json
|
||||
/.gitattributes
|
||||
/.gitignore
|
||||
/.phpunit.result.cache
|
||||
/.stylelintrc.json
|
||||
/.travis.yml
|
||||
/composer.json
|
||||
|
@ -6,11 +6,11 @@ steps:
|
||||
- name: composer-install
|
||||
image: composer:2
|
||||
commands:
|
||||
- composer install
|
||||
- composer install --ignore-platform-reqs
|
||||
- name: lint-php
|
||||
image: composer:2
|
||||
image: php:7.4
|
||||
commands:
|
||||
- composer lint-php
|
||||
- ./vendor/bin/phpcs
|
||||
depends_on:
|
||||
- composer-install
|
||||
- name: node-install
|
||||
@ -26,3 +26,4 @@ steps:
|
||||
- npx stylelint styles/liveticker.css
|
||||
depends_on:
|
||||
- node-install
|
||||
|
||||
|
34
.gitattributes
vendored
34
.gitattributes
vendored
@ -1,16 +1,20 @@
|
||||
/assets export-ignore
|
||||
.distignore export-ignore
|
||||
.drone.yml export-ignore
|
||||
.eslintrc.json export-ignore
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.stylelintrc.json export-ignore
|
||||
.travis.yml export-ignore
|
||||
composer.json export-ignore
|
||||
composer.lock export-ignore
|
||||
CONTRIBUTING.md export-ignore
|
||||
package.json export-ignore
|
||||
package-lock.json export-ignore
|
||||
phpcs.xml export-ignore
|
||||
phpunit.xml export-ignore
|
||||
RoboFile.php export-ignore
|
||||
/.github export-ignore
|
||||
/.distignore export-ignore
|
||||
/.drone.yml export-ignore
|
||||
/.eslintrc.json export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.stylelintrc.json export-ignore
|
||||
/.travis.yml export-ignore
|
||||
/bin export-ignore
|
||||
/composer.json export-ignore
|
||||
/composer.lock export-ignore
|
||||
/CONTRIBUTING.md export-ignore
|
||||
/package.json export-ignore
|
||||
/package-lock.json export-ignore
|
||||
/phpcs.xml export-ignore
|
||||
/phpunit.xml export-ignore
|
||||
/RoboFile.php export-ignore
|
||||
/tests export-ignore
|
||||
|
||||
|
29
.github/workflows/test.yml
vendored
29
.github/workflows/test.yml
vendored
@ -1,6 +1,32 @@
|
||||
name: CI
|
||||
on: push
|
||||
jobs:
|
||||
integration:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- php: '7.4'
|
||||
wordpress: '5.7'
|
||||
- php: '5.6'
|
||||
wordpress: '4.7'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
tools: composer
|
||||
- name: Setup DB
|
||||
run: sudo /etc/init.d/mysql start
|
||||
- name: Setup WP
|
||||
run: bash bin/install-wp-tests.sh wordpress root root localhost "${{ matrix.wordpress }}"
|
||||
- name: Install
|
||||
run: composer install
|
||||
- name: Test
|
||||
run: composer test
|
||||
|
||||
quality:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -9,7 +35,7 @@ jobs:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
php-version: '7.4'
|
||||
tools: composer
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v2
|
||||
@ -24,6 +50,7 @@ jobs:
|
||||
composer lint-php
|
||||
composer lint-js
|
||||
composer lint-css
|
||||
|
||||
analysis:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,7 +1,6 @@
|
||||
/vendor/
|
||||
/node_modules/
|
||||
/dist/
|
||||
.idea
|
||||
.phpunit.result.cache
|
||||
/.phpunit.result.cache
|
||||
**/*.min.css
|
||||
**/*.min.js
|
||||
|
152
bin/install-wp-tests.sh
Executable file
152
bin/install-wp-tests.sh
Executable file
@ -0,0 +1,152 @@
|
||||
#!/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}
|
||||
|
||||
TMPDIR=${TMPDIR-/tmp}
|
||||
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
|
||||
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
|
||||
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/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]+$ ]]; then
|
||||
WP_TESTS_TAG="branches/$WP_VERSION"
|
||||
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
||||
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
||||
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
||||
WP_TESTS_TAG="tags/${WP_VERSION%??}"
|
||||
else
|
||||
WP_TESTS_TAG="tags/$WP_VERSION"
|
||||
fi
|
||||
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 $TMPDIR/wordpress-nightly
|
||||
download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip
|
||||
unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/
|
||||
mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR
|
||||
else
|
||||
if [ $WP_VERSION == 'latest' ]; then
|
||||
local ARCHIVE_NAME='latest'
|
||||
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
|
||||
# https serves multiple offers, whereas http serves single.
|
||||
download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
|
||||
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
||||
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
||||
LATEST_VERSION=${WP_VERSION%??}
|
||||
else
|
||||
# otherwise, scan the releases and get the most up to date minor version of the major release
|
||||
local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
|
||||
LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
|
||||
fi
|
||||
if [[ -z "$LATEST_VERSION" ]]; then
|
||||
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
||||
else
|
||||
local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
|
||||
fi
|
||||
else
|
||||
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
||||
fi
|
||||
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
|
||||
tar --strip-components=1 -zxmf $TMPDIR/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
|
@ -23,8 +23,7 @@
|
||||
"require-dev": {
|
||||
"php": ">=7",
|
||||
"consolidation/robo": "^2",
|
||||
"phpunit/phpunit": "^9",
|
||||
"phpunit/php-code-coverage": "^9",
|
||||
"phpunit/phpunit": "^7",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
|
||||
"slowprog/composer-copy-file": "~0.3",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
|
931
composer.lock
generated
931
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,7 @@ class Api {
|
||||
if ( ! empty( $limit ) && $limit > 0 ) {
|
||||
$args['posts_per_page'] = $limit;
|
||||
} else {
|
||||
$args['paged'] = false;
|
||||
$args['nopaging'] = true;
|
||||
}
|
||||
|
||||
if ( $last_poll > 0 ) {
|
||||
|
15
phpunit.xml
15
phpunit.xml
@ -1,8 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<phpunit bootstrap="./vendor/autoload.php">
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true">
|
||||
<testsuites>
|
||||
<testsuite name="WP Liveticker 2 TestSuite">
|
||||
<directory suffix="-test.php">./test/</directory>
|
||||
<directory prefix="test-" suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">includes</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
|
31
tests/bootstrap.php
Normal file
31
tests/bootstrap.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* PHPUnit bootstrap file
|
||||
*
|
||||
* @package SCLiveticker
|
||||
*/
|
||||
|
||||
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
||||
|
||||
if ( ! $_tests_dir ) {
|
||||
$_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib';
|
||||
}
|
||||
|
||||
if ( ! file_exists( $_tests_dir . '/includes/functions.php' ) ) {
|
||||
echo "Could not find $_tests_dir/includes/functions.php, have you run bin/install-wp-tests.sh ?";
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// 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__ ) ) . '/stklcode-liveticker.php';
|
||||
}
|
||||
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
||||
|
||||
// Start up the WP testing environment.
|
||||
require $_tests_dir . '/includes/bootstrap.php';
|
141
tests/test-api.php
Normal file
141
tests/test-api.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Liveticker: Plugin API tests.
|
||||
*
|
||||
* This file contains unit tests for the plugin's REST API extensions.
|
||||
*
|
||||
* @package SCLiveticker
|
||||
*/
|
||||
|
||||
namespace SCLiveticker;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Server;
|
||||
use WP_UnitTestCase;
|
||||
|
||||
/**
|
||||
* Class Test_API.
|
||||
*/
|
||||
class Test_API extends WP_UnitTestCase {
|
||||
/**
|
||||
* Initialize WP REST API for tests.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
global $wp_rest_server;
|
||||
$wp_rest_server = new WP_REST_Server();
|
||||
do_action( 'rest_api_init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test presence of registered routes for ticks and tickers.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_register_route() {
|
||||
global $wp_rest_server;
|
||||
|
||||
$routes = $wp_rest_server->get_routes();
|
||||
|
||||
self::assertArrayHasKey( '/wp/v2/scliveticker_tick', $routes, 'Ticks not exposed in API' );
|
||||
self::assertArrayHasKey( '/wp/v2/scliveticker_tick/(?P<id>[\d]+)', $routes, 'Specific ticks not exposed in API' );
|
||||
self::assertArrayHasKey( '/wp/v2/scliveticker_ticker', $routes, 'Tickers not exposed in API' );
|
||||
self::assertArrayHasKey( '/wp/v2/scliveticker_ticker/(?P<id>[\d]+)', $routes, 'Specific tickers not exposed in API' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetching ticks and tickers via the REST API.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_ticks() {
|
||||
global $wp_rest_server;
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/scliveticker_tick' );
|
||||
$response = $wp_rest_server->dispatch( $request );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code' );
|
||||
self::assertEmpty( $response->get_data(), 'No data expected on empty database' );
|
||||
|
||||
// Create two tickers with 10 ticks each.
|
||||
wp_set_current_user( 1 );
|
||||
$ticker_id = array(
|
||||
1 => self::factory()->term->create(
|
||||
array(
|
||||
'name' => 'Ticker 1',
|
||||
'description' => 'Test Liveticker 1',
|
||||
'slug' => 'ticker1',
|
||||
'taxonomy' => 'scliveticker_ticker',
|
||||
)
|
||||
),
|
||||
2 >= self::factory()->term->create(
|
||||
array(
|
||||
'name' => 'Ticker 2',
|
||||
'description' => 'Test Liveticker 2',
|
||||
'slug' => 'ticker2',
|
||||
'taxonomy' => 'scliveticker_ticker',
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
$dt = new DateTime( '2021-05-22 16:17:18' );
|
||||
foreach ( range( 1, 20 ) as $n ) {
|
||||
$t = 0 === $n % 2 ? '1' : '2';
|
||||
$i = ceil( $n / 2 );
|
||||
$p = self::factory()->post->create(
|
||||
array(
|
||||
'post_type' => 'scliveticker_tick',
|
||||
'post_date_gmt' => $dt->format( 'Y-m-d H_i_s' ),
|
||||
'post_title' => 'Tick ' . $t . '.' . $i,
|
||||
'post_status' => 'publish',
|
||||
'post_content' => 'Content of Tick ' . $t . '.' . $i,
|
||||
)
|
||||
);
|
||||
wp_set_object_terms( $p, $ticker_id[ $t ], 'scliveticker_ticker' );
|
||||
$dt->add( new DateInterval( 'PT1M' ) );
|
||||
}
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
// Verify ticker presence via API.
|
||||
$response = $wp_rest_server->dispatch( new WP_REST_Request( 'GET', '/wp/v2/scliveticker_ticker' ) );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code' );
|
||||
self::assertEquals( 2, count( $response->get_data() ), 'Unexpected number of tickers' );
|
||||
|
||||
// Query all entries.
|
||||
$response = $wp_rest_server->dispatch( $request );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code' );
|
||||
self::assertEquals( 20, count( $response->get_data() ), 'Unexpected number of ticks without filter' );
|
||||
|
||||
// Limit number of entries.
|
||||
$request->set_param( 'limit', 12 );
|
||||
$response = $wp_rest_server->dispatch( $request );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code with limit' );
|
||||
self::assertEquals( 12, count( $response->get_data() ), 'Unexpected number of ticks with limit' );
|
||||
|
||||
// Filter by time.
|
||||
$request->set_param( 'limit', null );
|
||||
$request->set_param( 'last', $response->get_data()[5]['date_gmt'] );
|
||||
$response = $wp_rest_server->dispatch( $request );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code with time filter' );
|
||||
self::assertEquals( 5, count( $response->get_data() ), 'Unexpected number of ticks with time filter' );
|
||||
|
||||
// Filter by ticker.
|
||||
$request->set_param( 'last', null );
|
||||
$request->set_param( 'ticker', 'ticker1' );
|
||||
$response = $wp_rest_server->dispatch( $request );
|
||||
self::assertEquals( 200, $response->get_status(), 'Unexpected status code with ticker filter' );
|
||||
self::assertEquals( 10, count( $response->get_data() ), 'Unexpected number of ticks with ticker filter' );
|
||||
self::assertEmpty(
|
||||
array_filter(
|
||||
$response->get_data(),
|
||||
function ( $t ) use ( $ticker_id ) {
|
||||
return 1 !== count( $t['scliveticker_ticker'] ) || ! in_array( $ticker_id[1], $t['scliveticker_ticker'], true );
|
||||
}
|
||||
),
|
||||
'No tick from ticker 2 should be present filtering for ticker1'
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user