Skip to content

Commit 70c3fc4

Browse files
committed
Tweak callalble stringifier
The library was not showing when a variable is passed by reference, but more importantly, it would throw an exception when it could not get the default value. Signed-off-by: Henrique Moody <[email protected]>
1 parent 9aa80f9 commit 70c3fc4

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

src/Stringifiers/CallableStringifier.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ private function buildParameter(ReflectionParameter $reflectionParameter, int $d
151151
return $parameter . ' ...$' . $reflectionParameter->getName();
152152
}
153153

154-
$parameter .= ' $' . $reflectionParameter->getName();
154+
$parameter .= $reflectionParameter->isPassedByReference() ? ' &' : ' ';
155+
$parameter .= '$' . $reflectionParameter->getName();
155156
if ($reflectionParameter->isOptional()) {
156157
$parameter .= ' = ' . $this->buildValue($reflectionParameter, $depth);
157158
}
@@ -161,9 +162,12 @@ private function buildParameter(ReflectionParameter $reflectionParameter, int $d
161162

162163
private function buildValue(ReflectionParameter $reflectionParameter, int $depth): ?string
163164
{
164-
$value = $reflectionParameter->getDefaultValueConstantName();
165-
if ($value !== null) {
166-
return $value;
165+
if (!$reflectionParameter->isDefaultValueAvailable()) {
166+
return $this->stringifier->stringify(null, $depth);
167+
}
168+
169+
if ($reflectionParameter->isDefaultValueConstant()) {
170+
return $reflectionParameter->getDefaultValueConstantName();
167171
}
168172

169173
return $this->stringifier->stringify($reflectionParameter->getDefaultValue(), $depth);

tests/unit/Stringifiers/CallableStringifierTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
use function array_sum;
2626
use function sprintf;
2727

28+
use const PHP_MAJOR_VERSION;
29+
use const PHP_MINOR_VERSION;
30+
2831
#[CoversClass(ObjectHelper::class)]
2932
#[CoversClass(CallableStringifier::class)]
3033
final class CallableStringifierTest extends TestCase
@@ -72,6 +75,28 @@ public function itShouldStringifyWhenRawValueIsCallableWithDefaultValues(): void
7275
self::assertEquals($expected, $actual);
7376
}
7477

78+
#[Test]
79+
public function itShouldStringifyWhenRawValueIsCallableThatDoesNotHaveAnAccessibleDefaultValue(): void
80+
{
81+
if ([8, 1] !== [PHP_MAJOR_VERSION, PHP_MINOR_VERSION]) {
82+
self::markTestSkipped('This test is not applicable to PHP 8.1+');
83+
}
84+
85+
$raw = 'array_walk';
86+
87+
$quoter = new FakeQuoter();
88+
89+
$sut = new CallableStringifier(new FakeStringifier(), $quoter);
90+
91+
$actual = $sut->stringify($raw, self::DEPTH);
92+
$expected = $quoter->quote(
93+
'array_walk(object|array &$array, callable $callback, ?mixed $arg = fake.1.cbade92e): bool',
94+
self::DEPTH
95+
);
96+
97+
self::assertEquals($expected, $actual);
98+
}
99+
75100
/**
76101
* @return array<int, array{0: callable, 1: string}>
77102
*/
@@ -84,6 +109,7 @@ public static function callableRawValuesProvider(): array
84109
[static fn() => 1, 'function ()'],
85110
[static fn(): int => 1, 'function (): int'],
86111
[static fn(float $value): int => (int) $value, 'function (float $value): int'],
112+
[static fn(float &$value): int => (int) $value, 'function (float &$value): int'],
87113
[static fn(?float $value): int => (int) $value, 'function (?float $value): int'],
88114
[static fn(int $value = self::DEPTH): int => $value, 'function (int $value = self::DEPTH): int'],
89115
[static fn(int|float $value): int => (int) $value, 'function (int|float $value): int'],

0 commit comments

Comments
 (0)