test(templates): uniform init_hooks() contract test across all 22 module classes (D) - #17
Merged
Merged
Conversation
…ule classes (D) Adds tests/Unit/Module_Hooks_Test.php: one data-provider test asserting that every module class present in a given build registers exactly the hooks its init_hooks() claims to -- action, filter, shortcode, and WP-CLI command registrations all covered uniformly. Ships only when at least one module contributes a case (a zero-module, non-React build has none, matching the has_services / Services_Test convention). Each of the 22 module classes gets one addModuleHookCase() call at its existing writeTemplateFile() site in index.js, alongside a table of what init_hooks() actually registers, surveyed directly from every module's source: - 16 classes take no constructor args; 5 (Settings_Registrar and 4 Woo providers) are constructor-injected with a service, built via a fresh Mockery double per test through a factory closure -- so the double is built when the test runs, not when the data provider is collected. - Two hooks are built from a class constant at runtime rather than a literal (Account_Endpoint_Service::ENDPOINT, Action_Scheduler_Service::HOOK); those render as a raw PHP expression referencing the real constant instead of duplicating its value as a string. - add_shortcode and \WP_CLI::add_command() aren't add_action/add_filter, so they're verified through Functions\expect()/\WP_CLI::$commands respectively rather than Brain Monkey's Actions/Filters helpers. This closes real gaps beyond the six single-assertion tests the report named: Admin\Assets, Admin\Settings_Registrar, Frontend\Interactivity, and all 9 Woo\Providers\* classes had no test coverage of any kind before this -- their init_hooks() wiring is exactly what a real plugin's boot sequence depends on. The six existing single-assertion tests are untouched; each already covers a different method's behavior (e.g. Shortcode_Test asserts render_shortcode()'s output), which this file doesn't duplicate or replace. Verified beyond the CLI's own suite (70/70, +1 new test covering the generator logic itself -- conditional shipping, the DI/raw-constant cases, and cross-entry `=>` alignment): - A negative control: broke Cron\Scheduler's add_action() call in a generated scaffold and confirmed the test fails with a precise Mockery message naming the missing hook -- not vacuously green. - Full-build scaffold (all 22 modules + React): composer test -> 74/74 (117 assertions, 0 risky -- the expectation-only cases needed a trailing assertTrue(true), matching this suite's own convention for Mockery-verified tests), composer lint -> 0 errors / 9 warnings (the same three pre-existing, legitimate warnings every prior audit has confirmed). - A second, differently-shaped scaffold mixing the DI and raw-constant cases together (cron, shortcode, cli, admin_settings, woo:action-scheduler, woo:my-account): composer test -> 24/24, composer lint -> 0 errors / 0 warnings. - php -l clean on every generated file in both. Two real WPCS formatting rules only surfaced by actually linting generated output, not by reading the diff: multi-item associative arrays need one key per line (WordPress.Arrays.ArrayDeclarationSpacing), and the data-provider's `=>` arrows must align to the widest key across all 22 entries (WordPress.Arrays.MultipleStatementAlignment) -- which forced deferring rendering until every module block has run, since the alignment width isn't known until then.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes item D — the last open item across all five audit reports.
What this adds
tests/Unit/Module_Hooks_Test.php: one data-provider test asserting every module class present in a build registers exactly the hooks itsinit_hooks()claims to — actions, filters, shortcodes, and WP-CLI commands, all covered uniformly. Ships only when at least one module contributes a case (mirrors thehas_servicesconvention: a zero-module, non-React build has none).Each of the 22 module classes with an
init_hooks()gets oneaddModuleHookCase()call at its existingwriteTemplateFile()site inindex.js, driven by a table of whatinit_hooks()actually registers — surveyed directly from every module's source, not guessed:Settings_Registrar+ 4 Woo providers) are constructor-injected with a service, built via a fresh Mockery double per test, through a factory closure — the double is built when the test runs, not when the data provider is collected.Account_Endpoint_Service::ENDPOINT,Action_Scheduler_Service::HOOK) rather than a literal — those render as a raw PHP expression referencing the real constant, not a duplicated string.add_shortcodeand\WP_CLI::add_command()aren'tadd_action/add_filter, so they're verified throughFunctions\expect()/\WP_CLI::$commandsrespectively, not Brain Monkey'sActions/Filtershelpers.Beyond the report's literal ask
The report framed this as replacing six single-assertion tests. Those six are untouched — each already covers a different method's actual behavior (e.g.
Shortcode_Testassertsrender_shortcode()'s output), which this file doesn't duplicate.What it actually closes is bigger:
Admin\Assets,Admin\Settings_Registrar,Frontend\Interactivity, and all 9Woo\Providers\*classes had no test coverage of any kind before this — and theirinit_hooks()wiring is exactly what a real plugin's boot sequence depends on.Verification
Beyond the CLI's own suite (70/70, +1 new test covering the generator logic itself — conditional shipping, the DI/raw-constant cases, and cross-entry
=>alignment):Cron\Scheduler'sadd_action()call in a generated scaffold and confirmed the test fails with a precise Mockery message naming the missing hook — not vacuously green.composer test→ 74/74 (117 assertions, 0 risky — the expectation-only cases needed a trailingassertTrue(true), matching this suite's own convention for Mockery-verified tests),composer lint→ 0 errors / 9 warnings (the same three pre-existing, legitimate warnings every prior audit has confirmed).cron,shortcode,cli,admin_settings,woo:action-scheduler,woo:my-account):composer test→ 24/24,composer lint→ 0 errors / 0 warnings.php -lclean on every generated file in both.Two real WPCS formatting rules only surfaced by actually linting generated output, not by reading the diff: multi-item associative arrays need one key per line (
WordPress.Arrays.ArrayDeclarationSpacing), and the data-provider's=>arrows must align to the widest key across all 22 entries (WordPress.Arrays.MultipleStatementAlignment) — which forced deferring rendering until every module block has run, since the alignment width isn't knowable until then.🤖 Generated with Claude Code