mirror of
https://github.com/danog/endtoend-test-psl.git
synced 2024-11-26 20:34:59 +01:00
[Str] add grarpheme support
This commit is contained in:
parent
c5256f3006
commit
e1b45c2680
@ -14,7 +14,8 @@
|
||||
"ext-bcmath": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-sodium": "*"
|
||||
"ext-sodium": "*",
|
||||
"ext-intl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.4",
|
||||
|
@ -336,6 +336,20 @@ final class Loader
|
||||
'Psl\Hash\equals',
|
||||
'Psl\Hash\Hmac\hash',
|
||||
'Psl\Hash\Hmac\algorithms',
|
||||
'Psl\Str\Grapheme\contains',
|
||||
'Psl\Str\Grapheme\contains_ci',
|
||||
'Psl\Str\Grapheme\ends_with',
|
||||
'Psl\Str\Grapheme\ends_with_ci',
|
||||
'Psl\Str\Grapheme\length',
|
||||
'Psl\Str\Grapheme\search',
|
||||
'Psl\Str\Grapheme\search_ci',
|
||||
'Psl\Str\Grapheme\search_last',
|
||||
'Psl\Str\Grapheme\search_last_ci',
|
||||
'Psl\Str\Grapheme\slice',
|
||||
'Psl\Str\Grapheme\starts_with',
|
||||
'Psl\Str\Grapheme\starts_with_ci',
|
||||
'Psl\Str\Grapheme\strip_prefix',
|
||||
'Psl\Str\Grapheme\strip_suffix',
|
||||
];
|
||||
|
||||
public const INTERFACES = [
|
||||
|
30
src/Psl/Str/Grapheme/contains.php
Normal file
30
src/Psl/Str/Grapheme/contains.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns whether the 'haystack' string contains the 'needle' string.
|
||||
*
|
||||
* An optional offset determines where in the haystack the search begins. If the
|
||||
* offset is negative, the search will begin that many characters from the end
|
||||
* of the string. If the offset is out-of-bounds, a ViolationException will be
|
||||
* thrown.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If the $offset is out-of-bounds.
|
||||
*/
|
||||
function contains(string $haystack, string $needle, int $offset = 0): bool
|
||||
{
|
||||
if ('' === $needle) {
|
||||
Psl\Internal\validate_offset($offset, length($haystack));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null !== search($haystack, $needle, $offset);
|
||||
}
|
30
src/Psl/Str/Grapheme/contains_ci.php
Normal file
30
src/Psl/Str/Grapheme/contains_ci.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns whether the 'haystack' string contains the 'needle' string.
|
||||
*
|
||||
* An optional offset determines where in the haystack the search begins. If the
|
||||
* offset is negative, the search will begin that many characters from the end
|
||||
* of the string. If the offset is out-of-bounds, a ViolationException will be
|
||||
* thrown.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If the $offset is out-of-bounds.
|
||||
*/
|
||||
function contains_ci(string $haystack, string $needle, int $offset = 0): bool
|
||||
{
|
||||
if ('' === $needle) {
|
||||
Psl\Internal\validate_offset($offset, length($haystack));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null !== search_ci($haystack, $needle, $offset);
|
||||
}
|
36
src/Psl/Str/Grapheme/ends_with.php
Normal file
36
src/Psl/Str/Grapheme/ends_with.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns whether the string ends with the given suffix.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If unable to convert $string to UTF-16,
|
||||
* or split it into graphemes.
|
||||
*/
|
||||
function ends_with(string $string, string $suffix): bool
|
||||
{
|
||||
if ($suffix === $string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$suffix_length = length($suffix);
|
||||
$total_length = length($string);
|
||||
if ($suffix_length > $total_length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
$position = search_last($string, $suffix);
|
||||
if (null === $position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $position + $suffix_length === $total_length;
|
||||
}
|
36
src/Psl/Str/Grapheme/ends_with_ci.php
Normal file
36
src/Psl/Str/Grapheme/ends_with_ci.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns whether the string ends with the given suffix (case-insensitive).
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If unable to convert $string to UTF-16,
|
||||
* or split it into graphemes.
|
||||
*/
|
||||
function ends_with_ci(string $string, string $suffix): bool
|
||||
{
|
||||
if ($suffix === $string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$suffix_length = length($suffix);
|
||||
$total_length = length($string);
|
||||
if ($suffix_length > $total_length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
$position = search_last_ci($string, $suffix);
|
||||
if (null === $position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $position + $suffix_length === $total_length;
|
||||
}
|
27
src/Psl/Str/Grapheme/length.php
Normal file
27
src/Psl/Str/Grapheme/length.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
use function grapheme_strlen;
|
||||
|
||||
/**
|
||||
* Returns the length of the given string in grapheme units
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If unable to convert $string to UTF-16,
|
||||
* or split it into graphemes.
|
||||
*/
|
||||
function length(string $string): int
|
||||
{
|
||||
$length = grapheme_strlen($string);
|
||||
|
||||
Psl\invariant(null !== $length, 'unable to convert $string to UTF-16');
|
||||
Psl\invariant(false !== $length, 'unable to split $string into graphemes');
|
||||
|
||||
return $length;
|
||||
}
|
34
src/Psl/Str/Grapheme/search.php
Normal file
34
src/Psl/Str/Grapheme/search.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
use function grapheme_strpos;
|
||||
|
||||
/**
|
||||
* Returns the first position of the 'needle' string in the 'haystack' string
|
||||
* grapheme units, or null if it isn't found.
|
||||
*
|
||||
* An optional offset determines where in the haystack the search begins. If the
|
||||
* offset is negative, the search will begin that many characters from the end
|
||||
* of the string.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If the $offset is out-of-bounds.
|
||||
*/
|
||||
function search(string $haystack, string $needle, int $offset = 0): ?int
|
||||
{
|
||||
if ('' === $needle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$offset = Psl\Internal\validate_offset($offset, length($haystack));
|
||||
|
||||
return false === ($pos = grapheme_strpos($haystack, $needle, $offset)) ?
|
||||
null :
|
||||
$pos;
|
||||
}
|
34
src/Psl/Str/Grapheme/search_ci.php
Normal file
34
src/Psl/Str/Grapheme/search_ci.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
use function grapheme_stripos;
|
||||
|
||||
/**
|
||||
* Returns the first position of the 'needle' string in the 'haystack' string,
|
||||
* in grapheme units, or null if it isn't found (case-insensitive).
|
||||
*
|
||||
* An optional offset determines where in the haystack the search begins. If the
|
||||
* offset is negative, the search will begin that many characters from the end
|
||||
* of the string.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If $offset is out-of-bounds.
|
||||
*/
|
||||
function search_ci(string $haystack, string $needle, int $offset = 0): ?int
|
||||
{
|
||||
if ('' === $needle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$offset = Psl\Internal\validate_offset($offset, length($haystack));
|
||||
|
||||
return false === ($pos = grapheme_stripos($haystack, $needle, $offset)) ?
|
||||
null :
|
||||
$pos;
|
||||
}
|
35
src/Psl/Str/Grapheme/search_last.php
Normal file
35
src/Psl/Str/Grapheme/search_last.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
use function grapheme_strrpos;
|
||||
|
||||
/**
|
||||
* Returns the last position of the 'needle' string in the 'haystack' string,
|
||||
* or null if it isn't found.
|
||||
*
|
||||
* An optional offset determines where in the haystack (from the beginning) the
|
||||
* search begins. If the offset is negative, the search will begin that many
|
||||
* characters from the end of the string and go backwards.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If the $offset is out-of-bounds.
|
||||
*/
|
||||
function search_last(string $haystack, string $needle, int $offset = 0): ?int
|
||||
{
|
||||
if ('' === $needle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$haystack_length = length($haystack);
|
||||
Psl\invariant($offset >= -$haystack_length && $offset <= $haystack_length, 'Offset is out-of-bounds.');
|
||||
|
||||
return false === ($pos = grapheme_strrpos($haystack, $needle, $offset)) ?
|
||||
null :
|
||||
$pos;
|
||||
}
|
35
src/Psl/Str/Grapheme/search_last_ci.php
Normal file
35
src/Psl/Str/Grapheme/search_last_ci.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
use function grapheme_strripos;
|
||||
|
||||
/**
|
||||
* Returns the last position of the 'needle' string in the 'haystack' string,
|
||||
* or null if it isn't found (case-insensitive).
|
||||
*
|
||||
* An optional offset determines where in the haystack (from the beginning) the
|
||||
* search begins. If the offset is negative, the search will begin that many
|
||||
* characters from the end of the string and go backwards.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If the offset is out-of-bounds.
|
||||
*/
|
||||
function search_last_ci(string $haystack, string $needle, int $offset = 0): ?int
|
||||
{
|
||||
if ('' === $needle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$haystack_length = length($haystack);
|
||||
Psl\invariant($offset >= -$haystack_length && $offset <= $haystack_length, 'Offset is out-of-bounds.');
|
||||
|
||||
return false === ($pos = grapheme_strripos($haystack, $needle, $offset)) ?
|
||||
null :
|
||||
$pos;
|
||||
}
|
36
src/Psl/Str/Grapheme/slice.php
Normal file
36
src/Psl/Str/Grapheme/slice.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
use Psl;
|
||||
|
||||
/**
|
||||
* Returns a substring of length `$length` of the given string starting at the
|
||||
* `$offset`.
|
||||
*
|
||||
* If no length is given, the slice will contain the rest of the
|
||||
* string. If the length is zero, the empty string will be returned. If the
|
||||
* offset is out-of-bounds, an InvariantViolationException will be thrown.
|
||||
*
|
||||
* @psalm-pure
|
||||
*
|
||||
* @throws Psl\Exception\InvariantViolationException If a negative $length is given, or $offset is out-of-bounds.
|
||||
*/
|
||||
function slice(string $string, int $offset, ?int $length = null): string
|
||||
{
|
||||
Psl\invariant(null === $length || $length >= 0, 'Expected a non-negative length.');
|
||||
$string_length = length($string);
|
||||
$offset = Psl\Internal\validate_offset($offset, $string_length);
|
||||
|
||||
if (0 === $offset && (null === $length || $string_length <= $length)) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
if (null === $length) {
|
||||
return (string) grapheme_substr($string, $offset);
|
||||
}
|
||||
|
||||
return (string) grapheme_substr($string, $offset, $length);
|
||||
}
|
16
src/Psl/Str/Grapheme/starts_with.php
Normal file
16
src/Psl/Str/Grapheme/starts_with.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
/**
|
||||
* Returns whether the string starts with the given prefix.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function starts_with(string $string, string $prefix): bool
|
||||
{
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
return 0 === search($string, $prefix);
|
||||
}
|
16
src/Psl/Str/Grapheme/starts_with_ci.php
Normal file
16
src/Psl/Str/Grapheme/starts_with_ci.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
/**
|
||||
* Returns whether the string starts with the given prefix (case-insensitive).
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function starts_with_ci(string $string, string $prefix): bool
|
||||
{
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
return 0 === search_ci($string, $prefix);
|
||||
}
|
21
src/Psl/Str/Grapheme/strip_prefix.php
Normal file
21
src/Psl/Str/Grapheme/strip_prefix.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
/**
|
||||
* Returns the string with the given prefix removed, or the string itself if
|
||||
* it doesn't start with the prefix.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function strip_prefix(string $string, string $prefix): string
|
||||
{
|
||||
if ('' === $prefix || !starts_with($string, $prefix)) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
return slice($string, length($prefix));
|
||||
}
|
21
src/Psl/Str/Grapheme/strip_suffix.php
Normal file
21
src/Psl/Str/Grapheme/strip_suffix.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Str\Grapheme;
|
||||
|
||||
/**
|
||||
* Returns the string with the given suffix removed, or the string itself if
|
||||
* it doesn't end with the suffix.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
function strip_suffix(string $string, string $suffix): string
|
||||
{
|
||||
if ('' === $suffix || !ends_with($string, $suffix)) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
/** @psalm-suppress MissingThrowsDocblock */
|
||||
return slice($string, 0, length($string) - length($suffix));
|
||||
}
|
32
tests/Psl/Str/Grapheme/ContainsCiTest.php
Normal file
32
tests/Psl/Str/Grapheme/ContainsCiTest.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class ContainsCiTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testContainsCi(bool $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\contains_ci($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[true, 'Hello, World', 'Hello', 0],
|
||||
[true, 'Hello, World', 'world', 0],
|
||||
[true, 'Hello, World', '', 8],
|
||||
[false, 'hello, world', 'hey', 5],
|
||||
[true, 'Azjezz', 'az', 0],
|
||||
[false, 'azjezz', 'Az', 2],
|
||||
[true, 'مرحبا بكم', 'بكم', 5],
|
||||
];
|
||||
}
|
||||
}
|
72
tests/Psl/Str/Grapheme/ContainsTest.php
Normal file
72
tests/Psl/Str/Grapheme/ContainsTest.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class ContainsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testContains(bool $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\contains($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
true,
|
||||
'Hello, World',
|
||||
'Hello',
|
||||
0
|
||||
],
|
||||
|
||||
[
|
||||
false,
|
||||
'Hello, World',
|
||||
'world',
|
||||
0
|
||||
],
|
||||
|
||||
[
|
||||
true,
|
||||
'Hello, World',
|
||||
'',
|
||||
8
|
||||
],
|
||||
|
||||
[
|
||||
false,
|
||||
'hello, world',
|
||||
'hey',
|
||||
5
|
||||
],
|
||||
|
||||
[
|
||||
true,
|
||||
'azjezz',
|
||||
'az',
|
||||
0
|
||||
],
|
||||
[
|
||||
false,
|
||||
'azjezz',
|
||||
'Az',
|
||||
2
|
||||
],
|
||||
|
||||
[
|
||||
true,
|
||||
'مرحبا بكم',
|
||||
'بكم',
|
||||
5
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
35
tests/Psl/Str/Grapheme/EndsWithCiTest.php
Normal file
35
tests/Psl/Str/Grapheme/EndsWithCiTest.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class EndsWithCiTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testEndsWithCi(bool $expected, string $haystack, string $suffix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\ends_with_ci($haystack, $suffix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[true, 'Hello', 'Hello'],
|
||||
[true, 'Hello, World', 'world', ],
|
||||
[true, 'Hello, WorlḐ', 'worlḑ', ],
|
||||
[false, 'T U N I S I A', 'e', ],
|
||||
[true, 'تونس', 'س'],
|
||||
[false, 'Hello, World', '', ],
|
||||
[false, 'hello, world', 'hey', ],
|
||||
[false, 'hello, world', 'hello cruel world'],
|
||||
[true, 'azjezz', 'z', ],
|
||||
[true, 'مرحبا بكم', 'بكم', ],
|
||||
];
|
||||
}
|
||||
}
|
34
tests/Psl/Str/Grapheme/EndsWithTest.php
Normal file
34
tests/Psl/Str/Grapheme/EndsWithTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class EndsWithTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testEndsWith(bool $expected, string $haystack, string $suffix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\ends_with($haystack, $suffix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[true, 'Hello', 'Hello'],
|
||||
[false, 'Hello, World', 'world', ],
|
||||
[false, 'T U N I S I A', 'e', ],
|
||||
[true, 'تونس', 'س'],
|
||||
[false, 'Hello, World', '', ],
|
||||
[false, 'Hello, World', 'Hello, cruel world!', ],
|
||||
[false, 'hello, world', 'hey', ],
|
||||
[true, 'azjezz', 'z', ],
|
||||
[true, 'مرحبا بكم', 'بكم', ],
|
||||
];
|
||||
}
|
||||
}
|
33
tests/Psl/Str/Grapheme/LengthTest.php
Normal file
33
tests/Psl/Str/Grapheme/LengthTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class LengthTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testLength(int $expected, string $str): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\length($str));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[6, 'azjezz'],
|
||||
[4, 'تونس'],
|
||||
[3, 'سيف'],
|
||||
[7, 'こんにちは世界'],
|
||||
[3, '🥇🥈🥉'],
|
||||
[2, '你好'],
|
||||
[4, 'สวัสดี'],
|
||||
[3, 'ؤخى']
|
||||
];
|
||||
}
|
||||
}
|
33
tests/Psl/Str/Grapheme/SearchCiTest.php
Normal file
33
tests/Psl/Str/Grapheme/SearchCiTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class SearchCiTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSearchCi(?int $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\search_ci($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[7, 'Hello, you!', 'You', ],
|
||||
[7, 'Hello, You!', 'You', ],
|
||||
[0, 'Ho! Ho! Ho!', 'ho', ],
|
||||
[0, 'Ho! Ho! Ho!', 'Ho', ],
|
||||
[7, 'Hello, You!', 'You', 5],
|
||||
[null, 'Hello, World!', 'You', 5],
|
||||
[6, 'مرحبا سيف', 'سيف', 4],
|
||||
[null, 'foo', 'bar', 2],
|
||||
];
|
||||
}
|
||||
}
|
33
tests/Psl/Str/Grapheme/SearchLastCiTest.php
Normal file
33
tests/Psl/Str/Grapheme/SearchLastCiTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class SearchLastCiTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSearchLastCi(?int $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\search_last_ci($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[7, 'Hello, you!', 'You', ],
|
||||
[7, 'Hello, You!', 'You', ],
|
||||
[8, 'Ho! Ho! Ho!', 'ho', ],
|
||||
[8, 'Ho! Ho! Ho!', 'Ho', ],
|
||||
[7, 'Hello, You!', 'You', 5],
|
||||
[null, 'Hello, World!', 'You', 5],
|
||||
[6, 'مرحبا سيف', 'سيف', 4],
|
||||
[null, 'foo', 'bar', 2],
|
||||
];
|
||||
}
|
||||
}
|
33
tests/Psl/Str/Grapheme/SearchLastTest.php
Normal file
33
tests/Psl/Str/Grapheme/SearchLastTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class SearchLastTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSearchLast(?int $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\search_last($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[null, 'Hello, you!', 'You', ],
|
||||
[7, 'Hello, You!', 'You', ],
|
||||
[null, 'Ho! Ho! Ho!', 'ho', ],
|
||||
[8, 'Ho! Ho! Ho!', 'Ho', ],
|
||||
[7, 'Hello, You!', 'You', 5],
|
||||
[null, 'Hello, World!', 'You', 5],
|
||||
[6, 'مرحبا سيف', 'سيف', 4],
|
||||
[null, 'foo', 'bar', 2],
|
||||
];
|
||||
}
|
||||
}
|
33
tests/Psl/Str/Grapheme/SearchTest.php
Normal file
33
tests/Psl/Str/Grapheme/SearchTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class SearchTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSearch(?int $expected, string $haystack, string $needle, int $offset = 0): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\search($haystack, $needle, $offset));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[null, 'Hello, you!', 'You', ],
|
||||
[7, 'Hello, You!', 'You', ],
|
||||
[null, 'Ho! Ho! Ho!', 'ho', ],
|
||||
[0, 'Ho! Ho! Ho!', 'Ho', ],
|
||||
[7, 'Hello, You!', 'You', 5],
|
||||
[null, 'Hello, World!', 'You', 5],
|
||||
[6, 'مرحبا سيف', 'سيف', 4],
|
||||
[null, 'foo', 'bar', 2],
|
||||
];
|
||||
}
|
||||
}
|
62
tests/Psl/Str/Grapheme/SliceTest.php
Normal file
62
tests/Psl/Str/Grapheme/SliceTest.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Exception;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class SliceTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSlice(string $expected, string $string, int $offset, ?int $length = null): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\slice($string, $offset, $length));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
['', '', 0, 0, ],
|
||||
['Hello', 'Hello, World!', 0, 5],
|
||||
['Hello, World!', 'Hello, World!', 0],
|
||||
['World', 'Hello, World!', 7, 5],
|
||||
['سيف', 'مرحبا سيف', 6, 3],
|
||||
['اهلا', 'اهلا بكم', 0, 4],
|
||||
['destiny', 'People linked by destiny will always find each other.', 17, 7],
|
||||
['lö ', 'héllö wôrld', 3, 3, ],
|
||||
['lö wôrld', 'héllö wôrld', 3, null, ],
|
||||
['', 'héllö wôrld', 3, 0],
|
||||
['', 'fôo', 3, null, ],
|
||||
['', 'fôo', 3, 12, ],
|
||||
['wôrld', 'héllö wôrld', -5, null, ],
|
||||
['wôrld', 'héllö wôrld', -5, 100, ],
|
||||
['wôr', 'héllö wôrld', -5, 3, ],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSliceThrowsForNegativeLength(): void
|
||||
{
|
||||
$this->expectException(Exception\InvariantViolationException::class);
|
||||
|
||||
Grapheme\slice('Hello', 0, -1);
|
||||
}
|
||||
|
||||
public function testSliceThrowsForOutOfBoundOffset(): void
|
||||
{
|
||||
$this->expectException(Exception\InvariantViolationException::class);
|
||||
|
||||
Grapheme\slice('Hello', 10);
|
||||
}
|
||||
|
||||
public function testSliceThrowsForNegativeOutOfBoundOffset(): void
|
||||
{
|
||||
$this->expectException(Exception\InvariantViolationException::class);
|
||||
|
||||
Grapheme\slice('hello', -6);
|
||||
}
|
||||
}
|
41
tests/Psl/Str/Grapheme/StartsWithCiTest.php
Normal file
41
tests/Psl/Str/Grapheme/StartsWithCiTest.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class StartsWithCiTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testStartsWithCi(bool $expected, string $haystack, string $prefix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\starts_with_ci($haystack, $prefix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[true, 'Hello, World', 'Hello', ],
|
||||
[false, 'Hello, World', 'world', ],
|
||||
[false, 'Hello, World', '', ],
|
||||
[false, 'hello, world', 'hey', ],
|
||||
[true, 'azjezz', 'az', ],
|
||||
[true, 'azjezz', 'Az', ],
|
||||
[false, 'مرحبا بكم', 'بكم', ],
|
||||
[true, 'مرحبا بكم', 'مرحبا', ],
|
||||
[true, 'مرحبا سيف', 'مرحبا', 3],
|
||||
[false, 'مرحبا سيف', 'سيف', 3],
|
||||
[true, 'اهلا بكم', 'اهلا', 2],
|
||||
[true, 'héllö wôrld', 'héllö', ],
|
||||
[false, 'héllö wôrld', 'hello', ],
|
||||
[true, 'fôo', 'fôo', ],
|
||||
[true, 'fôo', 'f', ],
|
||||
[true, 'fôo', 'fô', ],
|
||||
];
|
||||
}
|
||||
}
|
41
tests/Psl/Str/Grapheme/StartsWithTest.php
Normal file
41
tests/Psl/Str/Grapheme/StartsWithTest.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class StartsWithTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testStartsWith(bool $expected, string $haystack, string $prefix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\starts_with($haystack, $prefix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
[true, 'Hello, World', 'Hello', ],
|
||||
[false, 'Hello, World', 'world', ],
|
||||
[false, 'Hello, World', '', ],
|
||||
[false, 'hello, world', 'hey', ],
|
||||
[true, 'azjezz', 'az', ],
|
||||
[false, 'azjezz', 'Az', ],
|
||||
[false, 'مرحبا بكم', 'بكم', ],
|
||||
[true, 'مرحبا بكم', 'مرحبا', ],
|
||||
[true, 'مرحبا سيف', 'مرحبا', 3],
|
||||
[false, 'مرحبا سيف', 'سيف', 3],
|
||||
[true, 'اهلا بكم', 'اهلا', 2],
|
||||
[true, 'héllö wôrld', 'héllö', ],
|
||||
[false, 'héllö wôrld', 'hello', ],
|
||||
[true, 'fôo', 'fôo', ],
|
||||
[true, 'fôo', 'f', ],
|
||||
[true, 'fôo', 'fô', ],
|
||||
];
|
||||
}
|
||||
}
|
41
tests/Psl/Str/Grapheme/StripPrefixTest.php
Normal file
41
tests/Psl/Str/Grapheme/StripPrefixTest.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
class StripPrefixTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testStripPrefix(string $expected, string $haystack, string $prefix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\strip_prefix($haystack, $prefix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
['World', 'Hello, World', 'Hello, '],
|
||||
['Hello, World', 'Hello, World', 'world'],
|
||||
['Hello, World', 'Hello, World', ''],
|
||||
['hello, world', 'hello, world', 'hey'],
|
||||
['jezz', 'azjezz', 'az'],
|
||||
['azjezz', 'azjezz', 'Az'],
|
||||
['مرحبا بكم', 'مرحبا بكم', 'بكم'],
|
||||
['بكم', 'مرحبا بكم', 'مرحبا '],
|
||||
['سيف', 'مرحبا سيف', 'مرحبا ', 3],
|
||||
['مرحبا سيف', 'مرحبا سيف', 'سيف', 3],
|
||||
[' بكم', 'اهلا بكم', 'اهلا', 2],
|
||||
['wôrld', 'héllö wôrld', 'héllö '],
|
||||
['héllö wôrld', 'héllö wôrld', 'hello'],
|
||||
['', 'fôo', 'fôo'],
|
||||
['ôo', 'fôo', 'f'],
|
||||
['o', 'fôo', 'fô'],
|
||||
];
|
||||
}
|
||||
}
|
48
tests/Psl/Str/Grapheme/StripSuffixTest.php
Normal file
48
tests/Psl/Str/Grapheme/StripSuffixTest.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Tests\Str\Grapheme;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Str\Grapheme;
|
||||
|
||||
final class StripSuffixTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testStripSuffix(string $expected, string $haystack, string $suffix): void
|
||||
{
|
||||
static::assertSame($expected, Grapheme\strip_suffix($haystack, $suffix));
|
||||
}
|
||||
|
||||
public function provideData(): array
|
||||
{
|
||||
return [
|
||||
['', 'Hello', 'Hello'],
|
||||
['Hello, World', 'Hello, World', 'world', ],
|
||||
['T U N I S I A', 'T U N I S I A', 'e', ],
|
||||
['تون', 'تونس', 'س'],
|
||||
['Hello, World', 'Hello, World', '', ],
|
||||
['Hello, World', 'Hello, World', 'Hello, cruel world!', ],
|
||||
['hello, world', 'hello, world', 'hey', ],
|
||||
['azjez', 'azjezz', 'z', ],
|
||||
['مرحبا ', 'مرحبا بكم', 'بكم', ],
|
||||
['Hello', 'Hello, World', ', World', ],
|
||||
['Hello, World', 'Hello, World', 'world', ],
|
||||
['Hello, World', 'Hello, World', '', ],
|
||||
['hello, world', 'hello, world', 'universe', ],
|
||||
['azje', 'azjezz', 'zz', ],
|
||||
['azjezz', 'azjezz', 'ZZ', ],
|
||||
['مرحبا', 'مرحبا سيف', ' سيف', 3],
|
||||
['اهلا', 'اهلا بكم', ' بكم', 3],
|
||||
['héllö', 'héllö wôrld', ' wôrld', ],
|
||||
['héllö wôrld', 'héllö wôrld', ' world', ],
|
||||
['fô', 'fôo', 'o', ],
|
||||
['fôo', 'fôo', 'ô', ],
|
||||
['f', 'fôo', 'ôo', ],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user