From e7bf21caee4c84362380491afd5c4008a4aad626 Mon Sep 17 00:00:00 2001 From: Fabio Capucci Date: Mon, 27 May 2024 17:41:30 +0200 Subject: [PATCH] pass filter arguments as array --- src/Nodes/Variable.php | 2 +- src/Render/RenderContext.php | 4 +- src/Support/FilterRegistry.php | 8 +- tests/Integration/StandardFilterTest.php | 246 +++++++++++------------ 4 files changed, 130 insertions(+), 130 deletions(-) diff --git a/src/Nodes/Variable.php b/src/Nodes/Variable.php index ebbb141..d7d5754 100644 --- a/src/Nodes/Variable.php +++ b/src/Nodes/Variable.php @@ -87,7 +87,7 @@ public function evaluate(RenderContext $context): mixed foreach ($this->filters as [$filterName, $filterArgs, $filterNamedArgs]) { $filterArgs = $this->evaluateFilterExpressions($context, $filterArgs ?? []); $filterNamedArgs = $this->evaluateFilterExpressions($context, $filterNamedArgs ?? []); - $output = $context->applyFilter($filterName, $output, ...$filterArgs, ...$filterNamedArgs); + $output = $context->applyFilter($filterName, $output, [...$filterArgs, ...$filterNamedArgs]); } return $output; diff --git a/src/Render/RenderContext.php b/src/Render/RenderContext.php index 7c6ce72..1375263 100644 --- a/src/Render/RenderContext.php +++ b/src/Render/RenderContext.php @@ -222,9 +222,9 @@ public function normalizeValue(mixed $value): mixed return $value; } - public function applyFilter(string $filter, mixed $value, mixed ...$args): mixed + public function applyFilter(string $filter, mixed $value, array $args = []): mixed { - return $this->filterRegistry->invoke($this, $filter, $value, ...$args); + return $this->filterRegistry->invoke($this, $filter, $value, $args); } public function getRegister(string $name): mixed diff --git a/src/Support/FilterRegistry.php b/src/Support/FilterRegistry.php index ced0591..4d597e4 100644 --- a/src/Support/FilterRegistry.php +++ b/src/Support/FilterRegistry.php @@ -30,14 +30,14 @@ public function register(string $filterClass): static continue; } - $this->filters[Str::snake($method->getName())] = function (RenderContext $context, ...$args) use ($filterClass, $method) { + $this->filters[Str::snake($method->getName())] = function (RenderContext $context, mixed $value, array $args) use ($filterClass, $method) { $filterClassInstance = new $filterClass(); if ($filterClassInstance instanceof IsContextAware) { $filterClassInstance->setContext($context); } - return $filterClassInstance->{$method->getName()}(...$args); + return $filterClassInstance->{$method->getName()}($value, ...$args); }; } @@ -47,13 +47,13 @@ public function register(string $filterClass): static /** * @throws UndefinedFilterException|UndefinedVariableException */ - public function invoke(RenderContext $context, string $filterName, mixed $value, mixed ...$args): mixed + public function invoke(RenderContext $context, string $filterName, mixed $value, array $args = []): mixed { $filter = $this->filters[$filterName] ?? null; if ($filter !== null) { try { - return $filter($context, $value, ...$args); + return $filter($context, $value, $args); } catch (\TypeError $e) { if ($value instanceof UndefinedVariable) { throw new UndefinedVariableException($value->variableName); diff --git a/tests/Integration/StandardFilterTest.php b/tests/Integration/StandardFilterTest.php index fdc546a..95500d9 100644 --- a/tests/Integration/StandardFilterTest.php +++ b/tests/Integration/StandardFilterTest.php @@ -30,49 +30,49 @@ }); test('slice', function () { - expect($this->filters->invoke($this->context, 'slice', 'foobar', 1, 3))->toBe('oob'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', 1, 1000))->toBe('oobar'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', 1, 0))->toBe(''); - expect($this->filters->invoke($this->context, 'slice', 'foobar', 1, 1))->toBe('o'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', 3, 3))->toBe('bar'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', -2, 2))->toBe('ar'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', -2, 1000))->toBe('ar'); - expect($this->filters->invoke($this->context, 'slice', 'foobar', -1))->toBe('r'); - expect($this->filters->invoke($this->context, 'slice', null, 0))->toBe(''); - expect($this->filters->invoke($this->context, 'slice', 'foobar', 100, 10))->toBe(''); - expect($this->filters->invoke($this->context, 'slice', 'foobar', -100, 10))->toBe(''); - expect($this->filters->invoke($this->context, 'slice', 'foobar', '1', '3'))->toBe('oob'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [1, 3]))->toBe('oob'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [1, 1000]))->toBe('oobar'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [1, 0]))->toBe(''); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [1, 1]))->toBe('o'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [3, 3]))->toBe('bar'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [-2, 2]))->toBe('ar'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [-2, 1000]))->toBe('ar'); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [-1]))->toBe('r'); + expect($this->filters->invoke($this->context, 'slice', null, [0]))->toBe(''); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [100, 10]))->toBe(''); + expect($this->filters->invoke($this->context, 'slice', 'foobar', [-100, 10]))->toBe(''); + expect($this->filters->invoke($this->context, 'slice', 'foobar', ['1', '3']))->toBe('oob'); }); test('slice on arrays', function () { $input = mb_str_split('foobar'); - expect($this->filters->invoke($this->context, 'slice', $input, 1, 3))->toBe(['o', 'o', 'b']); - expect($this->filters->invoke($this->context, 'slice', $input, 1, 1000))->toBe(['o', 'o', 'b', 'a', 'r']); - expect($this->filters->invoke($this->context, 'slice', $input, 1, 0))->toBe([]); - expect($this->filters->invoke($this->context, 'slice', $input, 1, 1))->toBe(['o']); - expect($this->filters->invoke($this->context, 'slice', $input, 3, 3))->toBe(['b', 'a', 'r']); - expect($this->filters->invoke($this->context, 'slice', $input, -2, 2))->toBe(['a', 'r']); - expect($this->filters->invoke($this->context, 'slice', $input, -2, 1000))->toBe(['a', 'r']); - expect($this->filters->invoke($this->context, 'slice', $input, -1))->toBe(['r']); - expect($this->filters->invoke($this->context, 'slice', $input, 100, 10))->toBe([]); - expect($this->filters->invoke($this->context, 'slice', $input, -100, 10))->toBe([]); + expect($this->filters->invoke($this->context, 'slice', $input, [1, 3]))->toBe(['o', 'o', 'b']); + expect($this->filters->invoke($this->context, 'slice', $input, [1, 1000]))->toBe(['o', 'o', 'b', 'a', 'r']); + expect($this->filters->invoke($this->context, 'slice', $input, [1, 0]))->toBe([]); + expect($this->filters->invoke($this->context, 'slice', $input, [1, 1]))->toBe(['o']); + expect($this->filters->invoke($this->context, 'slice', $input, [3, 3]))->toBe(['b', 'a', 'r']); + expect($this->filters->invoke($this->context, 'slice', $input, [-2, 2]))->toBe(['a', 'r']); + expect($this->filters->invoke($this->context, 'slice', $input, [-2, 1000]))->toBe(['a', 'r']); + expect($this->filters->invoke($this->context, 'slice', $input, [-1]))->toBe(['r']); + expect($this->filters->invoke($this->context, 'slice', $input, [100, 10]))->toBe([]); + expect($this->filters->invoke($this->context, 'slice', $input, [-100, 10]))->toBe([]); }); test('truncate', function () { - expect($this->filters->invoke($this->context, 'truncate', '1234567890', 7))->toBe('1234...'); - expect($this->filters->invoke($this->context, 'truncate', '1234567890', 20))->toBe('1234567890'); - expect($this->filters->invoke($this->context, 'truncate', '1234567890', 0))->toBe('...'); + expect($this->filters->invoke($this->context, 'truncate', '1234567890', [7]))->toBe('1234...'); + expect($this->filters->invoke($this->context, 'truncate', '1234567890', [20]))->toBe('1234567890'); + expect($this->filters->invoke($this->context, 'truncate', '1234567890', [0]))->toBe('...'); expect($this->filters->invoke($this->context, 'truncate', '1234567890'))->toBe('1234567890'); - expect($this->filters->invoke($this->context, 'truncate', '测试测试测试测试', 5))->toBe('测试...'); - expect($this->filters->invoke($this->context, 'truncate', '1234567890', 5, 1))->toBe('12341'); + expect($this->filters->invoke($this->context, 'truncate', '测试测试测试测试', [5]))->toBe('测试...'); + expect($this->filters->invoke($this->context, 'truncate', '1234567890', [5, 1]))->toBe('12341'); }); test('split', function () { - expect($this->filters->invoke($this->context, 'split', '12~34', '~'))->toBe(['12', '34']); - expect($this->filters->invoke($this->context, 'split', 'A? ~ ~ ~ ,Z', '~ ~ ~'))->toBe(['A? ', ' ,Z']); - expect($this->filters->invoke($this->context, 'split', 'A?Z', '~'))->toBe(['A?Z']); - expect($this->filters->invoke($this->context, 'split', null, ' '))->toBe([]); - expect($this->filters->invoke($this->context, 'split', 'A1Z', 1))->toBe(['A', 'Z']); + expect($this->filters->invoke($this->context, 'split', '12~34', ['~']))->toBe(['12', '34']); + expect($this->filters->invoke($this->context, 'split', 'A? ~ ~ ~ ,Z', ['~ ~ ~']))->toBe(['A? ', ' ,Z']); + expect($this->filters->invoke($this->context, 'split', 'A?Z', ['~']))->toBe(['A?Z']); + expect($this->filters->invoke($this->context, 'split', null, [' ']))->toBe([]); + expect($this->filters->invoke($this->context, 'split', 'A1Z', [1]))->toBe(['A', 'Z']); }); test('escape', function () { @@ -112,16 +112,16 @@ }); test('truncatewords', function () { - expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', 4))->toBe('one two three'); - expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', 2))->toBe('one two...'); + expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', [4]))->toBe('one two three'); + expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', [2]))->toBe('one two...'); expect($this->filters->invoke($this->context, 'truncatewords', 'one two three'))->toBe('one two three'); - expect($this->filters->invoke($this->context, 'truncatewords', 'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13” x 16” x 10.5” high) with cover.', 15)) + expect($this->filters->invoke($this->context, 'truncatewords', 'Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13” x 16” x 10.5” high) with cover.', [15])) ->toBe('Two small (13” x 5.5” x 10” high) baskets fit inside one large basket (13”...'); - expect($this->filters->invoke($this->context, 'truncatewords', '测试测试测试测试', 5))->toBe('测试测试测试测试'); - expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', 2, 1))->toBe('one two1'); - expect($this->filters->invoke($this->context, 'truncatewords', "one two\tthree\nfour", 3))->toBe('one two three...'); - expect($this->filters->invoke($this->context, 'truncatewords', 'one two three four', 2))->toBe('one two...'); - expect($this->filters->invoke($this->context, 'truncatewords', 'one two three four', 0))->toBe('one...'); + expect($this->filters->invoke($this->context, 'truncatewords', '测试测试测试测试', [5]))->toBe('测试测试测试测试'); + expect($this->filters->invoke($this->context, 'truncatewords', 'one two three', [2, 1]))->toBe('one two1'); + expect($this->filters->invoke($this->context, 'truncatewords', "one two\tthree\nfour", [3]))->toBe('one two three...'); + expect($this->filters->invoke($this->context, 'truncatewords', 'one two three four', [2]))->toBe('one two...'); + expect($this->filters->invoke($this->context, 'truncatewords', 'one two three four', [0]))->toBe('one...'); }); test('strip html', function () { @@ -137,15 +137,15 @@ test('join', function () { expect($this->filters->invoke($this->context, 'join', [1, 2, 3, 4]))->toBe('1 2 3 4'); - expect($this->filters->invoke($this->context, 'join', [1, 2, 3, 4], ' - '))->toBe('1 - 2 - 3 - 4'); - expect($this->filters->invoke($this->context, 'join', [1, 2, 3, 4], 1))->toBe('1121314'); + expect($this->filters->invoke($this->context, 'join', [1, 2, 3, 4], [' - ']))->toBe('1 - 2 - 3 - 4'); + expect($this->filters->invoke($this->context, 'join', [1, 2, 3, 4], [1]))->toBe('1121314'); }); test('sort', function () { expect($this->filters->invoke($this->context, 'sort', [4, 3, 2, 1]))->toBe([1, 2, 3, 4]); - expect($this->filters->invoke($this->context, 'sort', [['a' => 4], ['a' => 3], ['a' => 1], ['a' => 2]], 'a'))->toBe([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]); + expect($this->filters->invoke($this->context, 'sort', [['a' => 4], ['a' => 3], ['a' => 1], ['a' => 2]], ['a']))->toBe([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]]); expect($this->filters->invoke($this->context, 'sort', [null, 4, 3, 2, 1]))->toBe([1, 2, 3, 4, null]); - expect($this->filters->invoke($this->context, 'sort', [['a' => 4], ['a' => 3], [], ['a' => 1], ['a' => 2]], 'a'))->toBe([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4], []]); + expect($this->filters->invoke($this->context, 'sort', [['a' => 4], ['a' => 3], [], ['a' => 1], ['a' => 2]], ['a']))->toBe([['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4], []]); }); test('sort when property is sometimes missing puts nulls last', function () { @@ -155,7 +155,7 @@ ['price' => 1, 'handle' => 'gamma'], ['handle' => 'delta'], ['price' => 2, 'handle' => 'epsilon'], - ], 'price'))->toBe([ + ], ['price']))->toBe([ ['price' => 1, 'handle' => 'gamma'], ['price' => 2, 'handle' => 'epsilon'], ['price' => 4, 'handle' => 'alpha'], @@ -166,9 +166,9 @@ test('sort natural', function () { expect($this->filters->invoke($this->context, 'sort_natural', ['c', 'D', 'a', 'B']))->toBe(['a', 'B', 'c', 'D']); - expect($this->filters->invoke($this->context, 'sort_natural', [['a' => 'D'], ['a' => 'c'], ['a' => 'a'], ['a' => 'B']], 'a'))->toBe([['a' => 'a'], ['a' => 'B'], ['a' => 'c'], ['a' => 'D']]); + expect($this->filters->invoke($this->context, 'sort_natural', [['a' => 'D'], ['a' => 'c'], ['a' => 'a'], ['a' => 'B']], ['a']))->toBe([['a' => 'a'], ['a' => 'B'], ['a' => 'c'], ['a' => 'D']]); expect($this->filters->invoke($this->context, 'sort_natural', [null, 'c', 'D', 'a', 'B']))->toBe(['a', 'B', 'c', 'D', null]); - expect($this->filters->invoke($this->context, 'sort_natural', [['a' => 'D'], ['a' => 'c'], [], ['a' => 'a'], ['a' => 'B']], 'a'))->toBe([['a' => 'a'], ['a' => 'B'], ['a' => 'c'], ['a' => 'D'], []]); + expect($this->filters->invoke($this->context, 'sort_natural', [['a' => 'D'], ['a' => 'c'], [], ['a' => 'a'], ['a' => 'B']], ['a']))->toBe([['a' => 'a'], ['a' => 'B'], ['a' => 'c'], ['a' => 'D'], []]); }); test('sort natural when property is sometimes missing puts nulls last', function () { @@ -178,7 +178,7 @@ ['price' => '1', 'handle' => 'gamma'], ['handle' => 'delta'], ['price' => 2, 'handle' => 'epsilon'], - ], 'price'))->toBe([ + ], ['price']))->toBe([ ['price' => '1', 'handle' => 'gamma'], ['price' => 2, 'handle' => 'epsilon'], ['price' => '4', 'handle' => 'alpha'], @@ -196,7 +196,7 @@ ['key' => 'a'], ['key' => 'b'], ['key' => 'c'], - ], 'key'))->toBe([ + ], ['key']))->toBe([ ['key' => 'a'], ['key' => 'b'], ['key' => 'c'], @@ -209,32 +209,32 @@ }); test('sort empty array', function () { - expect($this->filters->invoke($this->context, 'sort', [], 'a'))->toBe([]); - expect($this->filters->invoke($this->context, 'sort_natural', [], 'a'))->toBe([]); + expect($this->filters->invoke($this->context, 'sort', [], ['a']))->toBe([]); + expect($this->filters->invoke($this->context, 'sort_natural', [], ['a']))->toBe([]); }); test('numerical vs lexicographical sort', function () { expect($this->filters->invoke($this->context, 'sort', [10, 2]))->toBe([2, 10]); - expect($this->filters->invoke($this->context, 'sort', [['a' => 10], ['a' => 2]], 'a'))->toBe([['a' => 2], ['a' => 10]]); + expect($this->filters->invoke($this->context, 'sort', [['a' => 10], ['a' => 2]], ['a']))->toBe([['a' => 2], ['a' => 10]]); expect($this->filters->invoke($this->context, 'sort', ['10', '2']))->toBe(['10', '2']); - expect($this->filters->invoke($this->context, 'sort', [['a' => '10'], ['a' => '2']], 'a'))->toBe([['a' => '10'], ['a' => '2']]); + expect($this->filters->invoke($this->context, 'sort', [['a' => '10'], ['a' => '2']], ['a']))->toBe([['a' => '10'], ['a' => '2']]); }); test('uniq', function () { expect($this->filters->invoke($this->context, 'uniq', ['foo']))->toBe(['foo']); expect($this->filters->invoke($this->context, 'uniq', [1, 1, 3, 2, 3, 1, 4, 3, 2, 1]))->toBe([1, 3, 2, 4]); - expect($this->filters->invoke($this->context, 'uniq', [['a' => 1], ['a' => 3], ['a' => 1], ['a' => 2]], 'a'))->toBe([['a' => 1], ['a' => 3], ['a' => 2]]); - expect($this->filters->invoke($this->context, 'uniq', [], 'a'))->toBe([]); + expect($this->filters->invoke($this->context, 'uniq', [['a' => 1], ['a' => 3], ['a' => 1], ['a' => 2]], ['a']))->toBe([['a' => 1], ['a' => 3], ['a' => 2]]); + expect($this->filters->invoke($this->context, 'uniq', [], ['a']))->toBe([]); $testDrop = new TestDrop('test'); $testDropAlternate = new TestDrop('test'); - expect($this->filters->invoke($this->context, 'uniq', [$testDrop, $testDropAlternate], 'value'))->toBe([$testDrop]); + expect($this->filters->invoke($this->context, 'uniq', [$testDrop, $testDropAlternate], ['value']))->toBe([$testDrop]); }); test('compact', function () { expect($this->filters->invoke($this->context, 'compact', []))->toBe([]); expect($this->filters->invoke($this->context, 'compact', [1, null, 2, 3]))->toBe([1, 2, 3]); - expect($this->filters->invoke($this->context, 'compact', [['a' => 1], ['a' => 3], [], ['a' => 2]], 'a'))->toBe([['a' => 1], ['a' => 3], ['a' => 2]]); + expect($this->filters->invoke($this->context, 'compact', [['a' => 1], ['a' => 3], [], ['a' => 2]], ['a']))->toBe([['a' => 1], ['a' => 3], ['a' => 2]]); }); test('reverse', function () { @@ -242,7 +242,7 @@ }); test('map', function () { - expect($this->filters->invoke($this->context, 'map', [['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]], 'a'))->toBe([1, 2, 3, 4]); + expect($this->filters->invoke($this->context, 'map', [['a' => 1], ['a' => 2], ['a' => 3], ['a' => 4]], ['a']))->toBe([1, 2, 3, 4]); assertTemplateResult( 'abc', @@ -343,7 +343,7 @@ [3], ]; - expect(fn () => $this->filters->invoke($this->context, 'map', $foo, 'bar'))->toThrow(InvalidArgumentException::class); + expect(fn () => $this->filters->invoke($this->context, 'map', $foo, ['bar']))->toThrow(InvalidArgumentException::class); }); test('map returns empty with no property', function () { @@ -353,7 +353,7 @@ [3], ]; - expect(fn () => $this->filters->invoke($this->context, 'map', $foo, null))->toThrow(TypeError::class); + expect(fn () => $this->filters->invoke($this->context, 'map', $foo, [null]))->toThrow(TypeError::class); }); test('sort works on iterator', function () { @@ -386,28 +386,28 @@ }); test('date', function () { - expect($this->filters->invoke($this->context, 'date', new DateTime('2006-05-05 10:00:00'), '%B'))->toBe('May'); - expect($this->filters->invoke($this->context, 'date', new DateTime('2006-06-05 10:00:00'), '%B'))->toBe('June'); - expect($this->filters->invoke($this->context, 'date', new DateTime('2006-07-05 10:00:00'), '%B'))->toBe('July'); + expect($this->filters->invoke($this->context, 'date', new DateTime('2006-05-05 10:00:00'), ['%B']))->toBe('May'); + expect($this->filters->invoke($this->context, 'date', new DateTime('2006-06-05 10:00:00'), ['%B']))->toBe('June'); + expect($this->filters->invoke($this->context, 'date', new DateTime('2006-07-05 10:00:00'), ['%B']))->toBe('July'); - expect($this->filters->invoke($this->context, 'date', '2006-05-05 10:00:00', '%B'))->toBe('May'); - expect($this->filters->invoke($this->context, 'date', '2006-06-05 10:00:00', '%B'))->toBe('June'); - expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', '%B'))->toBe('July'); + expect($this->filters->invoke($this->context, 'date', '2006-05-05 10:00:00', ['%B']))->toBe('May'); + expect($this->filters->invoke($this->context, 'date', '2006-06-05 10:00:00', ['%B']))->toBe('June'); + expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', ['%B']))->toBe('July'); - expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', ''))->toBe('2006-07-05 10:00:00'); - expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', null))->toBe('2006-07-05 10:00:00'); + expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', ['']))->toBe('2006-07-05 10:00:00'); + expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', [null]))->toBe('2006-07-05 10:00:00'); - expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', '%m/%d/%Y'))->toBe('07/05/2006'); + expect($this->filters->invoke($this->context, 'date', '2006-07-05 10:00:00', ['%m/%d/%Y']))->toBe('07/05/2006'); - expect($this->filters->invoke($this->context, 'date', 'Fri Jul 16 01:00:00 2004', '%m/%d/%Y'))->toBe('07/16/2004'); - expect($this->filters->invoke($this->context, 'date', 'now', '%Y'))->toBe(date('Y')); - expect($this->filters->invoke($this->context, 'date', 'today', '%Y'))->toBe(date('Y')); + expect($this->filters->invoke($this->context, 'date', 'Fri Jul 16 01:00:00 2004', ['%m/%d/%Y']))->toBe('07/16/2004'); + expect($this->filters->invoke($this->context, 'date', 'now', ['%Y']))->toBe(date('Y')); + expect($this->filters->invoke($this->context, 'date', 'today', ['%Y']))->toBe(date('Y')); - expect($this->filters->invoke($this->context, 'date', null, '%B'))->toBeNull(); - expect($this->filters->invoke($this->context, 'date', '', '%B'))->toBe(''); + expect($this->filters->invoke($this->context, 'date', null, ['%B']))->toBeNull(); + expect($this->filters->invoke($this->context, 'date', '', ['%B']))->toBe(''); - expect($this->filters->invoke($this->context, 'date', 1152098955, '%m/%d/%Y'))->toBe('07/05/2006'); - expect($this->filters->invoke($this->context, 'date', '1152098955', '%m/%d/%Y'))->toBe('07/05/2006'); + expect($this->filters->invoke($this->context, 'date', 1152098955, ['%m/%d/%Y']))->toBe('07/05/2006'); + expect($this->filters->invoke($this->context, 'date', '1152098955', ['%m/%d/%Y']))->toBe('07/05/2006'); }); test('first last', function () { @@ -419,25 +419,25 @@ }); test('replace', function () { - expect($this->filters->invoke($this->context, 'replace', 'a a a a', 'a', 'b'))->toBe('b b b b'); - expect($this->filters->invoke($this->context, 'replace', '1 1 1 1', 1, 2))->toBe('2 2 2 2'); - expect($this->filters->invoke($this->context, 'replace', '1 1 1 1', 2, 3))->toBe('1 1 1 1'); + expect($this->filters->invoke($this->context, 'replace', 'a a a a', ['a', 'b']))->toBe('b b b b'); + expect($this->filters->invoke($this->context, 'replace', '1 1 1 1', [1, 2]))->toBe('2 2 2 2'); + expect($this->filters->invoke($this->context, 'replace', '1 1 1 1', [2, 3]))->toBe('1 1 1 1'); assertTemplateResult( '2 2 2 2', "{{ '1 1 1 1' | replace: '1', 2 }}", ); - expect($this->filters->invoke($this->context, 'replace_first', 'a a a a', 'a', 'b'))->toBe('b a a a'); - expect($this->filters->invoke($this->context, 'replace_first', '1 1 1 1', 1, 2))->toBe('2 1 1 1'); - expect($this->filters->invoke($this->context, 'replace_first', '1 1 1 1', 2, 3))->toBe('1 1 1 1'); + expect($this->filters->invoke($this->context, 'replace_first', 'a a a a', ['a', 'b']))->toBe('b a a a'); + expect($this->filters->invoke($this->context, 'replace_first', '1 1 1 1', [1, 2]))->toBe('2 1 1 1'); + expect($this->filters->invoke($this->context, 'replace_first', '1 1 1 1', [2, 3]))->toBe('1 1 1 1'); assertTemplateResult( '2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}", ); - expect($this->filters->invoke($this->context, 'replace_last', 'a a a a', 'a', 'b'))->toBe('a a a b'); - expect($this->filters->invoke($this->context, 'replace_last', '1 1 1 1', 1, 2))->toBe('1 1 1 2'); - expect($this->filters->invoke($this->context, 'replace_last', '1 1 1 1', 2, 3))->toBe('1 1 1 1'); + expect($this->filters->invoke($this->context, 'replace_last', 'a a a a', ['a', 'b']))->toBe('a a a b'); + expect($this->filters->invoke($this->context, 'replace_last', '1 1 1 1', [1, 2]))->toBe('1 1 1 2'); + expect($this->filters->invoke($this->context, 'replace_last', '1 1 1 1', [2, 3]))->toBe('1 1 1 1'); assertTemplateResult( '1 1 1 2', "{{ '1 1 1 1' | replace_last: '1', 2 }}", @@ -445,19 +445,19 @@ }); test('remove', function () { - expect($this->filters->invoke($this->context, 'remove', 'a a a a', 'a'))->toBe(' '); + expect($this->filters->invoke($this->context, 'remove', 'a a a a', ['a']))->toBe(' '); assertTemplateResult( ' ', "{{ '1 1 1 1' | remove: 1 }}", ); - expect($this->filters->invoke($this->context, 'remove_first', 'a b a a', 'a '))->toBe('b a a'); + expect($this->filters->invoke($this->context, 'remove_first', 'a b a a', ['a ']))->toBe('b a a'); assertTemplateResult( ' 1 1 1', "{{ '1 1 1 1' | remove_first: 1 }}", ); - expect($this->filters->invoke($this->context, 'remove_last', 'a a b a', ' a'))->toBe('a a b'); + expect($this->filters->invoke($this->context, 'remove_last', 'a a b a', [' a']))->toBe('a a b'); assertTemplateResult( '1 1 1 ', "{{ '1 1 1 1' | remove_last: 1 }}", @@ -598,19 +598,19 @@ }); test('concat', function () { - expect($this->filters->invoke($this->context, 'concat', [1, 2], [3, 4]))->toBe([1, 2, 3, 4]); - expect($this->filters->invoke($this->context, 'concat', [1, 2], ['a']))->toBe([1, 2, 'a']); - expect($this->filters->invoke($this->context, 'concat', [1, 2], [10]))->toBe([1, 2, 10]); + expect($this->filters->invoke($this->context, 'concat', [1, 2], [[3, 4]]))->toBe([1, 2, 3, 4]); + expect($this->filters->invoke($this->context, 'concat', [1, 2], [['a']]))->toBe([1, 2, 'a']); + expect($this->filters->invoke($this->context, 'concat', [1, 2], [[10]]))->toBe([1, 2, 10]); - expect(fn () => $this->filters->invoke($this->context, 'concat', [1, 2], 10))->toThrow(TypeError::class); + expect(fn () => $this->filters->invoke($this->context, 'concat', [1, 2], [10]))->toThrow(TypeError::class); }); test('default', function () { - expect($this->filters->invoke($this->context, 'default', 'foo', 'bar'))->toBe('foo'); - expect($this->filters->invoke($this->context, 'default', null, 'bar'))->toBe('bar'); - expect($this->filters->invoke($this->context, 'default', '', 'bar'))->toBe('bar'); - expect($this->filters->invoke($this->context, 'default', false, 'bar'))->toBe('bar'); - expect($this->filters->invoke($this->context, 'default', [], 'bar'))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', 'foo', ['bar']))->toBe('foo'); + expect($this->filters->invoke($this->context, 'default', null, ['bar']))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', '', ['bar']))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', false, ['bar']))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', [], ['bar']))->toBe('bar'); assertTemplateResult('bar', "{{ false | default: 'bar' }}"); assertTemplateResult('bar', "{{ drop | default: 'bar' }}", ['drop' => new BooleanDrop(false)]); @@ -618,7 +618,7 @@ }); test('default handle undefined variable', function (bool $strict) { - expect($this->filters->invoke($this->context, 'default', new UndefinedVariable('foo'), 'bar'))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', new UndefinedVariable('foo'), ['bar']))->toBe('bar'); assertTemplateResult('bar', '{{ foo | default: "bar" }}', strictVariables: $strict); assertTemplateResult('bar', '{{ foo.x | default: "bar" }}', strictVariables: $strict); @@ -629,11 +629,11 @@ ]); test('default handle false', function () { - expect($this->filters->invoke($this->context, 'default', 'foo', 'bar', allow_false: true))->toBe('foo'); - expect($this->filters->invoke($this->context, 'default', null, 'bar', allow_false: true))->toBe('bar'); - expect($this->filters->invoke($this->context, 'default', '', 'bar', allow_false: true))->toBe('bar'); - expect($this->filters->invoke($this->context, 'default', false, 'bar', allow_false: true))->toBe(false); - expect($this->filters->invoke($this->context, 'default', [], 'bar', allow_false: true))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', 'foo', ['bar', 'allow_false' => true]))->toBe('foo'); + expect($this->filters->invoke($this->context, 'default', null, ['bar', 'allow_false' => true]))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', '', ['bar', 'allow_false' => true]))->toBe('bar'); + expect($this->filters->invoke($this->context, 'default', false, ['bar', 'allow_false' => true]))->toBe(false); + expect($this->filters->invoke($this->context, 'default', [], ['bar', 'allow_false' => true]))->toBe('bar'); assertTemplateResult('false', "{{ false | default: 'bar', allow_false: true }}"); assertTemplateResult('Nay', "{{ drop | default: 'bar', allow_false: true }}", ['drop' => new BooleanDrop(false)]); @@ -653,8 +653,8 @@ ['handle' => 'delta', 'ok' => true], ]; - expect($this->filters->invoke($this->context, 'where', $input, 'ok', true))->toBe($expectation); - expect($this->filters->invoke($this->context, 'where', $input, 'ok'))->toBe($expectation); + expect($this->filters->invoke($this->context, 'where', $input, ['ok', true]))->toBe($expectation); + expect($this->filters->invoke($this->context, 'where', $input, ['ok']))->toBe($expectation); }); test('where string keys', function () { @@ -662,7 +662,7 @@ $expectation = ['beta']; - expect($this->filters->invoke($this->context, 'where', $input, 'be'))->toBe($expectation); + expect($this->filters->invoke($this->context, 'where', $input, ['be']))->toBe($expectation); }); test('where no key set', function () { @@ -678,8 +678,8 @@ ['handle' => 'delta', 'ok' => true], ]; - expect($this->filters->invoke($this->context, 'where', $input, 'ok', true))->toBe($expectation); - expect($this->filters->invoke($this->context, 'where', $input, 'ok'))->toBe($expectation); + expect($this->filters->invoke($this->context, 'where', $input, ['ok', true]))->toBe($expectation); + expect($this->filters->invoke($this->context, 'where', $input, ['ok']))->toBe($expectation); }); test('where non boolean value', function () { @@ -689,24 +689,24 @@ ['message' => 'Hallo!', 'language' => 'German'], ]; - expect($this->filters->invoke($this->context, 'where', $input, 'language', 'French'))->toBe([['message' => 'Bonjour!', 'language' => 'French']]); - expect($this->filters->invoke($this->context, 'where', $input, 'language', 'German'))->toBe([['message' => 'Hallo!', 'language' => 'German']]); - expect($this->filters->invoke($this->context, 'where', $input, 'language', 'English'))->toBe([['message' => 'Hello!', 'language' => 'English']]); + expect($this->filters->invoke($this->context, 'where', $input, ['language', 'French']))->toBe([['message' => 'Bonjour!', 'language' => 'French']]); + expect($this->filters->invoke($this->context, 'where', $input, ['language', 'German']))->toBe([['message' => 'Hallo!', 'language' => 'German']]); + expect($this->filters->invoke($this->context, 'where', $input, ['language', 'English']))->toBe([['message' => 'Hello!', 'language' => 'English']]); }); test('where non array map input', function () { - expect($this->filters->invoke($this->context, 'where', ['a' => 'ok'], 'a', 'ok'))->toBe([['a' => 'ok']]); - expect($this->filters->invoke($this->context, 'where', ['a' => 'not ok'], 'a', 'ok'))->toBe([]); + expect($this->filters->invoke($this->context, 'where', ['a' => 'ok'], ['a', 'ok']))->toBe([['a' => 'ok']]); + expect($this->filters->invoke($this->context, 'where', ['a' => 'not ok'], ['a', 'ok']))->toBe([]); }); test('where indexable but non map value', function () { - expect(fn () => $this->filters->invoke($this->context, 'where', 1, 'ok', true))->toThrow(TypeError::class); - expect(fn () => $this->filters->invoke($this->context, 'where', 1, 'ok'))->toThrow(TypeError::class); + expect(fn () => $this->filters->invoke($this->context, 'where', 1, ['ok', true]))->toThrow(TypeError::class); + expect(fn () => $this->filters->invoke($this->context, 'where', 1, ['ok']))->toThrow(TypeError::class); }); test('where array of only unindexable values', function () { - expect($this->filters->invoke($this->context, 'where', [null], 'ok', true))->toBe([]); - expect($this->filters->invoke($this->context, 'where', [null], 'ok'))->toBe([]); + expect($this->filters->invoke($this->context, 'where', [null], ['ok', true]))->toBe([]); + expect($this->filters->invoke($this->context, 'where', [null], ['ok']))->toBe([]); }); test('where no target value', function () { @@ -717,21 +717,21 @@ ['bar' => true], ]; - expect($this->filters->invoke($this->context, 'where', $input, 'foo'))->toBe([['foo' => true], ['foo' => 'for sure']]); + expect($this->filters->invoke($this->context, 'where', $input, ['foo']))->toBe([['foo' => true], ['foo' => 'for sure']]); }); test('sum with all numbers', function () { $input = [1, 2]; expect($this->filters->invoke($this->context, 'sum', $input))->toBe(3); - expect(fn () => $this->filters->invoke($this->context, 'sum', $input, 'quantity'))->toThrow(InvalidArgumentException::class); + expect(fn () => $this->filters->invoke($this->context, 'sum', $input, ['quantity']))->toThrow(InvalidArgumentException::class); }); test('sum with numeric strings', function () { $input = [1, 2, '3', '4']; expect($this->filters->invoke($this->context, 'sum', $input))->toBe(10); - expect(fn () => $this->filters->invoke($this->context, 'sum', $input, 'quantity'))->toThrow(InvalidArgumentException::class); + expect(fn () => $this->filters->invoke($this->context, 'sum', $input, ['quantity']))->toThrow(InvalidArgumentException::class); }); test('sum with indexable map values', function () { @@ -742,9 +742,9 @@ ]; expect($this->filters->invoke($this->context, 'sum', $input))->toBe(0); - expect($this->filters->invoke($this->context, 'sum', $input, 'quantity'))->toBe(3); - expect($this->filters->invoke($this->context, 'sum', $input, 'weight'))->toBe(7); - expect($this->filters->invoke($this->context, 'sum', $input, 'subtotal'))->toBe(0); + expect($this->filters->invoke($this->context, 'sum', $input, ['quantity']))->toBe(3); + expect($this->filters->invoke($this->context, 'sum', $input, ['weight']))->toBe(7); + expect($this->filters->invoke($this->context, 'sum', $input, ['subtotal']))->toBe(0); }); test('sum with indexable non map values', function () {