Skip to content

Commit fe97056

Browse files
committed
Replay PHPUnit dependency plugin hooks
1 parent be85eec commit fe97056

4 files changed

Lines changed: 14 additions & 3 deletions

File tree

docs/recipe-contract.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,9 @@ the PHPUnit database during activation. Mount each dependency through
721721
`inputs.extra_plugins` with `activate: false`, then provide its sandbox plugin
722722
directory in `dependencyMounts`. In managed bootstrap mode, `wordpress.phpunit`
723723
loads and activates those dependencies after the PHPUnit install stage has
724-
created test tables and before test discovery and execution.
724+
created test tables and before test discovery and execution. Any dependency
725+
`plugins_loaded` callbacks registered during that load are invoked once after
726+
dependency activation.
725727

726728
Use `recipe build phpunit` when generating recipes for plugin CI or offloaded lab
727729
runners:

packages/runtime-playground/src/phpunit-command-handlers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,9 @@ tests_add_filter('muplugins_loaded', function () use ($plugin_slug, $plugin_path
11121112
11131113
pg_run_install_stage(array('config_path' => $config_path, 'tests_dir' => $tests_dir, 'multisite' => $multisite));
11141114
pg_remove_new_wordpress_hook_callbacks('shutdown', $pre_component_shutdown_callbacks);
1115+
$pre_dependency_plugins_loaded_callbacks = pg_snapshot_wordpress_hook_callbacks('plugins_loaded');
11151116
$loaded_dep_files = pg_run_load_deps_stage(array('dep_mounts' => $dep_mounts));
1117+
$deferred_dependency_plugins_loaded_callbacks = pg_defer_new_wordpress_hook_callbacks('plugins_loaded', $pre_dependency_plugins_loaded_callbacks);
11161118
$activation_files = $loaded_dep_files;
11171119
if ($loaded_component_file !== null) {
11181120
$activation_files[] = $loaded_component_file;
@@ -1123,6 +1125,7 @@ $pre_replayed_plugins_loaded_init_callbacks = pg_snapshot_wordpress_hook_callbac
11231125
$reopened_ability_categories_init = pg_reopen_wordpress_action('wp_abilities_api_categories_init');
11241126
$reopened_ability_init = pg_reopen_wordpress_action('wp_abilities_api_init');
11251127
pg_run_deferred_wordpress_hook_callbacks($deferred_install_plugins_loaded_callbacks, array(), 'plugins_loaded');
1128+
pg_run_deferred_wordpress_hook_callbacks($deferred_dependency_plugins_loaded_callbacks, array(), 'plugins_loaded');
11261129
$deferred_install_init_callbacks = array_merge($deferred_install_init_callbacks, pg_defer_new_wordpress_hook_callbacks('init', $pre_replayed_plugins_loaded_init_callbacks));
11271130
usort($deferred_install_init_callbacks, static function (array $left, array $right): int {
11281131
return ($left['priority'] ?? 10) <=> ($right['priority'] ?? 10);

tests/phpunit-project-autoload.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,15 @@ assert.ok(managedModeCode.includes("'cacheResult' => false"))
413413
const installStageIndex = managedModeCode.indexOf("pg_run_install_stage(array(")
414414
const dependencyLoadStageIndex = managedModeCode.indexOf("$loaded_dep_files = pg_run_load_deps_stage", installStageIndex)
415415
const activationStageIndex = managedModeCode.indexOf("pg_run_activation_stage", dependencyLoadStageIndex)
416+
const dependencyPluginsLoadedSnapshotIndex = managedModeCode.indexOf("$pre_dependency_plugins_loaded_callbacks = pg_snapshot_wordpress_hook_callbacks('plugins_loaded');", installStageIndex)
417+
const dependencyPluginsLoadedDeferIndex = managedModeCode.indexOf("$deferred_dependency_plugins_loaded_callbacks = pg_defer_new_wordpress_hook_callbacks('plugins_loaded', $pre_dependency_plugins_loaded_callbacks);", dependencyLoadStageIndex)
418+
const dependencyPluginsLoadedReplayIndex = managedModeCode.indexOf("pg_run_deferred_wordpress_hook_callbacks($deferred_dependency_plugins_loaded_callbacks, array(), 'plugins_loaded');", activationStageIndex)
416419
assert.ok(installStageIndex > 0)
420+
assert.ok(dependencyPluginsLoadedSnapshotIndex > installStageIndex && dependencyPluginsLoadedSnapshotIndex < dependencyLoadStageIndex, "dependency plugins_loaded callbacks must be scoped to dependency loading")
417421
assert.ok(dependencyLoadStageIndex > installStageIndex, "dependency plugins must load after managed PHPUnit installation")
422+
assert.ok(dependencyPluginsLoadedDeferIndex > dependencyLoadStageIndex && dependencyPluginsLoadedDeferIndex < activationStageIndex, "dependency plugins_loaded callbacks must defer until activation completes")
418423
assert.ok(activationStageIndex > dependencyLoadStageIndex, "dependency plugins must activate after loading and before tests execute")
424+
assert.ok(dependencyPluginsLoadedReplayIndex > activationStageIndex, "dependency plugins_loaded callbacks must run once after activation")
419425

420426
const dependencyRecipe = buildWordPressPhpunitRecipe({
421427
pluginSlug: "demo-plugin",

tests/playground-phpunit-readonly-cache.integration.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ async function writeFixture(): Promise<void> {
6060
await mkdir(dependency, { recursive: true })
6161
await writeFile(join(plugin, "readonly-phpunit-fixture.php"), "<?php\n/**\n * Plugin Name: Readonly PHPUnit Fixture\n */\n")
6262
await writeFile(join(plugin, "source-sentinel.bin"), sentinel)
63-
await writeFile(join(plugin, "tests", "ReadonlyCacheTest.php"), "<?php\nclass ReadonlyCacheTest extends WP_UnitTestCase { public function test_sentinel_is_available(): void { $this->assertGreaterThan(0, filesize(dirname(__DIR__) . \'/source-sentinel.bin\')); } public function test_dependency_activation_runs_after_install(): void { $this->assertGreaterThanOrEqual(1, get_option(\'wp_codebox_dependency_activation_users\')); } }\n")
64-
await writeFile(join(dependency, "activation-dependency.php"), "<?php\n/**\n * Plugin Name: Activation Dependency\n */\nregister_activation_hook(__FILE__, static function (): void { update_option('wp_codebox_dependency_activation_users', count(get_users(array('number' => 1)))); });\n")
63+
await writeFile(join(plugin, "tests", "ReadonlyCacheTest.php"), "<?php\nclass ReadonlyCacheTest extends WP_UnitTestCase { public function test_sentinel_is_available(): void { $this->assertGreaterThan(0, filesize(dirname(__DIR__) . \'/source-sentinel.bin\')); } public function test_dependency_activation_runs_after_install(): void { $this->assertGreaterThanOrEqual(1, get_option(\'wp_codebox_dependency_activation_users\')); } public function test_dependency_plugins_loaded_runs_once(): void { $this->assertSame(1, (int) get_option(\'wp_codebox_dependency_plugins_loaded_count\')); } }\n")
64+
await writeFile(join(dependency, "activation-dependency.php"), "<?php\n/**\n * Plugin Name: Activation Dependency\n */\nadd_action('plugins_loaded', static function (): void { update_option('wp_codebox_dependency_plugins_loaded_count', (int) get_option('wp_codebox_dependency_plugins_loaded_count', 0) + 1); });\nregister_activation_hook(__FILE__, static function (): void { update_option('wp_codebox_dependency_activation_users', count(get_users(array('number' => 1)))); });\n")
6565
}
6666

6767
async function digestTree(directory: string): Promise<string> {

0 commit comments

Comments
 (0)