diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..3aa23717 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,62 @@ +build: false +platform: + - x64 +clone_folder: C:\projects\filesystem + +branches: + except: + - gh-pages + +## Build matrix for lowest and highest possible targets +environment: + PHPBuild: "x64" + VC: "vc15" + WINCACHE: "2.0.0.8" + matrix: + - php_ver_target: 5.3.10 + - php_ver_target: 5.3.29 + - php_ver_target: 5.4.45 + - php_ver_target: 7.0.33 + - php_ver_target: 7.1.33 + - php_ver_target: 7.2.34 + - php_ver_target: 7.3.33 + - php_ver_target: 7.4.27 + - php_ver_target: 8.0.15 + - php_ver_target: 8.1.2 + +init: + - SET PATH=C:\Program Files\OpenSSL;C:\tools\php;%PATH% + - SET COMPOSER_NO_INTERACTION=1 + - SET PHP=1 # This var relates to caching the php install + - SET ANSICON=121x90 (121x90) + +## Install PHP and composer, and run the appropriate composer command +install: + - IF EXIST C:\tools\php (SET PHP=0) + - ps: >- + If ($env:PHP -eq "1") { + appveyor-retry cinst php --version=$env:php_ver_target --package-parameters='""/InstallDir:C:\tools\php""' --ignore-checksums -y --no-progress --limit-output + } + - cd C:\tools\php + - IF %PHP%==1 copy php.ini-production php.ini /Y + - IF %PHP%==1 echo date.timezone="UTC" >> php.ini + - IF %PHP%==1 echo extension_dir=ext >> php.ini + - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini + - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini + - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini + - IF %PHP%==1 echo extension=php_ftp.dll >> php.ini + - IF %PHP%==1 echo extension=php_gd2.dll >> php.ini + - IF %PHP%==1 echo extension=php_gmp.dll >> php.ini + - IF %PHP%==1 echo extension=php_pgsql.dll >> php.ini + - IF %PHP%==1 echo extension=php_curl.dll >> php.ini + - IF %PHP%==1 echo zend_extension=php_opcache.dll >> php.ini + - IF %PHP%==1 echo opcache.enable_cli=1 >> php.ini + - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat + - IF %PHP%==1 php -r "readfile('http://getcomposer.org/installer');" | php + - cd C:\projects\filesystem + - IF NOT %php_ver_target%=="8.0.0" composer update --prefer-stable --no-progress + - IF %php_ver_target%=="8.0.0" composer update --prefer-stable --no-progress --ignore-platform-req=php + +test_script: + - cd C:\projects\filesystem + - vendor\bin\phpunit diff --git a/.drone.jsonnet b/.drone.jsonnet index 849dac07..7a122183 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -18,7 +18,6 @@ local composer(phpversion, params) = { volumes: volumes, commands: [ "php -v", - "composer --version", "composer update " + params, ] }; @@ -26,7 +25,6 @@ local composer(phpversion, params) = { local phpunit(phpversion) = { name: "PHPUnit", image: "joomlaprojects/docker-images:php" + phpversion, - [if phpversion == "8.0" then "failure"]: "ignore", commands: ["vendor/bin/phpunit"] }; @@ -52,17 +50,27 @@ local pipeline(name, phpversion, params) = { volumes: volumes, commands: [ "php -v", - "composer update", + "composer update --prefer-stable", "composer require phpmd/phpmd phpstan/phpstan" ] }, { - name: "phpcs", + name: "phpcs (loose)", image: "joomlaprojects/docker-images:php7.4", depends: [ "composer" ], commands: [ "vendor/bin/phpcs --config-set installed_paths vendor/joomla/coding-standards", - "vendor/bin/phpcs -p --report=full --extensions=php --standard=ruleset.xml src/" + "vendor/bin/phpcs -p --report=full --extensions=php --standard=ruleset.xml src/Inflector.php src/Normalise.php src/String.php src/StringHelper.php" + ] + }, + { + name: "phpcs (strict)", + image: "joomlaprojects/docker-images:php7.4", + depends: [ "composer" ], + failure: "ignore", + commands: [ + "vendor/bin/phpcs --config-set installed_paths vendor/joomla/coding-standards", + "vendor/bin/phpcs -p --report=full --extensions=php --standard=Joomla src/Inflector.php src/Normalise.php src/String.php src/StringHelper.php" ] }, { @@ -126,13 +134,12 @@ local pipeline(name, phpversion, params) = { ] }, pipeline("5.3", "5.3", "--prefer-stable"), - pipeline("5.4", "5.4", "--prefer-stable"), - pipeline("5.5", "5.5", "--prefer-stable"), pipeline("5.6", "5.6", "--prefer-stable"), pipeline("7.0", "7.0", "--prefer-stable"), pipeline("7.1", "7.1", "--prefer-stable"), pipeline("7.2", "7.2", "--prefer-stable"), pipeline("7.3", "7.3", "--prefer-stable"), pipeline("7.4", "7.4", "--prefer-stable"), - pipeline("8.0", "8.0", "--ignore-platform-reqs --prefer-stable") + pipeline("8.0", "8.0", "--prefer-stable"), + pipeline("8.1", "8.1", "--prefer-stable") ] diff --git a/.drone.yml b/.drone.yml index 0a0c59c6..6075525f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,17 +11,24 @@ steps: image: joomlaprojects/docker-images:php7.4 commands: - php -v - - composer update + - composer update --prefer-stable - composer require phpmd/phpmd phpstan/phpstan volumes: - name: composer-cache path: /tmp/composer-cache -- name: phpcs +- name: phpcs (loose) + image: joomlaprojects/docker-images:php7.4 + commands: + - vendor/bin/phpcs --config-set installed_paths vendor/joomla/coding-standards + - vendor/bin/phpcs -p --report=full --extensions=php --standard=ruleset.xml src/Inflector.php src/Normalise.php src/String.php src/StringHelper.php + +- name: phpcs (strict) image: joomlaprojects/docker-images:php7.4 commands: - vendor/bin/phpcs --config-set installed_paths vendor/joomla/coding-standards - - vendor/bin/phpcs -p --report=full --extensions=php --standard=ruleset.xml src/ + - vendor/bin/phpcs -p --report=full --extensions=php --standard=Joomla src/Inflector.php src/Normalise.php src/String.php src/StringHelper.php + failure: ignore - name: phpmd image: joomlaprojects/docker-images:php7.4 @@ -98,7 +105,6 @@ steps: image: joomlaprojects/docker-images:php5.3 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache @@ -116,7 +122,7 @@ volumes: --- kind: pipeline -name: PHP 5.4 +name: PHP 5.6 platform: os: linux @@ -124,17 +130,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php5.4 + image: joomlaprojects/docker-images:php5.6 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php5.4 + image: joomlaprojects/docker-images:php5.6 commands: - vendor/bin/phpunit @@ -145,7 +150,7 @@ volumes: --- kind: pipeline -name: PHP 5.5 +name: PHP 7.0 platform: os: linux @@ -153,17 +158,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php5.5 + image: joomlaprojects/docker-images:php7.0 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php5.5 + image: joomlaprojects/docker-images:php7.0 commands: - vendor/bin/phpunit @@ -174,7 +178,7 @@ volumes: --- kind: pipeline -name: PHP 5.6 +name: PHP 7.1 platform: os: linux @@ -182,17 +186,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php5.6 + image: joomlaprojects/docker-images:php7.1 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php5.6 + image: joomlaprojects/docker-images:php7.1 commands: - vendor/bin/phpunit @@ -203,7 +206,7 @@ volumes: --- kind: pipeline -name: PHP 7.0 +name: PHP 7.2 platform: os: linux @@ -211,17 +214,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php7.0 + image: joomlaprojects/docker-images:php7.2 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php7.0 + image: joomlaprojects/docker-images:php7.2 commands: - vendor/bin/phpunit @@ -232,7 +234,7 @@ volumes: --- kind: pipeline -name: PHP 7.1 +name: PHP 7.3 platform: os: linux @@ -240,17 +242,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php7.1 + image: joomlaprojects/docker-images:php7.3 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php7.1 + image: joomlaprojects/docker-images:php7.3 commands: - vendor/bin/phpunit @@ -261,7 +262,7 @@ volumes: --- kind: pipeline -name: PHP 7.2 +name: PHP 7.4 platform: os: linux @@ -269,17 +270,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php7.2 + image: joomlaprojects/docker-images:php7.4 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php7.2 + image: joomlaprojects/docker-images:php7.4 commands: - vendor/bin/phpunit @@ -290,7 +290,7 @@ volumes: --- kind: pipeline -name: PHP 7.3 +name: PHP 8.0 platform: os: linux @@ -298,17 +298,16 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php7.3 + image: joomlaprojects/docker-images:php8.0 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php7.3 + image: joomlaprojects/docker-images:php8.0 commands: - vendor/bin/phpunit @@ -319,7 +318,7 @@ volumes: --- kind: pipeline -name: PHP 7.4 +name: PHP 8.1 platform: os: linux @@ -327,49 +326,18 @@ platform: steps: - name: composer - image: joomlaprojects/docker-images:php7.4 + image: joomlaprojects/docker-images:php8.1 commands: - php -v - - composer --version - composer update --prefer-stable volumes: - name: composer-cache path: /tmp/composer-cache - name: PHPUnit - image: joomlaprojects/docker-images:php7.4 - commands: - - vendor/bin/phpunit - -volumes: -- name: composer-cache - host: - path: /tmp/composer-cache - ---- -kind: pipeline -name: PHP 8.0 - -platform: - os: linux - arch: amd64 - -steps: -- name: composer - image: joomlaprojects/docker-images:php8.0 - commands: - - php -v - - composer --version - - composer update --ignore-platform-reqs --prefer-stable - volumes: - - name: composer-cache - path: /tmp/composer-cache - -- name: PHPUnit - image: joomlaprojects/docker-images:php8.0 + image: joomlaprojects/docker-images:php8.1 commands: - vendor/bin/phpunit - failure: ignore volumes: - name: composer-cache @@ -378,6 +346,6 @@ volumes: --- kind: signature -hmac: b33ff1875a669dbf7ce59daaab139a1c7c46ecb03f9e03790046649bf39c44f5 +hmac: 4ea7263b0fb1627bb70e35ea29bd159eba3ac029b0ba18e7d3567f818457988b ... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..965065e3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# Unix-style newlines with a newline ending every file +[*] +indent_style=tab +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +insert_final_newline=true diff --git a/.gitattributes b/.gitattributes index bfb8d891..54dbb6e8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,12 @@ +.github/ export-ignore +docs/ export-ignore +Tests/ export-ignore +tests/ export-ignore +.appveyor.yml export-ignore +.drone.jsonnet export-ignore +.drone.yml export-ignore +.editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore -.gitmodules export-ignore -.travis/ export-ignore -.travis.yml export-ignore +phpunit.xml.dist export-ignore +ruleset.xml export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 368ba80a..e026a0cc 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,3 +1,3 @@ # Contributing to the Joomla! Framework -Please review [http://framework.joomla.org/contribute](http://framework.joomla.org/contribute) for information on how to contribute to the Framework's development. +Please review [https://framework.joomla.org/contribute](https://framework.joomla.org/contribute) for information on how to contribute to the Framework's development. diff --git a/.gitignore b/.gitignore index f432fce7..76367ee5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ vendor/ -composer.phar composer.lock phpunit.xml -.idea/ +.phpunit.result.cache diff --git a/.mono b/.mono new file mode 100644 index 00000000..da8b9b84 --- /dev/null +++ b/.mono @@ -0,0 +1 @@ +src="src/Inflector.php src/Normalise.php src/String.php src/StringHelper.php" diff --git a/Tests/InflectorTest.php b/Tests/php53/InflectorTest.php similarity index 99% rename from Tests/InflectorTest.php rename to Tests/php53/InflectorTest.php index 89850852..16f597f6 100644 --- a/Tests/InflectorTest.php +++ b/Tests/php53/InflectorTest.php @@ -4,7 +4,7 @@ * @license GNU General Public License version 2 or later; see LICENSE */ -namespace Joomla\String\Tests; +namespace Joomla\String\Tests\php53; use Joomla\String\Inflector; use Joomla\Test\TestHelper; diff --git a/Tests/NormaliseTest.php b/Tests/php53/NormaliseTest.php similarity index 99% rename from Tests/NormaliseTest.php rename to Tests/php53/NormaliseTest.php index 19aa51ef..940e6be9 100644 --- a/Tests/NormaliseTest.php +++ b/Tests/php53/NormaliseTest.php @@ -4,7 +4,7 @@ * @license GNU General Public License version 2 or later; see LICENSE */ -namespace Joomla\String\Tests; +namespace Joomla\String\Tests\php53; use Joomla\String\Normalise; use PHPUnit\Framework\TestCase; diff --git a/Tests/StringHelperTest.php b/Tests/php53/StringHelperTest.php similarity index 99% rename from Tests/StringHelperTest.php rename to Tests/php53/StringHelperTest.php index c5e1300a..5aead739 100644 --- a/Tests/StringHelperTest.php +++ b/Tests/php53/StringHelperTest.php @@ -4,7 +4,7 @@ * @license GNU General Public License version 2 or later; see LICENSE */ -namespace Joomla\String\Tests; +namespace Joomla\String\Tests\php53; use Joomla\String\StringHelper; use PHPUnit\Framework\TestCase; diff --git a/Tests/php71/InflectorTest.php b/Tests/php71/InflectorTest.php new file mode 100644 index 00000000..d4f420f9 --- /dev/null +++ b/Tests/php71/InflectorTest.php @@ -0,0 +1,576 @@ +inflector = Inflector::getInstance(true); + } + + /** + * Method to test Inflector::addRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::addRule + * @since 1.0 + */ + public function testAddRule() + { + // Case 1 + TestHelper::invoke($this->inflector, 'addRule', '/foo/', 'singular'); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + '/foo/', + $rules['singular'], + 'Checks if the singular rule was added correctly.' + ); + + // Case 2 + TestHelper::invoke($this->inflector, 'addRule', '/bar/', 'plural'); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + '/bar/', + $rules['plural'], + 'Checks if the plural rule was added correctly.' + ); + + // Case 3 + TestHelper::invoke($this->inflector, 'addRule', array('/goo/', '/car/'), 'singular'); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + '/goo/', + $rules['singular'], + 'Checks if an array of rules was added correctly (1).' + ); + + $this->assertContains( + '/car/', + $rules['singular'], + 'Checks if an array of rules was added correctly (2).' + ); + } + + /** + * Method to test Inflector::addRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::addRule + * + * @since 1.0 + */ + public function testAddRuleException() + { + $this->expectException(\InvalidArgumentException::class); + TestHelper::invoke($this->inflector, 'addRule', new \stdClass, 'singular'); + } + + /** + * Method to test Inflector::getCachedPlural(). + * + * @return void + * + * @covers Joomla\String\Inflector::getCachedPlural + * @since 1.0 + */ + public function testGetCachedPlural() + { + // Reset the cache. + TestHelper::setValue($this->inflector, 'cache', array('foo' => 'bar')); + + $this->assertFalse( + TestHelper::invoke($this->inflector, 'getCachedPlural', 'bar'), + 'Checks for an uncached plural.' + ); + + $this->assertEquals( + 'bar', + TestHelper::invoke($this->inflector, 'getCachedPlural', 'foo'), + 'Checks for a cached plural word.' + ); + } + + /** + * Method to test Inflector::getCachedSingular(). + * + * @return void + * + * @covers Joomla\String\Inflector::getCachedSingular + * @since 1.0 + */ + public function testGetCachedSingular() + { + // Reset the cache. + TestHelper::setValue($this->inflector, 'cache', array('foo' => 'bar')); + + $this->assertFalse( + TestHelper::invoke($this->inflector, 'getCachedSingular', 'foo'), + 'Checks for an uncached singular.' + ); + + $this->assertThat( + TestHelper::invoke($this->inflector, 'getCachedSingular', 'bar'), + $this->equalTo('foo'), + 'Checks for a cached singular word.' + ); + } + + /** + * Method to test Inflector::matchRegexRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::matchRegexRule + * @since 1.0 + */ + public function testMatchRegexRule() + { + $this->assertThat( + TestHelper::invoke($this->inflector, 'matchRegexRule', 'xyz', 'plural'), + $this->equalTo('xyzs'), + 'Checks pluralising against the basic regex.' + ); + + $this->assertThat( + TestHelper::invoke($this->inflector, 'matchRegexRule', 'xyzs', 'singular'), + $this->equalTo('xyz'), + 'Checks singularising against the basic regex.' + ); + + $this->assertFalse( + TestHelper::invoke($this->inflector, 'matchRegexRule', 'xyz', 'singular'), + 'Checks singularising against an unmatched regex.' + ); + } + + /** + * Method to test Inflector::setCache(). + * + * @return void + * + * @covers Joomla\String\Inflector::setCache + * @since 1.0 + */ + public function testSetCache() + { + TestHelper::invoke($this->inflector, 'setCache', 'foo', 'bar'); + + $cache = TestHelper::getValue($this->inflector, 'cache'); + + $this->assertThat( + $cache['foo'], + $this->equalTo('bar'), + 'Checks the cache was set.' + ); + + TestHelper::invoke($this->inflector, 'setCache', 'foo', 'car'); + + $cache = TestHelper::getValue($this->inflector, 'cache'); + + $this->assertThat( + $cache['foo'], + $this->equalTo('car'), + 'Checks an existing value in the cache was reset.' + ); + } + + /** + * Method to test Inflector::addCountableRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::addCountableRule + * @since 1.0 + */ + public function testAddCountableRule() + { + // Add string. + $this->inflector->addCountableRule('foo'); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + 'foo', + $rules['countable'], + 'Checks a countable rule was added.' + ); + + // Add array. + $this->inflector->addCountableRule(array('goo', 'car')); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + 'car', + $rules['countable'], + 'Checks a countable rule was added by array.' + ); + } + + /** + * Method to test Inflector::addWord(). + * + * @return void + * + * @covers Joomla\String\Inflector::addWord + * @since 1.2.0 + */ + public function testAddWord() + { + $this->assertEquals( + $this->inflector, + $this->inflector->addWord('foo') + ); + + $cache = TestHelper::getValue($this->inflector, 'cache'); + + $this->assertArrayHasKey('foo', $cache); + + $this->assertEquals( + 'foo', + $cache['foo'] + ); + + $this->assertEquals( + $this->inflector, + $this->inflector->addWord('bar', 'foo') + ); + + $cache = TestHelper::getValue($this->inflector, 'cache'); + + $this->assertArrayHasKey('bar', $cache); + + $this->assertEquals( + 'foo', + $cache['bar'] + ); + } + + /** + * Method to test Inflector::addPluraliseRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::addPluraliseRule + * @since 1.0 + */ + public function testAddPluraliseRule() + { + $chain = $this->inflector->addPluraliseRule(array('/foo/', '/bar/')); + + $this->assertThat( + $chain, + $this->identicalTo($this->inflector), + 'Checks chaining.' + ); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertCOntains( + '/bar/', + $rules['plural'], + 'Checks a pluralisation rule was added.' + ); + } + + /** + * Method to test Inflector::addSingulariseRule(). + * + * @return void + * + * @covers Joomla\String\Inflector::addSingulariseRule + * @since 1.0 + */ + public function testAddSingulariseRule() + { + $chain = $this->inflector->addSingulariseRule(array('/foo/', '/bar/')); + + $this->assertThat( + $chain, + $this->identicalTo($this->inflector), + 'Checks chaining.' + ); + + $rules = TestHelper::getValue($this->inflector, 'rules'); + + $this->assertContains( + '/bar/', + $rules['singular'], + 'Checks a singularisation rule was added.' + ); + } + + /** + * Method to test Inflector::getInstance(). + * + * @return void + * + * @covers Joomla\String\Inflector::getInstance + * @since 1.0 + */ + public function testGetInstance() + { + $this->assertInstanceOf( + \Joomla\String\Inflector::class, + Inflector::getInstance(), + 'Check getInstance returns the right class.' + ); + + // Inject an instance an test. + TestHelper::setValue($this->inflector, 'instance', new \stdClass); + + $this->assertThat( + Inflector::getInstance(), + $this->equalTo(new \stdClass), + 'Checks singleton instance is returned.' + ); + + $this->assertInstanceOf( + \Joomla\String\Inflector::class, + Inflector::getInstance(true), + 'Check getInstance a fresh object with true argument even though the instance is set to something else.' + ); + } + + /** + * Method to test Inflector::isCountable(). + * + * @param string $input A string. + * @param boolean $expected The expected result of the function call. + * + * @return void + * + * @covers Joomla\String\Inflector::isCountable + * @dataProvider seedIsCountable + * @since 1.0 + */ + public function testIsCountable($input, $expected) + { + $this->assertThat( + $this->inflector->isCountable($input), + $this->equalTo($expected) + ); + } + + /** + * Method to test Inflector::isPlural(). + * + * @param string $singular The singular form of a word. + * @param string $plural The plural form of a word. + * + * @return void + * + * @covers Joomla\String\Inflector::isPlural + * @dataProvider seedSinglePlural + * @since 1.0 + */ + public function testIsPlural($singular, $plural) + { + $this->assertTrue( + $this->inflector->isPlural($plural), + 'Checks the plural is a plural.' + ); + + if ($singular != $plural) + { + $this->assertFalse( + $this->inflector->isPlural($singular), + 'Checks the singular is not plural.' + ); + } + } + + /** + * Method to test Inflector::isSingular(). + * + * @param string $singular The singular form of a word. + * @param string $plural The plural form of a word. + * + * @return void + * + * @covers Joomla\String\Inflector::isSingular + * @dataProvider seedSinglePlural + * @since 1.0 + */ + public function testIsSingular($singular, $plural) + { + $this->assertTrue( + $this->inflector->isSingular($singular), + 'Checks the singular is a singular.' + ); + + if ($singular != $plural) + { + $this->assertFalse( + $this->inflector->isSingular($plural), + 'Checks the plural is not singular.' + ); + } + } + + /** + * Method to test Inflector::toPlural(). + * + * @param string $singular The singular form of a word. + * @param string $plural The plural form of a word. + * + * @return void + * + * @covers Joomla\String\Inflector::toPlural + * @dataProvider seedSinglePlural + * @since 1.0 + */ + public function testToPlural($singular, $plural) + { + $this->assertThat( + $this->inflector->toPlural($singular), + $this->equalTo($plural) + ); + } + + /** + * Method to test Inflector::toPlural(). + * + * @return void + * + * @covers Joomla\String\Inflector::toPlural + * @since 1.2.0 + */ + public function testToPluralAlreadyPlural() + { + $this->assertFalse($this->inflector->toPlural('buses')); + } + + /** + * Method to test Inflector::toPlural(). + * + * @param string $singular The singular form of a word. + * @param string $plural The plural form of a word. + * + * @return void + * + * @covers Joomla\String\Inflector::toSingular + * @dataProvider seedSinglePlural + * @since 1.0 + */ + public function testToSingular($singular, $plural) + { + $this->assertThat( + $this->inflector->toSingular($plural), + $this->equalTo($singular) + ); + } + + /** + * Method to test Inflector::toPlural(). + * + * @return void + * + * @covers Joomla\String\Inflector::toSingular + * @since 1.2.0 + */ + public function testToSingularRetFalse() + { + // Assertion for already singular + $this->assertFalse($this->inflector->toSingular('bus')); + + $this->assertFalse($this->inflector->toSingular('foo')); + } +} diff --git a/Tests/php71/NormaliseTest.php b/Tests/php71/NormaliseTest.php new file mode 100644 index 00000000..2459b0e9 --- /dev/null +++ b/Tests/php71/NormaliseTest.php @@ -0,0 +1,316 @@ +assertEquals($expected, Normalise::fromCamelcase($input)); + } + + /** + * Method to test Normalise::fromCamelCase(string, true). + * + * @param string $input The input value for the method. + * @param string $expected The expected value from the method. + * + * @return void + * + * @covers Joomla\String\Normalise::fromCamelcase + * @dataProvider seedTestFromCamelCase + * @since 1.0 + */ + public function testFromCamelCase_grouped($input, $expected) + { + $this->assertEquals($expected, Normalise::fromCamelcase($input, true)); + } + + /** + * Method to test Normalise::toCamelCase(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toCamelcase + * @dataProvider seedTestToCamelCase + * @since 1.0 + */ + public function testToCamelCase($expected, $input) + { + $this->assertEquals($expected, Normalise::toCamelcase($input)); + } + + /** + * Method to test Normalise::toDashSeparated(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toDashSeparated + * @dataProvider seedTestToDashSeparated + * @since 1.0 + */ + public function testToDashSeparated($expected, $input) + { + $this->assertEquals($expected, Normalise::toDashSeparated($input)); + } + + /** + * Method to test Normalise::toSpaceSeparated(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toSpaceSeparated + * @dataProvider seedTestToSpaceSeparated + * @since 1.0 + */ + public function testToSpaceSeparated($expected, $input) + { + $this->assertEquals($expected, Normalise::toSpaceSeparated($input)); + } + + /** + * Method to test Normalise::toUnderscoreSeparated(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toUnderscoreSeparated + * @dataProvider seedTestToUnderscoreSeparated + * @since 1.0 + */ + public function testToUnderscoreSeparated($expected, $input) + { + $this->assertEquals($expected, Normalise::toUnderscoreSeparated($input)); + } + + /** + * Method to test Normalise::toVariable(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toVariable + * @dataProvider seedTestToVariable + * @since 1.0 + */ + public function testToVariable($expected, $input) + { + $this->assertEquals($expected, Normalise::toVariable($input)); + } + + /** + * Method to test Normalise::toKey(). + * + * @param string $expected The expected value from the method. + * @param string $input The input value for the method. + * + * @return void + * + * @covers Joomla\String\Normalise::toKey + * @dataProvider seedTestToKey + * @since 1.0 + */ + public function testToKey($expected, $input) + { + $this->assertEquals($expected, Normalise::toKey($input)); + } +} diff --git a/Tests/php71/StringHelperTest.php b/Tests/php71/StringHelperTest.php new file mode 100644 index 00000000..ccff8d2c --- /dev/null +++ b/Tests/php71/StringHelperTest.php @@ -0,0 +1,1090 @@ + array('title', null, 0, 'title (2)'), + 'Second default increment' => array('title(2)', null, 0, 'title(3)'), + 'First dash increment' => array('title', 'dash', 0, 'title-2'), + 'Second dash increment' => array('title-2', 'dash', 0, 'title-3'), + 'Set default increment' => array('title', null, 4, 'title (4)'), + 'Unknown style fallback to default' => array('title', 'foo', 0, 'title (2)'), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.2.0 + */ + public function seedTestIs_ascii() + { + return array( + array('ascii', true), + array('1024', true), + array('#$#@$%', true), + array('áÑ', false), + array('ÿ©', false), + array('¡¾', false), + array('÷™', false), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrpos() + { + return array( + array(3, 'missing', 'sing', 0), + array(false, 'missing', 'sting', 0), + array(4, 'missing', 'ing', 0), + array(10, ' объектов на карте с', 'на карте', 0), + array(0, 'на карте с', 'на карте', 0, 0), + array(false, 'на карте с', 'на каррте', 0), + array(false, 'на карте с', 'на карте', 2), + array(3, 'missing', 'sing', false) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestGetStrrpos() + { + return array( + array(3, 'missing', 'sing', 0), + array(false, 'missing', 'sting', 0), + array(4, 'missing', 'ing', 0), + array(10, ' объектов на карте с', 'на карте', 0), + array(0, 'на карте с', 'на карте', 0), + array(false, 'на карте с', 'на каррте', 0), + array(3, 'на карте с', 'карт', 2) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestSubstr() + { + return array( + array('issauga', 'Mississauga', 4, false), + array('на карте с', ' объектов на карте с', 10, false), + array('на ка', ' объектов на карте с', 10, 5), + array('те с', ' объектов на карте с', -4, false), + array(false, ' объектов на карте с', 99, false) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrtolower() + { + return array( + array('Joomla! Rocks', 'joomla! rocks') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrtoupper() + { + return array( + array('Joomla! Rocks', 'JOOMLA! ROCKS') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrlen() + { + return array( + array('Joomla! Rocks', 13) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStr_ireplace() + { + return array( + array('Pig', 'cow', 'the pig jumped', false, 'the cow jumped'), + array('Pig', 'cow', 'the pig jumped', true, 'the cow jumped'), + array('Pig', 'cow', 'the pig jumped over the cow', true, 'the cow jumped over the cow'), + array(array('PIG', 'JUMPED'), array('cow', 'hopped'), 'the pig jumped over the pig', true, 'the cow hopped over the cow'), + array('шил', 'биш', 'Би шил идэй чадна', true, 'Би биш идэй чадна'), + array('/', ':', '/test/slashes/', true, ':test:slashes:'), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStr_split() + { + return array( + array('string', 1, array('s', 't', 'r', 'i', 'n', 'g')), + array('string', 2, array('st', 'ri', 'ng')), + array('волн', 3, array('вол', 'н')), + array('волн', 1, array('в', 'о', 'л', 'н')) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrcasecmp() + { + return array( + array('THIS IS STRING1', 'this is string1', false, 0), + array('this is string1', 'this is string2', false, -1), + array('this is string2', 'this is string1', false, 1), + array('бгдпт', 'бгдпт', false, 0), + array('àbc', 'abc', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), + array('àbc', 'bcd', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('é', 'è', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('É', 'é', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 0), + array('œ', 'p', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('œ', 'n', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrcmp() + { + return array( + array('THIS IS STRING1', 'this is string1', false, -1), + array('this is string1', 'this is string2', false, -1), + array('this is string2', 'this is string1', false, 1), + array('a', 'B', false, 1), + array('A', 'b', false, -1), + array('Àbc', 'abc', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), + array('Àbc', 'bcd', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('É', 'è', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('é', 'È', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('Œ', 'p', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + array('Œ', 'n', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), + array('œ', 'N', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), + array('œ', 'P', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrcspn() + { + return array( + array('subject string ', '<>', false, false, 8), + array('Би шил {123} идэй {456} чадна', '}{', null, false, 7), + array('Би шил {123} идэй {456} чадна', '}{', 13, 10, 5) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStristr() + { + return array( + array('haystack', 'needle', false), + array('before match, after match', 'match', 'match, after match'), + array('Би шил идэй чадна', 'шил', 'шил идэй чадна') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrrev() + { + return array( + array('abc def', 'fed cba'), + array('Би шил', 'лиш иБ') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestStrspn() + { + return array( + array('A321 Main Street', '0123456789', 1, 2, 2), + array('321 Main Street', '0123456789', null, 2, 2), + array('A321 Main Street', '0123456789', null, 10, 0), + array('321 Main Street', '0123456789', null, null, 3), + array('Main Street 321', '0123456789', null, -3, 0), + array('321 Main Street', '0123456789', null, -13, 2), + array('321 Main Street', '0123456789', null, -12, 3), + array('A321 Main Street', '0123456789', 0, null, 0), + array('A321 Main Street', '0123456789', 1, 10, 3), + array('A321 Main Street', '0123456789', 1, null, 3), + array('Би шил идэй чадна', 'Би', null, null, 2), + array('чадна Би шил идэй чадна', 'Би', null, null, 0) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestSubstr_replace() + { + return array( + array('321 Broadway Avenue', '321 Main Street', 'Broadway Avenue', 4, false), + array('321 Broadway Street', '321 Main Street', 'Broadway', 4, 4), + array('чадна 我能吞', 'чадна Би шил идэй чадна', '我能吞', 6, false), + array('чадна 我能吞 шил идэй чадна', 'чадна Би шил идэй чадна', '我能吞', 6, 2) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestLtrim() + { + return array( + array(' abc def', null, 'abc def'), + array(' abc def', '', ' abc def'), + array(' Би шил', null, 'Би шил'), + array("\t\n\r\x0BБи шил", null, 'Би шил'), + array("\x0B\t\n\rБи шил", "\t\n\x0B", "\rБи шил"), + array("\x09Би шил\x0A", "\x09\x0A", "Би шил\x0A"), + array('1234abc', '0123456789', 'abc') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestRtrim() + { + return array( + array('abc def ', null, 'abc def'), + array('abc def ', '', 'abc def '), + array('Би шил ', null, 'Би шил'), + array("Би шил\t\n\r\x0B", null, 'Би шил'), + array("Би шил\r\x0B\t\n", "\t\n\x0B", "Би шил\r"), + array("\x09Би шил\x0A", "\x09\x0A", "\x09Би шил"), + array('1234abc', 'abc', '1234') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestTrim() + { + return array( + array(' abc def ', null, 'abc def'), + array(' abc def ', '', ' abc def '), + array(' Би шил ', null, 'Би шил'), + array("\t\n\r\x0BБи шил\t\n\r\x0B", null, 'Би шил'), + array("\x0B\t\n\rБи шил\r\x0B\t\n", "\t\n\x0B", "\rБи шил\r"), + array("\x09Би шил\x0A", "\x09\x0A", "Би шил"), + array('1234abc56789', '0123456789', 'abc') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestUcfirst() + { + return array( + array('george', null, null, 'George'), + array('мога', null, null, 'Мога'), + array('ψυχοφθόρα', null, null, 'Ψυχοφθόρα'), + array('dr jekill and mister hyde', ' ', null, 'Dr Jekill And Mister Hyde'), + array('dr jekill and mister hyde', ' ', '_', 'Dr_Jekill_And_Mister_Hyde'), + array('dr jekill and mister hyde', ' ', '', 'DrJekillAndMisterHyde'), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestUcwords() + { + return array( + array('george washington', 'George Washington'), + array("george\r\nwashington", "George\r\nWashington"), + array('мога', 'Мога'), + array('αβγ δεζ', 'Αβγ Δεζ'), + array('åbc öde', 'Åbc Öde') + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestTranscode() + { + return array( + array('Åbc Öde €100', 'UTF-8', 'ISO-8859-1', "\xc5bc \xd6de EUR100"), + array(array('Åbc Öde €100'), 'UTF-8', 'ISO-8859-1', null), + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.0 + */ + public function seedTestValid() + { + return array( + array("\xCF\xB0", true), + array("\xFBa", false), + array("\xFDa", false), + array("foo\xF7bar", false), + array('george Мога Ž Ψυχοφθόρα ฉันกินกระจกได้ 我能吞下玻璃而不伤身体 ', true), + array("\xFF ABC", false), + array("0xfffd ABC", true), + array('', true) + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.2.0 + */ + public function seedTestUnicodeToUtf8() + { + return array( + array("\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"), + array("\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung") + ); + } + + /** + * Test... + * + * @return array + * + * @since 1.2.0 + */ + public function seedTestUnicodeToUtf16() + { + return array( + array("\u0422\u0435\u0441\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u044b", "Тест системы"), + array("\u00dcberpr\u00fcfung der Systemumstellung", "Überprüfung der Systemumstellung") + ); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $style @todo + * @param string $number @todo + * @param string $expected @todo + * + * @return void + * + * @covers Joomla\String\StringHelper::increment + * @dataProvider seedTestIncrement + * @since 1.0 + */ + public function testIncrement($string, $style, $number, $expected) + { + $this->assertEquals( + $expected, + StringHelper::increment($string, $style, $number) + ); + } + + /** + * Test... + * + * @param string $string @todo + * @param boolean $expected @todo + * + * @return void + * + * @covers Joomla\String\StringHelper::is_ascii + * @dataProvider seedTestIs_ascii + * @since 1.2.0 + */ + public function testIs_ascii($string, $expected) + { + $this->assertEquals( + $expected, + StringHelper::is_ascii($string) + ); + } + + /** + * Test... + * + * @param string $expect @todo + * @param string $haystack @todo + * @param string $needle @todo + * @param integer $offset @todo + * + * @return void + * + * @covers Joomla\String\StringHelper::strpos + * @dataProvider seedTestStrpos + * @since 1.0 + */ + public function testStrpos($expect, $haystack, $needle, $offset = 0) + { + $actual = StringHelper::strpos($haystack, $needle, $offset); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $expect @todo + * @param string $haystack @todo + * @param string $needle @todo + * @param integer $offset @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strrpos + * @dataProvider seedTestGetStrrpos + * @since 1.0 + */ + public function testStrrpos($expect, $haystack, $needle, $offset = 0) + { + $actual = StringHelper::strrpos($haystack, $needle, $offset); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $expect @todo + * @param string $string @todo + * @param string $start @todo + * @param bool|int $length @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::substr + * @dataProvider seedTestSubstr + * @since 1.0 + */ + public function testSubstr($expect, $string, $start, $length = false) + { + $actual = StringHelper::substr($string, $start, $length); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strtolower + * @dataProvider seedTestStrtolower + * @since 1.0 + */ + public function testStrtolower($string, $expect) + { + $actual = StringHelper::strtolower($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strtoupper + * @dataProvider seedTestStrtoupper + * @since 1.0 + */ + public function testStrtoupper($string, $expect) + { + $actual = StringHelper::strtoupper($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strlen + * @dataProvider seedTestStrlen + * @since 1.0 + */ + public function testStrlen($string, $expect) + { + $actual = StringHelper::strlen($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $search @todo + * @param string $replace @todo + * @param string $subject @todo + * @param integer $count @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::str_ireplace + * @dataProvider seedTestStr_ireplace + * @since 1.0 + */ + public function testStr_ireplace($search, $replace, $subject, $count, $expect) + { + $actual = StringHelper::str_ireplace($search, $replace, $subject, $count); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $split_length @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::str_split + * @dataProvider seedTestStr_split + * @since 1.0 + */ + public function testStr_split($string, $split_length, $expect) + { + $actual = StringHelper::str_split($string, $split_length); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string1 @todo + * @param string $string2 @todo + * @param string $locale @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strcasecmp + * @dataProvider seedTestStrcasecmp + * @since 1.0 + */ + public function testStrcasecmp($string1, $string2, $locale, $expect) + { + // Convert the $locale param to a string if it is an array + if (\is_array($locale)) + { + $locale = "'" . implode("', '", $locale) . "'"; + } + + if (substr(php_uname(), 0, 6) == 'Darwin' && $locale != false) + { + $this->markTestSkipped('Darwin bug prevents foreign conversion from working properly'); + } + elseif ($locale != false && !setlocale(LC_COLLATE, $locale)) + { + $this->markTestSkipped("Locale {$locale} is not available."); + } + else + { + $actual = StringHelper::strcasecmp($string1, $string2, $locale); + + if ($actual != 0) + { + $actual = $actual / abs($actual); + } + + $this->assertEquals($expect, $actual); + } + } + + /** + * Test... + * + * @param string $string1 @todo + * @param string $string2 @todo + * @param string $locale @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strcmp + * @dataProvider seedTestStrcmp + * @since 1.0 + */ + public function testStrcmp($string1, $string2, $locale, $expect) + { + // Convert the $locale param to a string if it is an array + if (\is_array($locale)) + { + $locale = "'" . implode("', '", $locale) . "'"; + } + + if (substr(php_uname(), 0, 6) == 'Darwin' && $locale != false) + { + $this->markTestSkipped('Darwin bug prevents foreign conversion from working properly'); + } + elseif ($locale != false && !setlocale(LC_COLLATE, $locale)) + { + // If the locale is not available, we can't have to transcode the string and can't reliably compare it. + $this->markTestSkipped("Locale {$locale} is not available."); + } + else + { + $actual = StringHelper::strcmp($string1, $string2, $locale); + + if ($actual != 0) + { + $actual = $actual / abs($actual); + } + + $this->assertEquals($expect, $actual); + } + } + + /** + * Test... + * + * @param string $haystack @todo + * @param string $needles @todo + * @param integer $start @todo + * @param integer $len @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strcspn + * @dataProvider seedTestStrcspn + * @since 1.0 + */ + public function testStrcspn($haystack, $needles, $start, $len, $expect) + { + $actual = StringHelper::strcspn($haystack, $needles, $start, $len); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $haystack @todo + * @param string $needle @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::stristr + * @dataProvider seedTestStristr + * @since 1.0 + */ + public function testStristr($haystack, $needle, $expect) + { + $actual = StringHelper::stristr($haystack, $needle); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strrev + * @dataProvider seedTestStrrev + * @since 1.0 + */ + public function testStrrev($string, $expect) + { + $actual = StringHelper::strrev($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $subject @todo + * @param string $mask @todo + * @param integer $start @todo + * @param integer $length @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::strspn + * @dataProvider seedTestStrspn + * @since 1.0 + */ + public function testStrspn($subject, $mask, $start, $length, $expect) + { + $actual = StringHelper::strspn($subject, $mask, $start, $length); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $expect @todo + * @param string $string @todo + * @param string $replacement @todo + * @param integer $start @todo + * @param integer $length @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::substr_replace + * @dataProvider seedTestSubstr_replace + * @since 1.0 + */ + public function testSubstr_replace($expect, $string, $replacement, $start, $length) + { + $actual = StringHelper::substr_replace($string, $replacement, $start, $length); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $charlist @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::ltrim + * @dataProvider seedTestLtrim + * @since 1.0 + */ + public function testLtrim($string, $charlist, $expect) + { + if ($charlist === null) + { + $actual = StringHelper::ltrim($string); + } + else + { + $actual = StringHelper::ltrim($string, $charlist); + } + + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $charlist @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::rtrim + * @dataProvider seedTestRtrim + * @since 1.0 + */ + public function testRtrim($string, $charlist, $expect) + { + if ($charlist === null) + { + $actual = StringHelper::rtrim($string); + } + else + { + $actual = StringHelper::rtrim($string, $charlist); + } + + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $charlist @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::trim + * @dataProvider seedTestTrim + * @since 1.0 + */ + public function testTrim($string, $charlist, $expect) + { + if ($charlist === null) + { + $actual = StringHelper::trim($string); + } + else + { + $actual = StringHelper::trim($string, $charlist); + } + + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $delimiter @todo + * @param string $newDelimiter @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::ucfirst + * @dataProvider seedTestUcfirst + * @since 1.0 + */ + public function testUcfirst($string, $delimiter, $newDelimiter, $expect) + { + $actual = StringHelper::ucfirst($string, $delimiter, $newDelimiter); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::ucwords + * @dataProvider seedTestUcwords + * @since 1.0 + */ + public function testUcwords($string, $expect) + { + $actual = StringHelper::ucwords($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $source @todo + * @param string $from_encoding @todo + * @param string $to_encoding @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::transcode + * @dataProvider seedTestTranscode + * @since 1.0 + */ + public function testTranscode($source, $from_encoding, $to_encoding, $expect) + { + $actual = StringHelper::transcode($source, $from_encoding, $to_encoding); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::valid + * @dataProvider seedTestValid + * @since 1.0 + */ + public function testValid($string, $expect) + { + $actual = StringHelper::valid($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::unicode_to_utf8 + * @dataProvider seedTestUnicodeToUtf8 + * @since 1.2.0 + */ + public function testUnicodeToUtf8($string, $expect) + { + $actual = StringHelper::unicode_to_utf8($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::unicode_to_utf16 + * @dataProvider seedTestUnicodeToUtf16 + * @since 1.2.0 + */ + public function testUnicodeToUtf16($string, $expect) + { + $actual = StringHelper::unicode_to_utf16($string); + $this->assertEquals($expect, $actual); + } + + /** + * Test... + * + * @param string $string @todo + * @param string $expect @todo + * + * @return array + * + * @covers Joomla\String\StringHelper::compliant + * @dataProvider seedTestValid + * @since 1.0 + */ + public function testCompliant($string, $expect) + { + $actual = StringHelper::compliant($string); + $this->assertEquals($expect, $actual); + } +} diff --git a/composer.json b/composer.json index b15fe4a4..44df8f12 100644 --- a/composer.json +++ b/composer.json @@ -2,16 +2,20 @@ "name": "joomla/string", "type": "joomla-package", "description": "Joomla String Package", - "keywords": ["joomla", "framework", "string"], + "keywords": [ + "joomla", + "framework", + "string" + ], "homepage": "https://github.com/joomla-framework/string", "license": "GPL-2.0-or-later", "require": { - "php": "^5.3.10|~7.0" + "php": "^5.3.10|^7.0|^8.0" }, "require-dev": { - "joomla/coding-standards": "~2.0@alpha", - "joomla/test": "~1.0", - "phpunit/phpunit": "^4.8.35|^5.4.3|~6.0" + "joomla/coding-standards": "^2.0@alpha", + "joomla/test": "^1.0", + "phpunit/phpunit": "^4.8.35|^5.4.3|^6.0|^7.0|^8.0" }, "suggest": { "ext-mbstring": "For improved processing" @@ -43,6 +47,7 @@ "Joomla\\String\\Tests\\": "Tests/" } }, + "minimum-stability": "dev", "extra": { "branch-alias": { "dev-master": "1.x-dev" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f867589b..11468057 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,25 @@ - - - src/phputf8 - - - Tests + Tests/php53 + Tests/php71 + + + + + + + + + src + + diff --git a/ruleset.xml b/ruleset.xml index d9f24b82..626812e3 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -1,21 +1,33 @@ - - - - - + + + + + - - */.github/* + + */.github/* - - */src/phputf8/* - */vendor/* + + */vendor/* - - - - + + + + + + + + + + + + + + + + + diff --git a/src/phputf8/mbstring/core.php b/src/phputf8/mbstring/core.php index 6cb5501d..997bca67 100644 --- a/src/phputf8/mbstring/core.php +++ b/src/phputf8/mbstring/core.php @@ -91,9 +91,9 @@ function utf8_strrpos($str, $search, $offset = FALSE){ */ function utf8_substr($str, $offset, $length = FALSE){ if ( $length === FALSE ) { - return mb_substr($str, $offset); + return mb_substr($str, (int)$offset); } else { - return mb_substr($str, $offset, $length); + return mb_substr($str, (int)$offset, (int)$length); } } diff --git a/src/phputf8/utf8.php b/src/phputf8/utf8.php index af8b4127..e498763f 100644 --- a/src/phputf8/utf8.php +++ b/src/phputf8/utf8.php @@ -34,7 +34,7 @@ * Also need to check we have the correct internal mbstring * encoding */ -if ( extension_loaded('mbstring')) { +if (extension_loaded('mbstring')) { /* * Joomla modification - As of PHP 8, the `mbstring.func_overload` configuration has been removed and the * MB_OVERLOAD_STRING constant will no longer be present, so this check only runs for PHP 7 and older @@ -42,9 +42,10 @@ * and https://github.com/php/php-src/commit/97df99a6d7d96a886ac143337fecad775907589a * for additional references */ - if ( PHP_VERSION_ID < 80000 && ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING ) { + if (defined('MB_OVERLOAD_STRING') && ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING) { trigger_error('String functions are overloaded by mbstring',E_USER_ERROR); } + mb_internal_encoding('UTF-8'); }