Skip to content

Tests: Preserve registered metadata between methods and classes - #14774

Closed
salvatorecorsi wants to merge 2 commits into
WordPress:trunkfrom
salvatorecorsi:fix/48300-preserve-registered-meta-fixtures
Closed

salvatorecorsi wants to merge 2 commits into
WordPress:trunkfrom
salvatorecorsi:fix/48300-preserve-registered-meta-fixtures

Conversation

@salvatorecorsi

@salvatorecorsi salvatorecorsi commented Oct 23, 2026 •

Copy link
Copy Markdown

A plugin can register metadata during init, then find that registration missing after the first WP_UnitTestCase method. Teardown currently unregisters every key, while restoring hooks from a separate baseline. This also breaks metadata fixtures created in wpSetUpBeforeClass().

Preserve the metadata registry together with its sanitization, authorization and default-value hooks at the method and class boundaries. Restore cloned hook objects without replaying register_meta() filters. Class fixtures survive their class's methods and are removed after class teardown; bootstrap registrations remain available. The existing unregister_all_meta_keys() helper and the general hook-backup policy are unchanged.

Three metadata unit-test classes now explicitly request an empty registry in their setup, preserving their existing whole-registry assertions.

Trac ticket: https://core.trac.wordpress.org/ticket/48300

Testing instructions

Register metadata with a default, sanitizer and authorization callback before a test class starts. Run two methods that modify or unregister it: each method should start with the original registration and callbacks. Repeat with metadata registered in wpSetUpBeforeClass(); it should survive both methods and be absent after the class finishes.

The new isolated-process regressions exercise the real WordPress test-case lifecycle, including post-wide and subtype registrations, term and user metadata, legacy callback-only registrations, temporary-key cleanup, and actual post defaults, sanitization and current_user_can( 'edit_post_meta', ... ).

Validation

  • The six isolated lifecycle cases fail against the unchanged framework (six failures, 17 assertions), then pass with the fix (45 assertions). The provider keeps four scoped/unscoped and non-post representatives; the separate class-fixture and authorization tests remain unchanged.
  • Complete phpunit,meta groups: 547 tests, 1,563 assertions.
  • Before this provider-only reduction, the complete REST post-meta, term-meta, posts, users, comments and block-type controller classes passed: 934 tests, 6,096 assertions. Those classes and the framework fix are unchanged; that selection was not rerun for the reduction.
  • WPCS, PHP 7.4+ compatibility and PHP syntax checks pass for all five changed files.
  • The complete Core build passed before the test-only edits; runtime source and build inputs are unchanged.

Native PHPUnit used the workspace's serialized private-database runner. These are the listed scopes, not a claim that the entire Core suite passed.

Use of AI Tools

AI assistance: Yes
Tool(s): OpenAI Codex
Used for: Investigation, implementation, regression tests and automated validation. No separate human review by the repository owner is claimed; WordPress maintainer review is requested.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props salvatorecorsi, lancewillett.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Registration snapshots still share mutable object-valued defaults, allowing test mutations to survive teardown and leak into later tests; independent copying and regression coverage are needed.

1 open issue
What changed in this PR

This PR updates the WordPress test framework to preserve registered metadata and its associated hooks across test methods and classes, while retaining bootstrap registrations.

Changes:

  • Snapshot and restore metadata registrations and cloned hooks at method and class boundaries.
  • Add isolated-process regression tests for registration cleanup, class fixtures, defaults, sanitization, and authorization.
  • Explicitly clear registrations in three metadata test classes that assert against the complete registry.
File Description
tests/​phpunit/​tests/​term/​meta.php Clear registrations before term metadata tests.
tests/​phpunit/​tests/​post/​meta.php Clear registrations before post metadata tests.
tests/​phpunit/​tests/​meta/​registerMeta.php Clear registrations before registration tests.
tests/​phpunit/​tests/​includes/​registeredMeta.php Add metadata lifecycle and callback regression tests.
tests/​phpunit/​includes/​abstract-testcase.php Capture and restore metadata state around methods and classes.

Review effort: Balanced

*/
private static function backup_meta_state() {
$state = array(
'keys' => $GLOBALS['wp_meta_keys'] ?? array(),

@lancewillett lancewillett left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registry and its callbacks are restored together, preserving metadata across method and class lifetimes. Local targeted runs passed: 152 tests/531 assertions single-site and 156/537 multisite. Removing only the framework fix made all 12 lifecycle cases fail.

Optional: reduce the isolated provider matrix to representative scoped/unscoped and non-post cases while retaining the distinct class-fixture and authorization checks. The single-site run took 3m45s with child-process bootstraps; avoid expanding this matrix further.

AI review · gpt-6

@lancewillett

Copy link
Copy Markdown
Member

I checked the object-default observation. Shallow copies do retain object identity, but the existing object-default tests register fresh defaults after the snapshot and use separate REST payload objects. I did not find an existing consumer that mutates a pre-existing default across this boundary.

The demonstrated registration-loss fix remains useful. I would not require deep cloning or another isolated matrix without an affected consumer; keep that separate from this fix.

AI review · gpt-6

@salvatorecorsi

Copy link
Copy Markdown
Author

I've reduced the provider to four representative cases, keeping scoped and unscoped metadata, non-post registrations, and both replacement and removal. The separate class-fixture and real authorization tests are unchanged, so this halves the isolated processes while retaining the distinct lifecycle checks. I left object-default copying outside this fix, as you suggested.

@lancewillett lancewillett left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reduced provider retains the distinct registration scopes and mutation modes. Rechecked the updated patch; randomized metadata and term-cache suites passed on single-site and multisite.

AI review · gpt-6

wporg-sync pushed a commit that referenced this pull request Oct 31, 2026
Capture and restore metadata registrations and their hooks around test methods and class fixtures. Preserve bootstrap registrations without rerunning registration filters, and explicitly clear the registry in tests that require an empty baseline.

Developed in: #14774

Props salvatorecorsi.
See #48300.


git-svn-id: https://develop.svn.wordpress.org/trunk@65126 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 31, 2026
Capture and restore metadata registrations and their hooks around test methods and class fixtures. Preserve bootstrap registrations without rerunning registration filters, and explicitly clear the registry in tests that require an empty baseline.

Developed in: WordPress/wordpress-develop#14774

Props salvatorecorsi.
See #48300.

Built from https://develop.svn.wordpress.org/trunk@65126


git-svn-id: http://core.svn.wordpress.org/trunk@64275 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@lancewillett

Copy link
Copy Markdown
Member

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.

3 participants