feat: add Liquid filter 'find_by'

This commit is contained in:
Benjamin Nussbaum 2025-08-25 14:33:26 +02:00
parent 6cd00943a1
commit f4f8ab5181
4 changed files with 158 additions and 0 deletions

View file

@ -172,4 +172,60 @@ LIQUID
$this->assertStringContainsString('This is a test', $result);
$this->assertStringContainsString('class="simple"', $result);
}
public function test_plugin_with_find_by_filter(): void
{
$plugin = Plugin::factory()->create([
'markup_language' => 'liquid',
'render_markup' => <<<'LIQUID'
{% template user_info %}
<div class="user">
<h2>{{ user.name }}</h2>
<p>Age: {{ user.age }}</p>
</div>
{% endtemplate %}
{% assign found_user = collection | find_by: 'name', 'Ryan' %}
{% render "user_info", user: found_user %}
LIQUID
,
'data_payload' => [
'collection' => [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
],
],
]);
$result = $plugin->render('full');
// Should render the user info for Ryan
$this->assertStringContainsString('Ryan', $result);
$this->assertStringContainsString('Age: 35', $result);
$this->assertStringContainsString('class="user"', $result);
}
public function test_plugin_with_find_by_filter_and_fallback(): void
{
$plugin = Plugin::factory()->create([
'markup_language' => 'liquid',
'render_markup' => <<<'LIQUID'
{{ collection | find_by: 'name', 'ronak', 'Not Found' }}
LIQUID
,
'data_payload' => [
'collection' => [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
],
],
]);
$result = $plugin->render('full');
// Should return the fallback value
$this->assertStringContainsString('Not Found', $result);
}
}

View file

@ -53,3 +53,83 @@ test('json filter does not escape slashes', function () {
expect($filter->json($data))->toBe('{"url":"https://example.com/path"}');
});
test('find_by filter finds object by key-value pair', function () {
$filter = new Data();
$collection = [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
];
$result = $filter->find_by($collection, 'name', 'Ryan');
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
});
test('find_by filter returns null when no match found', function () {
$filter = new Data();
$collection = [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
];
$result = $filter->find_by($collection, 'name', 'ronak');
expect($result)->toBeNull();
});
test('find_by filter returns fallback when no match found', function () {
$filter = new Data();
$collection = [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
];
$result = $filter->find_by($collection, 'name', 'ronak', 'Not Found');
expect($result)->toBe('Not Found');
});
test('find_by filter finds by age', function () {
$filter = new Data();
$collection = [
['name' => 'Ryan', 'age' => 35],
['name' => 'Sara', 'age' => 29],
['name' => 'Jimbob', 'age' => 29],
];
$result = $filter->find_by($collection, 'age', 29);
expect($result)->toBe(['name' => 'Sara', 'age' => 29]);
});
test('find_by filter handles empty collection', function () {
$filter = new Data();
$collection = [];
$result = $filter->find_by($collection, 'name', 'Ryan');
expect($result)->toBeNull();
});
test('find_by filter handles collection with non-array items', function () {
$filter = new Data();
$collection = [
'not an array',
['name' => 'Ryan', 'age' => 35],
null,
];
$result = $filter->find_by($collection, 'name', 'Ryan');
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
});
test('find_by filter handles items without the specified key', function () {
$filter = new Data();
$collection = [
['age' => 35],
['name' => 'Ryan', 'age' => 35],
['title' => 'Developer'],
];
$result = $filter->find_by($collection, 'name', 'Ryan');
expect($result)->toBe(['name' => 'Ryan', 'age' => 35]);
});

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Tests\Unit\Liquid;
use App\Liquid\FileSystems\InlineTemplatesFileSystem;
use App\Liquid\Filters\Data;
use App\Liquid\Tags\TemplateTag;
use Keepsuit\Liquid\Environment;
use Keepsuit\Liquid\Exceptions\LiquidException;
@ -27,6 +28,7 @@ class InlineTemplatesTest extends TestCase
);
$this->environment->tagRegistry->register(TemplateTag::class);
$this->environment->tagRegistry->register(RenderTag::class);
$this->environment->filterRegistry->register(Data::class);
}
public function test_template_tag_registers_template(): void