Skip to content

Tests: Use strict assertions in the style engine CSS rules store tests. - #83777

Open
haritpanchal wants to merge 1 commit into
WordPress:trunkfrom
haritpanchal:tests/style-engine-strict-assertions
Open

haritpanchal wants to merge 1 commit into
WordPress:trunkfrom
haritpanchal:tests/style-engine-strict-assertions

Conversation

@haritpanchal

Copy link
Copy Markdown
Contributor

What?

See https://core.trac.wordpress.org/ticket/64895 (Gutenberg follow-up requested in
comment 89)

Converts the three assertEquals() calls in
phpunit/style-engine/class-wp-style-engine-css-rules-store-test.php to assertSame(). This is
the style engine group of the Gutenberg inventory on that ticket, and it leaves no
assertEquals() calls in the file.

Why?

assertEquals() compares by value, so it cannot tell the store's singleton instance apart from
a copy of it. That matters here specifically, because returning the same instance is the whole
contract of WP_Style_Engine_CSS_Rules_Store::get_store(): block supports accumulate rules by
calling it repeatedly, and if it ever handed back a copy, rules added by one caller would be
silently dropped. The existing assertions could not have caught that.

Trac #64895 is the ongoing effort to replace loose assertions with type-strict ones, and its
description asks for the same changes upstream in Gutenberg to ease merging tests between the
two repositories.

How?

WP_Style_Engine_CSS_Rules_Store is a static registry. get_store( $name ) lazily creates and
returns static::$stores[ $name ], get_stores() returns that same array, and
remove_all_stores() assigns array().

test_should_get_all_existing_stores() and test_should_remove_all_stores() build their
expected array out of the very objects get_store() just returned. Because those are the stored
instances rather than copies, assertSame() asserts identity, which is what the registry
actually guarantees.

The final assertion in test_should_remove_all_stores() compares array() against
get_stores() after the reset, so the strict form additionally pins that the return value is a
real array rather than merely something falsey.

Two things were checked rather than assumed, since a strict array comparison is sensitive to
both:

  • Key order. These are string-keyed arrays, where == ignores order and === does not, so
    the ordering is genuinely asserted here. Confirmed by swapping the two keys in the expected
    array: assertSame() fails, and the same swap under assertEquals() passes.
  • Leakage between tests. A strict comparison would break if stores from earlier tests
    survived into get_stores(). The class's tear_down() calls remove_all_stores(), and the
    tests were additionally run in two different randomized orders to confirm no order dependence.

The identity gain was confirmed the same way, by running each mutation under both assertions so
the result isolates what the conversion buys:

mutation assertSame() assertEquals()
expected uses clone $burrito_store fails, "two arrays are identical" passes
expected key order swapped fails passes

No other assertions are touched.

Testing Instructions

This is a test-only change, so the verification is that the suite still passes with the stricter
assertions in place.

  1. Check out this branch and make sure the environment is running:
    nvm use
    npm run test:unit:php:setup
    
  2. Run the affected tests:
    npm run test:unit:php:base -- --filter WP_Style_Engine_CSS_Rules_Store_Test
    
    Expected: OK (8 tests, 14 assertions)
  3. Run the same tests under multisite:
    npm run test:unit:php:multisite:base -- --filter WP_Style_Engine_CSS_Rules_Store_Test
    
    Expected: OK (8 tests, 14 assertions)
  4. Run them in randomized order to confirm no order dependence:
    npm run test:unit:php:base -- --filter WP_Style_Engine_CSS_Rules_Store_Test --order-by=random --random-order-seed=64895
    
    Expected: OK (8 tests, 14 assertions)

To see that the assertions actually got stricter, change the expected value in
test_should_get_all_existing_stores() from $burrito_store to clone $burrito_store. The test
now fails, and reverting that one assertion to assertEquals() makes it pass again.

Coding standards on the changed file:

npx wp-env --config .wp-env.test.json run --env-cwd='wp-content/plugins/gutenberg' cli composer run-script lint -- phpunit/style-engine/class-wp-style-engine-css-rules-store-test.php

Testing Instructions for Keyboard

Not applicable. This PR changes PHPUnit test assertions only and has no user interface.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Checking each assertion against the store implementation it exercises, and confirming
by mutation what the strict form adds. I reviewed the changes and take responsibility for the
final code.

The store's get_store() returns the stored instance rather than a copy, so
assertSame() asserts the identity the registry actually guarantees. The loose
assertions could not tell the singleton apart from a clone of it.

See https://core.trac.wordpress.org/ticket/64895
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🎉 Props

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: haritpanchal <haritpanchal@git.wordpress.org>

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

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you.

@haritpanchal

haritpanchal commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

This has been waiting a while, so flagging it for review — @lancewillett, you reviewed the
earlier Core-sync PR (#83619) from the same Trac ticket.

One CI note: "Check for a Core backport changelog entry" is failing. The workflow runs on
phpunit/** with phpunit/blocks/** excluded, so it triggers for this file but not for the
block-level test PRs on the same ticket. There is nothing to backport here: this is a
test-only change, and the equivalent Core conversion already landed in [63934]. Could someone
with triage access add the "No Core Sync Required" label so the check is skipped? Happy to add
a backport-changelog entry instead if that is preferred.

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

This branch has not been deployed

No deployments
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