-
Notifications
You must be signed in to change notification settings - Fork 3.6k
View config: reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members #12644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e53eca9
356606e
b75fdfa
d29a35c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1721,6 +1721,233 @@ public function test_merge_rejects_unknown_key() { | |
| $this->assertSame( array( 'default_view' => array( 'type' => 'table' ) ), self::read_config( $data ) ); | ||
| } | ||
|
|
||
| /** | ||
| * merge() rejects an associative patch value where a list lives: the shapes | ||
| * do not line up, so merging would have to guess what the string keys mean. | ||
| * The current list survives untouched instead of being discarded. | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::merge | ||
| */ | ||
| public function test_merge_rejects_associative_patch_over_a_list() { | ||
| $this->setExpectedIncorrectUsage( 'WP_View_Config_Data::merge_properties' ); | ||
|
|
||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'view_list' => array( | ||
| array( | ||
| 'slug' => 'all', | ||
| 'title' => 'All items', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
| $before = self::read_config( $data ); | ||
|
|
||
| // The pre-7.1 slug-keyed shape, not the documented list of members. | ||
| $data->merge( | ||
| array( | ||
| 'view_list' => array( | ||
| 'published' => array( 'title' => 'Live' ), | ||
| ), | ||
| ), | ||
| 1 | ||
| ); | ||
|
|
||
| $this->assertSame( $before, self::read_config( $data ) ); | ||
| } | ||
|
|
||
| /** | ||
| * merge() rejects a non-empty list patch value where an associative value | ||
| * lives, the mirror of the associative-over-list mismatch: the current map | ||
| * survives untouched instead of being discarded. | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::merge | ||
| */ | ||
| public function test_merge_rejects_list_patch_over_an_associative_value() { | ||
| $this->setExpectedIncorrectUsage( 'WP_View_Config_Data::merge_properties' ); | ||
|
|
||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'default_view' => array( | ||
| 'sort' => array( | ||
| 'field' => 'title', | ||
| 'direction' => 'asc', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
| $before = self::read_config( $data ); | ||
|
|
||
| $data->merge( | ||
| array( | ||
| 'default_view' => array( | ||
| 'sort' => array( 'title', 'asc' ), | ||
| ), | ||
| ), | ||
| 1 | ||
| ); | ||
|
|
||
| $this->assertSame( $before, self::read_config( $data ) ); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Result of this assertion without the fix: array(
'default_view' => array(
'sort' => array( 'title', 'asc' ),
),
)The |
||
| } | ||
|
|
||
| /** | ||
| * An empty array under merge() is a no-op for both shapes: it has no | ||
| * members to merge, and being shape-ambiguous it must not reset the | ||
| * current value either. Clearing a list is spelled replace() with an | ||
| * empty list; resetting a key is spelled null. | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::merge | ||
| */ | ||
| public function test_merge_empty_array_is_a_noop() { | ||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'default_view' => array( | ||
| 'filters' => array( | ||
| array( | ||
| 'field' => 'author', | ||
| 'operator' => 'isAny', | ||
| ), | ||
| ), | ||
| 'sort' => array( | ||
| 'field' => 'title', | ||
| 'direction' => 'asc', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
| $before = self::read_config( $data ); | ||
|
|
||
| $data->merge( | ||
| array( | ||
| 'default_view' => array( | ||
| 'filters' => array(), | ||
| 'sort' => array(), | ||
| ), | ||
| ), | ||
| 1 | ||
| ); | ||
|
|
||
| $this->assertSame( $before, self::read_config( $data ) ); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Result of this assertion without the fix: array(
'default_view' => array(
'filters' => array(
array(
'field' => 'author',
'operator' => 'isAny',
),
),
'sort' => array(),
),
)The same empty-array patch left |
||
| } | ||
|
|
||
| /** | ||
| * A nested null deletes just the leaf it names in every case, including | ||
| * inside a list member that did not exist yet: an appended member has no | ||
| * existing leaf to delete, so its nulls are dropped rather than stored | ||
| * (the same rationale as set() and the lists replace() swaps in). | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::merge | ||
| */ | ||
| public function test_merge_appended_member_drops_nested_nulls() { | ||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'view_list' => array( | ||
| array( | ||
| 'slug' => 'all', | ||
| 'title' => 'All items', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
| $data->merge( | ||
| array( | ||
| 'view_list' => array( | ||
| array( | ||
| 'slug' => 'mine', | ||
| 'view' => array( 'filters' => null ), | ||
| ), | ||
| ), | ||
| ), | ||
| 1 | ||
| ); | ||
|
|
||
| $this->assertSame( | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Result of this assertion without the fix: array(
'view_list' => array(
array(
'slug' => 'all',
'title' => 'All items',
),
array(
'slug' => 'mine',
'view' => array( 'filters' => null ),
),
),
)The appended member kept the literal |
||
| array( | ||
| 'view_list' => array( | ||
| array( | ||
| 'slug' => 'all', | ||
| 'title' => 'All items', | ||
| ), | ||
| array( | ||
| 'slug' => 'mine', | ||
| 'view' => array(), | ||
| ), | ||
| ), | ||
| ), | ||
| self::read_config( $data ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * replace() rejects a non-empty list patch value where an associative value | ||
| * lives, the same rule merge() enforces: a list in the patch replaces the | ||
| * current list wholesale, but it cannot land where a map lives. The current | ||
| * map survives untouched instead of being discarded. | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::replace | ||
| */ | ||
| public function test_replace_rejects_list_patch_over_an_associative_value() { | ||
| $this->setExpectedIncorrectUsage( 'WP_View_Config_Data::merge_properties' ); | ||
|
|
||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'default_view' => array( | ||
| 'sort' => array( | ||
| 'field' => 'title', | ||
| 'direction' => 'asc', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
| $before = self::read_config( $data ); | ||
|
|
||
| $data->replace( | ||
| array( | ||
| 'default_view' => array( | ||
| 'sort' => array( 'title', 'asc' ), | ||
| ), | ||
| ), | ||
| 1 | ||
| ); | ||
|
|
||
| $this->assertSame( $before, self::read_config( $data ) ); | ||
| } | ||
|
|
||
| /** | ||
| * An empty array is exempt from the shape guard, so replace() with an | ||
| * empty list stays the documented way to clear a list. | ||
| * | ||
| * @ticket 65577 | ||
| * | ||
| * @covers ::replace | ||
| */ | ||
| public function test_replace_empty_list_still_clears_a_list() { | ||
| $data = new WP_View_Config_Data( | ||
| array( | ||
| 'view_list' => array( | ||
| array( | ||
| 'slug' => 'all', | ||
| 'title' => 'All items', | ||
| ), | ||
| ), | ||
| ) | ||
| ); | ||
|
|
||
| $data->replace( array( 'view_list' => array() ), 1 ); | ||
|
|
||
| $this->assertSame( array( 'view_list' => array() ), self::read_config( $data ) ); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * merge() treats a scalar list member as its own identity: an incoming | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Result of this assertion without the fix:
The default
allview is gone,view_listbecame a slug-keyed map instead of a list, with no notice.