Skip to content

test(templates): uniform init_hooks() contract test across all 22 module classes (D) - #17

Merged
akshat009 merged 1 commit into
mainfrom
test/init-hooks-contract
Aug 30, 2026
Merged

test(templates): uniform init_hooks() contract test across all 22 module classes (D)#17
akshat009 merged 1 commit into
mainfrom
test/init-hooks-contract

Conversation

@akshat009

Copy link
Copy Markdown
Owner

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 its init_hooks() claims to — actions, filters, shortcodes, and WP-CLI commands, all covered uniformly. Ships only when at least one module contributes a case (mirrors the has_services convention: a zero-module, non-React build has none).

Each of the 22 module classes with an init_hooks() gets one addModuleHookCase() call at its existing writeTemplateFile() site in index.js, driven by a table of what init_hooks() actually registers — surveyed directly from every module's source, not guessed:

  • 16 classes take no constructor args; 5 (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.
  • Two hooks are built from a class constant at runtime (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_shortcode and \WP_CLI::add_command() aren't add_action/add_filter, so they're verified through Functions\expect() / \WP_CLI::$commands respectively, not Brain Monkey's Actions/Filters helpers.

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_Test asserts render_shortcode()'s output), which this file doesn't duplicate.

What it actually closes is bigger: Admin\Assets, Admin\Settings_Registrar, Frontend\Interactivity, and all 9 Woo\Providers\* classes had no test coverage of any kind before this — and their init_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):

  • 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 test74/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 lint0 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 test24/24, composer lint0 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 knowable until then.

🤖 Generated with Claude Code

…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.
@akshat009
akshat009 merged commit 3436b13 into main Aug 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant