diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d667097..6b22e2e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,42 +1,37 @@ +# .github/workflows/tests.yaml name: Tests -on: [push] +on: ["push", "pull_request"] jobs: - phpunit73: - name: "Tests on PHP 7.3" + tests: runs-on: ubuntu-latest - container: - image: lorisleiva/laravel-docker:7.3 - steps: - - uses: actions/checkout@v2 - - name: Validate composer.json and composer.lock - run: composer validate - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: /composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.json') }} - - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest - - name: Run tests - run: phpunit - - phpunit74: - name: "Tests on PHP 7.4" - runs-on: ubuntu-latest - container: - image: lorisleiva/laravel-docker:7.4 + strategy: + fail-fast: false + matrix: + php: ['7.4', '8.0', '8.1'] + stability: [ prefer-lowest, prefer-stable ] + + name: PHP ${{ matrix.php }} - ${{ matrix.stability }} tests steps: - - uses: actions/checkout@v2 - - name: Validate composer.json and composer.lock - run: composer validate - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: /composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.json') }} - - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest - - name: Run tests - run: phpunit + # basically git clone + - uses: actions/checkout@v2 + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache/files + key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + + # use PHP of specific version + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: pcov + coverage: pcov + + - name: Install dependencies + run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --no-suggest + + - name: Execute tests + run: vendor/bin/phpunit --verbose diff --git a/composer.json b/composer.json index 69bf80b..1853c3d 100644 --- a/composer.json +++ b/composer.json @@ -16,10 +16,10 @@ } ], "require": { - "php" : "^7.3 || ^8.0" + "php" : "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit" : "^8.0" + "phpunit/phpunit" : "^8.5.21 || ^9.5" }, "autoload": { "psr-4": { @@ -30,7 +30,5 @@ "psr-4": { "Lorisleiva\\CronTranslator\\Tests\\": "tests" } - }, - "minimum-stability": "dev", - "prefer-stable": true + } } diff --git a/phpunit.xml b/phpunit.xml index 8ebf05d..d543c47 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,6 @@ - - - - ./tests - - - - - ./src - - - \ No newline at end of file + stopOnFailure="false" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + + + ./src + + + + + ./tests + + + diff --git a/src/CronExpression.php b/src/CronExpression.php index 1b71e19..f129e11 100644 --- a/src/CronExpression.php +++ b/src/CronExpression.php @@ -4,32 +4,15 @@ class CronExpression { - /** @var string */ - public $raw; - - /** @var MinutesField */ - public $minute; - - /** @var HoursField */ - public $hour; - - /** @var DaysOfMonthField */ - public $day; - - /** @var MonthsField */ - public $month; - - /** @var DaysOfWeekField */ - public $weekday; - - /** @var string */ - public $locale; - - /** @var bool */ - public $timeFormat24hours; - - /** @var array */ - public $translations; + public string $raw; + public MinutesField $minute; + public HoursField $hour; + public DaysOfMonthField $day; + public MonthsField $month; + public DaysOfWeekField $weekday; + public string $locale; + public bool $timeFormat24hours; + public array $translations; public function __construct(string $cron, string $locale = 'en', bool $timeFormat24hours = false) { @@ -46,7 +29,7 @@ public function __construct(string $cron, string $locale = 'en', bool $timeForma $this->loadTranslations(); } - public function getFields() + public function getFields(): array { return [ $this->minute, @@ -61,9 +44,7 @@ public function langCountable(string $type, int $number) { $array = $this->translations[$type]; - $value = isset($array[$number]) - ? $array[$number] - : ($array['default'] ?: ''); + $value = $array[$number] ?? ($array['default'] ?: ''); return str_replace(':number', $number, $value); } @@ -86,6 +67,9 @@ protected function ensureLocaleExists(string $fallbackLocale = 'en') } } + /** + * @throws TranslationFileMissingException + */ protected function loadTranslations() { $this->translations = [ @@ -108,7 +92,7 @@ protected function loadTranslationFile(string $file) return include $filename; } - protected function getTranslationDirectory() + protected function getTranslationDirectory(): string { return __DIR__ . '/lang/' . $this->locale; } diff --git a/src/CronTranslator.php b/src/CronTranslator.php index be1b275..c1ff48b 100644 --- a/src/CronTranslator.php +++ b/src/CronTranslator.php @@ -6,7 +6,7 @@ class CronTranslator { - private static $extendedMap = [ + private static array $extendedMap = [ '@yearly' => '0 0 1 1 *', '@annually' => '0 0 1 1 *', '@monthly' => '0 0 1 * *', @@ -15,7 +15,7 @@ class CronTranslator '@hourly' => '0 * * * *' ]; - public static function translate(string $cron, string $locale = 'en', bool $timeFormat24hours = false) + public static function translate(string $cron, string $locale = 'en', bool $timeFormat24hours = false): string { if (isset(self::$extendedMap[$cron])) { $cron = self::$extendedMap[$cron]; @@ -67,7 +67,7 @@ protected static function orderFields(array $fields) ); } - protected static function filterType(array $fields, ...$types) + protected static function filterType(array $fields, ...$types): array { return array_filter($fields, function (Field $field) use ($types) { return $field->hasType(...$types); diff --git a/src/CronType.php b/src/CronType.php index ff41032..3c4629b 100644 --- a/src/CronType.php +++ b/src/CronType.php @@ -8,17 +8,10 @@ class CronType 'Every', 'Increment', 'Multiple', 'Once', ]; - /** @var string */ - public $type; - - /** @var ?int */ - public $value; - - /** @var ?int */ - public $count; - - /** @var ?int */ - public $increment; + public string $type; + public ?int $value; + public ?int $count; + public ?int $increment; private function __construct(string $type, ?int $value = null, ?int $count = null, ?int $increment = null) { @@ -28,27 +21,30 @@ private function __construct(string $type, ?int $value = null, ?int $count = nul $this->increment = $increment; } - public static function every() + public static function every(): CronType { return new static('Every'); } - public static function increment(int $increment, int $count = 1) + public static function increment(int $increment, int $count = 1): CronType { return new static('Increment', null, $count, $increment); } - public static function multiple(int $count) + public static function multiple(int $count): CronType { return new static('Multiple', null, $count); } - public static function once(int $value) + public static function once(int $value): CronType { return new static('Once', $value); } - public static function parse(string $expression) + /** + * @throws CronParsingException + */ + public static function parse(string $expression): CronType { // Parse "*". if ($expression === '*') { @@ -88,7 +84,7 @@ public static function parse(string $expression) throw new CronParsingException($expression); } - public function hasType() + public function hasType(): bool { return in_array($this->type, func_get_args()); } diff --git a/src/DaysOfMonthField.php b/src/DaysOfMonthField.php index 5461cef..16143f2 100644 --- a/src/DaysOfMonthField.php +++ b/src/DaysOfMonthField.php @@ -4,7 +4,7 @@ class DaysOfMonthField extends Field { - public $position = 2; + public int $position = 2; public function translateEvery() { @@ -38,16 +38,16 @@ public function translateMultiple() ]); } - public function translateOnce() + public function translateOnce(): ?string { $month = $this->expression->month; if ($month->hasType('Once')) { - return; // MonthsField adapts to "On January the 1st". + return null; // MonthsField adapts to "On January the 1st". } if ($month->hasType('Every') && ! $month->dropped) { - return; // MonthsField adapts to "The 1st of every month". + return null; // MonthsField adapts to "The 1st of every month". } if ($month->hasType('Every') && $month->dropped) { diff --git a/src/DaysOfWeekField.php b/src/DaysOfWeekField.php index 7ed1ecf..60a615a 100644 --- a/src/DaysOfWeekField.php +++ b/src/DaysOfWeekField.php @@ -4,7 +4,7 @@ class DaysOfWeekField extends Field { - public $position = 4; + public int $position = 4; public function translateEvery() { @@ -43,7 +43,7 @@ public function translateOnce() ]); } - public function format() + public function format(): string { $weekday = $this->getValue() === 0 ? 7 : $this->getValue(); diff --git a/src/Field.php b/src/Field.php index f1f314f..83470b4 100644 --- a/src/Field.php +++ b/src/Field.php @@ -4,20 +4,11 @@ abstract class Field { - /** @var CronExpression */ - public $expression; - - /** @var string */ - public $rawField; - - /** @var CronType */ - public $type; - - /** @var bool */ - public $dropped = false; - - /** @var int */ - public $position; + public CronExpression $expression; + public string $rawField; + public CronType $type; + public bool $dropped = false; + public int $position; public function __construct(CronExpression $expression, string $rawField) { @@ -35,22 +26,22 @@ public function translate() } } - public function hasType() + public function hasType(): bool { return $this->type->hasType(...func_get_args()); } - public function getValue() + public function getValue(): ?int { return $this->type->value; } - public function getCount() + public function getCount(): ?int { return $this->type->count; } - public function getIncrement() + public function getIncrement(): ?int { return $this->type->increment; } diff --git a/src/HoursField.php b/src/HoursField.php index 4e20290..7bb91c3 100644 --- a/src/HoursField.php +++ b/src/HoursField.php @@ -4,7 +4,7 @@ class HoursField extends Field { - public $position = 1; + public int $position = 1; public function translateEvery() { @@ -66,7 +66,7 @@ public function translateOnce() ]); } - public function format(?MinutesField $minute = null) + public function format(?MinutesField $minute = null): string { if ($this->expression->timeFormat24hours) { $hour = $this->getValue(); diff --git a/src/MinutesField.php b/src/MinutesField.php index b17c527..926efb1 100644 --- a/src/MinutesField.php +++ b/src/MinutesField.php @@ -4,7 +4,7 @@ class MinutesField extends Field { - public $position = 0; + public int $position = 0; public function translateEvery() { @@ -32,7 +32,7 @@ public function translateMultiple() ]); } - public function format() + public function format(): string { return ($this->getValue() < 10 ? '0' : '') . $this->getValue(); } diff --git a/src/MonthsField.php b/src/MonthsField.php index ab2343a..71b54a2 100644 --- a/src/MonthsField.php +++ b/src/MonthsField.php @@ -4,7 +4,7 @@ class MonthsField extends Field { - public $position = 3; + public int $position = 3; public function translateEvery() { @@ -52,6 +52,9 @@ public function translateOnce() ]); } + /** + * @throws CronParsingException + */ public function format() { if ($this->getValue() < 1 || $this->getValue() > 12) { diff --git a/tests/TestCase.php b/tests/TestCase.php index 39301c5..e9c4c3b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,12 +8,12 @@ class TestCase extends BaseTestCase { - public function assertCronTranslateTo($expected, $actual, $locale = 'en', $timeFormat24hours = false) + public function assertCronTranslateTo(string $expected, string $actual, string $locale = 'en', bool $timeFormat24hours = false) { $this->assertEquals($expected, CronTranslator::translate($actual, $locale, $timeFormat24hours)); } - public function assertCronThrowsParsingError($cron) + public function assertCronThrowsParsingError(string $cron) { try { CronTranslator::translate($cron); @@ -25,9 +25,10 @@ public function assertCronThrowsParsingError($cron) $this->fail("Expected CronParsingError exception for [$cron]"); } - public function generateCombinationsFromMatrix($matrix, $locale = 'en', $timeFormat24hours = false) + public function generateCombinationsFromMatrix(array $matrix, string $locale = 'en', bool $timeFormat24hours = false) { - function combinations($matrix, $acc = []) { + function combinations($matrix, $acc = []): array + { if (empty($matrix)) { return [implode(' ', $acc)]; }