Files
comic-easel/tests/bootstrap.php
T
coraislovely-code 1a405071aa Add a PHPUnit harness that runs without WordPress
The plugin has never had a test of any kind. The obstacle has always been that testing a
WordPress plugin appears to require WordPress, and therefore a database.

It does not, for the part that matters. The plugin's logic -- escaping decisions, SQL
construction, payment validation -- depends only on its arguments plus a small set of
WordPress helpers. Stubbing those gives a suite that runs in milliseconds with no database,
no Docker and no WordPress checkout.

Three of the stubs have to be faithful or the tests they support quietly stop meaning
anything, and this is documented at the top of tests/stubs.php:

- esc_html()/esc_attr() call _wp_specialchars() with $double_encode = false, so they leave
  existing entities alone, while esc_textarea() double-encodes. Much of this plugin's
  escaping behaviour turns on that difference, so a naive htmlspecialchars() stub would
  give the wrong answer.
- wp_kses_post() is a recorder returning a sentinel rather than a reimplementation. The
  question worth asking is "was filtering applied", not "what did it strip".
- apply_filters() passes through by default but is overridable, because the plugin's
  filters are the seams the tests need.

Also included is a $wpdb spy that records the SQL it is handed. That is what allows the
query construction to be tested without a database at all -- which matters here, because
the plugin's queries use MySQL-only date functions that a SQLite test database would
misreport.

HarnessTest.php asserts these properties of the harness itself. If it fails, nothing else
in the suite should be trusted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 08:36:22 -04:00

50 lines
1.4 KiB
PHP

<?php
/**
* PHPUnit bootstrap for Comic Easel.
*
* WordPress is not loaded. See tests/stubs.php for the rationale and for the stubs the
* tests depend on.
*/
// Plugin files guard themselves with `if (!defined('ABSPATH')) exit;`, so this has to be
// defined before any of them are required.
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __DIR__ ) . '/' );
}
define( 'CE_PLUGIN_DIR', dirname( __DIR__ ) );
require_once __DIR__ . '/stubs.php';
/**
* ceo_pluginfo() is the plugin's own config accessor. It lives in comiceasel.php, which
* does far too much at load time to require in a unit test, so it is stubbed here and
* driven from CE_Test_State::$pluginfo.
*/
if ( ! function_exists( 'ceo_pluginfo' ) ) {
function ceo_pluginfo( $which = null ) {
if ( null === $which ) {
return CE_Test_State::$pluginfo;
}
return array_key_exists( $which, CE_Test_State::$pluginfo ) ? CE_Test_State::$pluginfo[ $which ] : '';
}
}
/**
* Plugin-local navigation helpers, stubbed so the archive listings can be called without
* dragging in functions/navigation.php and its query dependencies. Not under test here.
*/
if ( ! function_exists( 'ceo_get_last_comic' ) ) {
function ceo_get_last_comic( $in_same_chapter = false ) {
return null;
}
}
if ( ! function_exists( 'ceo_get_first_comic' ) ) {
function ceo_get_first_comic( $in_same_chapter = false ) {
return null;
}
}
require_once __DIR__ . '/CE_TestCase.php';