Files
2meet-data-optimizer-hivepr…/tests/bootstrap.php
T
wpdev 0a3b05789e test: 建立 phpunit 測試基建並移植 25 個 HivePress 測試
AddOn 先前 tests=0。新增:
- composer.json(dev 依賴 + phpunit/phpcs script)
- phpunit.xml(failOnWarning=true)
- tests/bootstrap.php:直接 require 核心 plugin 的 unit bootstrap,避免複製
  ~700 行 WP stub,再載入本 AddOn 的類別;補 trait wrapper 與自動 WPDO_ alias
  (includes/back-compat-aliases.php 掛在 plugins_loaded:7,PHPUnit 下不會跑)
- tests/unit/ 25 個測試 + WpdbMockTrait(自 A 移植)

生產碼一併修對外契約:interface-tmdo-hp-adapter.php 改為先宣告空的
WPDO_HivePress_Adapter、再讓 TMDO_HivePress_Adapter extends 它(PHP 無法
class_alias 介面,只有繼承能讓 instanceof WPDO_HivePress_Adapter 對
implements TMDO_ 名稱的 adapter 成立)。與核心 interface-entity-adapter.php
同一模式。這也讓第三方自訂 adapter 用舊介面名仍可通過核心檢查。

145 tests / 357 assertions GREEN

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
2026-07-31 09:19:01 +08:00

93 lines
3.9 KiB
PHP

<?php
/**
* PHPUnit bootstrap for the HivePress AddOn.
*
* Reuses the core plugin's unit bootstrap (WP function stubs, $wpdb stub,
* constants, WPDO_* aliases) instead of duplicating ~700 lines of stubs, then
* loads this AddOn's own classes on top.
*
* The core plugin must sit next to this one under wp-content/plugins/.
*
* @package TMDO_HIVEPRESS
*/
declare(strict_types=1);
$tmdo_core_bootstrap = dirname( __DIR__, 2 ) . '/2meet-data-optimizer/tests/bootstrap.php';
if ( ! file_exists( $tmdo_core_bootstrap ) ) {
throw new RuntimeException(
'HivePress AddOn tests require the core plugin at ' . dirname( __DIR__, 2 ) . '/2meet-data-optimizer'
);
}
require_once $tmdo_core_bootstrap;
define( 'TMDO_HIVEPRESS_PATH', dirname( __DIR__ ) . '/' );
define( 'TMDO_HIVEPRESS_URL', 'http://localhost/wp-content/plugins/2meet-data-optimizer-hivepress-addon/' );
define( 'TMDO_HIVEPRESS_FILE', dirname( __DIR__ ) . '/2meet-data-optimizer-hivepress-addon.php' );
define( 'TMDO_HIVEPRESS_VERSION', '0.1.0' );
// ── AddOn classes ──────────────────────────────────────────────────────────
$tmdo_hp_files = array(
'includes/class-tmdo-hivepress.php',
'includes/hivepress/interface-tmdo-hp-adapter.php',
'includes/hivepress/trait-tmdo-hp-adapter.php',
'includes/hivepress/class-tmdo-hivepress-detector.php',
'includes/hivepress/class-tmdo-hivepress-conflict-guard.php',
'includes/hivepress/class-tmdo-hivepress-bootstrap.php',
'includes/hivepress/class-tmdo-hivepress-comment-router.php',
'includes/hivepress/class-tmdo-hivepress-cron-optimizer.php',
'includes/hivepress/class-tmdo-hivepress-attribute-bridge.php',
'includes/hivepress/class-tmdo-hivepress-suitability-scorer.php',
'includes/hivepress/class-tmdo-hivepress-benchmark.php',
'includes/hivepress/class-tmdo-hivepress-rest.php',
'includes/class-tmdo-hivepress-transient-filter.php',
'includes/class-tmdo-hivepress-term-comment-fields.php',
'includes/class-tmdo-hpct-import.php',
// class-tmdo-listing-stats.php is deliberately NOT loaded: the core unit
// bootstrap already declares a TMDO_Listing_Stats stub, and no test in this
// suite exercises the real implementation.
'admin/class-tmdo-admin-hivepress.php',
'cli/class-tmdo-cli-hivepress.php',
);
foreach ( glob( TMDO_HIVEPRESS_PATH . 'includes/hivepress/adapters/*.php' ) ?: array() as $tmdo_hp_adapter ) {
$tmdo_hp_files[] = 'includes/hivepress/adapters/' . basename( $tmdo_hp_adapter );
}
foreach ( $tmdo_hp_files as $tmdo_hp_file ) {
$tmdo_hp_path = TMDO_HIVEPRESS_PATH . $tmdo_hp_file;
if ( file_exists( $tmdo_hp_path ) ) {
require_once $tmdo_hp_path;
}
}
unset( $tmdo_hp_files, $tmdo_hp_file, $tmdo_hp_path, $tmdo_hp_adapter, $tmdo_core_bootstrap );
// ── Back-compat aliases for this AddOn's classes ───────────────────────────
// Mirrors includes/back-compat-aliases.php, which runs on plugins_loaded:7 and
// therefore never fires under PHPUnit.
foreach ( get_declared_classes() as $tmdo_declared ) {
if ( str_starts_with( $tmdo_declared, 'TMDO_' ) ) {
$tmdo_alias = 'WPDO_' . substr( $tmdo_declared, 5 );
if ( ! class_exists( $tmdo_alias, false ) ) {
class_alias( $tmdo_declared, $tmdo_alias );
}
}
}
unset( $tmdo_declared, $tmdo_alias );
// PHP cannot class_alias() traits or interfaces — declare thin wrappers so the
// suite can keep referring to the WPDO_ names.
if ( trait_exists( 'TMDO_HivePress_Adapter_Trait' ) && ! trait_exists( 'WPDO_HivePress_Adapter_Trait', false ) ) {
trait WPDO_HivePress_Adapter_Trait {
use TMDO_HivePress_Adapter_Trait;
}
}
// WPDO_HivePress_Adapter is declared by interface-tmdo-hp-adapter.php itself
// (TMDO_ extends WPDO_), so no wrapper is needed here.
// Shared $wpdb mock helper used by the adapter tests.
if ( file_exists( __DIR__ . '/unit/WpdbMockTrait.php' ) ) {
require_once __DIR__ . '/unit/WpdbMockTrait.php';
}