Skip to content
Snippets Groups Projects
Commit 72b9b496 authored by Georg Ringer's avatar Georg Ringer Committed by Oliver Hader
Browse files

[TASK] Add StringUtility::cast and ::filter

Resolves: #100824
Relates: #100739
Releases: main, 12.4, 11.5
Change-Id: I91bf93adbf390e84beda871c399f4785a83d8571
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78993


Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: default avatarOliver Hader <oliver.hader@typo3.org>
parent e939b071
Branches
Tags
No related merge requests found
...@@ -20,6 +20,38 @@ namespace TYPO3\CMS\Core\Utility; ...@@ -20,6 +20,38 @@ namespace TYPO3\CMS\Core\Utility;
*/ */
class StringUtility class StringUtility
{ {
/**
* Casts applicable types (string, bool, finite numeric) to string.
*
* Any other type will be replaced by the `$default` value.
*
* @param mixed $value
*/
public static function cast($value, ?string $default = null): ?string
{
if (is_string($value)) {
return $value;
}
if (is_bool($value) || (is_numeric($value) && is_finite($value))) {
return (string)$value;
}
return $default;
}
/**
* Keeps only string types (filters out non-strings).
*
* Any other non-string type will be replaced by the `$default` value.
*
* @param mixed $value
*/
public static function filter($value, ?string $default = null): ?string
{
return is_string($value) ? $value : $default;
}
/** /**
* Returns TRUE if $haystack begins with $needle. * Returns TRUE if $haystack begins with $needle.
* The input string is not trimmed before and search is done case sensitive. * The input string is not trimmed before and search is done case sensitive.
......
...@@ -25,6 +25,129 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase; ...@@ -25,6 +25,129 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
*/ */
class StringUtilityTest extends UnitTestCase class StringUtilityTest extends UnitTestCase
{ {
/**
* @return \Generator<string, array{0: mixed}>
*/
public static function stringCastableValuesDataProvider(): \Generator
{
yield 'empty string' => [''];
yield 'string' => ['value'];
yield 'int' => [1];
yield 'float' => [1.2345];
yield 'bool' => [true];
}
/**
* @param mixed $value
*
* @test
* @dataProvider stringCastableValuesDataProvider
*/
public function castWithStringCastableReturnsValueCastToString($value): void
{
$expected = (string)$value;
self::assertSame($expected, StringUtility::cast($value, 'default'));
}
/**
* @return \Generator<string, array{0: mixed}>
*/
public static function nonStringCastableValuesDataProvider(): \Generator
{
yield 'array' => [['1']];
yield 'null' => [null];
yield 'object' => [new \stdClass()];
yield 'closure' => [static fn (): string => 'fn'];
// PHP interprets it as `lim(x→0) log(x) = -∞`
yield 'infinite' => [log(0)];
// acos only supports values in range [-1; +1]
yield 'NaN' => [acos(2)];
}
/**
* @param mixed $value
*
* @test
* @dataProvider nonStringCastableValuesDataProvider
*/
public function castWithWithNonStringCastableReturnsDefault($value): void
{
$default = 'default';
self::assertSame($default, StringUtility::cast($value, $default));
}
/**
* @param mixed $value
*
* @test
* @dataProvider nonStringCastableValuesDataProvider
*/
public function castWithWithNonStringCastableAndNoDefaultProvidedReturnsNull($value): void
{
self::assertNull(StringUtility::cast($value));
}
/**
* @return \Generator<string, array{0: mixed}>
*/
public static function nonStringValueToFilterDataProvider(): \Generator
{
yield 'int' => [1];
yield 'float' => [1.2345];
yield 'bool' => [true];
yield 'array' => [['1']];
yield 'null' => [null];
yield 'object' => [new \stdClass()];
yield 'closure' => [static fn (): string => 'fn'];
// PHP interprets it as `lim(x→0) log(x) = -∞`
yield 'infinite' => [log(0)];
// acos only supports values in range [-1; +1]
yield 'NaN' => [acos(2)];
}
/**
* @param mixed $value
*
* @test
* @dataProvider nonStringValueToFilterDataProvider
*/
public function filterForNonStringValueAndDefaultProvidedReturnsDefault($value): void
{
$default = 'default';
self::assertSame($default, StringUtility::filter($value, $default));
}
/**
* @param mixed $value
*
* @test
* @dataProvider nonStringValueToFilterDataProvider
*/
public function filterForNonStringValueAndNoDefaultProvidedReturnsNull($value): void
{
self::assertNull(StringUtility::filter($value));
}
/**
* @return \Generator<string, array{0: string}>
*/
public static function stringValueToFilterDataProvider(): \Generator
{
yield 'empty string' => [''];
yield 'non-empty string' => ['value'];
}
/**
* @test
* @dataProvider stringValueToFilterDataProvider
*/
public function filterForStringValuesReturnsProvidedValue(string $value): void
{
self::assertSame($value, StringUtility::filter($value, 'some default'));
}
/** /**
* @test * @test
*/ */
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment