Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 3 additions & 2 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
"."
],
"phpVersion": "8.4",
"core": "WordPress/WordPress#6.9",
"config": {
"WP_DEBUG": true,
"WP_DEBUG_LOG": true,
"SCRIPT_DEBUG": true
},
"env": {
"tests": {
"phpVersion": "8.4",
"core": "WordPress/WordPress#6.9"
"phpVersion": "8.5",
"core": "WordPress/WordPress#7.0"
}
}
}
9 changes: 6 additions & 3 deletions bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

This directory contains helper scripts used during development and CI:

- `php-lint`: lints all PHP files for syntax errors.
- `xml-lint`: lints `.xml` and `.xml.dist` config files against their schemas.
- `wp-env-phpunit`: runs PHPUnit inside the wp-env tests container, deriving the plugin mount path from the clone directory name. Pass `--multisite` to run against a multisite installation.
- `xml-lint`: validates `.phpcs.xml.dist` and `phpunit.xml.dist` against their bundled schemas, and checks the formatting of the PHPCS ruleset. Requires `composer install` first.

PHP syntax linting is handled by [PHP Parallel Lint](https://github.com/php-parallel-lint/PHP-Parallel-Lint) via `composer lint`.

## Running integration tests

Expand All @@ -12,5 +14,6 @@ Integration tests run inside [`@wordpress/env`](https://developer.wordpress.org/
```sh
npm -g install @wordpress/env
wp-env start
composer integration
composer test:integration
composer test:integration-ms
```
26 changes: 7 additions & 19 deletions bin/php-lint
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
#!/usr/bin/env bash
#
# Lint the PHP files against parse errors.
#
# The find utility recursively descends the directory tree for each path listed.
#
# find . = Start with all files in this package
# -path ./vendor -prune = But remove those in the vendor directory
# -o -path ./bin -prune = And remove those in the bin directory
# -o -path ./.git -prune = And remove those in the .git directory
# -o -name "*.php" = And only consider those with a .php extension
# -exec php -l {} = Run PHP linter on the remaining files
# | grep "^[Parse error|Fatal error]" = Look in the results for any parse or fatal errors.
#
# EXAMPLE TO RUN LOCALLY:
#
# ./bin/php-lint
#
# Temporary shim for the pre-refresh CI workflow, which calls bin/php-lint
# directly. PHP syntax linting now lives in `composer lint` via
# php-parallel-lint; the CI refresh removes this file when it switches the
# workflow to the new entry points.

set -euo pipefail

if find . -path ./vendor -prune -o -path ./bin -prune -o -path ./.git -prune -o -name "*.php" -exec php -l -f {} \; | grep "^[Errors parsing]"; then
exit 1;
fi
exec vendor/bin/parallel-lint . --exclude vendor --exclude node_modules
31 changes: 31 additions & 0 deletions bin/wp-env-phpunit
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
#
# Run PHPUnit inside the wp-env tests-cli container.
#
# wp-env mounts the plugin into the container at
# wp-content/plugins/<directory name>, where <directory name> is whatever
# the repository was cloned as on the host. Derive that mount point from
# the repository root rather than hardcoding the plugin slug, so the
# integration tests work regardless of the clone directory name.
#
# Pass --multisite as the first argument to run the suite against a
# WordPress multisite installation (sets WP_MULTISITE=1 for the WordPress
# core test framework). All other arguments are passed through to PHPUnit.
#
# EXAMPLES TO RUN LOCALLY:
#
# ./bin/wp-env-phpunit --testsuite integration
# ./bin/wp-env-phpunit --multisite --testsuite integration

set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
env_cwd="wp-content/plugins/$(basename "${repo_root}")"

if [[ "${1:-}" == "--multisite" ]]; then
shift
args="$(printf ' %q' "$@")"
exec wp-env run tests-cli --env-cwd="${env_cwd}" /bin/bash -c "WP_MULTISITE=1 ./vendor/bin/phpunit${args}"
fi

exec wp-env run tests-cli --env-cwd="${env_cwd}" ./vendor/bin/phpunit "$@"
16 changes: 13 additions & 3 deletions bin/xml-lint
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
#!/usr/bin/env bash
#
# Check XML files.
# Check XML configuration files.
#
# Validates the dist config files against the schemas bundled with their
# respective tools, then checks the code-style consistency of the PHPCS
# ruleset. Requires `composer install` to have been run first, as the
# schemas live in vendor/.
#
# @link http://xmlsoft.org/xmllint.html
#
# EXAMPLE TO RUN LOCALLY:
#
# ./bin/xml-lint

# Validate the ruleset XML files.
set -euo pipefail

# Validate the PHPCS ruleset against the schema bundled with PHP_CodeSniffer.
xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd .phpcs.xml.dist

# Check the code-style consistency of the XML files.
# Validate the PHPUnit configuration against the schema bundled with PHPUnit.
xmllint --noout --schema ./vendor/phpunit/phpunit/phpunit.xsd phpunit.xml.dist

# Check the code-style consistency of the PHPCS ruleset.
export XMLLINT_INDENT=" " # This is a tab character.
diff -B --tabsize=4 .phpcs.xml.dist <(xmllint --format ".phpcs.xml.dist")
86 changes: 57 additions & 29 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
{
"name": "gamajo/plugin-slug",
"type": "wordpress-plugin",
"description": "Test plugin",
"license": "GPL-2.0-or-later",
"type": "wordpress-plugin",
"keywords": [
"plugin",
"plugin-slug"
],
"homepage": "https://github.com/GaryJones/plugin-slug",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "Gary Jones",
"homepage": "https://garyjones.io",
"role": "Developer"
}
],
"homepage": "https://github.com/GaryJones/plugin-slug",
"support": {
"issues": "https://github.com/GaryJones/plugin-slug/issues",
"source": "https://github.com/GaryJones/plugin-slug"
},
"require": {
"php": "^8.4",
"brightnucleus/config": "^0.5",
Expand All @@ -25,23 +29,20 @@
"automattic/vipwpcs": "^3",
"brain/monkey": "^2",
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"ergebnis/composer-normalize": "^2.52",
"infection/infection": "^0.33",
"mockery/mockery": "^1.6",
"php-parallel-lint/php-parallel-lint": "^1.4",
"phpcompatibility/phpcompatibility-wp": "^2",
"phpunit/phpunit": "^9",
"phpunit/phpunit": "^9.6",
"rector/rector": "^2.4",
"roave/security-advisories": "dev-master",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3",
"wp-coding-standards/wpcs": "^3",
"yoast/phpunit-polyfills": "^4"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"infection/extension-installer": true
}
},
"minimum-stability": "stable",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Gamajo\\PluginSlug\\": "src/"
Expand All @@ -52,33 +53,60 @@
"Gamajo\\PluginSlug\\Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"ergebnis/composer-normalize": true,
"infection/extension-installer": true
},
"sort-packages": true
},
"scripts": {
"infection": "./vendor/bin/infection --no-progress",
"integration": "wp-env run tests-cli --env-cwd=wp-content/plugins/plugin-slug ./vendor/bin/phpunit --testsuite integration",
"coverage": "@php ./vendor/bin/phpunit --testsuite unit --coverage-html .phpunit.cache/coverage-html",
"cs": "@php ./vendor/bin/phpcs",
"cs-fix": "@php ./vendor/bin/phpcbf",
"infection": "./vendor/bin/infection --no-progress --threads=max --show-mutations",
"integration": "@test:integration",
"lint": [
"bin/php-lint",
"@php ./vendor/bin/parallel-lint . --exclude vendor --exclude node_modules",
"bin/xml-lint"
],
"cbf": "@php vendor/bin/phpcbf",
"cs": "@php vendor/bin/phpcs",
"rector": "@php ./vendor/bin/rector process --dry-run",
"rector:fix": "@php ./vendor/bin/rector process",
"test": [
"@lint",
"@unit",
"@cs"
"@cs",
"@test:unit"
],
"test-full": [
"@lint",
"@unit",
"@cs",
"@rector",
"@test:unit",
"@infection",
"@integration",
"@cs"
"@test:integration",
"@test:integration-ms"
],
"unit": "./vendor/bin/phpunit --testsuite unit"
"test:integration": "bin/wp-env-phpunit --testsuite integration",
"test:integration-ms": "bin/wp-env-phpunit --multisite --testsuite integration",
"test:unit": "@php ./vendor/bin/phpunit --testsuite unit",
"unit": "@test:unit"
},
"support": {
"issues": "https://github.com/GaryJones/plugin-slug/issues",
"source": "https://github.com/GaryJones/plugin-slug"
"scripts-descriptions": {
"coverage": "Run the unit tests and generate an HTML coverage report in .phpunit.cache/coverage-html.",
"cs": "Check coding standards with PHP_CodeSniffer.",
"cs-fix": "Fix automatically fixable coding standards violations with PHP Code Beautifier and Fixer.",
"infection": "Run mutation testing with Infection.",
"integration": "Deprecated alias for test:integration, kept until CI moves to the new script names.",
"lint": "Check PHP files for syntax errors and XML config files against their schemas.",
"rector": "Preview automated refactorings with Rector (dry run).",
"rector:fix": "Apply automated refactorings with Rector.",
"test": "Run the quick checks: lint, coding standards, and unit tests.",
"test-full": "Run every check: lint, coding standards, Rector, unit, mutation, and integration tests.",
"test:integration": "Run the integration tests inside the wp-env tests container.",
"test:integration-ms": "Run the integration tests against WordPress multisite inside the wp-env tests container.",
"test:unit": "Run the unit tests.",
"unit": "Deprecated alias for test:unit, kept until CI moves to the new script names."
}
}
3 changes: 3 additions & 0 deletions infection.json.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"$schema": "vendor/infection/infection/resources/schema.json",
"timeout": 10,
"minMsi": 100,
"minCoveredMsi": 100,
"source": {
"directories": [
"src"
Expand Down
11 changes: 7 additions & 4 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Deliberately pinned to the PHPUnit 9.6 schema: the integration suite
extends WP_UnitTestCase from the WordPress core test framework, which
still targets yoast/phpunit-polyfills 1.x / PHPUnit 9.6 or earlier.
Revisit when WordPress core moves to a newer PHPUnit.
-->
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
Expand Down Expand Up @@ -29,11 +35,8 @@
<directory suffix=".php">src</directory>
</include>
<report>
<clover outputFile=".phpunit.cache/clover.xml"/>
<text outputFile="php://stdout"/>
</report>
</coverage>

<logging>
<!--<log type="coverage-html" target="coverage"/>-->
</logging>
</phpunit>
6 changes: 4 additions & 2 deletions tests/Integration/FooTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @package Gamajo\PluginSlug\Tests\Integration
* @author Gary Jones
* @copyright 2024 Gary Jones
* @copyright 2024-2026 Gary Jones
* @license GPL-2.0-or-later
*/

Expand All @@ -17,13 +17,15 @@

/**
* Foo test case.
*
* @covers \Gamajo\PluginSlug\Foo
*/
class FooTest extends WP_UnitTestCase {
/**
* A single example test.
*/
public function test_foo(): void {
// Replace this with some actual integration testing code.
static::assertTrue( ( new Testee() )->is_true() );
static::assertTrue( new Testee()->is_true() );
}
}
8 changes: 4 additions & 4 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @package Gamajo\PluginSlug\Tests
* @author Gary Jones
* @copyright 2024 Gary Jones
* @copyright 2024-2026 Gary Jones
* @license GPL-2.0-or-later
*/

Expand All @@ -20,15 +20,15 @@
* Abstract base class for all test case implementations.
*
* @package Gamajo\PluginSlug\Tests
* @since 1.0.0
* @since 0.1.0
*/
abstract class TestCase extends PHPUnitTestCase {
use MockeryPHPUnitIntegration;

/**
* Prepares the test environment before each test.
*
* @since 1.0.0
* @since 0.1.0
*/
protected function setUp(): void {
parent::setUp();
Expand All @@ -38,7 +38,7 @@ protected function setUp(): void {
/**
* Cleans up the test environment after each test.
*
* @since 1.0.0
* @since 0.1.0
*/
protected function tearDown(): void {
Monkey\tearDown();
Expand Down
8 changes: 5 additions & 3 deletions tests/Unit/FooTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @package Gamajo\PluginSlug\Tests\Unit
* @author Gary Jones
* @copyright 2024 Gary Jones
* @copyright 2024-2026 Gary Jones
* @license GPL-2.0-or-later
*/

Expand All @@ -17,6 +17,8 @@

/**
* Foo test case.
*
* @covers \Gamajo\PluginSlug\Foo
*/
class FooTest extends TestCase {

Expand All @@ -25,7 +27,7 @@ class FooTest extends TestCase {
*/
public function test_method_asserts_as_true(): void {
// Replace this with some actual testing code.
static::assertTrue( ( new Testee() )->is_true() );
static::assertTrue( new Testee()->is_true() );
}

/**
Expand All @@ -41,6 +43,6 @@ public function test_false_asserts_as_false(): void {
*/
public function test_method_call_value_equals_method_call_value(): void {
// Replace this with some actual testing code.
static::assertEquals( 'Foo::bar()', ( new Testee() )->bar() );
static::assertSame( 'Foo::bar()', new Testee()->bar() );
}
}
Loading