Skip to content

Commit

Permalink
Add str_increment and str_decrement functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Fan2Shrek committed Oct 13, 2023
1 parent 4051889 commit c4a185a
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 3 deletions.
40 changes: 39 additions & 1 deletion src/Php83/Php83.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Polyfill\Php83;

/**
* @author Ion Bazan <[email protected]>
* @author Ion Bazan <[email protected]>, Pierre Ambroise <[email protected]>
*
* @internal
*/
Expand Down Expand Up @@ -82,4 +82,42 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin
return mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
}
}

public static function str_increment(string $string): string
{
if ('' === $string) {
throw new \ValueError('str_increment(): Argument #1 ($string) cannot be empty');
}

if (1 === preg_match('/[^\x00-\x7F]/', $string)) {
throw new \ValueError('str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters');
}

return ++$string;
}

public static function str_decrement(string $string): string
{
if ('' === $string) {
throw new \ValueError('str_decrement(): Argument #1 ($string) cannot be empty');
}

if (1 === preg_match('/[^\x00-\x7F]/', $string)) {
throw new \ValueError('str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters');
}

if (1 === preg_match('/^A|0+$/', $string)) {
throw new \ValueError('str_decrement(): Argument #1 ($string) "A" is out of decrement range');
}

if (!in_array(substr($string, -1), ['A', '0'])){
return join('', array_slice(str_split($string), 0, -1)) . chr(ord(substr($string, -1)) - 1);
}

if (strlen($string) === 1) {
return '';
}

return self::str_decrement(substr($string, 0, -1)) . 'Z';
}
}
8 changes: 8 additions & 0 deletions src/Php83/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $
function stream_context_set_options($context, array $options): bool { return stream_context_set_option($context, $options); }
}

if (!function_exists('str_increment')) {
function str_increment(string $string): string { return p\Php83::str_increment($string); }
}

if (!function_exists('str_decrement')) {
function str_decrement(string $string): string { return p\Php83::str_decrement($string); }
}

if (\PHP_VERSION_ID >= 80100) {
return require __DIR__.'/bootstrap81.php';
}
Expand Down
66 changes: 64 additions & 2 deletions tests/Php83/Php83Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function testMbStrPad(string $expectedResult, string $string, int $length
public function testMbStrPadInvalidArguments(string $expectedError, string $string, int $length, string $padString, int $padType, string $encoding = null): void
{
$this->expectException(\ValueError::class);
$this->expectErrorMessage($expectedError);
$this->expectExceptionMessage($expectedError);

mb_str_pad($string, $length, $padString, $padType, $encoding);
}
Expand Down Expand Up @@ -161,7 +161,7 @@ public static function jsonDataProvider(): iterable
public function testJsonValidateInvalidOptionsProvided(int $depth, int $flags, string $expectedError)
{
$this->expectException(\ValueError::class);
$this->expectErrorMessage($expectedError);
$this->expectExceptionMessage($expectedError);
json_validate('{}', $depth, $flags);
}

Expand Down Expand Up @@ -202,4 +202,66 @@ public function testDateTimeExceptionClassesExist()
$this->assertTrue(class_exists(\DateMalformedIntervalStringException::class));
$this->assertTrue(class_exists(\DateMalformedPeriodStringException::class));
}

/**
* @dataProvider strIncrementProvider
*/
public function testStrIncrement(string $result, string $string)
{
$this->assertSame($result, str_increment($string));
}

/**
* @dataProvider strIncrementProvider
*/
public function testStrDecrements(string $string, string $result)
{
$this->assertSame($result, str_decrement($string));
}

public static function strIncrementProvider(): iterable
{
yield ['ABD', 'ABC'];
yield ['EB', 'EA'];
yield ['AAA', 'ZZ'];
yield ['AAA2', 'AAA1'];
}

/**
* @dataProvider strInvalidIncrementProvider
*/
public function testInvalidStrIncrements(string $errorMessage, string $string)
{
$this->expectException(\ValueError::class);
$this->expectExceptionMessage($errorMessage);

str_increment($string);
}


public static function strInvalidIncrementProvider(): iterable
{
yield ['str_increment(): Argument #1 ($string) cannot be empty', ""];
yield ['str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters', '我喜歡雞肉'];
yield ['str_increment(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters', '書左'];
}


/**
* @dataProvider strInvalidDecrementProvider
*/
public function testInvalidStrDecrements(string $errorMessage, string $string)
{
$this->expectException(\ValueError::class);
$this->expectExceptionMessage($errorMessage);

str_decrement($string);
}

public static function strInvalidDecrementProvider(): iterable
{
yield ['str_decrement(): Argument #1 ($string) cannot be empty', ''];
yield ['str_decrement(): Argument #1 ($string) must be composed only of alphanumeric ASCII characters', '我喜歡雞肉'];
yield ['str_decrement(): Argument #1 ($string) "A" is out of decrement range', 'A'];
}
}

0 comments on commit c4a185a

Please sign in to comment.