Skip to content

Commit 29bcf2f

Browse files
committed
SmartNull: getIterator() delegates to the empty collection, not SmartString
Both classes define getIterator(), and the HTML-mode SmartString-first delegation routed it to SmartString, so an explicit ->getIterator() on a missing value threw "Can't foreach over SmartString NULL" - a type the caller never touched. A missing value now iterates like an empty collection (zero times), matching what foreach already did via SmartNull's own Iterator implementation.
1 parent 94a7bc7 commit 29bcf2f

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

src/SmartNull.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,11 @@ public function __call($name, array $arguments): mixed
285285
// SmartString methods only delegate in HTML mode: raw values are plain scalars
286286
// with no methods, so a miss answers SmartString calls the same way - with the
287287
// standard undefined-method Error. The isPublic() check keeps private helpers
288-
// out: method_exists() reports them, but they aren't part of the API
288+
// out: method_exists() reports them, but they aren't part of the API.
289+
// getIterator is defined by both classes and skips SmartString: a missing value
290+
// iterates like an empty collection, it doesn't throw SmartString's can't-foreach error
289291
$isSmartStringMethod = $this->useSmartStrings
292+
&& $name !== 'getIterator'
290293
&& method_exists(SmartString::class, $name)
291294
&& (new ReflectionMethod(SmartString::class, $name))->isPublic();
292295

tests/Unit/SmartNullTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ public function testForeachIteratesZeroTimes(string $class): void
183183
$this->assertSame([], $seen);
184184
}
185185

186+
#[DataProvider('modeProvider')]
187+
public function testGetIteratorReturnsEmptyCollectionIterator(string $class): void
188+
{
189+
// getIterator exists on SmartString too, but a missing value iterates like
190+
// an empty collection instead of throwing SmartString's can't-foreach error
191+
$smartNull = $this->smartNullFrom($class);
192+
193+
$this->assertSame([], iterator_to_array($smartNull->getIterator()));
194+
}
195+
186196
//endregion
187197
//region Method delegation: SmartArray methods and mode inheritance
188198

0 commit comments

Comments
 (0)