From 3f78192801c36d36866b1a3108abe625113cb194 Mon Sep 17 00:00:00 2001 From: Pascal Schneider <77938819+passchn@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:10:29 +0200 Subject: [PATCH 1/7] allow \Stringable in Runtime::ifVar --- src/Runtime.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Runtime.php b/src/Runtime.php index f143ae9..28a5890 100644 --- a/src/Runtime.php +++ b/src/Runtime.php @@ -37,14 +37,19 @@ public static function lo(array $v): string /** * For {{#if}} and {{#unless}}. * - * @param array|string|int>|string|int|float|bool|null $v value to be tested + * @param array|string|int>|string|\Stringable|int|float|bool|null $v value to be tested * @param bool $zero include zero as true * * @return bool Return true when the value is not null nor false. */ public static function ifvar(mixed $v, bool $zero): bool { - return $v !== null && $v !== false && ($zero || ($v !== 0 && $v !== 0.0)) && $v !== '' && (!is_array($v) || count($v) > 0); + return $v !== null + && $v !== false + && ($zero || ($v !== 0 && $v !== 0.0)) + && $v !== '' + && (!$v instanceof \Stringable || (string) $v !== '') + && (!is_array($v) || count($v) > 0); } /** From 650de0cbcdadabe8092ecb14bbf794aa399f7bec Mon Sep 17 00:00:00 2001 From: Pascal Schneider <77938819+passchn@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:29:53 +0200 Subject: [PATCH 2/7] add test for stringable value --- tests/RuntimeTest.php | 90 +++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index 109857f..4f113bf 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -1,44 +1,60 @@ assertFalse(Runtime::ifvar(null, false)); - $this->assertFalse(Runtime::ifvar(0, false)); - $this->assertTrue(Runtime::ifvar(0, true)); - $this->assertFalse(Runtime::ifvar(false, false)); - $this->assertTrue(Runtime::ifvar(true, false)); - $this->assertTrue(Runtime::ifvar(1, false)); - $this->assertFalse(Runtime::ifvar('', false)); - $this->assertTrue(Runtime::ifvar('0', false)); - $this->assertFalse(Runtime::ifvar([], false)); - $this->assertTrue(Runtime::ifvar([''], false)); - $this->assertTrue(Runtime::ifvar([0], false)); - } + class RuntimeTest extends TestCase { + public function testIfVar(): void { + $this->assertFalse(Runtime::ifvar(null, false)); + $this->assertFalse(Runtime::ifvar(0, false)); + $this->assertTrue(Runtime::ifvar(0, true)); + $this->assertFalse(Runtime::ifvar(false, false)); + $this->assertTrue(Runtime::ifvar(true, false)); + $this->assertTrue(Runtime::ifvar(1, false)); + $this->assertFalse(Runtime::ifvar('', false)); + $this->assertTrue(Runtime::ifvar('0', false)); + $this->assertFalse(Runtime::ifvar([], false)); + $this->assertTrue(Runtime::ifvar([''], false)); + $this->assertTrue(Runtime::ifvar([0], false)); + $this->assertFalse(Runtime::ifvar($this->createStringable(''), false)); + $this->assertTrue(Runtime::ifvar($this->createStringable('0'), false)); + } - public function testIsec(): void - { - $this->assertTrue(Runtime::isec(null)); - $this->assertFalse(Runtime::isec(0)); - $this->assertTrue(Runtime::isec(false)); - $this->assertFalse(Runtime::isec('false')); - $this->assertTrue(Runtime::isec([])); - $this->assertFalse(Runtime::isec(['1'])); - } + public function testIsec(): void { + $this->assertTrue(Runtime::isec(null)); + $this->assertFalse(Runtime::isec(0)); + $this->assertTrue(Runtime::isec(false)); + $this->assertFalse(Runtime::isec('false')); + $this->assertTrue(Runtime::isec([])); + $this->assertFalse(Runtime::isec(['1'])); + } + + public function testWi(): void { + $cx = new RuntimeContext(); + $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () { + return 'A'; + })); + $this->assertSame('', Runtime::wi($cx, null, null, null, function () { + return 'A'; + })); + $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) { + return json_encode($i); + })); + $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) { + return "-$i="; + })); + } - public function testWi(): void - { - $cx = new RuntimeContext(); - $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () {return 'A'; })); - $this->assertSame('', Runtime::wi($cx, null, null, null, function () {return 'A'; })); - $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) {return json_encode($i); })); - $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) {return "-$i="; })); + private function createStringable(string $value): \Stringable { + return new class ($value) implements \Stringable { + public function __construct(private string $value) {} + public function __toString(): string { + return $this->value; + } + }; + } } -} From b2e032d61e07008cabfc8ee764fa649e08a06d0d Mon Sep 17 00:00:00 2001 From: Pascal Schneider <77938819+passchn@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:32:34 +0200 Subject: [PATCH 3/7] static + code style --- tests/RuntimeTest.php | 104 +++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index 4f113bf..6184486 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -1,60 +1,60 @@ assertFalse(Runtime::ifvar(null, false)); - $this->assertFalse(Runtime::ifvar(0, false)); - $this->assertTrue(Runtime::ifvar(0, true)); - $this->assertFalse(Runtime::ifvar(false, false)); - $this->assertTrue(Runtime::ifvar(true, false)); - $this->assertTrue(Runtime::ifvar(1, false)); - $this->assertFalse(Runtime::ifvar('', false)); - $this->assertTrue(Runtime::ifvar('0', false)); - $this->assertFalse(Runtime::ifvar([], false)); - $this->assertTrue(Runtime::ifvar([''], false)); - $this->assertTrue(Runtime::ifvar([0], false)); - $this->assertFalse(Runtime::ifvar($this->createStringable(''), false)); - $this->assertTrue(Runtime::ifvar($this->createStringable('0'), false)); - } +class RuntimeTest extends TestCase { + public function testIfVar(): void { + $this->assertFalse(Runtime::ifvar(null, false)); + $this->assertFalse(Runtime::ifvar(0, false)); + $this->assertTrue(Runtime::ifvar(0, true)); + $this->assertFalse(Runtime::ifvar(false, false)); + $this->assertTrue(Runtime::ifvar(true, false)); + $this->assertTrue(Runtime::ifvar(1, false)); + $this->assertFalse(Runtime::ifvar('', false)); + $this->assertTrue(Runtime::ifvar('0', false)); + $this->assertFalse(Runtime::ifvar([], false)); + $this->assertTrue(Runtime::ifvar([''], false)); + $this->assertTrue(Runtime::ifvar([0], false)); + $this->assertFalse(Runtime::ifvar(self::createStringable(''), false)); + $this->assertTrue(Runtime::ifvar(self::createStringable('0'), false)); + } - public function testIsec(): void { - $this->assertTrue(Runtime::isec(null)); - $this->assertFalse(Runtime::isec(0)); - $this->assertTrue(Runtime::isec(false)); - $this->assertFalse(Runtime::isec('false')); - $this->assertTrue(Runtime::isec([])); - $this->assertFalse(Runtime::isec(['1'])); - } + public function testIsec(): void { + $this->assertTrue(Runtime::isec(null)); + $this->assertFalse(Runtime::isec(0)); + $this->assertTrue(Runtime::isec(false)); + $this->assertFalse(Runtime::isec('false')); + $this->assertTrue(Runtime::isec([])); + $this->assertFalse(Runtime::isec(['1'])); + } - public function testWi(): void { - $cx = new RuntimeContext(); - $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () { - return 'A'; - })); - $this->assertSame('', Runtime::wi($cx, null, null, null, function () { - return 'A'; - })); - $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) { - return json_encode($i); - })); - $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) { - return "-$i="; - })); - } + public function testWi(): void { + $cx = new RuntimeContext(); + $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () { + return 'A'; + })); + $this->assertSame('', Runtime::wi($cx, null, null, null, function () { + return 'A'; + })); + $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) { + return json_encode($i); + })); + $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) { + return "-$i="; + })); + } - private function createStringable(string $value): \Stringable { - return new class ($value) implements \Stringable { - public function __construct(private string $value) {} - public function __toString(): string { - return $this->value; - } - }; - } + private static function createStringable(string $value): \Stringable { + return new class ($value) implements \Stringable { + public function __construct(private string $value) {} + public function __toString(): string { + return $this->value; + } + }; } +} From bd91594a87033fc5bdd81a8a628a0bd93804b6fa Mon Sep 17 00:00:00 2001 From: Pascal Schneider <77938819+passchn@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:40:42 +0200 Subject: [PATCH 4/7] revert github codestyle changes --- tests/RuntimeTest.php | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index 6184486..a724217 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -4,11 +4,12 @@ use DevTheorem\Handlebars\Runtime; use DevTheorem\Handlebars\RuntimeContext; -use PhpOffice\PhpSpreadsheet\RichText\Run; use PHPUnit\Framework\TestCase; -class RuntimeTest extends TestCase { - public function testIfVar(): void { +class RuntimeTest extends TestCase +{ + public function testIfVar(): void + { $this->assertFalse(Runtime::ifvar(null, false)); $this->assertFalse(Runtime::ifvar(0, false)); $this->assertTrue(Runtime::ifvar(0, true)); @@ -24,7 +25,8 @@ public function testIfVar(): void { $this->assertTrue(Runtime::ifvar(self::createStringable('0'), false)); } - public function testIsec(): void { + public function testIsec(): void + { $this->assertTrue(Runtime::isec(null)); $this->assertFalse(Runtime::isec(0)); $this->assertTrue(Runtime::isec(false)); @@ -33,23 +35,17 @@ public function testIsec(): void { $this->assertFalse(Runtime::isec(['1'])); } - public function testWi(): void { + public function testWi(): void + { $cx = new RuntimeContext(); - $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () { - return 'A'; - })); - $this->assertSame('', Runtime::wi($cx, null, null, null, function () { - return 'A'; - })); - $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) { - return json_encode($i); - })); - $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) { - return "-$i="; - })); + $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () {return 'A'; })); + $this->assertSame('', Runtime::wi($cx, null, null, null, function () {return 'A'; })); + $this->assertSame('{"a":"b"}', Runtime::wi($cx, ['a' => 'b'], null, ['a' => 'c'], function ($c, $i) {return json_encode($i); })); + $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) {return "-$i="; })); } - private static function createStringable(string $value): \Stringable { + private static function createStringable(string $value): \Stringable + { return new class ($value) implements \Stringable { public function __construct(private string $value) {} public function __toString(): string { From b4212eabf800d64b2291d22e0bc4c8b32bf990fb Mon Sep 17 00:00:00 2001 From: Pascal Schneider <77938819+passchn@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:41:48 +0200 Subject: [PATCH 5/7] fix cs --- tests/RuntimeTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index a724217..d47b8b4 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -6,9 +6,9 @@ use DevTheorem\Handlebars\RuntimeContext; use PHPUnit\Framework\TestCase; -class RuntimeTest extends TestCase +class RuntimeTest extends TestCase { - public function testIfVar(): void + public function testIfVar(): void { $this->assertFalse(Runtime::ifvar(null, false)); $this->assertFalse(Runtime::ifvar(0, false)); @@ -25,7 +25,7 @@ public function testIfVar(): void $this->assertTrue(Runtime::ifvar(self::createStringable('0'), false)); } - public function testIsec(): void + public function testIsec(): void { $this->assertTrue(Runtime::isec(null)); $this->assertFalse(Runtime::isec(0)); @@ -35,7 +35,7 @@ public function testIsec(): void $this->assertFalse(Runtime::isec(['1'])); } - public function testWi(): void + public function testWi(): void { $cx = new RuntimeContext(); $this->assertSame('', Runtime::wi($cx, false, null, new \stdClass(), function () {return 'A'; })); @@ -44,7 +44,7 @@ public function testWi(): void $this->assertSame('-b=', Runtime::wi($cx, 'b', null, ['a' => 'b'], function ($c, $i) {return "-$i="; })); } - private static function createStringable(string $value): \Stringable + private static function createStringable(string $value): \Stringable { return new class ($value) implements \Stringable { public function __construct(private string $value) {} From 992c7302e63221ee0801e9337b3c88996d135e90 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Tue, 14 Oct 2025 09:34:25 -0500 Subject: [PATCH 6/7] Fix CS --- src/Runtime.php | 8 ++++---- tests/RuntimeTest.php | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Runtime.php b/src/Runtime.php index 28a5890..2d22c64 100644 --- a/src/Runtime.php +++ b/src/Runtime.php @@ -44,10 +44,10 @@ public static function lo(array $v): string */ public static function ifvar(mixed $v, bool $zero): bool { - return $v !== null - && $v !== false - && ($zero || ($v !== 0 && $v !== 0.0)) - && $v !== '' + return $v !== null + && $v !== false + && ($zero || ($v !== 0 && $v !== 0.0)) + && $v !== '' && (!$v instanceof \Stringable || (string) $v !== '') && (!is_array($v) || count($v) > 0); } diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index d47b8b4..97ebdc9 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -48,7 +48,9 @@ private static function createStringable(string $value): \Stringable { return new class ($value) implements \Stringable { public function __construct(private string $value) {} - public function __toString(): string { + + public function __toString(): string + { return $this->value; } }; From be9cb025575ed769f9fccb4b80ac71541dc02f54 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Tue, 14 Oct 2025 09:51:12 -0500 Subject: [PATCH 7/7] Simplify ifvar tests --- src/Runtime.php | 2 +- tests/RuntimeTest.php | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Runtime.php b/src/Runtime.php index 2d22c64..736dd71 100644 --- a/src/Runtime.php +++ b/src/Runtime.php @@ -42,7 +42,7 @@ public static function lo(array $v): string * * @return bool Return true when the value is not null nor false. */ - public static function ifvar(mixed $v, bool $zero): bool + public static function ifvar(mixed $v, bool $zero = false): bool { return $v !== null && $v !== false diff --git a/tests/RuntimeTest.php b/tests/RuntimeTest.php index 97ebdc9..c696624 100644 --- a/tests/RuntimeTest.php +++ b/tests/RuntimeTest.php @@ -10,19 +10,19 @@ class RuntimeTest extends TestCase { public function testIfVar(): void { - $this->assertFalse(Runtime::ifvar(null, false)); - $this->assertFalse(Runtime::ifvar(0, false)); + $this->assertFalse(Runtime::ifvar(null)); + $this->assertFalse(Runtime::ifvar(0)); $this->assertTrue(Runtime::ifvar(0, true)); - $this->assertFalse(Runtime::ifvar(false, false)); - $this->assertTrue(Runtime::ifvar(true, false)); - $this->assertTrue(Runtime::ifvar(1, false)); - $this->assertFalse(Runtime::ifvar('', false)); - $this->assertTrue(Runtime::ifvar('0', false)); - $this->assertFalse(Runtime::ifvar([], false)); - $this->assertTrue(Runtime::ifvar([''], false)); - $this->assertTrue(Runtime::ifvar([0], false)); - $this->assertFalse(Runtime::ifvar(self::createStringable(''), false)); - $this->assertTrue(Runtime::ifvar(self::createStringable('0'), false)); + $this->assertFalse(Runtime::ifvar(false)); + $this->assertTrue(Runtime::ifvar(true)); + $this->assertTrue(Runtime::ifvar(1)); + $this->assertFalse(Runtime::ifvar('')); + $this->assertTrue(Runtime::ifvar('0')); + $this->assertFalse(Runtime::ifvar([])); + $this->assertTrue(Runtime::ifvar([''])); + $this->assertTrue(Runtime::ifvar([0])); + $this->assertFalse(Runtime::ifvar(self::createStringable(''))); + $this->assertTrue(Runtime::ifvar(self::createStringable('0'))); } public function testIsec(): void