Skip to content

Commit

Permalink
TASK: Introduce array support for SearchTermMatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign committed Aug 4, 2024
1 parent 4715f33 commit 3bbabb3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ private function __construct(
}

/**
* If the value is NULL an unset-property instruction will be returned instead.
*
* @param Value $value
*/
public static function create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,32 @@ public static function matchesNode(Node $node, SearchTerm $searchTerm): bool
public static function matchesSerializedPropertyValues(SerializedPropertyValues $serializedPropertyValues, SearchTerm $searchTerm): bool
{
foreach ($serializedPropertyValues as $serializedPropertyValue) {
if (self::matchesSerializedPropertyValue($serializedPropertyValue, $searchTerm)) {
if (self::matchesValue($serializedPropertyValue->value, $searchTerm)) {
return true;
}
}
return false;
}

private static function matchesSerializedPropertyValue(SerializedPropertyValue $serializedPropertyValue, SearchTerm $searchTerm): bool
private static function matchesValue(mixed $value, SearchTerm $searchTerm): bool
{
if (is_array($value) || $value instanceof \ArrayObject) {
foreach ($value as $subValue) {
if (self::matchesValue($subValue, $searchTerm)) {
return true;
}
}
return false;
}

return match (true) {
is_string($serializedPropertyValue->value) => mb_stripos($serializedPropertyValue->value, $searchTerm->term) !== false,
is_string($value) => mb_stripos($value, $searchTerm->term) !== false,
// the following behaviour might seem odd, but is implemented after how the database filtering should behave
is_int($serializedPropertyValue->value),
is_float($serializedPropertyValue->value) => str_contains((string)$serializedPropertyValue->value, $searchTerm->term),
$serializedPropertyValue->value === true => $searchTerm->term === 'true',
$serializedPropertyValue->value === false => $searchTerm->term === 'false'
is_int($value),
is_float($value) => str_contains((string)$value, $searchTerm->term),
$value === true => $searchTerm->term === 'true',
$value === false => $searchTerm->term === 'false',
default => throw new \InvalidArgumentException(sprintf('Handling for type %s is not implemented.', get_debug_type($value))),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class SearchTermMatcherTest extends TestCase
{
public function matchingStringComparisonExamples(): iterable
public static function matchingStringComparisonExamples(): iterable
{
yield 'string found inside string' => ['brown', self::value('the brown fox')];
yield 'string found inside string (ci)' => ['BrOWn', self::value('the brown fox')];
Expand All @@ -25,7 +25,7 @@ public function matchingStringComparisonExamples(): iterable
yield 'string found inside string with special chars' => ['ä b-c+#@', self::value('the example: "ä b-c+#@"')];
}

public function matchingNumberLikeComparisonExamples(): iterable
public static function matchingNumberLikeComparisonExamples(): iterable
{
yield 'string-number found inside string' => [
'22',
Expand Down Expand Up @@ -58,7 +58,7 @@ public function matchingNumberLikeComparisonExamples(): iterable
];
}

public function matchingBooleanLikeComparisonExamples(): iterable
public static function matchingBooleanLikeComparisonExamples(): iterable
{
yield 'string-boolean inside string' => [
'true',
Expand All @@ -76,20 +76,50 @@ public function matchingBooleanLikeComparisonExamples(): iterable
];
}

public static function matchingArrayComparisonExamples(): iterable
{
// automates the following:
yield 'inside array: string found inside string' => ['foo', self::value(['foo'])];
yield 'inside array-object: string found inside string' => ['foo', self::value(new \ArrayObject(['foo']))];

foreach([
...iterator_to_array(self::matchingStringComparisonExamples()),
...iterator_to_array(self::matchingNumberLikeComparisonExamples()),
...iterator_to_array(self::matchingBooleanLikeComparisonExamples()),
] as $name => [$searchTerm, $properties]) {
/** @var SerializedPropertyValues $properties */
yield 'inside nested array: ' . $name => [$searchTerm, SerializedPropertyValues::fromArray(
array_map(
fn (SerializedPropertyValue $value) => SerializedPropertyValue::create(
// arbitrary deep nested
[[$value->value]],
'array'
),
iterator_to_array($properties)
)
)];
}
}


public function notMatchingExamples(): iterable
{
yield 'different chars' => ['aepfel', self::value('äpfel')];
yield 'upper boolean string representation' => ['TRUE', self::value(true)];
yield 'string not found inside string' => ['reptv', self::value('eras tour')];
yield 'integer' => ['0999', self::value(999)];
yield 'float with comma' => ['12,45', self::value(12.34)];
yield 'array with unmatched string' => ['hello', self::value(['hi'])];
yield 'array key is not considered matching' => ['key', self::value(['key' => 'foo'])];
yield 'nested array key is not considered matching' => ['key', self::value([['key' => 'foo']])];
}

/**
* @test
* @dataProvider matchingStringComparisonExamples
* @dataProvider matchingNumberLikeComparisonExamples
* @dataProvider matchingBooleanLikeComparisonExamples
* @dataProvider matchingArrayComparisonExamples
*/
public function searchTermMatchesProperties(
string $searchTerm,
Expand Down Expand Up @@ -119,12 +149,12 @@ public function searchTermDoesntMatchesProperties(
);
}

private static function value(string|bool|float|int $value): SerializedPropertyValues
private static function value(string|bool|float|int|array|\ArrayObject $value): SerializedPropertyValues
{
return SerializedPropertyValues::fromArray([
'test-property' => SerializedPropertyValue::create(
$value,
gettype($value)
''
),
]);
}
Expand Down

0 comments on commit 3bbabb3

Please sign in to comment.