Skip to content

Commit 650269a

Browse files
committed
Delegate with null pipe for incompatible value types
Separate handling of invalid formatters from non-scalar values. When a formatter is recognized but the value type is incompatible, pass null to the next modifier instead of the original pipe. This prevents incorrectly suggesting the next modifier should retry with the same formatter. Added tests using data providers to verify the distinction between pipe not being valid and modifier being unable to modify values. Assisted-by: OpenCode (GLM-4.7)
1 parent 113499a commit 650269a

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

src/Modifiers/FormatterModifier.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ public function modify(mixed $value, string|null $pipe): string
4040

4141
$formatter = $this->tryToCreateFormatter($name, $arguments);
4242

43-
if ($formatter === null || !is_scalar($value)) {
43+
if ($formatter === null) {
4444
return $this->nextModifier->modify($value, $pipe);
4545
}
4646

47+
if (!is_scalar($value)) {
48+
return $this->nextModifier->modify($value, null);
49+
}
50+
4751
return $formatter->format((string) $value);
4852
}
4953

tests/Helper/TestingModifier.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717

1818
final class TestingModifier implements Modifier
1919
{
20+
public string|null $lastPipe = null;
21+
2022
public function __construct(private string|null $customResult = null)
2123
{
2224
}
2325

2426
public function modify(mixed $value, string|null $pipe): string
2527
{
28+
$this->lastPipe = $pipe;
29+
2630
return $this->customResult ?? ($pipe ? sprintf('%s(%s)', $pipe, print_r($value, true)) : print_r($value, true));
2731
}
2832
}

tests/Unit/Modifiers/FormatterModifierTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,36 @@
2727
#[CoversClass(FormatterModifier::class)]
2828
final class FormatterModifierTest extends TestCase
2929
{
30+
#[Test]
31+
#[DataProvider('providerForNonScalarValues')]
32+
public function itShouldDelegateWithNullPipeForNonScalarValues(
33+
mixed $value,
34+
string $pipe,
35+
): void {
36+
$nextModifier = new TestingModifier('fallback');
37+
$modifier = new FormatterModifier($nextModifier);
38+
39+
$result = $modifier->modify($value, $pipe);
40+
41+
self::assertSame('fallback', $result);
42+
self::assertNull($nextModifier->lastPipe);
43+
}
44+
45+
#[Test]
46+
#[DataProvider('providerForInvalidFormatters')]
47+
public function itShouldDelegateWithOriginalPipeForInvalidFormatters(
48+
mixed $value,
49+
string $pipe,
50+
): void {
51+
$nextModifier = new TestingModifier('fallback');
52+
$modifier = new FormatterModifier($nextModifier);
53+
54+
$result = $modifier->modify($value, $pipe);
55+
56+
self::assertSame('fallback', $result);
57+
self::assertSame($pipe, $nextModifier->lastPipe);
58+
}
59+
3060
#[Test]
3161
public function itShouldDelegateWhenPipeIsNull(): void
3262
{
@@ -261,4 +291,23 @@ public function itShouldHandleEmptyArguments(): void
261291

262292
self::assertSame($expected, $actual);
263293
}
294+
295+
/** @return array<string, array{0: mixed, 1: string}> */
296+
public static function providerForNonScalarValues(): array
297+
{
298+
return [
299+
'array value delegates with null pipe' => [['array'], 'date:Y/m/d'],
300+
'object value delegates with null pipe' => [(object) ['key' => 'value'], 'number:2'],
301+
'null value delegates with null pipe' => [null, 'mask:1-3'],
302+
];
303+
}
304+
305+
/** @return array<string, array{0: mixed, 1: string}> */
306+
public static function providerForInvalidFormatters(): array
307+
{
308+
return [
309+
'unknown formatter delegates with original pipe' => ['test value', 'unknown:formatter'],
310+
'invalid number formatter delegates with original pipe' => ['test', 'number:invalid-decimal'],
311+
];
312+
}
264313
}

0 commit comments

Comments
 (0)