mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 15:07:49 +00:00
feat: add Liquid filters where_exp and map_to_i
This commit is contained in:
parent
4af4bfe14a
commit
93dacb0baf
5 changed files with 629 additions and 3 deletions
|
|
@ -325,3 +325,173 @@ test('parse_json filter handles primitive values', function (): void {
|
|||
expect($filter->parse_json('false'))->toBe(false);
|
||||
expect($filter->parse_json('null'))->toBe(null);
|
||||
});
|
||||
|
||||
test('map_to_i filter converts string numbers to integers', function (): void {
|
||||
$filter = new Data();
|
||||
$input = ['1', '2', '3', '4', '5'];
|
||||
|
||||
expect($filter->map_to_i($input))->toBe([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
test('map_to_i filter handles mixed string numbers', function (): void {
|
||||
$filter = new Data();
|
||||
$input = ['5', '4', '3', '2', '1'];
|
||||
|
||||
expect($filter->map_to_i($input))->toBe([5, 4, 3, 2, 1]);
|
||||
});
|
||||
|
||||
test('map_to_i filter handles decimal strings', function (): void {
|
||||
$filter = new Data();
|
||||
$input = ['1.5', '2.7', '3.0'];
|
||||
|
||||
expect($filter->map_to_i($input))->toBe([1, 2, 3]);
|
||||
});
|
||||
|
||||
test('map_to_i filter handles empty array', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [];
|
||||
|
||||
expect($filter->map_to_i($input))->toBe([]);
|
||||
});
|
||||
|
||||
test('where_exp filter returns string as array when input is string', function (): void {
|
||||
$filter = new Data();
|
||||
$input = 'just a string';
|
||||
|
||||
expect($filter->where_exp($input, 'la', 'le'))->toBe(['just a string']);
|
||||
});
|
||||
|
||||
test('where_exp filter filters numbers with comparison', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [1, 2, 3, 4, 5];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n >= 3'))->toBe([3, 4, 5]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters numbers with greater than', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [1, 2, 3, 4, 5];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n > 2'))->toBe([3, 4, 5]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters numbers with less than', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [1, 2, 3, 4, 5];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n < 4'))->toBe([1, 2, 3]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters numbers with equality', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [1, 2, 3, 4, 5];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n == 3'))->toBe([3]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters numbers with not equal', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [1, 2, 3, 4, 5];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n != 3'))->toBe([1, 2, 4, 5]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters objects by property', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
['name' => 'Alice', 'age' => 25],
|
||||
['name' => 'Bob', 'age' => 30],
|
||||
['name' => 'Charlie', 'age' => 35],
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'person', 'person.age >= 30'))->toBe([
|
||||
['name' => 'Bob', 'age' => 30],
|
||||
['name' => 'Charlie', 'age' => 35],
|
||||
]);
|
||||
});
|
||||
|
||||
test('where_exp filter filters objects by string property', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
['name' => 'Alice', 'role' => 'admin'],
|
||||
['name' => 'Bob', 'role' => 'user'],
|
||||
['name' => 'Charlie', 'role' => 'admin'],
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'user', 'user.role == "admin"'))->toBe([
|
||||
['name' => 'Alice', 'role' => 'admin'],
|
||||
['name' => 'Charlie', 'role' => 'admin'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles and operator', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
['name' => 'Alice', 'age' => 25, 'active' => true],
|
||||
['name' => 'Bob', 'age' => 30, 'active' => false],
|
||||
['name' => 'Charlie', 'age' => 35, 'active' => true],
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'person', 'person.age >= 30 and person.active == true'))->toBe([
|
||||
['name' => 'Charlie', 'age' => 35, 'active' => true],
|
||||
]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles or operator', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
['name' => 'Alice', 'age' => 25, 'role' => 'admin'],
|
||||
['name' => 'Bob', 'age' => 30, 'role' => 'user'],
|
||||
['name' => 'Charlie', 'age' => 35, 'role' => 'user'],
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'person', 'person.age < 30 or person.role == "admin"'))->toBe([
|
||||
['name' => 'Alice', 'age' => 25, 'role' => 'admin'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles simple boolean expressions', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
['name' => 'Alice', 'active' => true],
|
||||
['name' => 'Bob', 'active' => false],
|
||||
['name' => 'Charlie', 'active' => true],
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'person', 'person.active'))->toBe([
|
||||
['name' => 'Alice', 'active' => true],
|
||||
['name' => 'Charlie', 'active' => true],
|
||||
]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles empty array', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n >= 3'))->toBe([]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles associative array', function (): void {
|
||||
$filter = new Data();
|
||||
$input = [
|
||||
'a' => 1,
|
||||
'b' => 2,
|
||||
'c' => 3,
|
||||
];
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n >= 2'))->toBe([2, 3]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles non-array input', function (): void {
|
||||
$filter = new Data();
|
||||
$input = 123;
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n >= 3'))->toBe([]);
|
||||
});
|
||||
|
||||
test('where_exp filter handles null input', function (): void {
|
||||
$filter = new Data();
|
||||
$input = null;
|
||||
|
||||
expect($filter->where_exp($input, 'n', 'n >= 3'))->toBe([]);
|
||||
});
|
||||
|
|
|
|||
201
tests/Unit/Liquid/Utils/ExpressionUtilsTest.php
Normal file
201
tests/Unit/Liquid/Utils/ExpressionUtilsTest.php
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
|
||||
use App\Liquid\Utils\ExpressionUtils;
|
||||
|
||||
test('isAssociativeArray returns true for associative array', function (): void {
|
||||
$array = ['a' => 1, 'b' => 2, 'c' => 3];
|
||||
|
||||
expect(ExpressionUtils::isAssociativeArray($array))->toBeTrue();
|
||||
});
|
||||
|
||||
test('isAssociativeArray returns false for indexed array', function (): void {
|
||||
$array = [1, 2, 3, 4, 5];
|
||||
|
||||
expect(ExpressionUtils::isAssociativeArray($array))->toBeFalse();
|
||||
});
|
||||
|
||||
test('isAssociativeArray returns false for empty array', function (): void {
|
||||
$array = [];
|
||||
|
||||
expect(ExpressionUtils::isAssociativeArray($array))->toBeFalse();
|
||||
});
|
||||
|
||||
test('parseCondition handles simple comparison', function (): void {
|
||||
$result = ExpressionUtils::parseCondition('n >= 3');
|
||||
|
||||
expect($result)->toBe([
|
||||
'type' => 'comparison',
|
||||
'left' => 'n',
|
||||
'operator' => '>=',
|
||||
'right' => '3',
|
||||
]);
|
||||
});
|
||||
|
||||
test('parseCondition handles equality comparison', function (): void {
|
||||
$result = ExpressionUtils::parseCondition('user.role == "admin"');
|
||||
|
||||
expect($result)->toBe([
|
||||
'type' => 'comparison',
|
||||
'left' => 'user.role',
|
||||
'operator' => '==',
|
||||
'right' => '"admin"',
|
||||
]);
|
||||
});
|
||||
|
||||
test('parseCondition handles and operator', function (): void {
|
||||
$result = ExpressionUtils::parseCondition('user.age >= 30 and user.active == true');
|
||||
|
||||
expect($result)->toBe([
|
||||
'type' => 'and',
|
||||
'left' => [
|
||||
'type' => 'comparison',
|
||||
'left' => 'user.age',
|
||||
'operator' => '>=',
|
||||
'right' => '30',
|
||||
],
|
||||
'right' => [
|
||||
'type' => 'comparison',
|
||||
'left' => 'user.active',
|
||||
'operator' => '==',
|
||||
'right' => 'true',
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('parseCondition handles or operator', function (): void {
|
||||
$result = ExpressionUtils::parseCondition('user.age < 30 or user.role == "admin"');
|
||||
|
||||
expect($result)->toBe([
|
||||
'type' => 'or',
|
||||
'left' => [
|
||||
'type' => 'comparison',
|
||||
'left' => 'user.age',
|
||||
'operator' => '<',
|
||||
'right' => '30',
|
||||
],
|
||||
'right' => [
|
||||
'type' => 'comparison',
|
||||
'left' => 'user.role',
|
||||
'operator' => '==',
|
||||
'right' => '"admin"',
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
test('parseCondition handles simple expression', function (): void {
|
||||
$result = ExpressionUtils::parseCondition('user.active');
|
||||
|
||||
expect($result)->toBe([
|
||||
'type' => 'simple',
|
||||
'expression' => 'user.active',
|
||||
]);
|
||||
});
|
||||
|
||||
test('evaluateCondition handles comparison with numbers', function (): void {
|
||||
$condition = ExpressionUtils::parseCondition('n >= 3');
|
||||
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'n', 5))->toBeTrue();
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'n', 2))->toBeFalse();
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'n', 3))->toBeTrue();
|
||||
});
|
||||
|
||||
test('evaluateCondition handles comparison with strings', function (): void {
|
||||
$condition = ExpressionUtils::parseCondition('user.role == "admin"');
|
||||
$user = ['role' => 'admin'];
|
||||
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeTrue();
|
||||
|
||||
$user = ['role' => 'user'];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeFalse();
|
||||
});
|
||||
|
||||
test('evaluateCondition handles and operator', function (): void {
|
||||
$condition = ExpressionUtils::parseCondition('user.age >= 30 and user.active == true');
|
||||
$user = ['age' => 35, 'active' => true];
|
||||
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeTrue();
|
||||
|
||||
$user = ['age' => 25, 'active' => true];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeFalse();
|
||||
|
||||
$user = ['age' => 35, 'active' => false];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeFalse();
|
||||
});
|
||||
|
||||
test('evaluateCondition handles or operator', function (): void {
|
||||
$condition = ExpressionUtils::parseCondition('user.age < 30 or user.role == "admin"');
|
||||
$user = ['age' => 25, 'role' => 'user'];
|
||||
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeTrue();
|
||||
|
||||
$user = ['age' => 35, 'role' => 'admin'];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeTrue();
|
||||
|
||||
$user = ['age' => 35, 'role' => 'user'];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeFalse();
|
||||
});
|
||||
|
||||
test('evaluateCondition handles simple boolean expression', function (): void {
|
||||
$condition = ExpressionUtils::parseCondition('user.active');
|
||||
$user = ['active' => true];
|
||||
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeTrue();
|
||||
|
||||
$user = ['active' => false];
|
||||
expect(ExpressionUtils::evaluateCondition($condition, 'user', $user))->toBeFalse();
|
||||
});
|
||||
|
||||
test('resolveValue returns object when expression matches variable', function (): void {
|
||||
$object = ['name' => 'Alice', 'age' => 25];
|
||||
|
||||
expect(ExpressionUtils::resolveValue('user', 'user', $object))->toBe($object);
|
||||
});
|
||||
|
||||
test('resolveValue resolves property access for arrays', function (): void {
|
||||
$object = ['name' => 'Alice', 'age' => 25];
|
||||
|
||||
expect(ExpressionUtils::resolveValue('user.name', 'user', $object))->toBe('Alice');
|
||||
expect(ExpressionUtils::resolveValue('user.age', 'user', $object))->toBe(25);
|
||||
});
|
||||
|
||||
test('resolveValue resolves property access for objects', function (): void {
|
||||
$object = new stdClass();
|
||||
$object->name = 'Alice';
|
||||
$object->age = 25;
|
||||
|
||||
expect(ExpressionUtils::resolveValue('user.name', 'user', $object))->toBe('Alice');
|
||||
expect(ExpressionUtils::resolveValue('user.age', 'user', $object))->toBe(25);
|
||||
});
|
||||
|
||||
test('resolveValue returns null for non-existent properties', function (): void {
|
||||
$object = ['name' => 'Alice'];
|
||||
|
||||
expect(ExpressionUtils::resolveValue('user.age', 'user', $object))->toBeNull();
|
||||
});
|
||||
|
||||
test('resolveValue parses numeric values', function (): void {
|
||||
expect(ExpressionUtils::resolveValue('123', 'user', []))->toBe(123);
|
||||
expect(ExpressionUtils::resolveValue('45.67', 'user', []))->toBe(45.67);
|
||||
});
|
||||
|
||||
test('resolveValue parses boolean values', function (): void {
|
||||
expect(ExpressionUtils::resolveValue('true', 'user', []))->toBeTrue();
|
||||
expect(ExpressionUtils::resolveValue('false', 'user', []))->toBeFalse();
|
||||
expect(ExpressionUtils::resolveValue('TRUE', 'user', []))->toBeTrue();
|
||||
expect(ExpressionUtils::resolveValue('FALSE', 'user', []))->toBeFalse();
|
||||
});
|
||||
|
||||
test('resolveValue parses null value', function (): void {
|
||||
expect(ExpressionUtils::resolveValue('null', 'user', []))->toBeNull();
|
||||
expect(ExpressionUtils::resolveValue('NULL', 'user', []))->toBeNull();
|
||||
});
|
||||
|
||||
test('resolveValue removes quotes from strings', function (): void {
|
||||
expect(ExpressionUtils::resolveValue('"hello"', 'user', []))->toBe('hello');
|
||||
expect(ExpressionUtils::resolveValue("'world'", 'user', []))->toBe('world');
|
||||
});
|
||||
|
||||
test('resolveValue returns expression as-is for unquoted strings', function (): void {
|
||||
expect(ExpressionUtils::resolveValue('hello', 'user', []))->toBe('hello');
|
||||
expect(ExpressionUtils::resolveValue('world', 'user', []))->toBe('world');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue