Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
288 changes: 279 additions & 9 deletions tests/phpunit/tests/functions/wpListFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
class Tests_Functions_wpListFilter extends WP_UnitTestCase {

/**
* @ticket 53987
*
* @dataProvider data_wp_list_filter
*
* @param array $input_list An array of objects to filter.
Expand All @@ -22,32 +24,58 @@ public function test_wp_list_filter( $input_list, $args, $operator, $expected )
$this->assertEqualSetsWithIndex( $expected, wp_list_filter( $input_list, $args, $operator ) );
}

/**
* Tests that the 'AND' operator is used when no operator is passed.
*
* @ticket 53987
*/
public function test_wp_list_filter_should_default_to_and_operator() {
$input_list = array(
(object) array(
'foo' => 'bar',
'bar' => 'baz',
),
(object) array( 'foo' => 'bar' ),
);

$this->assertEqualSetsWithIndex(
array( 0 => $input_list[0] ),
wp_list_filter(
$input_list,
array(
'foo' => 'bar',
'bar' => 'baz',
)
)
);
}

/**
* Data provider.
*
* @return array[]
*/
public static function data_wp_list_filter() {
return array(
'string instead of array' => array(
'string instead of array' => array(
'foo',
array(),
'AND',
array(),
),
'object instead of array' => array(
'object instead of array' => array(
(object) array( 'foo' ),
array(),
'AND',
array(),
),
'empty args' => array(
'empty args' => array(
array( 'foo', 'bar' ),
array(),
'AND',
array( 'foo', 'bar' ),
),
'invalid operator' => array(
'invalid operator' => array(
array(
(object) array( 'foo' => 'bar' ),
(object) array( 'foo' => 'baz' ),
Expand All @@ -56,7 +84,7 @@ public static function data_wp_list_filter() {
'XOR',
array(),
),
'single argument to match' => array(
'single argument to match' => array(
array(
(object) array(
'foo' => 'bar',
Expand Down Expand Up @@ -94,7 +122,7 @@ public static function data_wp_list_filter() {
),
),
),
'all must match' => array(
'all must match' => array(
array(
(object) array(
'foo' => 'bar',
Expand Down Expand Up @@ -132,7 +160,7 @@ public static function data_wp_list_filter() {
),
),
),
'any must match' => array(
'any must match' => array(
array(
(object) array(
'foo' => 'bar',
Expand Down Expand Up @@ -179,7 +207,7 @@ public static function data_wp_list_filter() {
),
),
),
'none must match' => array(
'none must match' => array(
array(
(object) array(
'foo' => 'bar',
Expand Down Expand Up @@ -216,7 +244,7 @@ public static function data_wp_list_filter() {
),
),
),
'string to int comparison' => array(
'string to int comparison' => array(
array(
(object) array(
'foo' => '1',
Expand All @@ -230,6 +258,248 @@ public static function data_wp_list_filter() {
),
),
),
'bool to string comparison' => array(
array(
(object) array(
'foo' => true,
),
),
array( 'foo' => 'yes' ),
'AND',
array(
0 => (object) array(
'foo' => true,
),
),
),
'null instead of array' => array(
null,
array( 'foo' => 'bar' ),
'AND',
array(),
),
'empty list' => array(
array(),
array( 'foo' => 'bar' ),
'AND',
array(),
),

/*
* Empty arguments are checked before the operator is validated,
* so the original list is returned even for an invalid operator.
*/
'empty args, invalid operator' => array(
array( 'foo', 'bar' ),
array(),
'XOR',
array( 'foo', 'bar' ),
),

// The operator is uppercased before it is validated.
'lowercase AND operator' => array(
array(
(object) array( 'foo' => 'bar' ),
(object) array( 'foo' => 'baz' ),
),
array( 'foo' => 'bar' ),
'and',
array(
0 => (object) array( 'foo' => 'bar' ),
),
),
'mixed case OR operator' => array(
array(
(object) array( 'foo' => 'bar' ),
(object) array( 'foo' => 'baz' ),
),
array( 'foo' => 'bar' ),
'oR',
array(
0 => (object) array( 'foo' => 'bar' ),
),
),
'lowercase NOT operator' => array(
array(
(object) array( 'foo' => 'bar' ),
(object) array( 'foo' => 'baz' ),
),
array( 'foo' => 'bar' ),
'not',
array(
1 => (object) array( 'foo' => 'baz' ),
),
),

// Lists of arrays are supported alongside lists of objects.
'arrays: single argument to match' => array(
array(
array(
'foo' => 'bar',
'key' => 'foo',
),
array(
'foo' => 'baz',
'key' => 'value',
),
array(
'foo' => 'bar',
'key' => 'value',
),
),
array( 'foo' => 'bar' ),
'AND',
array(
0 => array(
'foo' => 'bar',
'key' => 'foo',
),
2 => array(
'foo' => 'bar',
'key' => 'value',
),
),
),
'arrays: all must match' => array(
array(
array(
'foo' => 'bar',
'bar' => 'baz',
),
array( 'foo' => 'bar' ),
),
array(
'foo' => 'bar',
'bar' => 'baz',
),
'AND',
array(
0 => array(
'foo' => 'bar',
'bar' => 'baz',
),
),
),
'arrays: any must match' => array(
array(
array( 'foo' => 'bar' ),
array( 'bar' => 'baz' ),
array( 'foo' => 'baz' ),
),
array(
'foo' => 'bar',
'bar' => 'baz',
),
'OR',
array(
0 => array( 'foo' => 'bar' ),
1 => array( 'bar' => 'baz' ),
),
),
'arrays: none must match' => array(
array(
array( 'foo' => 'bar' ),
array( 'bar' => 'baz' ),
array( 'foo' => 'baz' ),
),
array(
'foo' => 'bar',
'bar' => 'baz',
),
'NOT',
array(
2 => array( 'foo' => 'baz' ),
),
),
'mixed arrays and objects' => array(
array(
array( 'foo' => 'bar' ),
(object) array( 'foo' => 'bar' ),
array( 'foo' => 'baz' ),
(object) array( 'foo' => 'baz' ),
),
array( 'foo' => 'bar' ),
'AND',
array(
0 => array( 'foo' => 'bar' ),
1 => (object) array( 'foo' => 'bar' ),
),
),

/*
* Values that are neither arrays nor objects can never match,
* so they are only returned by the 'NOT' operator.
*/
'scalar values with AND' => array(
array( 'a string', 42, null, array( 'foo' => 'bar' ) ),
array( 'foo' => 'bar' ),
'AND',
array(
3 => array( 'foo' => 'bar' ),
),
),
'scalar values with NOT' => array(
array( 'a string', 42, null, array( 'foo' => 'bar' ) ),
array( 'foo' => 'bar' ),
'NOT',
array(
0 => 'a string',
1 => 42,
2 => null,
),
),

/*
* Array values are checked with array_key_exists(), so a null value
* matches, while object properties are checked with isset(),
* so a null property does not.
*/
'array with a null value matching null' => array(
array( array( 'foo' => null ) ),
array( 'foo' => null ),
'AND',
array(
0 => array( 'foo' => null ),
),
),
'object with a null property matching null' => array(
array( (object) array( 'foo' => null ) ),
array( 'foo' => null ),
'AND',
array(),
),

'string keys are preserved' => array(
array(
'first' => (object) array( 'foo' => 'bar' ),
'second' => (object) array( 'foo' => 'baz' ),
'third' => (object) array( 'foo' => 'bar' ),
),
array( 'foo' => 'bar' ),
'AND',
array(
'first' => (object) array( 'foo' => 'bar' ),
'third' => (object) array( 'foo' => 'bar' ),
),
),
'no matches with OR' => array(
array(
(object) array( 'foo' => 'baz' ),
(object) array( 'foo' => 'qux' ),
),
array( 'foo' => 'bar' ),
'OR',
array(),
),
'all matches with NOT' => array(
array(
(object) array( 'foo' => 'bar' ),
(object) array( 'foo' => 'bar' ),
),
array( 'foo' => 'bar' ),
'NOT',
array(),
),
);
}
}
Loading