From d52a020e8c5673a6a54499a0f40c6190f6fa5f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Rie=C3=9F?= Date: Wed, 27 May 2026 11:42:02 +0200 Subject: [PATCH] Add isEmpty method --- src/Str.php | 17 +++++++++++ tests/StrTest.php | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/src/Str.php b/src/Str.php index 0dac0bb..c7ab22b 100644 --- a/src/Str.php +++ b/src/Str.php @@ -2,6 +2,8 @@ namespace ipl\Stdlib; +use Stringable; + /** * Collection of string manipulation functions */ @@ -90,4 +92,19 @@ public static function trimSplit(?string $subject, string $delimiter = ',', ?int return array_map('trim', $exploded); } + + /** + * Check if the given string is empty + * + * Null is considered empty, and strings consisting only of whitespace or visually + * empty characters are considered empty. + * + * @param string|Stringable|null $subject + * + * @return bool + */ + public static function isEmpty(string|Stringable|null $subject): bool + { + return $subject === null || preg_match('/^[\s\x{3164}\x{1160}]*$/u', $subject) === 1; + } } diff --git a/tests/StrTest.php b/tests/StrTest.php index d4c7075..bcff7db 100644 --- a/tests/StrTest.php +++ b/tests/StrTest.php @@ -47,6 +47,80 @@ public function testStartsWithReturnsFalseIfStringDoesNotStartWithTheSpecifiedSu $this->assertFalse(Str::startsWith('FOOBAR', 'foo', true)); } + public function testIsEmptyReturnsTrueForNull() + { + $this->assertTrue(Str::isEmpty(null)); + } + + public function testIsEmptyReturnsTrueForEmptyString() + { + $this->assertTrue(Str::isEmpty('')); + } + + public function testIsEmptyReturnsTrueForStringWithLeadingAndTrailingWhitespace() + { + $this->assertTrue(Str::isEmpty(' ')); + } + + public function testIsEmptyReturnsTrueForStringWithOnlyWhitespace() + { + $this->assertTrue(Str::isEmpty("\t\n")); + } + + public function testIsEmptyReturnsFalseForZero() + { + $this->assertFalse(Str::isEmpty('0')); + } + + public function testIsEmptyReturnsFalseForNonEmptyString() + { + $this->assertFalse(Str::isEmpty('Warning')); + } + + public function testIsEmptyReturnsFalseForStringWithContentAndSurroundingWhitespace() + { + $this->assertFalse(Str::isEmpty(' Warning ')); + } + + public function testIsEmptyReturnsFalseForUtf8String() + { + $this->assertFalse(Str::isEmpty('接続エラー')); + } + + public function testIsEmptyReturnsFalseForUtf8StringWithSurroundingWhitespace() + { + $this->assertFalse(Str::isEmpty(' 接続エラー ')); + } + + public function testIsEmptyReturnsTrueForVisuallyEmptyUtf8String() + { + $this->assertTrue(Str::isEmpty("\u{3164}\u{1160}")); + } + + public function testIsEmptyReturnsFalseForStringable() + { + $subject = new class { + public function __toString(): string + { + return 'Warning'; + } + }; + + $this->assertFalse(Str::isEmpty($subject)); + } + + public function testIsEmptyReturnsTrueForStringableWithWhitespaceOnly() + { + $subject = new class { + public function __toString(): string + { + return ' '; + } + }; + + $this->assertTrue(Str::isEmpty($subject)); + } + public function testSymmetricSplitReturnsArrayPaddedToTheSizeSpecifiedByLimitUsingNullAsValueByDefault() { $this->assertSame(['foo', 'bar', null, null], Str::symmetricSplit('foo,bar', ',', 4));