From 427887d3f96aee2be36715c86f3546a1580dfb8e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Fri, 3 Nov 2023 15:30:38 +0800 Subject: [PATCH 01/16] wip Signed-off-by: Lloric Mayuga Garcia --- .github/dependabot.yml | 12 + .github/workflows/analyse.yml | 31 +++ .github/workflows/format.yml | 22 ++ .github/workflows/pull-requests.yml | 12 + .github/workflows/tests.yml | 50 ++++ .gitignore | 1 + .travis.yml | 40 --- composer.json | 25 +- phpunit.xml | 2 +- pint.json | 19 ++ src/Duration.php | 103 ++++---- test/DurationTest.php | 370 ---------------------------- tests/DurationTest.php | 333 +++++++++++++++++++++++++ tests/Pest.php | 6 + 14 files changed, 550 insertions(+), 476 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/analyse.yml create mode 100644 .github/workflows/format.yml create mode 100644 .github/workflows/pull-requests.yml create mode 100644 .github/workflows/tests.yml delete mode 100755 .travis.yml create mode 100644 pint.json delete mode 100755 test/DurationTest.php create mode 100755 tests/DurationTest.php create mode 100644 tests/Pest.php diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0bc378d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" diff --git a/.github/workflows/analyse.yml b/.github/workflows/analyse.yml new file mode 100644 index 0000000..f866070 --- /dev/null +++ b/.github/workflows/analyse.yml @@ -0,0 +1,31 @@ +name: Static Analysis (PHPStan) + +on: + push: + branches: + - master + paths: + - '**.php' + - 'phpstan.neon' + pull_request: +# schedule: +# - cron: '0 0 * * 5' + +jobs: + phpstan: + name: phpstan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + coverage: none + + - name: Install composer dependencies + uses: ramsey/composer-install@v2 + + - name: Run PHPStan + run: ./vendor/bin/phpstan --error-format=github diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..13e1043 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,22 @@ +name: Format Dry Run (Pint) + +on: + push: + paths: + - '**.php' + branches: + - master + # - develop + # - '*.x' + pull_request: + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: "Run formatter" + uses: aglipanci/laravel-pint-action@2.3.0 + with: + testMode: true + useComposer: true diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml new file mode 100644 index 0000000..18b32b3 --- /dev/null +++ b/.github/workflows/pull-requests.yml @@ -0,0 +1,12 @@ +name: pull requests + +on: + pull_request_target: + types: [opened] + +permissions: + pull-requests: write + +jobs: + uneditable: + uses: laravel/.github/.github/workflows/pull-requests.yml@main diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..736926d --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,50 @@ +name: Tests + +#on: [push] + +on: + push: + branches: + - master +# - develop +# - '*.x' + pull_request: +# schedule: +# - cron: '0 0 * * 5' + +#permissions: +# contents: read + +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: [8.1, 8.2, 8.3] + + name: PHP ${{ matrix.php }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite + coverage: pcov + + - name: Install Composer dependencies + run: composer i --prefer-dist --no-interaction --no-progress + + - name: Copy environment file + run: cp .env.example .env + + - name: Generate app key + run: php artisan key:generate + + - name: Execute tests + run: vendor/bin/pest --ci --parallel --coverage \ No newline at end of file diff --git a/.gitignore b/.gitignore index dbcd112..c772037 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ vendor/ build/ +composer.lock \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 3c42620..0000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: php - -dist: trusty - -sudo: false - -matrix: - fast_finish: true - include: - - php: 7.0 - - php: 7.1 - - php: 7.2 - - php: 7.3 - - php: 7.4 - - php: 8.0 - -branches: - only: - - "master" - -cache: - directories: - - $HOME/.composer/cache - - vendor - -before_install: - - composer selfupdate - -install: - - composer install --no-progress --no-interaction --prefer-dist - -before_script: - - mkdir -p build/logs - -script: - - composer run test - - composer run phpstan - -after_script: - - php ./vendor/bin/coveralls diff --git a/composer.json b/composer.json index e4e8c30..ed8db73 100755 --- a/composer.json +++ b/composer.json @@ -20,18 +20,13 @@ } ], "require": { - "php": ">=5.4" + "php": "^8.1" }, "require-dev": { - "phpstan/phpstan": "^0.12.81", - "phpunit/phpunit": "~4.8|~5.0", - "satooshi/php-coveralls": "~1.0", - "symfony/yaml": "~2.0", - "symfony/config": "~2.0", - "symfony/console": "~2.0", - "symfony/stopwatch": "~2.0", - "symfony/filesystem": "~2.0", - "doctrine/instantiator": "1.0.4" + "composer-runtime-api": "^2.2", + "phpstan/phpstan": "^1.10.40", + "pestphp/pest": "^2.24.2", + "laravel/pint": "^1.13.5" }, "autoload": { "psr-4": { @@ -39,8 +34,14 @@ } }, "scripts": { - "test": "phpunit -c phpunit.xml", + "test": "vendor/bin/pest --parallel", + "format": "vendor/bin/pint", "phpstan": "vendor/bin/phpstan" }, - "minimum-stability": "stable" + "minimum-stability": "stable", + "config": { + "allow-plugins": { + "pestphp/pest-plugin": true + } + } } diff --git a/phpunit.xml b/phpunit.xml index bd8e429..9f368f7 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,7 +10,7 @@ > - test/ + tests/ diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..e27c478 --- /dev/null +++ b/pint.json @@ -0,0 +1,19 @@ +{ + "preset": "laravel", + "exclude": [ + "config", + "build" + ], + "notPath": [ + "ray.php", + "composer-setup.php" + ], + "rules": { + "declare_strict_types": true, + "single_trait_insert_per_statement": true, + "new_with_braces" : { + "anonymous_class": false + }, + "yoda_style": true + } +} diff --git a/src/Duration.php b/src/Duration.php index 82f5d73..5c76a91 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -1,5 +1,7 @@ seconds = (float)$duration; + $this->seconds = (float) $duration; if ($this->seconds >= 60) { - $this->minutes = (int)floor($this->seconds / 60); + $this->minutes = (int) floor($this->seconds / 60); // count current precision $precision = 0; - if (($delimiterPos = strpos((string)$this->seconds, '.')) !== false) { - $precision = strlen(substr((string)$this->seconds, $delimiterPos + 1)); + if (($delimiterPos = strpos((string) $this->seconds, '.')) !== false) { + $precision = strlen(substr((string) $this->seconds, $delimiterPos + 1)); } - $this->seconds = (float)round(($this->seconds - ($this->minutes * 60)), $precision); + $this->seconds = (float) round(($this->seconds - ($this->minutes * 60)), $precision); } if ($this->minutes >= 60) { - $this->hours = (int)floor($this->minutes / 60); - $this->minutes = (int)($this->minutes - ($this->hours * 60)); + $this->hours = (int) floor($this->minutes / 60); + $this->minutes = (int) ($this->minutes - ($this->hours * 60)); } if ($this->hours >= $this->hoursPerDay) { - $this->days = (int)floor($this->hours / $this->hoursPerDay); - $this->hours = (int)($this->hours - ($this->days * $this->hoursPerDay)); + $this->days = (int) floor($this->hours / $this->hoursPerDay); + $this->hours = (int) ($this->hours - ($this->days * $this->hoursPerDay)); } return $this; @@ -121,14 +123,14 @@ public function parse($duration) if (preg_match('/\:/', $duration)) { $parts = explode(':', $duration); - if (count($parts) == 2) { - $this->minutes = (int)$parts[0]; - $this->seconds = (float)$parts[1]; + if (2 == count($parts)) { + $this->minutes = (int) $parts[0]; + $this->seconds = (float) $parts[1]; } else { - if (count($parts) == 3) { - $this->hours = (int)$parts[0]; - $this->minutes = (int)$parts[1]; - $this->seconds = (float)$parts[2]; + if (3 == count($parts)) { + $this->hours = (int) $parts[0]; + $this->minutes = (int) $parts[1]; + $this->seconds = (float) $parts[2]; } } @@ -141,22 +143,22 @@ public function parse($duration) preg_match($this->secondsRegex, $duration)) { if (preg_match($this->daysRegex, $duration, $matches)) { $num = $this->numberBreakdown((float) $matches[1]); - $this->days += (int)$num[0]; + $this->days += (int) $num[0]; $this->hours += $num[1] * $this->hoursPerDay; } if (preg_match($this->hoursRegex, $duration, $matches)) { $num = $this->numberBreakdown((float) $matches[1]); - $this->hours += (int)$num[0]; + $this->hours += (int) $num[0]; $this->minutes += $num[1] * 60; } if (preg_match($this->minutesRegex, $duration, $matches)) { - $this->minutes += (int)$matches[1]; + $this->minutes += (int) $matches[1]; } if (preg_match($this->secondsRegex, $duration, $matches)) { - $this->seconds += (float)$matches[1]; + $this->seconds += (float) $matches[1]; } return $this; @@ -170,8 +172,8 @@ public function parse($duration) * * For example, one hour and 42 minutes would be "6120" * - * @param int|float|string $duration A string or number, representing a duration - * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. + * @param int|float|string $duration A string or number, representing a duration + * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. * @return int|float */ public function toSeconds($duration = null, $precision = false) @@ -181,7 +183,7 @@ public function toSeconds($duration = null, $precision = false) } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; - return $precision !== false ? round($this->output, $precision) : $this->output; + return false !== $precision ? round($this->output, $precision) : $this->output; } /** @@ -189,8 +191,8 @@ public function toSeconds($duration = null, $precision = false) * * For example, one hour and 42 minutes would be "102" minutes * - * @param int|float|string $duration A string or number, representing a duration - * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. + * @param int|float|string $duration A string or number, representing a duration + * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. * @return int|float */ public function toMinutes($duration = null, $precision = false) @@ -200,14 +202,14 @@ public function toMinutes($duration = null, $precision = false) } // backward compatibility, true = round to integer - if ($precision === true) { + if (true === $precision) { $precision = 0; } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; $result = intval($this->output()) / 60; - return $precision !== false ? round($result, $precision) : $result; + return false !== $precision ? round($result, $precision) : $result; } /** @@ -218,8 +220,8 @@ public function toMinutes($duration = null, $precision = false) * - 42 minutes would be "0:42:00" * - 28 seconds would be "0:00:28" * - * @param int|float|string|null $duration A string or number, representing a duration - * @param bool $zeroFill A boolean, to force zero-fill result or not (see example) + * @param int|float|string|null $duration A string or number, representing a duration + * @param bool $zeroFill A boolean, to force zero-fill result or not (see example) * @return string */ public function formatted($duration = null, $zeroFill = false) @@ -232,7 +234,7 @@ public function formatted($duration = null, $zeroFill = false) if ($this->seconds > 0) { if ($this->seconds < 10 && ($this->minutes > 0 || $hours > 0 || $zeroFill)) { - $this->output .= '0' . $this->seconds; + $this->output .= '0'.$this->seconds; } else { $this->output .= $this->seconds; } @@ -246,21 +248,21 @@ public function formatted($duration = null, $zeroFill = false) if ($this->minutes > 0) { if ($this->minutes <= 9 && ($hours > 0 || $zeroFill)) { - $this->output = '0' . $this->minutes . ':' . $this->output; + $this->output = '0'.$this->minutes.':'.$this->output; } else { - $this->output = $this->minutes . ':' . $this->output; + $this->output = $this->minutes.':'.$this->output; } } else { if ($hours > 0 || $zeroFill) { - $this->output = '00' . ':' . $this->output; + $this->output = '00'.':'.$this->output; } } if ($hours > 0) { - $this->output = $hours . ':' . $this->output; + $this->output = $hours.':'.$this->output; } else { if ($zeroFill) { - $this->output = '0' . ':' . $this->output; + $this->output = '0'.':'.$this->output; } } @@ -272,7 +274,7 @@ public function formatted($duration = null, $zeroFill = false) * * For example, one hour and 42 minutes would be "1h 42m" * - * @param int|float|string $duration A string or number, representing a duration + * @param int|float|string $duration A string or number, representing a duration * @return string */ public function humanize($duration = null) @@ -281,28 +283,27 @@ public function humanize($duration = null) $this->parse($duration); } - if ($this->seconds > 0 || ($this->seconds === 0.0 && $this->minutes === 0 && $this->hours === 0 && $this->days === 0)) { - $this->output .= $this->seconds . 's'; + if ($this->seconds > 0 || (0.0 === $this->seconds && 0 === $this->minutes && 0 === $this->hours && 0 === $this->days)) { + $this->output .= $this->seconds.'s'; } if ($this->minutes > 0) { - $this->output = $this->minutes . 'm ' . $this->output; + $this->output = $this->minutes.'m '.$this->output; } if ($this->hours > 0) { - $this->output = $this->hours . 'h ' . $this->output; + $this->output = $this->hours.'h '.$this->output; } if ($this->days > 0) { - $this->output = $this->days . 'd ' . $this->output; + $this->output = $this->days.'d '.$this->output; } return trim($this->output()); } - /** - * @param float $number + * @param float $number * @return array|float[]|int[] */ private function numberBreakdown($number) @@ -314,17 +315,15 @@ private function numberBreakdown($number) $number *= -1; } - return array( + return [ floor($number) * $negative, - ($number - floor($number)) * $negative - ); + ($number - floor($number)) * $negative, + ]; } - /** * Resets the Duration object by clearing the output and values. * - * @access private * @return void */ private function reset() @@ -339,7 +338,6 @@ private function reset() /** * Returns the output of the Duration object and resets. * - * @access private * @return string */ private function output() @@ -351,4 +349,3 @@ private function output() return $out; } } - diff --git a/test/DurationTest.php b/test/DurationTest.php deleted file mode 100755 index 0564564..0000000 --- a/test/DurationTest.php +++ /dev/null @@ -1,370 +0,0 @@ -d = new Duration; - } - - public function secondsSampleData() - { - return array( - array(false, null), - array(false, ' '), - array(0, '0 s'), - array(1, '1 s'), - array(1, '1 sec'), - array(3, '3S'), - array(7, '7 S'), - array(51, '51seconds'), - array(4, '4 Sec.'), - array(15, '15 SEcONDs'), - array(1, '1.0 s'), - array(1.5689, '1.5689 S'), - array(1.00342, '1.00342 S'), - ); - } - - /** - * @dataProvider secondsSampleData - */ - public function testGettingValueFromSecondSuffixes($expectedSeconds, $secStr) - { - $this->d->parse($secStr); - $this->assertEquals($expectedSeconds, $this->d->seconds); - } - - public function minutesSampleData() - { - return array( - array(0, '0m'), - array(1, '1 m'), - array(4, '4 min'), - array(6, '6M'), - array(14, '14 Ms'), - array(31, '31 minutes'), - array(9, '9Min.'), - array(11, '11 MINUTE') - ); - } - - /** - * @dataProvider minutesSampleData - */ - public function testGettingValueFromMinuteSuffixes($intVal, $minStr) - { - $this->d->parse($minStr); - $this->assertEquals($intVal, $this->d->minutes); - } - - public function hoursSampleData() - { - return array( - array(0, '0h'), - array(1, '1 h'), - array(1, '1 hr'), - array(1, '1H'), - array(24, '24 Hrs'), - array(3, '3hours'), - array(6, '6HoUr'), - array(14, '14 HOURs'), - array(36, '36h') - ); - } - - /** - * @dataProvider hoursSampleData - */ - public function testGettingValueFromHourSuffixes($intVal, $hrStr) - { - $this->d->parse($hrStr); - $this->assertEquals($intVal, $this->d->hours); - } - - public function daysSampleData() - { - return array( - array(0, '0d'), - array(1, '1 d'), - array(1, '1 D'), - array(1, '1D'), - array(24, '24 ds'), - array(3, '3days'), - array(6, '6DaY'), - array(14, '14 DAYs') - ); - } - - /** - * @dataProvider daysSampleData - */ - public function testGettingValueFromDaySuffixes($intVal, $dayStr) - { - $this->d->parse($dayStr); - $this->assertEquals($intVal, $this->d->days); - } - - - public function testConvertingSecondsToFormattedString() - { - $this->assertEquals('0', $this->d->formatted(0)); - $this->assertEquals('4', $this->d->formatted(4)); - $this->assertEquals('9', $this->d->formatted(9)); - $this->assertEquals('42', $this->d->formatted(42)); - $this->assertEquals('1:02', $this->d->formatted(62)); - $this->assertEquals('1:09', $this->d->formatted(69)); - $this->assertEquals('1:42', $this->d->formatted(102)); - $this->assertEquals('10:47', $this->d->formatted(647)); - $this->assertEquals('1:00:00', $this->d->formatted(3600)); - $this->assertEquals('1:00:01', $this->d->formatted(3601)); - $this->assertEquals('1:00:11', $this->d->formatted(3611)); - $this->assertEquals('1:01:00', $this->d->formatted(3660)); - $this->assertEquals('1:01:14', $this->d->formatted(3674)); - $this->assertEquals('1:04:25', $this->d->formatted(3865)); - $this->assertEquals('1:09:09', $this->d->formatted(4149)); - - // microseconds - $this->assertEquals('0.0', $this->d->formatted(0.0)); - $this->assertEquals('4.987', $this->d->formatted(4.987)); - $this->assertEquals('9.123', $this->d->formatted(9.123)); - $this->assertEquals('42.672', $this->d->formatted(42.672)); - $this->assertEquals('1:02.23', $this->d->formatted(62.23)); - $this->assertEquals('1:09.9', $this->d->formatted(69.9)); - $this->assertEquals('1:42.62394', $this->d->formatted(102.62394)); - $this->assertEquals('10:47.5', $this->d->formatted(647.5)); - $this->assertEquals('1:00:00.954', $this->d->formatted(3600.954)); - $this->assertEquals('1:00:01.5123', $this->d->formatted(3601.5123)); - $this->assertEquals('1:00:11.0412368456', $this->d->formatted(3611.0412368456)); - $this->assertEquals('1:01:00.56945', $this->d->formatted(3660.56945)); - $this->assertEquals('1:01:14.3', $this->d->formatted(3674.3)); - $this->assertEquals('1:04:25.0005598', $this->d->formatted(3865.0005598)); - $this->assertEquals('1:09:09.123', $this->d->formatted(4149.123)); - } - - public function testConvertingSecondsToFormattedStringZeroFilled() - { - $this->assertEquals('0:00:00', $this->d->formatted(0, true)); - $this->assertEquals('0:00:04', $this->d->formatted(4, true)); - $this->assertEquals('0:00:09', $this->d->formatted(9, true)); - $this->assertEquals('0:00:42', $this->d->formatted(42, true)); - $this->assertEquals('0:01:02', $this->d->formatted(62, true)); - $this->assertEquals('0:01:09', $this->d->formatted(69, true)); - $this->assertEquals('0:01:42', $this->d->formatted(102, true)); - $this->assertEquals('0:10:47', $this->d->formatted(647, true)); - $this->assertEquals('1:00:00', $this->d->formatted(3600, true)); - $this->assertEquals('1:00:01', $this->d->formatted(3601, true)); - $this->assertEquals('1:00:11', $this->d->formatted(3611, true)); - $this->assertEquals('1:01:00', $this->d->formatted(3660, true)); - $this->assertEquals('1:01:14', $this->d->formatted(3674, true)); - $this->assertEquals('1:04:25', $this->d->formatted(3865, true)); - $this->assertEquals('1:09:09', $this->d->formatted(4149, true)); - - // microseconds - $this->assertEquals('0:00:04.542', $this->d->formatted(4.542, true)); - $this->assertEquals('1:09:09.0987', $this->d->formatted(4149.0987, true)); - } - - public function testConvertingFormattedStringsToSeconds() - { - $this->assertEquals(0, $this->d->toSeconds('0')); - $this->assertEquals(4, $this->d->toSeconds('4')); - $this->assertEquals(9, $this->d->toSeconds('9')); - $this->assertEquals(42, $this->d->toSeconds('42')); - $this->assertEquals(62, $this->d->toSeconds('1:02')); - $this->assertEquals(69, $this->d->toSeconds('1:09')); - $this->assertEquals(102, $this->d->toSeconds('1:42')); - $this->assertEquals(647, $this->d->toSeconds('10:47')); - $this->assertEquals(3600, $this->d->toSeconds('1:00:00')); - $this->assertEquals(3601, $this->d->toSeconds('1:00:01')); - $this->assertEquals(3611, $this->d->toSeconds('1:00:11')); - $this->assertEquals(3660, $this->d->toSeconds('1:01:00')); - $this->assertEquals(3674, $this->d->toSeconds('1:01:14')); - $this->assertEquals(3865, $this->d->toSeconds('1:04:25')); - $this->assertEquals(4149, $this->d->toSeconds('1:09:09')); - - // microseconds - $this->assertEquals(4.6, $this->d->toSeconds('4.6')); - $this->assertEquals(9.5, $this->d->toSeconds('9.5')); - $this->assertEquals(42.1, $this->d->toSeconds('42.1')); - $this->assertEquals(62.96, $this->d->toSeconds('1:02.96')); - $this->assertEquals(69.23, $this->d->toSeconds('1:09.23')); - $this->assertEquals(102.55, $this->d->toSeconds('1:42.55')); - $this->assertEquals(647.999, $this->d->toSeconds('10:47.999')); - $this->assertEquals(3600.9987, $this->d->toSeconds('1:00:00.9987')); - $this->assertEquals(3601.000111, $this->d->toSeconds('1:00:01.000111')); - $this->assertEquals(3611.0999, $this->d->toSeconds('1:00:11.0999')); - $this->assertEquals(3660.500001, $this->d->toSeconds('1:01:00.500001')); - $this->assertEquals(3674.00001, $this->d->toSeconds('1:01:14.00001')); - $this->assertEquals(3865.499999, $this->d->toSeconds('1:04:25.499999')); - $this->assertEquals(4149.499999, $this->d->toSeconds('1:09:09.499999')); - - // precision - $this->assertEquals(0, $this->d->toSeconds('0', 0)); - $this->assertEquals(5, $this->d->toSeconds('4.6', 0)); - $this->assertEquals(10, $this->d->toSeconds('9.5', 0)); - $this->assertEquals(42.1, $this->d->toSeconds('42.1', 1)); - $this->assertEquals(63, $this->d->toSeconds('1:02.96', 1)); - $this->assertEquals(69.23, $this->d->toSeconds('1:09.23')); - $this->assertEquals(102.55, $this->d->toSeconds('1:42.55', 2)); - $this->assertEquals(648, $this->d->toSeconds('10:47.999', 2)); - $this->assertEquals(3601, $this->d->toSeconds('1:00:00.9987', 2)); - $this->assertEquals(3601, $this->d->toSeconds('1:00:01.000111', 3)); - $this->assertEquals(3611.0999, $this->d->toSeconds('1:00:11.0999', 4)); - $this->assertEquals(3660.5, $this->d->toSeconds('1:01:00.500001', 2)); - $this->assertEquals(3674, $this->d->toSeconds('1:01:14.00001', 2)); - $this->assertEquals(3865.5, $this->d->toSeconds('1:04:25.499999', 3)); - $this->assertEquals(4149.499997, $this->d->toSeconds('1:09:09.4999971', 6)); - } - - public function testConvertingFormattedStringsToMinutes() - { - $this->assertEquals(0, $this->d->toMinutes('0')); - $this->assertEquals(4 / 60, $this->d->toMinutes('4')); - $this->assertEquals(9 / 60, $this->d->toMinutes('9')); - $this->assertEquals(42 / 60, $this->d->toMinutes('42')); - $this->assertEquals(62 / 60, $this->d->toMinutes('1:02')); - $this->assertEquals(69 / 60, $this->d->toMinutes('1:09')); - $this->assertEquals(102 / 60, $this->d->toMinutes('1:42')); - $this->assertEquals(647 / 60, $this->d->toMinutes('10:47')); - $this->assertEquals(3600 / 60, $this->d->toMinutes('1:00:00')); - $this->assertEquals(3601 / 60, $this->d->toMinutes('1:00:01')); - $this->assertEquals(3611 / 60, $this->d->toMinutes('1:00:11')); - $this->assertEquals(3660 / 60, $this->d->toMinutes('1:01:00')); - $this->assertEquals(3674 / 60, $this->d->toMinutes('1:01:14')); - $this->assertEquals(3865 / 60, $this->d->toMinutes('1:04:25')); - $this->assertEquals(4149 / 60, $this->d->toMinutes('1:09:09')); - - // to integer - BC - $this->assertEquals(0, $this->d->toMinutes('0', true)); - $this->assertEquals(0, $this->d->toMinutes('4', true)); - $this->assertEquals(0, $this->d->toMinutes('9', true)); - $this->assertEquals(1, $this->d->toMinutes('42', true)); - $this->assertEquals(1, $this->d->toMinutes('1:02', true)); - $this->assertEquals(1, $this->d->toMinutes('1:09', true)); - $this->assertEquals(2, $this->d->toMinutes('1:42', true)); - $this->assertEquals(11, $this->d->toMinutes('10:47', true)); - $this->assertEquals(60, $this->d->toMinutes('1:00:00', true)); - $this->assertEquals(60, $this->d->toMinutes('1:00:01', true)); - $this->assertEquals(60, $this->d->toMinutes('1:00:11', true)); - $this->assertEquals(61, $this->d->toMinutes('1:01:00', true)); - $this->assertEquals(61, $this->d->toMinutes('1:01:14', true)); - $this->assertEquals(64, $this->d->toMinutes('1:04:25', true)); - $this->assertEquals(65, $this->d->toMinutes('1:04:55', true)); - $this->assertEquals(69, $this->d->toMinutes('1:09:09', true)); - - // precision - $this->assertEquals(0, $this->d->toMinutes('0', 0)); - $this->assertEquals(0, $this->d->toMinutes('4', 0)); - $this->assertEquals(0, $this->d->toMinutes('9', 0)); - $this->assertEquals(1, $this->d->toMinutes('42', 0)); - $this->assertEquals(1, $this->d->toMinutes('1:02', 0)); - $this->assertEquals(1, $this->d->toMinutes('1:09', 0)); - $this->assertEquals(2, $this->d->toMinutes('1:42', 0)); - $this->assertEquals(11, $this->d->toMinutes('10:47', 0)); - $this->assertEquals(60, $this->d->toMinutes('1:00:00', 0)); - $this->assertEquals(60, $this->d->toMinutes('1:00:01', 0)); - $this->assertEquals(60, $this->d->toMinutes('1:00:11', 0)); - $this->assertEquals(61, $this->d->toMinutes('1:01:00', 0)); - $this->assertEquals(61, $this->d->toMinutes('1:01:14', 0)); - $this->assertEquals(64, $this->d->toMinutes('1:04:25', 0)); - $this->assertEquals(65, $this->d->toMinutes('1:04:55', 0)); - $this->assertEquals(69, $this->d->toMinutes('1:09:09', 0)); - - $this->assertEquals(0, $this->d->toMinutes('0', 1)); - $this->assertEquals(0.1, $this->d->toMinutes('4', 1)); - $this->assertEquals(0.15, $this->d->toMinutes('9', 2)); - $this->assertEquals(0.7, $this->d->toMinutes('42', 3)); - $this->assertEquals(1, $this->d->toMinutes('1:02', 1)); - $this->assertEquals(1.15, $this->d->toMinutes('1:09', 2)); - $this->assertEquals(1.7, $this->d->toMinutes('1:42', 3)); - $this->assertEquals(10.8, $this->d->toMinutes('10:47', 1)); - $this->assertEquals(60, $this->d->toMinutes('1:00:00', 2)); - $this->assertEquals(60.017, $this->d->toMinutes('1:00:01', 3)); - $this->assertEquals(60.2, $this->d->toMinutes('1:00:11', 1)); - $this->assertEquals(61, $this->d->toMinutes('1:01:00', 2)); - $this->assertEquals(61.233, $this->d->toMinutes('1:01:14', 3)); - $this->assertEquals(64.42, $this->d->toMinutes('1:04:25', 2)); - $this->assertEquals(64.92, $this->d->toMinutes('1:04:55', 2)); - $this->assertEquals(69.15, $this->d->toMinutes('1:09:09', 2)); - } - - public function testConvertSecondsToHumanizedString() - { - $this->assertEquals('0s', $this->d->humanize(0)); - $this->assertEquals('4s', $this->d->humanize(4)); - $this->assertEquals('42s', $this->d->humanize(42)); - $this->assertEquals('1m 2s', $this->d->humanize(62)); - $this->assertEquals('1m 42s', $this->d->humanize(102)); - $this->assertEquals('10m 47s', $this->d->humanize(647)); - $this->assertEquals('1h', $this->d->humanize(3600)); - $this->assertEquals('1h 5s', $this->d->humanize(3605)); - $this->assertEquals('1h 1m', $this->d->humanize(3660)); - $this->assertEquals('1h 1m 5s', $this->d->humanize(3665)); - $this->assertEquals('3d', $this->d->humanize(259200)); - $this->assertEquals('2d 11h 30m', $this->d->humanize(214200)); - - $this->assertEquals('4.0596s', $this->d->humanize(4.0596)); - $this->assertEquals('2d 11h 30m 0.9542s', $this->d->humanize(214200.9542)); - - } - - /** - * @depends testGettingValueFromSecondSuffixes - * @depends testGettingValueFromMinuteSuffixes - * @depends testGettingValueFromHourSuffixes - */ - public function testConvertHumanizedStringToSeconds() - { - $this->assertEquals(0, $this->d->toSeconds('0s')); - $this->assertEquals(4, $this->d->toSeconds('4s')); - $this->assertEquals(42, $this->d->toSeconds('42s')); - $this->assertEquals(72, $this->d->toSeconds('1m 12s')); - $this->assertEquals(102, $this->d->toSeconds('1m 42s')); - $this->assertEquals(647, $this->d->toSeconds('10m 47s')); - $this->assertEquals(3600, $this->d->toSeconds('1h')); - $this->assertEquals(3605, $this->d->toSeconds('1h 5s')); - $this->assertEquals(3660, $this->d->toSeconds('1h 1m')); - $this->assertEquals(3665, $this->d->toSeconds('1h 1m 5s')); - $this->assertEquals(86400, $this->d->toSeconds('1d')); - $this->assertEquals(214200, $this->d->toSeconds('2d 11h 30m')); - $this->assertEquals(214214, $this->d->toSeconds('2d 11h 30m 14s')); - } - - public function testConvertHumanizedStringToSeconds7HourDay() - { - $d = new Duration(null, 7); - - $this->assertEquals(0, $d->toSeconds('0d')); - $this->assertEquals(25200, $d->toSeconds('1d')); - $this->assertEquals(91800, $d->toSeconds('2d 11h 30m')); - } - - public function testSupportDecimals() - { - $d = new Duration(null, 6); - - $this->assertEquals(0, $d->toMinutes('0d')); - $this->assertEquals(6 * 60, $d->toMinutes('1d')); - $this->assertEquals((6 + 3) * 60, $d->toMinutes('1.5d')); - $this->assertEquals(60, $d->toMinutes('1h')); - $this->assertEquals(60 + 30, $d->toMinutes('1.5h')); - $this->assertEquals((12 * 60) + 60 + 30, $d->toMinutes('2d 1.5h')); - } - - public function testConvertHumanizedWithSupportDecimals() - { - $t = '1.5d 1.5h 2m 5s'; - - $this->assertEquals('1d 4h 32m 5s', (new Duration($t, 6))->humanize(), "Test humanize with: {$t}"); - $this->assertEquals('10:32:05', (new Duration($t, 6))->formatted(), "Test formatted with: {$t}"); - $this->assertEquals(37925, (new Duration($t, 6))->toSeconds(), "Test toSeconds with: {$t}"); - $this->assertEquals(37925/60, (new Duration($t, 6))->toMinutes(), "Test toMinutes with: {$t}"); - $this->assertEquals(632, (new Duration($t, 6))->toMinutes(null, 0), "Test toMinutes with: {$t}"); - } - -} diff --git a/tests/DurationTest.php b/tests/DurationTest.php new file mode 100755 index 0000000..de5f355 --- /dev/null +++ b/tests/DurationTest.php @@ -0,0 +1,333 @@ + $this->duration = new Duration()); + +dataset('seconds_sample_data', [ + [false, null], + [false, ' '], + [0, '0 s'], + [1, '1 s'], + [1, '1 sec'], + [3, '3S'], + [7, '7 S'], + [51, '51seconds'], + [4, '4 Sec.'], + [15, '15 SEcONDs'], + [1, '1.0 s'], + [1.5689, '1.5689 S'], + [1.00342, '1.00342 S'], +]); + +dataset('minutes_sample_data', [ + [0, '0m'], + [1, '1 m'], + [4, '4 min'], + [6, '6M'], + [14, '14 Ms'], + [31, '31 minutes'], + [9, '9Min.'], + [11, '11 MINUTE'], +]); + +dataset('hours_sample_data', [ + [0, '0h'], + [1, '1 h'], + [1, '1 hr'], + [1, '1H'], + [24, '24 Hrs'], + [3, '3hours'], + [6, '6HoUr'], + [14, '14 HOURs'], + [36, '36h'], +]); + +dataset('days_sample_data', [ + [0, '0d'], + [1, '1 d'], + [1, '1 D'], + [1, '1D'], + [24, '24 ds'], + [3, '3days'], + [6, '6DaY'], + [14, '14 DAYs'], +]); + +test('Getting Value From Second Suffixes', function ($expectedSeconds, $secStr) { + $this->duration->parse($secStr); + assertEquals($expectedSeconds, $this->duration->seconds); +}) + ->with('seconds_sample_data'); + +test('Getting Value From Minute Suffixes', function ($intVal, $minStr) { + $this->duration->parse($minStr); + assertEquals($intVal, $this->duration->minutes); +}) + ->with('minutes_sample_data'); + +test('Getting Value From Hour Suffixes', function ($intVal, $hrStr) { + $this->duration->parse($hrStr); + assertEquals($intVal, $this->duration->hours); +}) + ->with('hours_sample_data'); + +test('Getting Value From Day Suffixes', function ($intVal, $dayStr) { + $this->duration->parse($dayStr); + assertEquals($intVal, $this->duration->days); +}) + ->with('days_sample_data'); + +test('Converting Seconds To Formatted String', function () { + assertEquals('0', $this->duration->formatted(0)); + assertEquals('4', $this->duration->formatted(4)); + assertEquals('9', $this->duration->formatted(9)); + assertEquals('42', $this->duration->formatted(42)); + assertEquals('1:02', $this->duration->formatted(62)); + assertEquals('1:09', $this->duration->formatted(69)); + assertEquals('1:42', $this->duration->formatted(102)); + assertEquals('10:47', $this->duration->formatted(647)); + assertEquals('1:00:00', $this->duration->formatted(3600)); + assertEquals('1:00:01', $this->duration->formatted(3601)); + assertEquals('1:00:11', $this->duration->formatted(3611)); + assertEquals('1:01:00', $this->duration->formatted(3660)); + assertEquals('1:01:14', $this->duration->formatted(3674)); + assertEquals('1:04:25', $this->duration->formatted(3865)); + assertEquals('1:09:09', $this->duration->formatted(4149)); + + // microseconds + assertEquals('0.0', $this->duration->formatted(0.0)); + assertEquals('4.987', $this->duration->formatted(4.987)); + assertEquals('9.123', $this->duration->formatted(9.123)); + assertEquals('42.672', $this->duration->formatted(42.672)); + assertEquals('1:02.23', $this->duration->formatted(62.23)); + assertEquals('1:09.9', $this->duration->formatted(69.9)); + assertEquals('1:42.62394', $this->duration->formatted(102.62394)); + assertEquals('10:47.5', $this->duration->formatted(647.5)); + assertEquals('1:00:00.954', $this->duration->formatted(3600.954)); + assertEquals('1:00:01.5123', $this->duration->formatted(3601.5123)); + assertEquals('1:00:11.0412368456', $this->duration->formatted(3611.0412368456)); + assertEquals('1:01:00.56945', $this->duration->formatted(3660.56945)); + assertEquals('1:01:14.3', $this->duration->formatted(3674.3)); + assertEquals('1:04:25.0005598', $this->duration->formatted(3865.0005598)); + assertEquals('1:09:09.123', $this->duration->formatted(4149.123)); +}); + +test('Converting Seconds To Formatted String Zero Filled', function () { + assertEquals('0:00:00', $this->duration->formatted(0, true)); + assertEquals('0:00:04', $this->duration->formatted(4, true)); + assertEquals('0:00:09', $this->duration->formatted(9, true)); + assertEquals('0:00:42', $this->duration->formatted(42, true)); + assertEquals('0:01:02', $this->duration->formatted(62, true)); + assertEquals('0:01:09', $this->duration->formatted(69, true)); + assertEquals('0:01:42', $this->duration->formatted(102, true)); + assertEquals('0:10:47', $this->duration->formatted(647, true)); + assertEquals('1:00:00', $this->duration->formatted(3600, true)); + assertEquals('1:00:01', $this->duration->formatted(3601, true)); + assertEquals('1:00:11', $this->duration->formatted(3611, true)); + assertEquals('1:01:00', $this->duration->formatted(3660, true)); + assertEquals('1:01:14', $this->duration->formatted(3674, true)); + assertEquals('1:04:25', $this->duration->formatted(3865, true)); + assertEquals('1:09:09', $this->duration->formatted(4149, true)); + + // microseconds + assertEquals('0:00:04.542', $this->duration->formatted(4.542, true)); + assertEquals('1:09:09.0987', $this->duration->formatted(4149.0987, true)); +}); + +test('Converting Formatted Strings To Seconds', function () { + assertEquals(0, $this->duration->toSeconds('0')); + assertEquals(4, $this->duration->toSeconds('4')); + assertEquals(9, $this->duration->toSeconds('9')); + assertEquals(42, $this->duration->toSeconds('42')); + assertEquals(62, $this->duration->toSeconds('1:02')); + assertEquals(69, $this->duration->toSeconds('1:09')); + assertEquals(102, $this->duration->toSeconds('1:42')); + assertEquals(647, $this->duration->toSeconds('10:47')); + assertEquals(3600, $this->duration->toSeconds('1:00:00')); + assertEquals(3601, $this->duration->toSeconds('1:00:01')); + assertEquals(3611, $this->duration->toSeconds('1:00:11')); + assertEquals(3660, $this->duration->toSeconds('1:01:00')); + assertEquals(3674, $this->duration->toSeconds('1:01:14')); + assertEquals(3865, $this->duration->toSeconds('1:04:25')); + assertEquals(4149, $this->duration->toSeconds('1:09:09')); + + // microseconds + assertEquals(4.6, $this->duration->toSeconds('4.6')); + assertEquals(9.5, $this->duration->toSeconds('9.5')); + assertEquals(42.1, $this->duration->toSeconds('42.1')); + assertEquals(62.96, $this->duration->toSeconds('1:02.96')); + assertEquals(69.23, $this->duration->toSeconds('1:09.23')); + assertEquals(102.55, $this->duration->toSeconds('1:42.55')); + assertEquals(647.999, $this->duration->toSeconds('10:47.999')); + assertEquals(3600.9987, $this->duration->toSeconds('1:00:00.9987')); + assertEquals(3601.000111, $this->duration->toSeconds('1:00:01.000111')); + assertEquals(3611.0999, $this->duration->toSeconds('1:00:11.0999')); + assertEquals(3660.500001, $this->duration->toSeconds('1:01:00.500001')); + assertEquals(3674.00001, $this->duration->toSeconds('1:01:14.00001')); + assertEquals(3865.499999, $this->duration->toSeconds('1:04:25.499999')); + assertEquals(4149.499999, $this->duration->toSeconds('1:09:09.499999')); + + // precision + assertEquals(0, $this->duration->toSeconds('0', 0)); + assertEquals(5, $this->duration->toSeconds('4.6', 0)); + assertEquals(10, $this->duration->toSeconds('9.5', 0)); + assertEquals(42.1, $this->duration->toSeconds('42.1', 1)); + assertEquals(63, $this->duration->toSeconds('1:02.96', 1)); + assertEquals(69.23, $this->duration->toSeconds('1:09.23')); + assertEquals(102.55, $this->duration->toSeconds('1:42.55', 2)); + assertEquals(648, $this->duration->toSeconds('10:47.999', 2)); + assertEquals(3601, $this->duration->toSeconds('1:00:00.9987', 2)); + assertEquals(3601, $this->duration->toSeconds('1:00:01.000111', 3)); + assertEquals(3611.0999, $this->duration->toSeconds('1:00:11.0999', 4)); + assertEquals(3660.5, $this->duration->toSeconds('1:01:00.500001', 2)); + assertEquals(3674, $this->duration->toSeconds('1:01:14.00001', 2)); + assertEquals(3865.5, $this->duration->toSeconds('1:04:25.499999', 3)); + assertEquals(4149.499997, $this->duration->toSeconds('1:09:09.4999971', 6)); +}); + +test('Converting Formatted Strings To Minutes', function () { + assertEquals(0, $this->duration->toMinutes('0')); + assertEquals(4 / 60, $this->duration->toMinutes('4')); + assertEquals(9 / 60, $this->duration->toMinutes('9')); + assertEquals(42 / 60, $this->duration->toMinutes('42')); + assertEquals(62 / 60, $this->duration->toMinutes('1:02')); + assertEquals(69 / 60, $this->duration->toMinutes('1:09')); + assertEquals(102 / 60, $this->duration->toMinutes('1:42')); + assertEquals(647 / 60, $this->duration->toMinutes('10:47')); + assertEquals(3600 / 60, $this->duration->toMinutes('1:00:00')); + assertEquals(3601 / 60, $this->duration->toMinutes('1:00:01')); + assertEquals(3611 / 60, $this->duration->toMinutes('1:00:11')); + assertEquals(3660 / 60, $this->duration->toMinutes('1:01:00')); + assertEquals(3674 / 60, $this->duration->toMinutes('1:01:14')); + assertEquals(3865 / 60, $this->duration->toMinutes('1:04:25')); + assertEquals(4149 / 60, $this->duration->toMinutes('1:09:09')); + + // to integer - BC + assertEquals(0, $this->duration->toMinutes('0', true)); + assertEquals(0, $this->duration->toMinutes('4', true)); + assertEquals(0, $this->duration->toMinutes('9', true)); + assertEquals(1, $this->duration->toMinutes('42', true)); + assertEquals(1, $this->duration->toMinutes('1:02', true)); + assertEquals(1, $this->duration->toMinutes('1:09', true)); + assertEquals(2, $this->duration->toMinutes('1:42', true)); + assertEquals(11, $this->duration->toMinutes('10:47', true)); + assertEquals(60, $this->duration->toMinutes('1:00:00', true)); + assertEquals(60, $this->duration->toMinutes('1:00:01', true)); + assertEquals(60, $this->duration->toMinutes('1:00:11', true)); + assertEquals(61, $this->duration->toMinutes('1:01:00', true)); + assertEquals(61, $this->duration->toMinutes('1:01:14', true)); + assertEquals(64, $this->duration->toMinutes('1:04:25', true)); + assertEquals(65, $this->duration->toMinutes('1:04:55', true)); + assertEquals(69, $this->duration->toMinutes('1:09:09', true)); + + // precision + assertEquals(0, $this->duration->toMinutes('0', 0)); + assertEquals(0, $this->duration->toMinutes('4', 0)); + assertEquals(0, $this->duration->toMinutes('9', 0)); + assertEquals(1, $this->duration->toMinutes('42', 0)); + assertEquals(1, $this->duration->toMinutes('1:02', 0)); + assertEquals(1, $this->duration->toMinutes('1:09', 0)); + assertEquals(2, $this->duration->toMinutes('1:42', 0)); + assertEquals(11, $this->duration->toMinutes('10:47', 0)); + assertEquals(60, $this->duration->toMinutes('1:00:00', 0)); + assertEquals(60, $this->duration->toMinutes('1:00:01', 0)); + assertEquals(60, $this->duration->toMinutes('1:00:11', 0)); + assertEquals(61, $this->duration->toMinutes('1:01:00', 0)); + assertEquals(61, $this->duration->toMinutes('1:01:14', 0)); + assertEquals(64, $this->duration->toMinutes('1:04:25', 0)); + assertEquals(65, $this->duration->toMinutes('1:04:55', 0)); + assertEquals(69, $this->duration->toMinutes('1:09:09', 0)); + + assertEquals(0, $this->duration->toMinutes('0', 1)); + assertEquals(0.1, $this->duration->toMinutes('4', 1)); + assertEquals(0.15, $this->duration->toMinutes('9', 2)); + assertEquals(0.7, $this->duration->toMinutes('42', 3)); + assertEquals(1, $this->duration->toMinutes('1:02', 1)); + assertEquals(1.15, $this->duration->toMinutes('1:09', 2)); + assertEquals(1.7, $this->duration->toMinutes('1:42', 3)); + assertEquals(10.8, $this->duration->toMinutes('10:47', 1)); + assertEquals(60, $this->duration->toMinutes('1:00:00', 2)); + assertEquals(60.017, $this->duration->toMinutes('1:00:01', 3)); + assertEquals(60.2, $this->duration->toMinutes('1:00:11', 1)); + assertEquals(61, $this->duration->toMinutes('1:01:00', 2)); + assertEquals(61.233, $this->duration->toMinutes('1:01:14', 3)); + assertEquals(64.42, $this->duration->toMinutes('1:04:25', 2)); + assertEquals(64.92, $this->duration->toMinutes('1:04:55', 2)); + assertEquals(69.15, $this->duration->toMinutes('1:09:09', 2)); +}); + +test('Convert Seconds To Humanized String', function () { + assertEquals('0s', $this->duration->humanize(0)); + assertEquals('4s', $this->duration->humanize(4)); + assertEquals('42s', $this->duration->humanize(42)); + assertEquals('1m 2s', $this->duration->humanize(62)); + assertEquals('1m 42s', $this->duration->humanize(102)); + assertEquals('10m 47s', $this->duration->humanize(647)); + assertEquals('1h', $this->duration->humanize(3600)); + assertEquals('1h 5s', $this->duration->humanize(3605)); + assertEquals('1h 1m', $this->duration->humanize(3660)); + assertEquals('1h 1m 5s', $this->duration->humanize(3665)); + assertEquals('3d', $this->duration->humanize(259200)); + assertEquals('2d 11h 30m', $this->duration->humanize(214200)); + + assertEquals('4.0596s', $this->duration->humanize(4.0596)); + assertEquals('2d 11h 30m 0.9542s', $this->duration->humanize(214200.9542)); + +}); + +test('Convert Humanized String To Seconds', function () { + assertEquals(0, $this->duration->toSeconds('0s')); + assertEquals(4, $this->duration->toSeconds('4s')); + assertEquals(42, $this->duration->toSeconds('42s')); + assertEquals(72, $this->duration->toSeconds('1m 12s')); + assertEquals(102, $this->duration->toSeconds('1m 42s')); + assertEquals(647, $this->duration->toSeconds('10m 47s')); + assertEquals(3600, $this->duration->toSeconds('1h')); + assertEquals(3605, $this->duration->toSeconds('1h 5s')); + assertEquals(3660, $this->duration->toSeconds('1h 1m')); + assertEquals(3665, $this->duration->toSeconds('1h 1m 5s')); + assertEquals(86400, $this->duration->toSeconds('1d')); + assertEquals(214200, $this->duration->toSeconds('2d 11h 30m')); + assertEquals(214214, $this->duration->toSeconds('2d 11h 30m 14s')); +}) + ->depends( + 'Getting Value From Second Suffixes', + 'Getting Value From Minute Suffixes', + 'Getting Value From Hour Suffixes' + ); + +test('Convert Humanized String To Seconds 7 Hour Day', function () { + $d = new Duration(null, 7); + + assertEquals(0, $d->toSeconds('0d')); + assertEquals(25200, $d->toSeconds('1d')); + assertEquals(91800, $d->toSeconds('2d 11h 30m')); +}); + +test('Support Decimals', function () { + $d = new Duration(null, 6); + + assertEquals(0, $d->toMinutes('0d')); + assertEquals(6 * 60, $d->toMinutes('1d')); + assertEquals((6 + 3) * 60, $d->toMinutes('1.5d')); + assertEquals(60, $d->toMinutes('1h')); + assertEquals(60 + 30, $d->toMinutes('1.5h')); + assertEquals((12 * 60) + 60 + 30, $d->toMinutes('2d 1.5h')); +}); + +test('Convert Humanized With Support Decimals', function () { + $t = '1.5d 1.5h 2m 5s'; + + assertEquals('1d 4h 32m 5s', (new Duration($t, 6))->humanize(), "Test humanize with: {$t}"); + assertEquals('10:32:05', (new Duration($t, 6))->formatted(), "Test formatted with: {$t}"); + assertEquals(37925, (new Duration($t, 6))->toSeconds(), "Test toSeconds with: {$t}"); + assertEquals(37925 / 60, (new Duration($t, 6))->toMinutes(), "Test toMinutes with: {$t}"); + assertEquals(632, (new Duration($t, 6))->toMinutes(null, 0), "Test toMinutes with: {$t}"); +}); diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..2fe1a60 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,6 @@ +in(__DIR__); From c8c6ed85fa1a83869e02f4d9bc4b3393d9a4bb14 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Fri, 3 Nov 2023 16:20:28 +0800 Subject: [PATCH 02/16] wip Signed-off-by: Lloric Mayuga Garcia --- src/Duration.php | 93 ++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 67 deletions(-) diff --git a/src/Duration.php b/src/Duration.php index 5c76a91..e216363 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -6,63 +6,30 @@ class Duration { - /** - * @var int|float|null - */ - public $days; + public int|null|float $days; - /** - * @var int|float|null - */ - public $hours; + public int|null|float $hours; - /** - * @var int|float|null - */ - public $minutes; + public int|null|float $minutes; - /** - * @var int|float|null - */ - public $seconds; + public int|null|float $seconds; - /** - * @var int|null - */ - public $hoursPerDay; + public ?int $hoursPerDay; - /** - * @var string|int - */ - private $output; + private string|int|float $output; - /** - * @var string - */ - private $daysRegex; + private string $daysRegex; - /** - * @var string - */ - private $hoursRegex; + private string $hoursRegex; - /** - * @var string - */ - private $minutesRegex; + private string $minutesRegex; - /** - * @var string - */ - private $secondsRegex; + private string $secondsRegex; /** * Duration constructor. - * - * @param int|float|string|null $duration - * @param int $hoursPerDay */ - public function __construct($duration = null, $hoursPerDay = 24) + public function __construct(float|int|string $duration = null, int $hoursPerDay = 24) { $this->reset(); @@ -81,10 +48,10 @@ public function __construct($duration = null, $hoursPerDay = 24) /** * Attempt to parse one of the forms of duration. * - * @param int|float|string|null $duration A string or number, representing a duration + * @param float|int|string|null $duration A string or number, representing a duration * @return self|bool returns the Duration object if successful, otherwise false */ - public function parse($duration) + public function parse(float|int|string|null $duration): bool|Duration|static { $this->reset(); @@ -172,11 +139,10 @@ public function parse($duration) * * For example, one hour and 42 minutes would be "6120" * - * @param int|float|string $duration A string or number, representing a duration - * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. - * @return int|float + * @param float|int|string|null $duration A string or number, representing a duration + * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. */ - public function toSeconds($duration = null, $precision = false) + public function toSeconds(float|int|string $duration = null, bool|int $precision = false): float|int|string|null { if (null !== $duration) { $this->parse($duration); @@ -191,11 +157,10 @@ public function toSeconds($duration = null, $precision = false) * * For example, one hour and 42 minutes would be "102" minutes * - * @param int|float|string $duration A string or number, representing a duration - * @param int|bool $precision Number of decimal digits to round to. If set to false, the number is not rounded. - * @return int|float + * @param float|int|string|null $duration A string or number, representing a duration + * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. */ - public function toMinutes($duration = null, $precision = false) + public function toMinutes(float|int|string $duration = null, bool|int $precision = false): float|int { if (null !== $duration) { $this->parse($duration); @@ -220,11 +185,11 @@ public function toMinutes($duration = null, $precision = false) * - 42 minutes would be "0:42:00" * - 28 seconds would be "0:00:28" * - * @param int|float|string|null $duration A string or number, representing a duration + * @param float|int|string|null $duration A string or number, representing a duration * @param bool $zeroFill A boolean, to force zero-fill result or not (see example) * @return string */ - public function formatted($duration = null, $zeroFill = false) + public function formatted(float|int|string $duration = null, bool $zeroFill = false): int|string { if (null !== $duration) { $this->parse($duration); @@ -275,9 +240,8 @@ public function formatted($duration = null, $zeroFill = false) * For example, one hour and 42 minutes would be "1h 42m" * * @param int|float|string $duration A string or number, representing a duration - * @return string */ - public function humanize($duration = null) + public function humanize(float|int|string $duration = null): string { if (null !== $duration) { $this->parse($duration); @@ -303,10 +267,9 @@ public function humanize($duration = null) } /** - * @param float $number - * @return array|float[]|int[] + * @return array */ - private function numberBreakdown($number) + private function numberBreakdown(float $number): array { $negative = 1; @@ -323,10 +286,8 @@ private function numberBreakdown($number) /** * Resets the Duration object by clearing the output and values. - * - * @return void */ - private function reset() + private function reset(): void { $this->output = ''; $this->seconds = 0.0; @@ -337,10 +298,8 @@ private function reset() /** * Returns the output of the Duration object and resets. - * - * @return string */ - private function output() + private function output(): int|string|float { $out = $this->output; From 8989602015beaa87f2fef2a9e6ddaca7d9079e9b Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Fri, 3 Nov 2023 16:43:58 +0800 Subject: [PATCH 03/16] Fix test Signed-off-by: Lloric Mayuga Garcia --- tests/DurationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/DurationTest.php b/tests/DurationTest.php index de5f355..b1604a6 100755 --- a/tests/DurationTest.php +++ b/tests/DurationTest.php @@ -102,7 +102,7 @@ assertEquals('1:09:09', $this->duration->formatted(4149)); // microseconds - assertEquals('0.0', $this->duration->formatted(0.0)); + assertEquals('0', $this->duration->formatted(0.0)); assertEquals('4.987', $this->duration->formatted(4.987)); assertEquals('9.123', $this->duration->formatted(9.123)); assertEquals('42.672', $this->duration->formatted(42.672)); From 414619bcd1d082db41a7c326100c76fd912f638e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:36:39 +0800 Subject: [PATCH 04/16] wip Signed-off-by: Lloric Mayuga Garcia --- .github/workflows/analyse.yml | 2 +- .github/workflows/tests.yml | 2 +- composer.json | 10 +++--- phpstan.neon.dist => phpstan.neon | 2 +- pint.json | 7 ++-- src/Duration.php | 55 +++++++++++++++---------------- tests/DurationTest.php | 4 +-- 7 files changed, 40 insertions(+), 42 deletions(-) rename phpstan.neon.dist => phpstan.neon (74%) diff --git a/.github/workflows/analyse.yml b/.github/workflows/analyse.yml index f866070..7372b87 100644 --- a/.github/workflows/analyse.yml +++ b/.github/workflows/analyse.yml @@ -21,7 +21,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' coverage: none - name: Install composer dependencies diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 736926d..6e9309e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: true matrix: - php: [8.1, 8.2, 8.3] + php: [8.2, 8.3, 8.4] name: PHP ${{ matrix.php }} diff --git a/composer.json b/composer.json index ed8db73..be872a7 100755 --- a/composer.json +++ b/composer.json @@ -20,13 +20,13 @@ } ], "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { "composer-runtime-api": "^2.2", - "phpstan/phpstan": "^1.10.40", - "pestphp/pest": "^2.24.2", - "laravel/pint": "^1.13.5" + "phpstan/phpstan": "^2.1.12", + "pestphp/pest": "^3.8.2", + "laravel/pint": "^1.22" }, "autoload": { "psr-4": { @@ -36,7 +36,7 @@ "scripts": { "test": "vendor/bin/pest --parallel", "format": "vendor/bin/pint", - "phpstan": "vendor/bin/phpstan" + "analyse": "vendor/bin/phpstan" }, "minimum-stability": "stable", "config": { diff --git a/phpstan.neon.dist b/phpstan.neon similarity index 74% rename from phpstan.neon.dist rename to phpstan.neon index 6e451fa..1d5823a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 6 + level: 7 paths: - src diff --git a/pint.json b/pint.json index e27c478..d441625 100644 --- a/pint.json +++ b/pint.json @@ -8,12 +8,11 @@ "ray.php", "composer-setup.php" ], + "cache-file": "build/pint", "rules": { "declare_strict_types": true, "single_trait_insert_per_statement": true, - "new_with_braces" : { - "anonymous_class": false - }, - "yoda_style": true + "strict_comparison": true, + "strict_param": true } } diff --git a/src/Duration.php b/src/Duration.php index e216363..d8d8dc9 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -29,7 +29,7 @@ class Duration /** * Duration constructor. */ - public function __construct(float|int|string $duration = null, int $hoursPerDay = 24) + public function __construct(float|int|string|null $duration = null, int $hoursPerDay = 24) { $this->reset(); @@ -40,7 +40,7 @@ public function __construct(float|int|string $duration = null, int $hoursPerDay $this->hoursPerDay = $hoursPerDay; - if (null !== $duration) { + if ($duration !== null) { $this->parse($duration); } } @@ -48,14 +48,14 @@ public function __construct(float|int|string $duration = null, int $hoursPerDay /** * Attempt to parse one of the forms of duration. * - * @param float|int|string|null $duration A string or number, representing a duration + * @param float|int|string|null $duration A string or number, representing a duration * @return self|bool returns the Duration object if successful, otherwise false */ public function parse(float|int|string|null $duration): bool|Duration|static { $this->reset(); - if (null === $duration) { + if ($duration === null) { return false; } @@ -90,11 +90,11 @@ public function parse(float|int|string|null $duration): bool|Duration|static if (preg_match('/\:/', $duration)) { $parts = explode(':', $duration); - if (2 == count($parts)) { + if (count($parts) === 2) { $this->minutes = (int) $parts[0]; $this->seconds = (float) $parts[1]; } else { - if (3 == count($parts)) { + if (count($parts) === 3) { $this->hours = (int) $parts[0]; $this->minutes = (int) $parts[1]; $this->seconds = (float) $parts[2]; @@ -139,17 +139,17 @@ public function parse(float|int|string|null $duration): bool|Duration|static * * For example, one hour and 42 minutes would be "6120" * - * @param float|int|string|null $duration A string or number, representing a duration - * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. + * @param float|int|string|null $duration A string or number, representing a duration + * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. */ - public function toSeconds(float|int|string $duration = null, bool|int $precision = false): float|int|string|null + public function toSeconds(float|int|string|null $duration = null, bool|int $precision = false): float|int|string|null { - if (null !== $duration) { + if ($duration !== null) { $this->parse($duration); } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; - return false !== $precision ? round($this->output, $precision) : $this->output; + return $precision !== false ? round($this->output, $precision) : $this->output; } /** @@ -157,24 +157,24 @@ public function toSeconds(float|int|string $duration = null, bool|int $precision * * For example, one hour and 42 minutes would be "102" minutes * - * @param float|int|string|null $duration A string or number, representing a duration - * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. + * @param float|int|string|null $duration A string or number, representing a duration + * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. */ - public function toMinutes(float|int|string $duration = null, bool|int $precision = false): float|int + public function toMinutes(float|int|string|null $duration = null, bool|int $precision = false): float|int { - if (null !== $duration) { + if ($duration !== null) { $this->parse($duration); } // backward compatibility, true = round to integer - if (true === $precision) { + if ($precision === true) { $precision = 0; } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; $result = intval($this->output()) / 60; - return false !== $precision ? round($result, $precision) : $result; + return $precision !== false ? round($result, $precision) : $result; } /** @@ -185,13 +185,12 @@ public function toMinutes(float|int|string $duration = null, bool|int $precision * - 42 minutes would be "0:42:00" * - 28 seconds would be "0:00:28" * - * @param float|int|string|null $duration A string or number, representing a duration - * @param bool $zeroFill A boolean, to force zero-fill result or not (see example) - * @return string + * @param float|int|string|null $duration A string or number, representing a duration + * @param bool $zeroFill A boolean, to force zero-fill result or not (see example) */ - public function formatted(float|int|string $duration = null, bool $zeroFill = false): int|string + public function formatted(float|int|string|null $duration = null, bool $zeroFill = false): string { - if (null !== $duration) { + if ($duration !== null) { $this->parse($duration); } @@ -231,7 +230,7 @@ public function formatted(float|int|string $duration = null, bool $zeroFill = fa } } - return $this->output(); + return (string) $this->output(); } /** @@ -239,15 +238,15 @@ public function formatted(float|int|string $duration = null, bool $zeroFill = fa * * For example, one hour and 42 minutes would be "1h 42m" * - * @param int|float|string $duration A string or number, representing a duration + * @param int|float|string $duration A string or number, representing a duration */ - public function humanize(float|int|string $duration = null): string + public function humanize(float|int|string|null $duration = null): string { - if (null !== $duration) { + if ($duration !== null) { $this->parse($duration); } - if ($this->seconds > 0 || (0.0 === $this->seconds && 0 === $this->minutes && 0 === $this->hours && 0 === $this->days)) { + if ($this->seconds > 0 || ($this->seconds === 0.0 && $this->minutes === 0 && $this->hours === 0 && $this->days === 0)) { $this->output .= $this->seconds.'s'; } @@ -263,7 +262,7 @@ public function humanize(float|int|string $duration = null): string $this->output = $this->days.'d '.$this->output; } - return trim($this->output()); + return trim((string) $this->output()); } /** diff --git a/tests/DurationTest.php b/tests/DurationTest.php index b1604a6..45fb523 100755 --- a/tests/DurationTest.php +++ b/tests/DurationTest.php @@ -2,13 +2,13 @@ declare(strict_types=1); -//declare(strict_types=1); +// declare(strict_types=1); use Khill\Duration\Duration; use function PHPUnit\Framework\assertEquals; -beforeEach(fn () => $this->duration = new Duration()); +beforeEach(fn () => $this->duration = new Duration); dataset('seconds_sample_data', [ [false, null], From 3fa8a57c0b5ed5eaafe2df2b8f7b492b64730240 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:39:00 +0800 Subject: [PATCH 05/16] yoda_style Signed-off-by: Lloric Mayuga Garcia --- pint.json | 3 ++- src/Duration.php | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pint.json b/pint.json index d441625..d303053 100644 --- a/pint.json +++ b/pint.json @@ -13,6 +13,7 @@ "declare_strict_types": true, "single_trait_insert_per_statement": true, "strict_comparison": true, - "strict_param": true + "strict_param": true, + "yoda_style": true } } diff --git a/src/Duration.php b/src/Duration.php index d8d8dc9..e33ce3c 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -40,7 +40,7 @@ public function __construct(float|int|string|null $duration = null, int $hoursPe $this->hoursPerDay = $hoursPerDay; - if ($duration !== null) { + if (null !== $duration) { $this->parse($duration); } } @@ -55,7 +55,7 @@ public function parse(float|int|string|null $duration): bool|Duration|static { $this->reset(); - if ($duration === null) { + if (null === $duration) { return false; } @@ -90,11 +90,11 @@ public function parse(float|int|string|null $duration): bool|Duration|static if (preg_match('/\:/', $duration)) { $parts = explode(':', $duration); - if (count($parts) === 2) { + if (2 === count($parts)) { $this->minutes = (int) $parts[0]; $this->seconds = (float) $parts[1]; } else { - if (count($parts) === 3) { + if (3 === count($parts)) { $this->hours = (int) $parts[0]; $this->minutes = (int) $parts[1]; $this->seconds = (float) $parts[2]; @@ -144,12 +144,12 @@ public function parse(float|int|string|null $duration): bool|Duration|static */ public function toSeconds(float|int|string|null $duration = null, bool|int $precision = false): float|int|string|null { - if ($duration !== null) { + if (null !== $duration) { $this->parse($duration); } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; - return $precision !== false ? round($this->output, $precision) : $this->output; + return false !== $precision ? round($this->output, $precision) : $this->output; } /** @@ -162,19 +162,19 @@ public function toSeconds(float|int|string|null $duration = null, bool|int $prec */ public function toMinutes(float|int|string|null $duration = null, bool|int $precision = false): float|int { - if ($duration !== null) { + if (null !== $duration) { $this->parse($duration); } // backward compatibility, true = round to integer - if ($precision === true) { + if (true === $precision) { $precision = 0; } $this->output = ($this->days * $this->hoursPerDay * 60 * 60) + ($this->hours * 60 * 60) + ($this->minutes * 60) + $this->seconds; $result = intval($this->output()) / 60; - return $precision !== false ? round($result, $precision) : $result; + return false !== $precision ? round($result, $precision) : $result; } /** @@ -190,7 +190,7 @@ public function toMinutes(float|int|string|null $duration = null, bool|int $prec */ public function formatted(float|int|string|null $duration = null, bool $zeroFill = false): string { - if ($duration !== null) { + if (null !== $duration) { $this->parse($duration); } @@ -242,11 +242,11 @@ public function formatted(float|int|string|null $duration = null, bool $zeroFill */ public function humanize(float|int|string|null $duration = null): string { - if ($duration !== null) { + if (null !== $duration) { $this->parse($duration); } - if ($this->seconds > 0 || ($this->seconds === 0.0 && $this->minutes === 0 && $this->hours === 0 && $this->days === 0)) { + if ($this->seconds > 0 || (0.0 === $this->seconds && 0 === $this->minutes && 0 === $this->hours && 0 === $this->days)) { $this->output .= $this->seconds.'s'; } From f5dd6df679c453fb0f5f3c9d41d6353ed670c924 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:47:19 +0800 Subject: [PATCH 06/16] wip Signed-off-by: Lloric Mayuga Garcia --- src/Duration.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Duration.php b/src/Duration.php index e33ce3c..3c246d0 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -140,9 +140,9 @@ public function parse(float|int|string|null $duration): bool|Duration|static * For example, one hour and 42 minutes would be "6120" * * @param float|int|string|null $duration A string or number, representing a duration - * @param bool|int $precision Number of decimal digits to round to. If set to false, the number is not rounded. + * @param int|false $precision Number of decimal digits to round to. If set to false, the number is not rounded. */ - public function toSeconds(float|int|string|null $duration = null, bool|int $precision = false): float|int|string|null + public function toSeconds(float|int|string|null $duration = null, int|false $precision = false): int|float { if (null !== $duration) { $this->parse($duration); From 165481a0da7cb6bf7c499526523ae9517bfd6205 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:52:02 +0800 Subject: [PATCH 07/16] wip Signed-off-by: Lloric Mayuga Garcia --- src/Duration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Duration.php b/src/Duration.php index 3c246d0..672d31e 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -266,7 +266,7 @@ public function humanize(float|int|string|null $duration = null): string } /** - * @return array + * @return list */ private function numberBreakdown(float $number): array { From 70af40d13d28bd422f1a2d0881271299afb199f0 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:53:10 +0800 Subject: [PATCH 08/16] phpstan max level Signed-off-by: Lloric Mayuga Garcia --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 1d5823a..776ccd8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 7 + level: max paths: - src From 21c35db23342d9b1bf2bc31e18ec6d19cf055677 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:53:58 +0800 Subject: [PATCH 09/16] phpstan max level Signed-off-by: Lloric Mayuga Garcia --- src/Duration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Duration.php b/src/Duration.php index 672d31e..c54054a 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -238,7 +238,7 @@ public function formatted(float|int|string|null $duration = null, bool $zeroFill * * For example, one hour and 42 minutes would be "1h 42m" * - * @param int|float|string $duration A string or number, representing a duration + * @param float|int|string|null $duration A string or number, representing a duration */ public function humanize(float|int|string|null $duration = null): string { From bf36312cefa56f65fc460ceea34383b9b52e00e3 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 22:58:11 +0800 Subject: [PATCH 10/16] install rector Signed-off-by: Lloric Mayuga Garcia --- composer.json | 6 ++++-- rector.php | 14 ++++++++++++++ src/Duration.php | 14 +++++--------- 3 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 rector.php diff --git a/composer.json b/composer.json index be872a7..6e6e98f 100755 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "composer-runtime-api": "^2.2", "phpstan/phpstan": "^2.1.12", "pestphp/pest": "^3.8.2", - "laravel/pint": "^1.22" + "laravel/pint": "^1.22", + "rector/rector": "^2.0" }, "autoload": { "psr-4": { @@ -36,7 +37,8 @@ "scripts": { "test": "vendor/bin/pest --parallel", "format": "vendor/bin/pint", - "analyse": "vendor/bin/phpstan" + "analyse": "vendor/bin/phpstan", + "refactor": "vendor/bin/rector process" }, "minimum-stability": "stable", "config": { diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..b959170 --- /dev/null +++ b/rector.php @@ -0,0 +1,14 @@ +withPhpSets() + ->withPaths([ + __DIR__.'/src', + __DIR__.'/tests', + ]) + ->withCache( + cacheDirectory: 'build/rector', + cacheClass: Rector\Caching\ValueObject\Storage\FileCacheStorage::class, + ); diff --git a/src/Duration.php b/src/Duration.php index c54054a..723a1d5 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -14,22 +14,20 @@ class Duration public int|null|float $seconds; - public ?int $hoursPerDay; - private string|int|float $output; - private string $daysRegex; + private readonly string $daysRegex; - private string $hoursRegex; + private readonly string $hoursRegex; - private string $minutesRegex; + private readonly string $minutesRegex; - private string $secondsRegex; + private readonly string $secondsRegex; /** * Duration constructor. */ - public function __construct(float|int|string|null $duration = null, int $hoursPerDay = 24) + public function __construct(float|int|string|null $duration = null, public ?int $hoursPerDay = 24) { $this->reset(); @@ -38,8 +36,6 @@ public function __construct(float|int|string|null $duration = null, int $hoursPe $this->minutesRegex = '/([0-9]{1,2})\s?(?:m|M)/'; $this->secondsRegex = '/([0-9]{1,2}(\.\d+)?)\s?(?:s|S)/'; - $this->hoursPerDay = $hoursPerDay; - if (null !== $duration) { $this->parse($duration); } From 59cfb1851b291f5539cc3da971aceb2cdb27a4fe Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 23:00:13 +0800 Subject: [PATCH 11/16] install rector Signed-off-by: Lloric Mayuga Garcia --- src/Duration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Duration.php b/src/Duration.php index 723a1d5..84615bc 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -67,7 +67,7 @@ public function parse(float|int|string|null $duration): bool|Duration|static $precision = strlen(substr((string) $this->seconds, $delimiterPos + 1)); } - $this->seconds = (float) round(($this->seconds - ($this->minutes * 60)), $precision); + $this->seconds = round(($this->seconds - ($this->minutes * 60)), $precision); } if ($this->minutes >= 60) { From 5d20b093098a5cb1c8ab5afae3f13723077879fe Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 23:02:07 +0800 Subject: [PATCH 12/16] final test Signed-off-by: Lloric Mayuga Garcia --- tests/DurationTest.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/DurationTest.php b/tests/DurationTest.php index 45fb523..52d91bd 100755 --- a/tests/DurationTest.php +++ b/tests/DurationTest.php @@ -2,15 +2,13 @@ declare(strict_types=1); -// declare(strict_types=1); - use Khill\Duration\Duration; use function PHPUnit\Framework\assertEquals; beforeEach(fn () => $this->duration = new Duration); -dataset('seconds_sample_data', [ +dataset('seconds sample data', [ [false, null], [false, ' '], [0, '0 s'], @@ -26,7 +24,7 @@ [1.00342, '1.00342 S'], ]); -dataset('minutes_sample_data', [ +dataset('minutes sample data', [ [0, '0m'], [1, '1 m'], [4, '4 min'], @@ -37,7 +35,7 @@ [11, '11 MINUTE'], ]); -dataset('hours_sample_data', [ +dataset('hours sample data', [ [0, '0h'], [1, '1 h'], [1, '1 hr'], @@ -49,7 +47,7 @@ [36, '36h'], ]); -dataset('days_sample_data', [ +dataset('days sample data', [ [0, '0d'], [1, '1 d'], [1, '1 D'], @@ -64,25 +62,25 @@ $this->duration->parse($secStr); assertEquals($expectedSeconds, $this->duration->seconds); }) - ->with('seconds_sample_data'); + ->with('seconds sample data'); test('Getting Value From Minute Suffixes', function ($intVal, $minStr) { $this->duration->parse($minStr); assertEquals($intVal, $this->duration->minutes); }) - ->with('minutes_sample_data'); + ->with('minutes sample data'); test('Getting Value From Hour Suffixes', function ($intVal, $hrStr) { $this->duration->parse($hrStr); assertEquals($intVal, $this->duration->hours); }) - ->with('hours_sample_data'); + ->with('hours sample data'); test('Getting Value From Day Suffixes', function ($intVal, $dayStr) { $this->duration->parse($dayStr); assertEquals($intVal, $this->duration->days); }) - ->with('days_sample_data'); + ->with('days sample data'); test('Converting Seconds To Formatted String', function () { assertEquals('0', $this->duration->formatted(0)); From eed7c04f473f1049c85ed15f0bb83e07e48fc92e Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 23:10:00 +0800 Subject: [PATCH 13/16] make numeric readable Signed-off-by: Lloric Mayuga Garcia --- tests/DurationTest.php | 144 ++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/tests/DurationTest.php b/tests/DurationTest.php index 52d91bd..2831964 100755 --- a/tests/DurationTest.php +++ b/tests/DurationTest.php @@ -20,8 +20,8 @@ [4, '4 Sec.'], [15, '15 SEcONDs'], [1, '1.0 s'], - [1.5689, '1.5689 S'], - [1.00342, '1.00342 S'], + [1.5_689, '1.5689 S'], + [1.00_342, '1.00342 S'], ]); dataset('minutes sample data', [ @@ -91,13 +91,13 @@ assertEquals('1:09', $this->duration->formatted(69)); assertEquals('1:42', $this->duration->formatted(102)); assertEquals('10:47', $this->duration->formatted(647)); - assertEquals('1:00:00', $this->duration->formatted(3600)); - assertEquals('1:00:01', $this->duration->formatted(3601)); - assertEquals('1:00:11', $this->duration->formatted(3611)); - assertEquals('1:01:00', $this->duration->formatted(3660)); - assertEquals('1:01:14', $this->duration->formatted(3674)); - assertEquals('1:04:25', $this->duration->formatted(3865)); - assertEquals('1:09:09', $this->duration->formatted(4149)); + assertEquals('1:00:00', $this->duration->formatted(3_600)); + assertEquals('1:00:01', $this->duration->formatted(3_601)); + assertEquals('1:00:11', $this->duration->formatted(3_611)); + assertEquals('1:01:00', $this->duration->formatted(3_660)); + assertEquals('1:01:14', $this->duration->formatted(3_674)); + assertEquals('1:04:25', $this->duration->formatted(3_865)); + assertEquals('1:09:09', $this->duration->formatted(4_149)); // microseconds assertEquals('0', $this->duration->formatted(0.0)); @@ -106,15 +106,15 @@ assertEquals('42.672', $this->duration->formatted(42.672)); assertEquals('1:02.23', $this->duration->formatted(62.23)); assertEquals('1:09.9', $this->duration->formatted(69.9)); - assertEquals('1:42.62394', $this->duration->formatted(102.62394)); + assertEquals('1:42.62394', $this->duration->formatted(102.62_394)); assertEquals('10:47.5', $this->duration->formatted(647.5)); - assertEquals('1:00:00.954', $this->duration->formatted(3600.954)); - assertEquals('1:00:01.5123', $this->duration->formatted(3601.5123)); - assertEquals('1:00:11.0412368456', $this->duration->formatted(3611.0412368456)); - assertEquals('1:01:00.56945', $this->duration->formatted(3660.56945)); - assertEquals('1:01:14.3', $this->duration->formatted(3674.3)); - assertEquals('1:04:25.0005598', $this->duration->formatted(3865.0005598)); - assertEquals('1:09:09.123', $this->duration->formatted(4149.123)); + assertEquals('1:00:00.954', $this->duration->formatted(3_600.954)); + assertEquals('1:00:01.5123', $this->duration->formatted(3_601.5_123)); + assertEquals('1:00:11.0412368456', $this->duration->formatted(3_611.0_412_368_456)); + assertEquals('1:01:00.56945', $this->duration->formatted(3_660.56_945)); + assertEquals('1:01:14.3', $this->duration->formatted(3_674.3)); + assertEquals('1:04:25.0005598', $this->duration->formatted(3_865.0_005_598)); + assertEquals('1:09:09.123', $this->duration->formatted(4_149.123)); }); test('Converting Seconds To Formatted String Zero Filled', function () { @@ -126,17 +126,17 @@ assertEquals('0:01:09', $this->duration->formatted(69, true)); assertEquals('0:01:42', $this->duration->formatted(102, true)); assertEquals('0:10:47', $this->duration->formatted(647, true)); - assertEquals('1:00:00', $this->duration->formatted(3600, true)); - assertEquals('1:00:01', $this->duration->formatted(3601, true)); - assertEquals('1:00:11', $this->duration->formatted(3611, true)); - assertEquals('1:01:00', $this->duration->formatted(3660, true)); - assertEquals('1:01:14', $this->duration->formatted(3674, true)); - assertEquals('1:04:25', $this->duration->formatted(3865, true)); - assertEquals('1:09:09', $this->duration->formatted(4149, true)); + assertEquals('1:00:00', $this->duration->formatted(3_600, true)); + assertEquals('1:00:01', $this->duration->formatted(3_601, true)); + assertEquals('1:00:11', $this->duration->formatted(3_611, true)); + assertEquals('1:01:00', $this->duration->formatted(3_660, true)); + assertEquals('1:01:14', $this->duration->formatted(3_674, true)); + assertEquals('1:04:25', $this->duration->formatted(3_865, true)); + assertEquals('1:09:09', $this->duration->formatted(4_149, true)); // microseconds assertEquals('0:00:04.542', $this->duration->formatted(4.542, true)); - assertEquals('1:09:09.0987', $this->duration->formatted(4149.0987, true)); + assertEquals('1:09:09.0987', $this->duration->formatted(4_149.0987, true)); }); test('Converting Formatted Strings To Seconds', function () { @@ -148,13 +148,13 @@ assertEquals(69, $this->duration->toSeconds('1:09')); assertEquals(102, $this->duration->toSeconds('1:42')); assertEquals(647, $this->duration->toSeconds('10:47')); - assertEquals(3600, $this->duration->toSeconds('1:00:00')); - assertEquals(3601, $this->duration->toSeconds('1:00:01')); - assertEquals(3611, $this->duration->toSeconds('1:00:11')); - assertEquals(3660, $this->duration->toSeconds('1:01:00')); - assertEquals(3674, $this->duration->toSeconds('1:01:14')); - assertEquals(3865, $this->duration->toSeconds('1:04:25')); - assertEquals(4149, $this->duration->toSeconds('1:09:09')); + assertEquals(3_600, $this->duration->toSeconds('1:00:00')); + assertEquals(3_601, $this->duration->toSeconds('1:00:01')); + assertEquals(3_611, $this->duration->toSeconds('1:00:11')); + assertEquals(3_660, $this->duration->toSeconds('1:01:00')); + assertEquals(3_674, $this->duration->toSeconds('1:01:14')); + assertEquals(3_865, $this->duration->toSeconds('1:04:25')); + assertEquals(4_149, $this->duration->toSeconds('1:09:09')); // microseconds assertEquals(4.6, $this->duration->toSeconds('4.6')); @@ -164,13 +164,13 @@ assertEquals(69.23, $this->duration->toSeconds('1:09.23')); assertEquals(102.55, $this->duration->toSeconds('1:42.55')); assertEquals(647.999, $this->duration->toSeconds('10:47.999')); - assertEquals(3600.9987, $this->duration->toSeconds('1:00:00.9987')); - assertEquals(3601.000111, $this->duration->toSeconds('1:00:01.000111')); - assertEquals(3611.0999, $this->duration->toSeconds('1:00:11.0999')); - assertEquals(3660.500001, $this->duration->toSeconds('1:01:00.500001')); - assertEquals(3674.00001, $this->duration->toSeconds('1:01:14.00001')); - assertEquals(3865.499999, $this->duration->toSeconds('1:04:25.499999')); - assertEquals(4149.499999, $this->duration->toSeconds('1:09:09.499999')); + assertEquals(3_600.9_987, $this->duration->toSeconds('1:00:00.9987')); + assertEquals(3_601.000_111, $this->duration->toSeconds('1:00:01.000111')); + assertEquals(3_611.0_999, $this->duration->toSeconds('1:00:11.0999')); + assertEquals(3_660.500_001, $this->duration->toSeconds('1:01:00.500001')); + assertEquals(3_674.00_001, $this->duration->toSeconds('1:01:14.00001')); + assertEquals(3_865.499_999, $this->duration->toSeconds('1:04:25.499999')); + assertEquals(4_149.499_999, $this->duration->toSeconds('1:09:09.499999')); // precision assertEquals(0, $this->duration->toSeconds('0', 0)); @@ -181,13 +181,13 @@ assertEquals(69.23, $this->duration->toSeconds('1:09.23')); assertEquals(102.55, $this->duration->toSeconds('1:42.55', 2)); assertEquals(648, $this->duration->toSeconds('10:47.999', 2)); - assertEquals(3601, $this->duration->toSeconds('1:00:00.9987', 2)); - assertEquals(3601, $this->duration->toSeconds('1:00:01.000111', 3)); - assertEquals(3611.0999, $this->duration->toSeconds('1:00:11.0999', 4)); - assertEquals(3660.5, $this->duration->toSeconds('1:01:00.500001', 2)); - assertEquals(3674, $this->duration->toSeconds('1:01:14.00001', 2)); - assertEquals(3865.5, $this->duration->toSeconds('1:04:25.499999', 3)); - assertEquals(4149.499997, $this->duration->toSeconds('1:09:09.4999971', 6)); + assertEquals(3_601, $this->duration->toSeconds('1:00:00.9987', 2)); + assertEquals(3_601, $this->duration->toSeconds('1:00:01.000111', 3)); + assertEquals(3_611.0_999, $this->duration->toSeconds('1:00:11.0999', 4)); + assertEquals(3_660.5, $this->duration->toSeconds('1:01:00.500001', 2)); + assertEquals(3_674, $this->duration->toSeconds('1:01:14.00001', 2)); + assertEquals(3_865.5, $this->duration->toSeconds('1:04:25.499999', 3)); + assertEquals(4_149.499_997, $this->duration->toSeconds('1:09:09.4999971', 6)); }); test('Converting Formatted Strings To Minutes', function () { @@ -199,13 +199,13 @@ assertEquals(69 / 60, $this->duration->toMinutes('1:09')); assertEquals(102 / 60, $this->duration->toMinutes('1:42')); assertEquals(647 / 60, $this->duration->toMinutes('10:47')); - assertEquals(3600 / 60, $this->duration->toMinutes('1:00:00')); - assertEquals(3601 / 60, $this->duration->toMinutes('1:00:01')); - assertEquals(3611 / 60, $this->duration->toMinutes('1:00:11')); - assertEquals(3660 / 60, $this->duration->toMinutes('1:01:00')); - assertEquals(3674 / 60, $this->duration->toMinutes('1:01:14')); - assertEquals(3865 / 60, $this->duration->toMinutes('1:04:25')); - assertEquals(4149 / 60, $this->duration->toMinutes('1:09:09')); + assertEquals(3_600 / 60, $this->duration->toMinutes('1:00:00')); + assertEquals(3_601 / 60, $this->duration->toMinutes('1:00:01')); + assertEquals(3_611 / 60, $this->duration->toMinutes('1:00:11')); + assertEquals(3_660 / 60, $this->duration->toMinutes('1:01:00')); + assertEquals(3_674 / 60, $this->duration->toMinutes('1:01:14')); + assertEquals(3_865 / 60, $this->duration->toMinutes('1:04:25')); + assertEquals(4_149 / 60, $this->duration->toMinutes('1:09:09')); // to integer - BC assertEquals(0, $this->duration->toMinutes('0', true)); @@ -268,15 +268,15 @@ assertEquals('1m 2s', $this->duration->humanize(62)); assertEquals('1m 42s', $this->duration->humanize(102)); assertEquals('10m 47s', $this->duration->humanize(647)); - assertEquals('1h', $this->duration->humanize(3600)); - assertEquals('1h 5s', $this->duration->humanize(3605)); - assertEquals('1h 1m', $this->duration->humanize(3660)); - assertEquals('1h 1m 5s', $this->duration->humanize(3665)); - assertEquals('3d', $this->duration->humanize(259200)); - assertEquals('2d 11h 30m', $this->duration->humanize(214200)); + assertEquals('1h', $this->duration->humanize(3_600)); + assertEquals('1h 5s', $this->duration->humanize(3_605)); + assertEquals('1h 1m', $this->duration->humanize(3_660)); + assertEquals('1h 1m 5s', $this->duration->humanize(3_665)); + assertEquals('3d', $this->duration->humanize(259_200)); + assertEquals('2d 11h 30m', $this->duration->humanize(214_200)); - assertEquals('4.0596s', $this->duration->humanize(4.0596)); - assertEquals('2d 11h 30m 0.9542s', $this->duration->humanize(214200.9542)); + assertEquals('4.0596s', $this->duration->humanize(4.0_596)); + assertEquals('2d 11h 30m 0.9542s', $this->duration->humanize(214_200.9_542)); }); @@ -287,13 +287,13 @@ assertEquals(72, $this->duration->toSeconds('1m 12s')); assertEquals(102, $this->duration->toSeconds('1m 42s')); assertEquals(647, $this->duration->toSeconds('10m 47s')); - assertEquals(3600, $this->duration->toSeconds('1h')); - assertEquals(3605, $this->duration->toSeconds('1h 5s')); - assertEquals(3660, $this->duration->toSeconds('1h 1m')); - assertEquals(3665, $this->duration->toSeconds('1h 1m 5s')); - assertEquals(86400, $this->duration->toSeconds('1d')); - assertEquals(214200, $this->duration->toSeconds('2d 11h 30m')); - assertEquals(214214, $this->duration->toSeconds('2d 11h 30m 14s')); + assertEquals(3_600, $this->duration->toSeconds('1h')); + assertEquals(3_605, $this->duration->toSeconds('1h 5s')); + assertEquals(3_660, $this->duration->toSeconds('1h 1m')); + assertEquals(3_665, $this->duration->toSeconds('1h 1m 5s')); + assertEquals(86_400, $this->duration->toSeconds('1d')); + assertEquals(214_200, $this->duration->toSeconds('2d 11h 30m')); + assertEquals(214_214, $this->duration->toSeconds('2d 11h 30m 14s')); }) ->depends( 'Getting Value From Second Suffixes', @@ -305,8 +305,8 @@ $d = new Duration(null, 7); assertEquals(0, $d->toSeconds('0d')); - assertEquals(25200, $d->toSeconds('1d')); - assertEquals(91800, $d->toSeconds('2d 11h 30m')); + assertEquals(25_200, $d->toSeconds('1d')); + assertEquals(91_800, $d->toSeconds('2d 11h 30m')); }); test('Support Decimals', function () { @@ -325,7 +325,7 @@ assertEquals('1d 4h 32m 5s', (new Duration($t, 6))->humanize(), "Test humanize with: {$t}"); assertEquals('10:32:05', (new Duration($t, 6))->formatted(), "Test formatted with: {$t}"); - assertEquals(37925, (new Duration($t, 6))->toSeconds(), "Test toSeconds with: {$t}"); - assertEquals(37925 / 60, (new Duration($t, 6))->toMinutes(), "Test toMinutes with: {$t}"); + assertEquals(37_925, (new Duration($t, 6))->toSeconds(), "Test toSeconds with: {$t}"); + assertEquals(37_925 / 60, (new Duration($t, 6))->toMinutes(), "Test toMinutes with: {$t}"); assertEquals(632, (new Duration($t, 6))->toMinutes(null, 0), "Test toMinutes with: {$t}"); }); From 4ce50d71ff17e81634f1bfabd9b1d68a96c18da8 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sat, 26 Apr 2025 23:18:44 +0800 Subject: [PATCH 14/16] add gitattributes Signed-off-by: Lloric Mayuga Garcia --- .gitattributes | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..745bf99 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,18 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.github export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.idea export-ignore +/.vscode export-ignore +/tests export-ignore +/phpstan-baseline.neon export-ignore +/phpstan.neon export-ignore +/phpunit.xml export-ignore +/pint.json export-ignore +/UPGRADING.md export-ignore +/ray.php export-ignore +/.run export-ignore +/rector export-ignore From 0ea018bd6321491311d4fe8ca1423dca14fc7ca3 Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sun, 27 Apr 2025 02:16:29 +0800 Subject: [PATCH 15/16] Update Duration.php --- src/Duration.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Duration.php b/src/Duration.php index 84615bc..54ec695 100755 --- a/src/Duration.php +++ b/src/Duration.php @@ -24,9 +24,6 @@ class Duration private readonly string $secondsRegex; - /** - * Duration constructor. - */ public function __construct(float|int|string|null $duration = null, public ?int $hoursPerDay = 24) { $this->reset(); From ff10a3ee1ca59a4c3d8f2a3d3e1727cf3fda2eac Mon Sep 17 00:00:00 2001 From: Lloric Mayuga Garcia Date: Sun, 27 Apr 2025 08:47:33 +0800 Subject: [PATCH 16/16] Update .gitattributes --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 745bf99..18c9e75 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,4 +15,4 @@ /UPGRADING.md export-ignore /ray.php export-ignore /.run export-ignore -/rector export-ignore +/rector.php export-ignore