diff --git a/.drone.jsonnet b/.drone.jsonnet deleted file mode 100644 index d9a7bbdf..00000000 --- a/.drone.jsonnet +++ /dev/null @@ -1,108 +0,0 @@ -local volumes = [ - { - name: "composer-cache", - path: "/tmp/composer-cache", - }, -]; - -local hostvolumes = [ - { - name: "composer-cache", - host: {path: "/tmp/composer-cache"} - }, -]; - -local composer(phpversion, params) = { - name: "composer", - image: "joomlaprojects/docker-images:php" + phpversion, - volumes: volumes, - commands: [ - "php -v", - "composer update " + params, - ] -}; - -local phpunit(phpversion) = { - name: "PHPUnit", - image: "joomlaprojects/docker-images:php" + phpversion, - [if phpversion == "8.3" then "failure"]: "ignore", - commands: ["vendor/bin/phpunit"] -}; - -local pipeline(name, phpversion, params) = { - kind: "pipeline", - name: "PHP " + name, - volumes: hostvolumes, - steps: [ - composer(phpversion, params), - phpunit(phpversion) - ], -}; - -[ - { - kind: "pipeline", - name: "Codequality", - volumes: hostvolumes, - steps: [ - { - name: "composer", - image: "joomlaprojects/docker-images:php8.1", - volumes: volumes, - commands: [ - "php -v", - "composer update" - ] - }, - { - name: "phpcs", - image: "joomlaprojects/docker-images:php8.1", - depends: [ "composer" ], - commands: [ - "vendor/bin/phpcs --standard=ruleset.xml src/" - ] - }, - { - name: "phan", - image: "joomlaprojects/docker-images:php8.1-ast", - depends: [ "composer" ], - failure: "ignore", - commands: [ - "vendor/bin/phan" - ] - }, - { - name: "phpstan", - image: "joomlaprojects/docker-images:php8.1", - depends: [ "composer" ], - failure: "ignore", - commands: [ - "./vendor/bin/phpstan", - ] - }, - { - name: "phploc", - image: "joomlaprojects/docker-images:php8.1", - depends: [ "composer" ], - failure: "ignore", - commands: [ - "phploc src", - ] - }, - { - name: "phpcpd", - image: "joomlaprojects/docker-images:php8.1", - depends: [ "composer" ], - failure: "ignore", - commands: [ - "phpcpd src", - ] - } - ] - }, - pipeline("8.1 lowest", "8.1", "--prefer-stable --prefer-lowest"), - pipeline("8.1", "8.1", "--prefer-stable"), - pipeline("8.2", "8.2", "--prefer-stable"), - pipeline("8.3", "8.3", "--prefer-stable"), - pipeline("8.4", "8.4", "--prefer-stable"), -] diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index cd46e5e1..00000000 --- a/.drone.yml +++ /dev/null @@ -1,156 +0,0 @@ ---- -kind: pipeline -name: Codequality -steps: -- commands: - - php -v - - composer update - image: joomlaprojects/docker-images:php8.1 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpcs --standard=ruleset.xml src/ - depends: - - composer - image: joomlaprojects/docker-images:php8.1 - name: phpcs -- commands: - - vendor/bin/phan - depends: - - composer - failure: ignore - image: joomlaprojects/docker-images:php8.1-ast - name: phan -- commands: - - ./vendor/bin/phpstan - depends: - - composer - failure: ignore - image: joomlaprojects/docker-images:php8.1 - name: phpstan -- commands: - - phploc src - depends: - - composer - failure: ignore - image: joomlaprojects/docker-images:php8.1 - name: phploc -- commands: - - phpcpd src - depends: - - composer - failure: ignore - image: joomlaprojects/docker-images:php8.1 - name: phpcpd -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: pipeline -name: PHP 8.1 lowest -steps: -- commands: - - php -v - - composer update --prefer-stable --prefer-lowest - image: joomlaprojects/docker-images:php8.1 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpunit - image: joomlaprojects/docker-images:php8.1 - name: PHPUnit -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: pipeline -name: PHP 8.1 -steps: -- commands: - - php -v - - composer update --prefer-stable - image: joomlaprojects/docker-images:php8.1 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpunit - image: joomlaprojects/docker-images:php8.1 - name: PHPUnit -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: pipeline -name: PHP 8.2 -steps: -- commands: - - php -v - - composer update --prefer-stable - image: joomlaprojects/docker-images:php8.2 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpunit - image: joomlaprojects/docker-images:php8.2 - name: PHPUnit -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: pipeline -name: PHP 8.3 -steps: -- commands: - - php -v - - composer update --prefer-stable - image: joomlaprojects/docker-images:php8.3 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpunit - failure: ignore - image: joomlaprojects/docker-images:php8.3 - name: PHPUnit -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: pipeline -name: PHP 8.4 -steps: -- commands: - - php -v - - composer update --prefer-stable - image: joomlaprojects/docker-images:php8.4 - name: composer - volumes: - - name: composer-cache - path: /tmp/composer-cache -- commands: - - vendor/bin/phpunit - image: joomlaprojects/docker-images:php8.4 - name: PHPUnit -volumes: -- host: - path: /tmp/composer-cache - name: composer-cache ---- -kind: signature -hmac: c2a8a81e44011086f9f921bbc07769c0c52e98715b70002ef06da1d8fbca08e9 - -... diff --git a/.gitattributes b/.gitattributes index 44a57dcc..4ebfb831 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,6 @@ .github/ export-ignore -.phan/ export-ignore docs/ export-ignore Tests/ export-ignore -.drone.jsonnet export-ignore -.drone.yml export-ignore .editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore diff --git a/README.md b/README.md index 0a1fda2b..6b6a00d7 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ ## Installation via Composer -Add `"joomla/string": "~3.0"` to the require block in your composer.json and then run `composer install`. +Add `"joomla/string": "~4.0"` to the require block in your composer.json and then run `composer install`. ```json { "require": { - "joomla/string": "~3.0" + "joomla/string": "~4.0" } } ``` @@ -20,5 +20,5 @@ Add `"joomla/string": "~3.0"` to the require block in your composer.json and the Alternatively, you can simply run the following from the command line: ```sh -composer require joomla/string "~3.0" +composer require joomla/string "~4.0" ``` diff --git a/SECURITY.md b/SECURITY.md index 643dd83d..00bb3f37 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -5,7 +5,8 @@ These versions are currently being supported with security updates: | Version | Supported | -| ------- | ------------------ | +|---------| ------------------ | +| 4.x.x | :white_check_mark: | | 3.x.x | :white_check_mark: | | 2.0.x | :white_check_mark: | | 1.4.x | :x: | diff --git a/Tests/InflectorTest.php b/Tests/InflectorTest.php index 671e8353..2409e08b 100644 --- a/Tests/InflectorTest.php +++ b/Tests/InflectorTest.php @@ -10,6 +10,7 @@ use Doctrine\Common\Inflector\Inflector as DoctrineInflector; use Joomla\String\Inflector; use Joomla\Test\TestHelper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** @@ -28,51 +29,55 @@ class InflectorTest extends TestCase /** * Method to seed data to testIsCountable. * - * @return \Generator + * @return array */ - public function seedIsCountable(): \Generator + public static function seedIsCountable(): array { - yield ['id', true]; - yield ['title', false]; + return [ + ['id', true], + ['title', false], + ]; } /** * Method to seed data to testToPlural. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedSinglePlural(): \Generator + public static function seedSinglePlural(): array { - // Regular plurals - yield ['bus', 'buses']; - yield ['notify', 'notifies']; - yield ['click', 'clicks']; + return [ + // Regular plurals + ['bus', 'buses'], + ['notify', 'notifies'], + ['click', 'clicks'], - // Almost regular plurals. - yield ['photo', 'photos']; - yield ['zero', 'zeros']; + // Almost regular plurals. + ['photo', 'photos'], + ['zero', 'zeros'], - // Irregular identicals - yield ['salmon', 'salmon']; + // Irregular identicals + ['salmon', 'salmon'], - // Irregular plurals - yield ['ox', 'oxen']; - yield ['quiz', 'quizzes']; - yield ['status', 'statuses']; - yield ['matrix', 'matrices']; - yield ['index', 'indices']; - yield ['vertex', 'vertices']; - yield ['hive', 'hives']; + // Irregular plurals + ['ox', 'oxen'], + ['quiz', 'quizzes'], + ['status', 'statuses'], + ['matrix', 'matrices'], + ['index', 'indices'], + ['vertex', 'vertices'], + ['hive', 'hives'], - // Ablaut plurals - yield ['foot', 'feet']; - yield ['louse', 'lice']; - yield ['man', 'men']; - yield ['mouse', 'mice']; - yield ['tooth', 'teeth']; - yield ['woman', 'women']; + // Ablaut plurals + ['foot', 'feet'], + ['louse', 'lice'], + ['man', 'men'], + ['mouse', 'mice'], + ['tooth', 'teeth'], + ['woman', 'women'], + ]; } /** @@ -86,21 +91,7 @@ protected function setUp(): void { parent::setUp(); - $this->inflector = Inflector::getInstance(true); - DoctrineInflector::reset(); - } - - /** - * Tears down the fixture, for example, close a network connection. - * This method is called after a test is executed. - * - * @return void - */ - protected function tearDown(): void - { - DoctrineInflector::reset(); - - parent::tearDown(); + $this->inflector = new Inflector(); } /** @@ -142,136 +133,13 @@ public function testAddCountableRule() ); } - /** - * @testdox A word can be added to the inflector without a plural form - */ - public function testAddWordWithoutPlural() - { - if (!$this->checkInflectorImplementation($this->inflector)) { - $this->markTestSkipped('This test depends on the library\'s implementation'); - } - - $this->assertSame( - $this->inflector, - $this->inflector->addWord('foo') - ); - - $plural = TestHelper::getValue(DoctrineInflector::class, 'plural'); - - $this->assertTrue( - in_array('foo', $plural['uninflected']) - ); - - $singular = TestHelper::getValue(DoctrineInflector::class, 'singular'); - - $this->assertTrue( - in_array('foo', $singular['uninflected']) - ); - } - - /** - * @testdox A word can be added to the inflector with a plural form - */ - public function testAddWordWithPlural() - { - if (!$this->checkInflectorImplementation($this->inflector)) { - $this->markTestSkipped('This test depends on the library\'s implementation'); - } - - $this->assertEquals( - $this->inflector, - $this->inflector->addWord('bar', 'foo') - ); - - $plural = TestHelper::getValue(DoctrineInflector::class, 'plural'); - - $this->assertArrayHasKey( - 'foo', - $plural['irregular'] - ); - - $singular = TestHelper::getValue(DoctrineInflector::class, 'singular'); - - $this->assertArrayHasKey( - 'bar', - $singular['irregular'] - ); - } - - /** - * @testdox A pluralisation rule can be added to the inflector - */ - public function testAddPluraliseRule() - { - if (!$this->checkInflectorImplementation($this->inflector)) { - $this->markTestSkipped('This test depends on the library\'s implementation'); - } - - $this->assertSame( - $this->inflector->addPluraliseRule(['/^(custom)$/i' => '\1izables']), - $this->inflector, - 'Checks chaining.' - ); - - $plural = TestHelper::getValue(DoctrineInflector::class, 'plural'); - - $this->assertArrayHasKey( - '/^(custom)$/i', - $plural['rules'], - 'Checks a pluralisation rule was added.' - ); - } - - /** - * @testdox A singularisation rule can be added to the inflector - */ - public function testAddSingulariseRule() - { - if (!$this->checkInflectorImplementation($this->inflector)) { - $this->markTestSkipped('This test depends on the library\'s implementation'); - } - - $this->assertSame( - $this->inflector->addSingulariseRule(['/^(inflec|contribu)tors$/i' => '\1ta']), - $this->inflector, - 'Checks chaining.' - ); - - $singular = TestHelper::getValue(DoctrineInflector::class, 'singular'); - - $this->assertArrayHasKey( - '/^(inflec|contribu)tors$/i', - $singular['rules'], - 'Checks a singularisation rule was added.' - ); - } - - /** - * @testdox The singleton instance of the inflector can be retrieved - */ - public function testGetInstance() - { - $this->assertInstanceOf( - Inflector::class, - Inflector::getInstance(), - 'Check getInstance returns the right class.' - ); - - $this->assertNotSame( - Inflector::getInstance(), - Inflector::getInstance(true), - 'getInstance with the new flag should not return the singleton instance' - ); - } - /** * @testdox A string is checked to determine if it a countable word * * @param string $input A string. * @param boolean $expected The expected result of the function call. - * - * @dataProvider seedIsCountable */ + #[DataProvider('seedIsCountable')] public function testIsCountable(string $input, bool $expected) { $this->assertEquals( @@ -285,9 +153,8 @@ public function testIsCountable(string $input, bool $expected) * * @param string $singular The singular form of a word. * @param string $plural The plural form of a word. - * - * @dataProvider seedSinglePlural */ + #[Dataprovider('seedSinglePlural')] public function testIsPlural(string $singular, string $plural) { if ($singular === 'bus' && !$this->checkInflectorImplementation($this->inflector)) { @@ -312,9 +179,8 @@ public function testIsPlural(string $singular, string $plural) * * @param string $singular The singular form of a word. * @param string $plural The plural form of a word. - * - * @dataProvider seedSinglePlural */ + #[Dataprovider('seedSinglePlural')] public function testIsSingular(string $singular, string $plural) { if ($singular === 'bus' && !$this->checkInflectorImplementation($this->inflector)) { @@ -334,69 +200,7 @@ public function testIsSingular(string $singular, string $plural) } } - /** - * @testdox A string is converted to its plural form - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @dataProvider seedSinglePlural - */ - public function testToPlural(string $singular, string $plural) - { - $this->assertSame( - $plural, - $this->inflector->toPlural($singular), - "'$plural' should be the plural form of '$singular'" - ); - } - - /** - * @testdox A string that is already plural is returned in the same form - */ - public function testToPluralAlreadyPlural() - { - $this->assertSame( - 'buses', - $this->inflector->toPlural('buses'), - "'buses' should not be pluralised'" - ); - } - - /** - * @testdox A string is converted to its singular form - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @dataProvider seedSinglePlural - */ - public function testToSingular(string $singular, string $plural) - { - $this->assertSame( - $singular, - $this->inflector->toSingular($plural), - "'$singular' should be the singular form of '$plural'" - ); - } - - /** - * @testdox A string that is already singular is returned in the same form - */ - public function testToSingularAlreadySingular() - { - if (!$this->checkInflectorImplementation($this->inflector)) { - $this->markTestSkipped('"bus/buses" is not known to the new implementation'); - } - - $this->assertSame( - 'bus', - $this->inflector->toSingular('bus'), - "'bus' should not be singularised'" - ); - } - - private function checkInflectorImplementation(DoctrineInflector $inflector): bool + private function checkInflectorImplementation(Inflector $inflector): bool { $reflectionClass = new \ReflectionClass($inflector); diff --git a/Tests/NormaliseTest.php b/Tests/NormaliseTest.php index aae8a0c9..719d6b7f 100644 --- a/Tests/NormaliseTest.php +++ b/Tests/NormaliseTest.php @@ -8,6 +8,7 @@ namespace Joomla\String\Tests; use Joomla\String\Normalise; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** @@ -20,147 +21,163 @@ class NormaliseTest extends TestCase /** * Method to seed data to testFromCamelCase. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestFromCamelCase(): \Generator + public static function seedTestFromCamelCase(): array { - // Note: string, expected - yield ['FooBarABCDef', ['Foo', 'Bar', 'ABC', 'Def']]; - yield ['JFooBar', ['J', 'Foo', 'Bar']]; - yield ['J001FooBar002', ['J001', 'Foo', 'Bar002']]; - yield ['abcDef', ['abc', 'Def']]; - yield ['abc_defGhi_Jkl', ['abc_def', 'Ghi_Jkl']]; - yield ['ThisIsA_NASAAstronaut', ['This', 'Is', 'A_NASA', 'Astronaut']]; - yield ['JohnFitzgerald_Kennedy', ['John', 'Fitzgerald_Kennedy']]; + return [ + // Note: string, expected + ['FooBarABCDef', ['Foo', 'Bar', 'ABC', 'Def']], + ['JFooBar', ['J', 'Foo', 'Bar']], + ['J001FooBar002', ['J001', 'Foo', 'Bar002']], + ['abcDef', ['abc', 'Def']], + ['abc_defGhi_Jkl', ['abc_def', 'Ghi_Jkl']], + ['ThisIsA_NASAAstronaut', ['This', 'Is', 'A_NASA', 'Astronaut']], + ['JohnFitzgerald_Kennedy', ['John', 'Fitzgerald_Kennedy']], + ]; } /** * Method to seed data to testFromCamelCase. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestFromCamelCase_nongrouped(): \Generator + public static function seedTestFromCamelCase_nongrouped(): array { - yield ['Foo Bar', 'FooBar']; - yield ['foo Bar', 'fooBar']; - yield ['Foobar', 'Foobar']; - yield ['foobar', 'foobar']; + return [ + ['Foo Bar', 'FooBar'], + ['foo Bar', 'fooBar'], + ['Foobar', 'Foobar'], + ['foobar', 'foobar'], + ]; } /** * Method to seed data to testToCamelCase. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToCamelCase(): \Generator + public static function seedTestToCamelCase(): array { - yield ['FooBar', 'Foo Bar']; - yield ['FooBar', 'Foo-Bar']; - yield ['FooBar', 'Foo_Bar']; - yield ['FooBar', 'foo bar']; - yield ['FooBar', 'foo-bar']; - yield ['FooBar', 'foo_bar']; + return [ + ['FooBar', 'Foo Bar'], + ['FooBar', 'Foo-Bar'], + ['FooBar', 'Foo_Bar'], + ['FooBar', 'foo bar'], + ['FooBar', 'foo-bar'], + ['FooBar', 'foo_bar'], + ]; } /** * Method to seed data to testToDashSeparated. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToDashSeparated(): \Generator + public static function seedTestToDashSeparated(): array { - yield ['Foo-Bar', 'Foo Bar']; - yield ['Foo-Bar', 'Foo-Bar']; - yield ['Foo-Bar', 'Foo_Bar']; - yield ['foo-bar', 'foo bar']; - yield ['foo-bar', 'foo-bar']; - yield ['foo-bar', 'foo_bar']; - yield ['foo-bar', 'foo bar']; - yield ['foo-bar', 'foo---bar']; - yield ['foo-bar', 'foo___bar']; + return [ + ['Foo-Bar', 'Foo Bar'], + ['Foo-Bar', 'Foo-Bar'], + ['Foo-Bar', 'Foo_Bar'], + ['foo-bar', 'foo bar'], + ['foo-bar', 'foo-bar'], + ['foo-bar', 'foo_bar'], + ['foo-bar', 'foo bar'], + ['foo-bar', 'foo---bar'], + ['foo-bar', 'foo___bar'], + ]; } /** * Method to seed data to testToSpaceSeparated. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToSpaceSeparated(): \Generator + public static function seedTestToSpaceSeparated(): array { - yield ['Foo Bar', 'Foo Bar']; - yield ['Foo Bar', 'Foo-Bar']; - yield ['Foo Bar', 'Foo_Bar']; - yield ['foo bar', 'foo bar']; - yield ['foo bar', 'foo-bar']; - yield ['foo bar', 'foo_bar']; - yield ['foo bar', 'foo bar']; - yield ['foo bar', 'foo---bar']; - yield ['foo bar', 'foo___bar']; + return [ + ['Foo Bar', 'Foo Bar'], + ['Foo Bar', 'Foo-Bar'], + ['Foo Bar', 'Foo_Bar'], + ['foo bar', 'foo bar'], + ['foo bar', 'foo-bar'], + ['foo bar', 'foo_bar'], + ['foo bar', 'foo bar'], + ['foo bar', 'foo---bar'], + ['foo bar', 'foo___bar'], + ]; } /** * Method to seed data to testToUnderscoreSeparated. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToUnderscoreSeparated(): \Generator + public static function seedTestToUnderscoreSeparated(): array { - yield ['Foo_Bar', 'Foo Bar']; - yield ['Foo_Bar', 'Foo-Bar']; - yield ['Foo_Bar', 'Foo_Bar']; - yield ['foo_bar', 'foo bar']; - yield ['foo_bar', 'foo-bar']; - yield ['foo_bar', 'foo_bar']; - yield ['foo_bar', 'foo bar']; - yield ['foo_bar', 'foo---bar']; - yield ['foo_bar', 'foo___bar']; + return [ + ['Foo_Bar', 'Foo Bar'], + ['Foo_Bar', 'Foo-Bar'], + ['Foo_Bar', 'Foo_Bar'], + ['foo_bar', 'foo bar'], + ['foo_bar', 'foo-bar'], + ['foo_bar', 'foo_bar'], + ['foo_bar', 'foo bar'], + ['foo_bar', 'foo---bar'], + ['foo_bar', 'foo___bar'], + ]; } /** * Method to seed data to testToVariable. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToVariable(): \Generator + public static function seedTestToVariable(): array { - yield ['myFooBar', 'My Foo Bar']; - yield ['myFooBar', 'My Foo-Bar']; - yield ['myFooBar', 'My Foo_Bar']; - yield ['myFooBar', 'my foo bar']; - yield ['myFooBar', 'my foo-bar']; - yield ['myFooBar', 'my foo_bar']; - yield ['abc3def4', '1abc3def4']; + return [ + ['myFooBar', 'My Foo Bar'], + ['myFooBar', 'My Foo-Bar'], + ['myFooBar', 'My Foo_Bar'], + ['myFooBar', 'my foo bar'], + ['myFooBar', 'my foo-bar'], + ['myFooBar', 'my foo_bar'], + ['abc3def4', '1abc3def4'], + ]; } /** * Method to seed data to testToKey. * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestToKey(): \Generator + public static function seedTestToKey(): array { - yield ['foo_bar', 'Foo Bar']; - yield ['foo_bar', 'Foo-Bar']; - yield ['foo_bar', 'Foo_Bar']; - yield ['foo_bar', 'foo bar']; - yield ['foo_bar', 'foo-bar']; - yield ['foo_bar', 'foo_bar']; + return [ + ['foo_bar', 'Foo Bar'], + ['foo_bar', 'Foo-Bar'], + ['foo_bar', 'Foo_Bar'], + ['foo_bar', 'foo bar'], + ['foo_bar', 'foo-bar'], + ['foo_bar', 'foo_bar'], + ]; } /** @@ -168,9 +185,8 @@ public function seedTestToKey(): \Generator * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestFromCamelCase_nongrouped */ + #[DataProvider('seedTestFromCamelCase_nongrouped')] public function testFromCamelCase_nongrouped(string $expected, string $input) { $this->assertEquals($expected, Normalise::fromCamelcase($input)); @@ -181,9 +197,8 @@ public function testFromCamelCase_nongrouped(string $expected, string $input) * * @param string $input The input value for the method. * @param array|string $expected The expected value from the method. - * - * @dataProvider seedTestFromCamelCase */ + #[DataProvider('seedTestFromCamelCase')] public function testFromCamelCase_grouped(string $input, $expected) { $this->assertEquals($expected, Normalise::fromCamelcase($input, true)); @@ -194,9 +209,8 @@ public function testFromCamelCase_grouped(string $input, $expected) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToCamelCase */ + #[DataProvider('seedTestToCamelCase')] public function testToCamelCase(string $expected, string $input) { $this->assertEquals($expected, Normalise::toCamelcase($input)); @@ -207,9 +221,8 @@ public function testToCamelCase(string $expected, string $input) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToDashSeparated */ + #[DataProvider('seedTestToDashSeparated')] public function testToDashSeparated(string $expected, string $input) { $this->assertEquals($expected, Normalise::toDashSeparated($input)); @@ -220,9 +233,8 @@ public function testToDashSeparated(string $expected, string $input) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToSpaceSeparated */ + #[DataProvider('seedTestToSpaceSeparated')] public function testToSpaceSeparated(string $expected, string $input) { $this->assertEquals($expected, Normalise::toSpaceSeparated($input)); @@ -233,9 +245,8 @@ public function testToSpaceSeparated(string $expected, string $input) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToUnderscoreSeparated */ + #[DataProvider('seedTestToUnderscoreSeparated')] public function testToUnderscoreSeparated(string $expected, string $input) { $this->assertEquals($expected, Normalise::toUnderscoreSeparated($input)); @@ -246,9 +257,8 @@ public function testToUnderscoreSeparated(string $expected, string $input) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToVariable */ + #[DataProvider('seedTestToVariable')] public function testToVariable(string $expected, string $input) { $this->assertEquals($expected, Normalise::toVariable($input)); @@ -259,9 +269,8 @@ public function testToVariable(string $expected, string $input) * * @param string $expected The expected value from the method. * @param string $input The input value for the method. - * - * @dataProvider seedTestToKey */ + #[DataProvider('seedTestToKey')] public function testToKey(string $expected, string $input) { $this->assertEquals($expected, Normalise::toKey($input)); diff --git a/Tests/StringHelperTest.php b/Tests/StringHelperTest.php index e1fbcc44..8d6fd578 100644 --- a/Tests/StringHelperTest.php +++ b/Tests/StringHelperTest.php @@ -8,6 +8,7 @@ namespace Joomla\String\Tests; use Joomla\String\StringHelper; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; /** @@ -18,406 +19,458 @@ class StringHelperTest extends TestCase /** * Data provider for testIncrement * - * @return \Generator + * @return array */ - public function seedTestIncrement(): \Generator + public static function seedTestIncrement(): array { - // Note: string, style, number, expected - yield 'First default increment' => ['title', null, 0, 'title (2)']; - yield 'Second default increment' => ['title(2)', null, 0, 'title(3)']; - yield 'First dash increment' => ['title', 'dash', 0, 'title-2']; - yield 'Second dash increment' => ['title-2', 'dash', 0, 'title-3']; - yield 'Set default increment' => ['title', null, 4, 'title (4)']; - yield 'Unknown style fallback to default' => ['title', 'foo', 0, 'title (2)']; + return [ + // Note: string, style, number, expected + 'First default increment' => ['title', null, 0, 'title (2)'], + 'Second default increment' => ['title(2)', null, 0, 'title(3)'], + 'First dash increment' => ['title', 'dash', 0, 'title-2'], + 'Second dash increment' => ['title-2', 'dash', 0, 'title-3'], + 'Set default increment' => ['title', null, 4, 'title (4)'], + 'Unknown style fallback to default' => ['title', 'foo', 0, 'title (2)'], + ]; } /** * Data provider for testIs_ascii * - * @return \Generator + * @return array */ - public function seedTestIs_ascii(): \Generator + public static function seedTestIs_ascii(): array { - yield ['ascii', true]; - yield ['1024', true]; - yield ['#$#@$%', true]; - yield ['áÑ', false]; - yield ['ÿ©', false]; - yield ['¡¾', false]; - yield ['÷™', false]; + return [ + ['ascii', true], + ['1024', true], + ['#$#@$%', true], + ['áÑ', false], + ['ÿ©', false], + ['¡¾', false], + ['÷™', false], + ]; } /** * Data provider for testStrpos * - * @return \Generator + * @return array */ - public function seedTestStrpos(): \Generator + public static function seedTestStrpos(): array { - yield [3, 'missing', 'sing', 0]; - yield [false, 'missing', 'sting', 0]; - yield [4, 'missing', 'ing', 0]; - yield [10, ' объектов на карте с', 'на карте', 0]; - yield [0, 'на карте с', 'на карте', 0, 0]; - yield [false, 'на карте с', 'на каррте', 0]; - yield [false, 'на карте с', 'на карте', 2]; - yield [3, 'missing', 'sing', false]; + return [ + [3, 'missing', 'sing', 0], + [false, 'missing', 'sting', 0], + [4, 'missing', 'ing', 0], + [10, ' объектов на карте с', 'на карте', 0], + [0, 'на карте с', 'на карте', 0], + [false, 'на карте с', 'на каррте', 0], + [false, 'на карте с', 'на карте', 2], + [3, 'missing', 'sing', false], + ]; } /** * Data provider for testStrrpos * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStrrpos(): \Generator + public static function seedTestStrrpos(): array { - yield [3, 'missing', 'sing', 0]; - yield [false, 'missing', 'sting', 0]; - yield [4, 'missing', 'ing', 0]; - yield [10, ' объектов на карте с', 'на карте', 0]; - yield [0, 'на карте с', 'на карте', 0]; - yield [false, 'на карте с', 'на каррте', 0]; - yield [3, 'на карте с', 'карт', 2]; + return [ + [3, 'missing', 'sing', 0], + [false, 'missing', 'sting', 0], + [4, 'missing', 'ing', 0], + [10, ' объектов на карте с', 'на карте', 0], + [0, 'на карте с', 'на карте', 0], + [false, 'на карте с', 'на каррте', 0], + [3, 'на карте с', 'карт', 2], + ]; } /** * Data provider for testSubstr * - * @return \Generator + * @return array */ - public function seedTestSubstr(): \Generator + public static function seedTestSubstr(): array { - yield ['issauga', 'Mississauga', 4, false]; - yield ['на карте с', ' объектов на карте с', 10, false]; - yield ['на ка', ' объектов на карте с', 10, 5]; - yield ['те с', ' объектов на карте с', -4, false]; - yield [false, ' объектов на карте с', 99, false]; + return [ + ['issauga', 'Mississauga', 4, false], + ['на карте с', ' объектов на карте с', 10, false], + ['на ка', ' объектов на карте с', 10, 5], + ['те с', ' объектов на карте с', -4, false], + [false, ' объектов на карте с', 99, false], + ]; } /** * Data provider for testStrtolower * - * @return \Generator + * @return array */ - public function seedTestStrtolower(): \Generator + public static function seedTestStrtolower(): array { - yield ['Joomla! Rocks', 'joomla! rocks']; + return [ + ['Joomla! Rocks', 'joomla! rocks'], + ]; } /** * Data provider for testStrtoupper * - * @return \Generator + * @return array */ - public function seedTestStrtoupper(): \Generator + public static function seedTestStrtoupper(): array { - yield ['Joomla! Rocks', 'JOOMLA! ROCKS']; + return [ + ['Joomla! Rocks', 'JOOMLA! ROCKS'], + ]; } /** * Data provider for testStrlen * - * @return \Generator + * @return array */ - public function seedTestStrlen(): \Generator + public static function seedTestStrlen(): array { - yield ['Joomla! Rocks', 13]; + return [ + ['Joomla! Rocks', 13], + ]; } /** * Data provider for testStr_ireplace * - * @return \Generator + * @return array */ - public function seedTestStr_ireplace(): \Generator + public static function seedTestStr_ireplace(): array { - yield ['Pig', 'cow', 'the pig jumped', false, 'the cow jumped']; - yield ['Pig', 'cow', 'the pig jumped', true, 'the cow jumped']; - yield ['Pig', 'cow', 'the pig jumped over the cow', true, 'the cow jumped over the cow']; - yield [['PIG', 'JUMPED'], ['cow', 'hopped'], 'the pig jumped over the pig', true, 'the cow hopped over the cow']; - yield ['шил', 'биш', 'Би шил идэй чадна', true, 'Би биш идэй чадна']; - yield ['/', ':', '/test/slashes/', true, ':test:slashes:']; + return [ + ['Pig', 'cow', 'the pig jumped', false, 'the cow jumped'], + ['Pig', 'cow', 'the pig jumped', true, 'the cow jumped'], + ['Pig', 'cow', 'the pig jumped over the cow', true, 'the cow jumped over the cow'], + [['PIG', 'JUMPED'], ['cow', 'hopped'], 'the pig jumped over the pig', true, 'the cow hopped over the cow'], + ['шил', 'биш', 'Би шил идэй чадна', true, 'Би биш идэй чадна'], + ['/', ':', '/test/slashes/', true, ':test:slashes:'], + ]; } /** * Data provider for testStr_split * - * @return \Generator + * @return array */ - public function seedTestStr_split(): \Generator + public static function seedTestStr_split(): array { - yield ['string', 1, ['s', 't', 'r', 'i', 'n', 'g']]; - yield ['string', 2, ['st', 'ri', 'ng']]; - yield ['волн', 3, ['вол', 'н']]; - yield ['волн', 1, ['в', 'о', 'л', 'н']]; + return [ + ['string', 1, ['s', 't', 'r', 'i', 'n', 'g']], + ['string', 2, ['st', 'ri', 'ng']], + ['волн', 3, ['вол', 'н']], + ['волн', 1, ['в', 'о', 'л', 'н']], + ]; } /** * Data provider for testStrcasecmp * - * @return \Generator + * @return array */ - public function seedTestStrcasecmp(): \Generator + public static function seedTestStrcasecmp(): array { - yield ['THIS IS STRING1', 'this is string1', false, 0]; - yield ['this is string1', 'this is string2', false, -1]; - yield ['this is string2', 'this is string1', false, 1]; - yield ['бгдпт', 'бгдпт', false, 0]; - yield ['àbc', 'abc', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1]; - yield ['àbc', 'bcd', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['é', 'è', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['É', 'é', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 0]; - yield ['œ', 'p', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['œ', 'n', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1]; + return [ + ['THIS IS STRING1', 'this is string1', false, 0], + ['this is string1', 'this is string2', false, -1], + ['this is string2', 'this is string1', false, 1], + ['бгдпт', 'бгдпт', false, 0], + ['àbc', 'abc', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1], + ['àbc', 'bcd', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['é', 'è', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['É', 'é', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 0], + ['œ', 'p', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['œ', 'n', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1], + ]; } /** * Data provider for testStrcmp * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStrcmp(): \Generator + public static function seedTestStrcmp(): array { - yield ['THIS IS STRING1', 'this is string1', false, -1]; - yield ['this is string1', 'this is string2', false, -1]; - yield ['this is string2', 'this is string1', false, 1]; - yield ['a', 'B', false, 1]; - yield ['A', 'b', false, -1]; - yield ['Àbc', 'abc', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1]; - yield ['Àbc', 'bcd', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['É', 'è', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['é', 'È', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['Œ', 'p', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; - yield ['Œ', 'n', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1]; - yield ['œ', 'N', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1]; - yield ['œ', 'P', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1]; + return [ + ['THIS IS STRING1', 'this is string1', false, -1], + ['this is string1', 'this is string2', false, -1], + ['this is string2', 'this is string1', false, 1], + ['a', 'B', false, 1], + ['A', 'b', false, -1], + ['Àbc', 'abc', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1], + ['Àbc', 'bcd', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['É', 'è', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['é', 'È', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['Œ', 'p', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ['Œ', 'n', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1], + ['œ', 'N', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], 1], + ['œ', 'P', ['fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'], -1], + ]; } /** * Data provider for testStrcspn * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStrcspn(): \Generator + public static function seedTestStrcspn(): array { - yield ['subject string ', '<>', false, false, 8]; - yield ['Би шил {123} идэй {456} чадна', '}{', null, false, 7]; - yield ['Би шил {123} идэй {456} чадна', '}{', 13, 10, 5]; + return [ + ['subject string ', '<>', false, false, 8], + ['Би шил {123} идэй {456} чадна', '}{', null, false, 7], + ['Би шил {123} идэй {456} чадна', '}{', 13, 10, 5], + ]; } /** * Data provider for testStristr * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStristr(): \Generator + public static function seedTestStristr(): array { - yield ['haystack', 'needle', false]; - yield ['before match, after match', 'match', 'match, after match']; - yield ['Би шил идэй чадна', 'шил', 'шил идэй чадна']; + return [ + ['haystack', 'needle', false], + ['before match, after match', 'match', 'match, after match'], + ['Би шил идэй чадна', 'шил', 'шил идэй чадна'], + ]; } /** * Data provider for testStrrev * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStrrev(): \Generator + public static function seedTestStrrev(): array { - yield ['abc def', 'fed cba']; - yield ['Би шил', 'лиш иБ']; + return [ + ['abc def', 'fed cba'], + ['Би шил', 'лиш иБ'], + ]; } /** * Data provider for testStrspn * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestStrspn(): \Generator + public static function seedTestStrspn(): array { - yield ['A321 Main Street', '0123456789', 1, 2, 2]; - yield ['321 Main Street', '0123456789', null, 2, 2]; - yield ['A321 Main Street', '0123456789', null, 10, 0]; - yield ['321 Main Street', '0123456789', null, null, 3]; - yield ['Main Street 321', '0123456789', null, -3, 0]; - yield ['321 Main Street', '0123456789', null, -13, 2]; - yield ['321 Main Street', '0123456789', null, -12, 3]; - yield ['A321 Main Street', '0123456789', 0, null, 0]; - yield ['A321 Main Street', '0123456789', 1, 10, 3]; - yield ['A321 Main Street', '0123456789', 1, null, 3]; - yield ['Би шил идэй чадна', 'Би', null, null, 2]; - yield ['чадна Би шил идэй чадна', 'Би', null, null, 0]; + return [ + ['A321 Main Street', '0123456789', 1, 2, 2], + ['321 Main Street', '0123456789', 0, 2, 2], + ['A321 Main Street', '0123456789', 0, 10, 0], + ['321 Main Street', '0123456789', 0, null, 3], + ['Main Street 321', '0123456789', 0, -3, 0], + ['321 Main Street', '0123456789', 0, -13, 2], + ['321 Main Street', '0123456789', 0, -12, 3], + ['A321 Main Street', '0123456789', 0, null, 0], + ['A321 Main Street', '0123456789', 1, 10, 3], + ['A321 Main Street', '0123456789', 1, null, 3], + ['Би шил идэй чадна', 'Би', 0, null, 2], + ['чадна Би шил идэй чадна', 'Би', 0, null, 0], + ]; } /** * Data provider for testSubstr_replace * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestSubstr_replace(): \Generator + public static function seedTestSubstr_replace(): array { - yield ['321 Broadway Avenue', '321 Main Street', 'Broadway Avenue', 4, false]; - yield ['321 Broadway Street', '321 Main Street', 'Broadway', 4, 4]; - yield ['чадна 我能吞', 'чадна Би шил идэй чадна', '我能吞', 6, false]; - yield ['чадна 我能吞 шил идэй чадна', 'чадна Би шил идэй чадна', '我能吞', 6, 2]; + return [ + ['321 Broadway Avenue', '321 Main Street', 'Broadway Avenue', 4, false], + ['321 Broadway Street', '321 Main Street', 'Broadway', 4, 4], + ['чадна 我能吞', 'чадна Би шил идэй чадна', '我能吞', 6, false], + ['чадна 我能吞 шил идэй чадна', 'чадна Би шил идэй чадна', '我能吞', 6, 2], + ]; } /** * Data provider for testLtrim * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestLtrim(): \Generator + public static function seedTestLtrim(): array { - yield [' abc def', false, 'abc def']; - yield [' abc def', '', ' abc def']; - yield [' Би шил', false, 'Би шил']; - yield ["\t\n\r\x0BБи шил", false, 'Би шил']; - yield ["\x0B\t\n\rБи шил", "\t\n\x0B", "\rБи шил"]; - yield ["\x09Би шил\x0A", "\x09\x0A", "Би шил\x0A"]; - yield ['1234abc', '0123456789', 'abc']; + return [ + [' abc def', false, 'abc def'], + [' abc def', '', ' abc def'], + [' Би шил', false, 'Би шил'], + ["\t\n\r\x0BБи шил", false, 'Би шил'], + ["\x0B\t\n\rБи шил", "\t\n\x0B", "\rБи шил"], + ["\x09Би шил\x0A", "\x09\x0A", "Би шил\x0A"], + ['1234abc', '0123456789', 'abc'], + ]; } /** * Data provider for testRtrim * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestRtrim(): \Generator + public static function seedTestRtrim(): array { - yield ['abc def ', false, 'abc def']; - yield ['abc def ', '', 'abc def ']; - yield ['Би шил ', false, 'Би шил']; - yield ["Би шил\t\n\r\x0B", false, 'Би шил']; - yield ["Би шил\r\x0B\t\n", "\t\n\x0B", "Би шил\r"]; - yield ["\x09Би шил\x0A", "\x09\x0A", "\x09Би шил"]; - yield ['1234abc', 'abc', '1234']; + return [ + ['abc def ', false, 'abc def'], + ['abc def ', '', 'abc def '], + ['Би шил ', false, 'Би шил'], + ["Би шил\t\n\r\x0B", false, 'Би шил'], + ["Би шил\r\x0B\t\n", "\t\n\x0B", "Би шил\r"], + ["\x09Би шил\x0A", "\x09\x0A", "\x09Би шил"], + ['1234abc', 'abc', '1234'], + ]; } /** * Data provider for testTrim * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestTrim(): \Generator + public static function seedTestTrim(): array { - yield [' abc def ', false, 'abc def']; - yield [' abc def ', '', ' abc def ']; - yield [' Би шил ', false, 'Би шил']; - yield ["\t\n\r\x0BБи шил\t\n\r\x0B", false, 'Би шил']; - yield ["\x0B\t\n\rБи шил\r\x0B\t\n", "\t\n\x0B", "\rБи шил\r"]; - yield ["\x09Би шил\x0A", "\x09\x0A", "Би шил"]; - yield ['1234abc56789', '0123456789', 'abc']; + return [ + [' abc def ', false, 'abc def'], + [' abc def ', '', ' abc def '], + [' Би шил ', false, 'Би шил'], + ["\t\n\r\x0BБи шил\t\n\r\x0B", false, 'Би шил'], + ["\x0B\t\n\rБи шил\r\x0B\t\n", "\t\n\x0B", "\rБи шил\r"], + ["\x09Би шил\x0A", "\x09\x0A", "Би шил"], + ['1234abc56789', '0123456789', 'abc'], + ]; } /** * Data provider for testUcfirst * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestUcfirst(): \Generator + public static function seedTestUcfirst(): array { - yield ['george', null, null, 'George']; - yield ['мога', null, null, 'Мога']; - yield ['ψυχοφθόρα', null, null, 'Ψυχοφθόρα']; - yield ['dr jekill and mister hyde', ' ', null, 'Dr Jekill And Mister Hyde']; - yield ['dr jekill and mister hyde', ' ', '_', 'Dr_Jekill_And_Mister_Hyde']; - yield ['dr jekill and mister hyde', ' ', '', 'DrJekillAndMisterHyde']; + return [ + ['george', null, null, 'George'], + ['мога', null, null, 'Мога'], + ['ψυχοφθόρα', null, null, 'Ψυχοφθόρα'], + ['dr jekill and mister hyde', ' ', null, 'Dr Jekill And Mister Hyde'], + ['dr jekill and mister hyde', ' ', '_', 'Dr_Jekill_And_Mister_Hyde'], + ['dr jekill and mister hyde', ' ', '', 'DrJekillAndMisterHyde'], + ]; } /** * Data provider for testUcwords * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestUcwords(): \Generator + public static function seedTestUcwords(): array { - yield ['george washington', 'George Washington']; - yield ["george\r\nwashington", "George\r\nWashington"]; - yield ['мога', 'Мога']; - yield ['αβγ δεζ', 'Αβγ Δεζ']; - yield ['åbc öde', 'Åbc Öde']; + return [ + ['george washington', 'George Washington'], + ["george\r\nwashington", "George\r\nWashington"], + ['мога', 'Мога'], + ['αβγ δεζ', 'Αβγ Δεζ'], + ['åbc öde', 'Åbc Öde'], + ]; } /** * Data provider for testTranscode * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedTestTranscode(): \Generator + public static function seedTestTranscode(): array { - yield ['Åbc Öde €100', 'UTF-8', 'ISO-8859-1', "\xc5bc \xd6de EUR100"]; + return [ + ['Åbc Öde €100', 'UTF-8', 'ISO-8859-1', "\xc5bc \xd6de EUR100"], + ]; } /** * Data provider for testing compliant strings * - * @return \Generator + * @return array * * @since 1.0 */ - public function seedCompliantStrings(): \Generator + public static function seedCompliantStrings(): array { - yield ["\xCF\xB0", true]; - yield ["\xFBa", false]; - yield ["\xFDa", false]; - yield ["foo\xF7bar", false]; - yield ['george Мога Ž Ψυχοφθόρα ฉันกินกระจกได้ 我能吞下玻璃而不伤身体 ', true]; - yield ["\xFF ABC", false]; - yield ["0xfffd ABC", true]; - yield ['', true]; + return [ + ["\xCF\xB0", true], + ["\xFBa", false], + ["\xFDa", false], + ["foo\xF7bar", false], + ['george Мога Ž Ψυχοφθόρα ฉันกินกระจกได้ 我能吞下玻璃而不伤身体 ', true], + ["\xFF ABC", false], + ["0xfffd ABC", true], + ['', true], + ]; } /** * Data provider for testUnicodeToUtf8 * - * @return \Generator + * @return array * * @since 1.2.0 */ - public function seedTestUnicodeToUtf8(): \Generator + public static function seedTestUnicodeToUtf8(): array { - yield ["\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"]; - yield ["\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung"]; + return [ + ["\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"], + ["\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung"], + ]; } /** * Data provider for testUnicodeToUtf16 * - * @return \Generator + * @return array * * @since 1.2.0 */ - public function seedTestUnicodeToUtf16(): \Generator + public static function seedTestUnicodeToUtf16(): array { - yield ["\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"]; - yield ["\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung"]; + return [ + ["\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"], + ["\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung"], + ]; } /** @@ -427,9 +480,8 @@ public function seedTestUnicodeToUtf16(): \Generator * @param string|null $style The the style (default|dash). * @param integer $number If supplied, this number is used for the copy, otherwise it is the 'next' number. * @param string $expected Expected result. - * - * @dataProvider seedTestIncrement */ + #[DataProvider('seedTestIncrement')] public function testIncrement(string $string, ?string $style, int $number, string $expected) { $this->assertEquals( @@ -443,9 +495,8 @@ public function testIncrement(string $string, ?string $style, int $number, strin * * @param string $string The string to test. * @param boolean $expected Expected result. - * - * @dataProvider seedTestIs_ascii */ + #[DataProvider('seedTestIs_ascii')] public function testIs_ascii(string $string, bool $expected) { $this->assertEquals( @@ -461,9 +512,8 @@ public function testIs_ascii(string $string, bool $expected) * @param string $haystack String being examined * @param string $needle String being searched for * @param integer|null|boolean $offset Optional, specifies the position from which the search should be performed - * - * @dataProvider seedTestStrpos */ + #[DataProvider('seedTestStrpos')] public function testStrpos($expected, string $haystack, string $needle, $offset = 0) { $this->assertEquals( @@ -479,9 +529,8 @@ public function testStrpos($expected, string $haystack, string $needle, $offset * @param string $haystack String being examined * @param string $needle String being searched for * @param integer|null|boolean $offset Optional, specifies the position from which the search should be performed - * - * @dataProvider seedTestStrrpos */ + #[DataProvider('seedTestStrrpos')] public function testStrrpos($expected, string $haystack, string $needle, int $offset = 0) { $this->assertEquals( @@ -497,9 +546,8 @@ public function testStrrpos($expected, string $haystack, string $needle, int $of * @param string $string String being processed * @param integer $offset Number of UTF-8 characters offset (from left) * @param integer|null|boolean $offset Optional, specifies the position from which the search should be performed - * - * @dataProvider seedTestSubstr */ + #[DataProvider('seedTestSubstr')] public function testSubstr($expected, string $string, int $start, $length = false) { $this->assertEquals( @@ -513,9 +561,8 @@ public function testSubstr($expected, string $string, int $start, $length = fals * * @param string $string String being processed * @param string|boolean $expected Expected result - * - * @dataProvider seedTestStrtolower */ + #[DataProvider('seedTestStrtolower')] public function testStrtolower(string $string, $expected) { $this->assertEquals( @@ -529,9 +576,8 @@ public function testStrtolower(string $string, $expected) * * @param string $string String being processed * @param string|boolean $expected Expected result - * - * @dataProvider seedTestStrtoupper */ + #[DataProvider('seedTestStrtoupper')] public function testStrtoupper($string, $expected) { $this->assertEquals( @@ -545,9 +591,8 @@ public function testStrtoupper($string, $expected) * * @param string $string String being processed * @param string|boolean $expected Expected result - * - * @dataProvider seedTestStrlen */ + #[DataProvider('seedTestStrlen')] public function testStrlen(string $string, $expected) { $this->assertEquals( @@ -564,11 +609,8 @@ public function testStrlen(string $string, $expected) * @param string $subject New string to replace with * @param integer|null|boolean $count Optional count value to be passed by reference * @param string $expected Expected result - * - * @return array - * - * @dataProvider seedTestStr_ireplace */ + #[DataProvider('seedTestStr_ireplace')] public function testStr_ireplace($search, $replace, $subject, $count, $expected) { $this->assertEquals( @@ -583,9 +625,8 @@ public function testStr_ireplace($search, $replace, $subject, $count, $expected) * @param string $string UTF-8 encoded string to process * @param integer $splitLen Number to characters to split string by * @param array|string|boolean $expected Expected result - * - * @dataProvider seedTestStr_split */ + #[DataProvider('seedTestStr_split')] public function testStr_split($string, $splitLen, $expected) { $this->assertEquals( @@ -601,9 +642,8 @@ public function testStr_split($string, $splitLen, $expected) * @param string $string2 String 2 to compare * @param array|string|boolean $locale The locale used by strcoll or false to use classical comparison * @param integer $expected Expected result - * - * @dataProvider seedTestStrcasecmp */ + #[DataProvider('seedTestStrcasecmp')] public function testStrcasecmp(string $string1, string $string2, $locale, int $expected) { // Convert the $locale param to a string if it is an array @@ -635,9 +675,8 @@ public function testStrcasecmp(string $string1, string $string2, $locale, int $e * @param string $string2 String 2 to compare * @param mixed $locale The locale used by strcoll or false to use classical comparison * @param integer $expected Expected result - * - * @dataProvider seedTestStrcmp */ + #[DataProvider('seedTestStrcmp')] public function testStrcmp(string $string1, string $string2, $locale, int $expected) { // Convert the $locale param to a string if it is an array @@ -671,9 +710,8 @@ public function testStrcmp(string $string1, string $string2, $locale, int $expec * @param integer|boolean $start Optional starting character position (in characters) * @param integer|boolean $len Optional length * @param integer $expected Expected result - * - * @dataProvider seedTestStrcspn */ + #[DataProvider('seedTestStrcspn')] public function testStrcspn(string $haystack, string $needles, $start, $len, int $expected) { $this->assertEquals( @@ -688,9 +726,8 @@ public function testStrcspn(string $haystack, string $needles, $start, $len, int * @param string $haystack The haystack * @param string $needle The needle * @param string|boolean $expect Expected result - * - * @dataProvider seedTestStristr */ + #[DataProvider('seedTestStristr')] public function testStristr(string $haystack, string $needle, $expected) { $this->assertEquals( @@ -704,9 +741,9 @@ public function testStristr(string $haystack, string $needle, $expected) * * @param string $string String to be reversed * @param string $expected Expected result - * - * @dataProvider seedTestStrrev + */ + #[DataProvider('seedTestStrrev')] public function testStrrev(string $string, string $expected) { $this->assertEquals( @@ -723,9 +760,8 @@ public function testStrrev(string $string, string $expected) * @param integer|null $start Start optional * @param integer|null $length Length optional * @param integer $expect Expected result - * - * @dataProvider seedTestStrspn */ + #[DataProvider('seedTestStrspn')] public function testStrspn(string $subject, string $mask, $start, $length, int $expected) { $this->assertEquals( @@ -742,9 +778,8 @@ public function testStrspn(string $subject, string $mask, $start, $length, int $ * @param string $replacement The replacement string * @param integer $start Start * @param integer|boolean|null $length Length (optional) - * - * @dataProvider seedTestSubstr_replace */ + #[DataProvider('seedTestSubstr_replace')] public function testSubstr_replace(string $expected, string $string, string $replacement, int $start, $length) { $this->assertEquals( @@ -759,9 +794,8 @@ public function testSubstr_replace(string $expected, string $string, string $rep * @param string $string The string to be trimmed * @param string|boolean $charlist The optional charlist of additional characters to trim * @param string $expected Expected result - * - * @dataProvider seedTestLtrim */ + #[DataProvider('seedTestLtrim')] public function testLtrim(string $string, $charlist, string $expected) { $this->assertEquals( @@ -776,9 +810,8 @@ public function testLtrim(string $string, $charlist, string $expected) * @param string $string The string to be trimmed * @param string|boolean $charlist The optional charlist of additional characters to trim * @param string $expected Expected result - * - * @dataProvider seedTestRtrim */ + #[DataProvider('seedTestRtrim')] public function testRtrim(string $string, $charlist, string $expected) { $this->assertEquals( @@ -793,9 +826,8 @@ public function testRtrim(string $string, $charlist, string $expected) * @param string $string The string to be trimmed * @param string|boolean $charlist The optional charlist of additional characters to trim * @param string $expected Expected result - * - * @dataProvider seedTestTrim */ + #[DataProvider('seedTestTrim')] public function testTrim(string $string, $charlist, string $expected) { $this->assertEquals( @@ -811,9 +843,8 @@ public function testTrim(string $string, $charlist, string $expected) * @param string|null $delimiter The words delimiter (null means do not split the string) * @param string|null $newDelimiter The new words delimiter (null means equal to $delimiter) * @param string $expected Expected result - * - * @dataProvider seedTestUcfirst */ + #[DataProvider('seedTestUcfirst')] public function testUcfirst(string $string, ?string $delimiter, ?string $newDelimiter, string $expected) { $this->assertEquals( @@ -827,9 +858,8 @@ public function testUcfirst(string $string, ?string $delimiter, ?string $newDeli * * @param string $string String to be processed * @param string $expected Expected result - * - * @dataProvider seedTestUcwords */ + #[DataProvider('seedTestUcwords')] public function testUcwords(string $string, string $expected) { $this->assertEquals( @@ -845,9 +875,8 @@ public function testUcwords(string $string, string $expected) * @param string $fromEncoding The source encoding. * @param string $toEncoding The target encoding. * @param string|null $expect Expected result. - * - * @dataProvider seedTestTranscode */ + #[DataProvider('seedTestTranscode')] public function testTranscode(string $source, string $fromEncoding, string $toEncoding, ?string $expected) { $this->assertEquals( @@ -861,9 +890,8 @@ public function testTranscode(string $source, string $fromEncoding, string $toEn * * @param string $string UTF-8 encoded string. * @param boolean $expected Expected result. - * - * @dataProvider seedCompliantStrings */ + #[DataProvider('seedCompliantStrings')] public function testValid(string $string, bool $expected) { $this->assertEquals( @@ -877,9 +905,8 @@ public function testValid(string $string, bool $expected) * * @param string $string Unicode string to convert * @param string $expected Expected result - * - * @dataProvider seedTestUnicodeToUtf8 */ + #[DataProvider('seedTestUnicodeToUtf8')] public function testUnicodeToUtf8(string $string, string $expected) { $this->assertEquals( @@ -893,9 +920,8 @@ public function testUnicodeToUtf8(string $string, string $expected) * * @param string $string Unicode string to convert * @param string $expected Expected result - * - * @dataProvider seedTestUnicodeToUtf16 */ + #[DataProvider('seedTestUnicodeToUtf16')] public function testUnicodeToUtf16(string $string, string $expected) { $this->assertEquals( @@ -909,9 +935,8 @@ public function testUnicodeToUtf16(string $string, string $expected) * * @param string $string UTF-8 string to check * @param boolean $expected Expected result - * - * @dataProvider seedCompliantStrings */ + #[DataProvider('seedCompliantStrings')] public function testCompliant(string $string, bool $expected) { $this->assertEquals( diff --git a/composer.json b/composer.json index 6066559c..fa2f0abf 100644 --- a/composer.json +++ b/composer.json @@ -6,17 +6,17 @@ "homepage": "https://github.com/joomla-framework/string", "license": "GPL-2.0-or-later", "require": { - "php": "^8.1.0", + "php": "^8.3.0", "symfony/deprecation-contracts": "^2|^3", "symfony/polyfill-mbstring": "^1.31.0" }, "require-dev": { - "doctrine/inflector": "^1.2", + "doctrine/inflector": "^2.0.10", "joomla/test": "dev-4.x-dev", - "phpunit/phpunit": "^9.5.28", + "phpunit/phpunit": "^12.2.6", "squizlabs/php_codesniffer": "^3.7.2", - "phpstan/phpstan": "1.12.27", - "phpstan/phpstan-deprecation-rules": "1.2.1" + "phpstan/phpstan": "2.1.17", + "phpstan/phpstan-deprecation-rules": "2.0.3" }, "conflict": { "doctrine/inflector": "<1.2" diff --git a/docs/v2-to-v3-update.md b/docs/v2-to-v3-update.md new file mode 100644 index 00000000..bdb1f3e8 --- /dev/null +++ b/docs/v2-to-v3-update.md @@ -0,0 +1,5 @@ +## Updating from v2 to v3 + +### Minimum supported PHP version raised + +All Framework packages now require PHP 8.1 or newer. diff --git a/docs/v3-to-v4-update.md b/docs/v3-to-v4-update.md new file mode 100644 index 00000000..5abbd7bd --- /dev/null +++ b/docs/v3-to-v4-update.md @@ -0,0 +1,20 @@ +## Updating from v3 to v4 + +### Minimum supported PHP version raised + +All Framework packages now require PHP 8.3 or newer. + +### Deprecated methods from `Inflector` class have been removed + +The following deprecated methods have been removed in this release: + +* `Inflector::addWord()`: Use `Doctrine\Common\Inflector\Inflector::rules()` +* `Inflector::addPluraliseRule()`: Use `Doctrine\Common\Inflector\Inflector::rules()` +* `Inflector::addSingulariseRule()`: Use `Doctrine\Common\Inflector\Inflector::rules()` +* `Inflector::getInstance()`: Use the static methods without an instance instead. +* `Inflector::toPlural()`: Use static `Doctrine\Common\Inflector\Inflector::pluralize()` +* `Inflector::toSingular()`: Use static `Doctrine\Common\Inflector\Inflector::singularize()` + +### The `Inflector` class has been deprecated + +The `Inflector` class in this package does not provide benefits over the original `doctrine/inflector` package anymore and is currently only there to keep backwards compatibility with version 3. Use `doctrine/inflector` directly instead. This class will be removed in 5.0 of this package. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 844a69c7..2278bfba 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,5 @@ - - - src - - src/phputf8 - - - Tests diff --git a/src/Inflector.php b/src/Inflector.php index 1a54ad41..4f99f0fb 100644 --- a/src/Inflector.php +++ b/src/Inflector.php @@ -9,7 +9,7 @@ namespace Joomla\String; -use Doctrine\Common\Inflector\Inflector as DoctrineInflector; +use Doctrine\Inflector\InflectorFactory; /** * Joomla Framework String Inflector Class @@ -17,18 +17,10 @@ * The Inflector transforms words * * @since 1.0 + * @deprecated 5.0 Use doctrine/inflector package as complete replacement instead. */ -class Inflector extends DoctrineInflector +class Inflector { - /** - * The singleton instance. - * - * @var Inflector - * @since 1.0 - * @deprecated 3.0 - */ - private static $instance; - /** * The inflector rules for countability. * @@ -91,224 +83,116 @@ public function addCountableRule($data) } /** - * Adds a specific singular-plural pair for a word. + * Checks if a word is countable. * - * @param string $singular The singular form of the word. - * @param string $plural The plural form of the word. If omitted, it is assumed the singular and plural are identical. + * @param string $word The string input. * - * @return $this + * @return boolean True if word is countable, false otherwise. * * @since 1.0 - * @deprecated 3.0 Use Doctrine\Common\Inflector\Inflector::rules() instead. */ - public function addWord($singular, $plural = '') + public function isCountable($word) { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0, use %s::rules() instead.', - __METHOD__, - DoctrineInflector::class - ); - - if ($plural !== '') { - static::rules( - 'plural', - [ - 'irregular' => [$plural => $singular], - ] - ); - - static::rules( - 'singular', - [ - 'irregular' => [$singular => $plural], - ] - ); - } else { - static::rules( - 'plural', - [ - 'uninflected' => [$singular], - ] - ); - - static::rules( - 'singular', - [ - 'uninflected' => [$singular], - ] - ); - } - - return $this; + return \in_array($word, self::$countable['rules']); } /** - * Adds a pluralisation rule. + * Checks if a word is in a plural form. * - * @param mixed $data A string or an array of regex rules to add. + * @param string $word The string input. * - * @return $this + * @return boolean True if word is plural, false if not. * * @since 1.0 - * @deprecated 3.0 Use Doctrine\Common\Inflector\Inflector::rules() instead. */ - public function addPluraliseRule($data) + public function isPlural($word) { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0, use %s::rules() instead.', - __METHOD__, - DoctrineInflector::class - ); - - $this->addRule($data, 'plural'); - - return $this; + return static::pluralize(static::singularize($word)) === $word; } /** - * Adds a singularisation rule. + * Checks if a word is in a singular form. * - * @param mixed $data A string or an array of regex rules to add. + * @param string $word The string input. * - * @return $this + * @return boolean True if word is singular, false if not. * * @since 1.0 - * @deprecated 3.0 Use Doctrine\Common\Inflector\Inflector::rules() instead. */ - public function addSingulariseRule($data) + public function isSingular($word) { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0, use %s::rules() instead.', - __METHOD__, - DoctrineInflector::class - ); + return static::singularize($word) === $word; + } - $this->addRule($data, 'singular'); + /** + * Proxy for Inflector::tableize() + */ + public static function tableize(string $word): string + { + $inflector = InflectorFactory::create()->build(); - return $this; + return $inflector->tableize($word); } /** - * Gets an instance of the Inflector singleton. - * - * @param boolean $new If true (default is false), returns a new instance regardless if one exists. This argument is mainly used for testing. - * - * @return static - * - * @since 1.0 - * @deprecated 3.0 Use static methods without a class instance instead. + * Proxy for Inflector::classify() */ - public static function getInstance($new = false) + public static function classify(string $word): string { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0.', - __METHOD__ - ); + $inflector = InflectorFactory::create()->build(); - if ($new) { - return new static(); - } + return $inflector->classify($word); + } - if (!\is_object(self::$instance)) { - self::$instance = new static(); - } + /** + * Proxy for Inflector::camelize() + */ + public static function camelize(string $word): string + { + $inflector = InflectorFactory::create()->build(); - return self::$instance; + return $inflector->camelize($word); } /** - * Checks if a word is countable. - * - * @param string $word The string input. - * - * @return boolean True if word is countable, false otherwise. - * - * @since 1.0 + * Proxy for Inflector::ucwords() */ - public function isCountable($word) + public static function ucwords(string $string, string $delimiters = " \n\t\r\0\x0B-"): string { - return \in_array($word, self::$countable['rules']); + return ucwords($string, $delimiters); } /** - * Checks if a word is in a plural form. - * - * @param string $word The string input. - * - * @return boolean True if word is plural, false if not. - * - * @since 1.0 + * Empty method to suffice the former interface */ - public function isPlural($word) + public static function reset(): void { - return $this->toPlural($this->toSingular($word)) === $word; } /** - * Checks if a word is in a singular form. - * - * @param string $word The string input. - * - * @return boolean True if word is singular, false if not. - * - * @since 1.0 + * Empty method to suffice the former interface */ - public function isSingular($word) + public static function rules(string $type, iterable $rules, bool $reset = false): void { - return $this->toSingular($word) === $word; } /** - * Converts a word into its plural form. - * - * @param string $word The singular word to pluralise. - * - * @return string The word in plural form. - * - * @since 1.0 - * @deprecated 3.0 Use Doctrine\Common\Inflector\Inflector::pluralize() instead. + * Proxy for Inflector::pluralize() */ - public function toPlural($word) + public static function pluralize(string $word): string { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0, use %s::pluralize() instead.', - __METHOD__, - DoctrineInflector::class - ); + $inflector = InflectorFactory::create()->build(); - return static::pluralize($word); + return $inflector->pluralize($word); } /** - * Converts a word into its singular form. - * - * @param string $word The plural word to singularise. - * - * @return string The word in singular form. - * - * @since 1.0 - * @deprecated 3.0 Use Doctrine\Common\Inflector\Inflector::singularize() instead. + * Proxy for Inflector::singularize() */ - public function toSingular($word) + public static function singularize(string $word): string { - trigger_deprecation( - 'joomla/string', - '2.0.0', - '%s() is deprecated and will be removed in 3.0, use %s::singularize() instead.', - __METHOD__, - DoctrineInflector::class - ); + $inflector = InflectorFactory::create()->build(); - return static::singularize($word); + return $inflector->singularize($word); } } diff --git a/src/StringHelper.php b/src/StringHelper.php index 2b8a7d60..8f1a3c95 100644 --- a/src/StringHelper.php +++ b/src/StringHelper.php @@ -74,7 +74,7 @@ public static function increment($string, $style = 'default', $n = 0) // Check if we are incrementing an existing pattern, or appending a new one. if (preg_match($rxSearch, $string, $matches)) { - $n = empty($n) ? ($matches[1] + 1) : $n; + $n = empty($n) ? (1 + (int) $matches[1]) : $n; $string = preg_replace($rxReplace, sprintf($oldFormat, $n), $string); } else { $n = empty($n) ? 2 : $n; @@ -375,7 +375,7 @@ public static function strcasecmp($str1, $str2, $locale = false) } // Get current locale - $locale0 = setlocale(LC_COLLATE, 0); + $locale0 = setlocale(LC_COLLATE, null); if (!$locale = setlocale(LC_COLLATE, $locale)) { $locale = $locale0; @@ -421,7 +421,7 @@ public static function strcmp($str1, $str2, $locale = false) { if ($locale) { // Get current locale - $locale0 = setlocale(LC_COLLATE, 0); + $locale0 = setlocale(LC_COLLATE, null); if (!$locale = setlocale(LC_COLLATE, $locale)) { $locale = $locale0; @@ -462,9 +462,9 @@ public static function strcmp($str1, $str2, $locale = false) * @link https://www.php.net/strcspn * @since 1.3.0 */ - public static function strcspn($str, $mask, $start = null, $length = null) + public static function strcspn(string $str, string $mask, $start = null, $length = null) { - if (empty($mask) || strlen($mask) == 0) { + if (strlen($mask) == 0) { return 0; } @@ -535,15 +535,15 @@ public static function strrev($str) * @link https://www.php.net/strspn * @since 1.3.0 */ - public static function strspn($str, $mask, $start = null, $length = null) + public static function strspn(string $str, string $mask, ?int $start = null, ?int $length = null) { $mask = preg_replace('!([\\\\\\-\\]\\[/^])!', '\\\${1}', $mask); - if (is_int($start) && is_int($length)) { + if ($start && $length) { $str = mb_substr($str, $start, $length); - } elseif (is_int($start) && !is_int($length)) { + } elseif ($start) { $str = mb_substr($str, $start); - } elseif (!is_int($start) && is_int($length)) { + } elseif ($length) { trigger_error('\Joomla\String\StringHelper::strspn(): Passing null to parameter #3 ($start) of type int is deprecated', E_USER_DEPRECATED); $str = mb_substr($str, 0, $length); }