diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..39c176a --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,27 @@ +name: Tests + +env: + PHP_VERSION: 8.2 + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Test + run: ./vendor/bin/phpunit \ No newline at end of file diff --git a/.gitignore b/.gitignore index d5f2109..32bff83 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ composer.phar composer.lock /vendor/ .phpunit.result.cache +.phpunit.cache +.phpcs-cache diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 691473c..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,22 +0,0 @@ -filter: - excluded_paths: - - "tests/" - -checks: - php: - code_rating: true - duplication: true - -build: - nodes: - analysis: - tests: - override: - - php-scrutinizer-run - coverage: - tests: - override: - - command: './vendor/bin/phpunit --coverage-clover=clover.xml' - coverage: - file: 'clover.xml' - format: 'clover' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fdf799f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: php - -php: - - 7.4 - - 8.0snapshot - -before_script: - - composer selfupdate - - composer install --prefer-dist - -notifications: - email: false diff --git a/README.md b/README.md index 28bb394..d24e95b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -[![Build Status](https://travis-ci.org/cgauge/task-manager-lib.svg?branch=master)](https://travis-ci.org/cgauge/task-manager-lib) -[![Code Coverage](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/?branch=master) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/?branch=master) - # Task Manager ⚙️ # Installation diff --git a/composer.json b/composer.json index dcc0f14..569d241 100644 --- a/composer.json +++ b/composer.json @@ -13,12 +13,12 @@ } ], "require": { - "php": ">=7.4" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.5", - "doctrine/coding-standard": "^8.0", - "phpstan/phpstan": "^0.12.64" + "phpunit/phpunit": "^10.0", + "doctrine/coding-standard": "^12.0", + "phpstan/phpstan": "^1.0" }, "autoload": { "psr-4": { @@ -29,5 +29,10 @@ "psr-4": { "Test\\CustomerGauge\\TaskManager\\": "tests/" } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..c0e526a --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,18 @@ + + + + + + + + + + + + + src + tests + + + + \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 47d2d6b..24ef2ee 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,23 +1,22 @@ - - - ./src - - + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" + backupGlobals="false" + bootstrap="vendor/autoload.php" + colors="true" + processIsolation="false" + stopOnFailure="false" + cacheDirectory=".phpunit.cache" + backupStaticProperties="false"> + ./tests + + + ./src + + diff --git a/src/InvalidTaskAttribute.php b/src/InvalidTaskAttribute.php index 3e3ab11..4134970 100644 --- a/src/InvalidTaskAttribute.php +++ b/src/InvalidTaskAttribute.php @@ -24,21 +24,19 @@ namespace CustomerGauge\TaskManager; use InvalidArgumentException; -use function get_class; + use function implode; use function sprintf; class InvalidTaskAttribute extends InvalidArgumentException { - /** - * @param array $keys - */ - public static function duplicatedKey(Task $task, array $keys) : self + /** @param array $keys */ + public static function duplicatedKey(Task $task, array $keys): self { $message = sprintf( 'Duplicate task [%s] attribute keys [%s]. Use a different attribute key.', - get_class($task), - implode(', ', $keys) + $task::class, + implode(', ', $keys), ); return new static($message); diff --git a/src/Reversible.php b/src/Reversible.php index 3cdc3a1..83bb9f9 100644 --- a/src/Reversible.php +++ b/src/Reversible.php @@ -25,8 +25,6 @@ interface Reversible { - /** - * @param mixed[] $attributes - */ - public function reverse(array $attributes) : void; + /** @param mixed[] $attributes */ + public function reverse(array $attributes): void; } diff --git a/src/Strategy/ContinueOnFailure.php b/src/Strategy/ContinueOnFailure.php index 1f395a5..1e8d915 100644 --- a/src/Strategy/ContinueOnFailure.php +++ b/src/Strategy/ContinueOnFailure.php @@ -28,12 +28,10 @@ class ContinueOnFailure implements Strategy { /** @var Throwable[] */ - private $exceptions = []; + private array $exceptions = []; - /** - * @param mixed[] $context - */ - public function execute(callable $callback, array $context = []) : void + /** @param mixed[] $context */ + public function execute(callable $callback, array $context = []): void { try { $callback(); @@ -42,10 +40,8 @@ public function execute(callable $callback, array $context = []) : void } } - /** - * @return Throwable[] - */ - public function exceptions() : array + /** @return Throwable[] */ + public function exceptions(): array { return $this->exceptions; } diff --git a/src/Strategy/RollbackOnFailure.php b/src/Strategy/RollbackOnFailure.php index f09a646..ca068c1 100644 --- a/src/Strategy/RollbackOnFailure.php +++ b/src/Strategy/RollbackOnFailure.php @@ -26,21 +26,20 @@ use CustomerGauge\TaskManager\Reversible; use CustomerGauge\TaskManager\Task; use Throwable; + use function array_filter; use function array_unshift; class RollbackOnFailure implements Strategy { /** @var Task[] */ - private $executed = []; + private array $executed = []; /** @var mixed[] */ - private $context; + private array $context; - /** - * @param mixed[] $context - */ - public function execute(callable $callback, array $context = []) : void + /** @param mixed[] $context */ + public function execute(callable $callback, array $context = []): void { $this->context = $context; @@ -48,14 +47,14 @@ public function execute(callable $callback, array $context = []) : void $task = $callback(); array_unshift($this->executed, $task); - } catch (Throwable $e) { + } catch (Throwable) { $this->rollback(); } } - public function rollback() : void + public function rollback(): void { - $tasks = array_filter($this->executed, static function ($task) : bool { + $tasks = array_filter($this->executed, static function ($task): bool { return $task instanceof Reversible; }); diff --git a/src/Strategy/StopOnFailure.php b/src/Strategy/StopOnFailure.php index 7e54164..8296346 100644 --- a/src/Strategy/StopOnFailure.php +++ b/src/Strategy/StopOnFailure.php @@ -25,10 +25,8 @@ class StopOnFailure implements Strategy { - /** - * @param mixed[] $context - */ - public function execute(callable $callback, array $context = []) : void + /** @param mixed[] $context */ + public function execute(callable $callback, array $context = []): void { $callback(); } diff --git a/src/Strategy/Strategy.php b/src/Strategy/Strategy.php index 50de9e0..ee1716a 100644 --- a/src/Strategy/Strategy.php +++ b/src/Strategy/Strategy.php @@ -25,8 +25,6 @@ interface Strategy { - /** - * @param mixed[] $context - */ - public function execute(callable $callback, array $context = []) : void; + /** @param mixed[] $context */ + public function execute(callable $callback, array $context = []): void; } diff --git a/src/Task.php b/src/Task.php index 1e4d661..2851140 100644 --- a/src/Task.php +++ b/src/Task.php @@ -30,5 +30,5 @@ interface Task * * @return mixed[] */ - public function run(array $attributes) : array; + public function run(array $attributes): array; } diff --git a/src/TaskManager.php b/src/TaskManager.php index 80572eb..b87ab2a 100644 --- a/src/TaskManager.php +++ b/src/TaskManager.php @@ -25,6 +25,7 @@ use CustomerGauge\TaskManager\Strategy\StopOnFailure; use CustomerGauge\TaskManager\Strategy\Strategy; + use function array_filter; use function array_intersect_key; use function array_keys; @@ -32,21 +33,20 @@ class TaskManager implements Task { - /** @var Task[] */ - private $tasks = []; + /** @var Task[]|Reversible[] */ + private array $tasks = []; /** @var mixed[] */ - private $attributes = []; + private array $attributes = []; - /** @var Strategy */ - private $strategy; + private Strategy $strategy; - public function __construct(?Strategy $strategy = null) + public function __construct(Strategy|null $strategy = null) { $this->strategy = $strategy ?? new StopOnFailure(); } - public function add(Task $task) : self + public function add(Task $task): self { $this->tasks[] = $task; @@ -58,12 +58,12 @@ public function add(Task $task) : self * * @return mixed[] */ - public function run(array $attributes) : array + public function run(array $attributes): array { $this->attributes = $attributes; foreach ($this->tasks as $task) { - $this->strategy->execute(function () use ($task) : Task { + $this->strategy->execute(function () use ($task): Task { $attributes = $task->run($this->attributes); $this->checkForDuplicatedKey($task, $attributes); @@ -77,28 +77,24 @@ public function run(array $attributes) : array return $this->attributes; } - /** - * @param mixed[] $attributes - */ - public function reverse(array $attributes) : void + /** @param mixed[] $attributes */ + public function reverse(array $attributes): void { $tasks = array_reverse($this->tasks); - $tasks = array_filter($tasks, static function ($task) : bool { + $tasks = array_filter($tasks, static function ($task): bool { return $task instanceof Reversible; }); foreach ($this->tasks as $task) { - $this->strategy->execute(function () use ($task, $attributes) : void { + $this->strategy->execute(static function () use ($task, $attributes): void { $task->reverse($attributes); }, $attributes); } } - /** - * @param mixed[] $attributes - */ - private function checkForDuplicatedKey(Task $task, array $attributes) : void + /** @param mixed[] $attributes */ + private function checkForDuplicatedKey(Task $task, array $attributes): void { $duplicated = array_intersect_key($this->attributes, $attributes); diff --git a/tests/Strategy/ContinueOnFailureTest.php b/tests/Strategy/ContinueOnFailureTest.php index e34221f..249a66b 100644 --- a/tests/Strategy/ContinueOnFailureTest.php +++ b/tests/Strategy/ContinueOnFailureTest.php @@ -30,7 +30,7 @@ class ContinueOnFailureTest extends TestCase { - public function test_it_continues_when_a_task_fail() : void + public function test_it_continues_when_a_task_fail(): void { $createEmail = $this->createMock(Task::class); $createFolder = $this->createMock(Task::class); @@ -43,16 +43,16 @@ public function test_it_continues_when_a_task_fail() : void $strategy = new ContinueOnFailure(); - $strategy->execute(static function () use ($createEmail) : void { + $strategy->execute(static function () use ($createEmail): void { $createEmail->run([]); }); - $strategy->execute(static function () use ($createFolder) : void { + $strategy->execute(static function () use ($createFolder): void { $createFolder->run([]); }); } - public function test_it_stores_exceptions() : void + public function test_it_stores_exceptions(): void { $createEmail = $this->createMock(Task::class); $createFolder = $this->createMock(Task::class); @@ -65,11 +65,11 @@ public function test_it_stores_exceptions() : void $strategy = new ContinueOnFailure(); - $strategy->execute(static function () use ($createEmail) : void { + $strategy->execute(static function () use ($createEmail): void { $createEmail->run([]); }); - $strategy->execute(static function () use ($createFolder) : void { + $strategy->execute(static function () use ($createFolder): void { $createFolder->run([]); }); diff --git a/tests/Strategy/RollbackOnFailureTest.php b/tests/Strategy/RollbackOnFailureTest.php index b331765..14639a9 100644 --- a/tests/Strategy/RollbackOnFailureTest.php +++ b/tests/Strategy/RollbackOnFailureTest.php @@ -31,7 +31,7 @@ class RollbackOnFailureTest extends TestCase { - public function test_it_rollback_when_a_task_fail() : void + public function test_it_rollback_when_a_task_fail(): void { $createEmail = $this->createMock(ReversibleTask::class); $createFolder = $this->createMock(Task::class); @@ -53,7 +53,7 @@ public function test_it_rollback_when_a_task_fail() : void return $createEmail; }); - $strategy->execute(static function () use ($createFolder) : void { + $strategy->execute(static function () use ($createFolder): void { $createFolder->run([]); }); } diff --git a/tests/Strategy/StopOnFailureTest.php b/tests/Strategy/StopOnFailureTest.php index ddffaa3..6106477 100644 --- a/tests/Strategy/StopOnFailureTest.php +++ b/tests/Strategy/StopOnFailureTest.php @@ -31,7 +31,7 @@ class StopOnFailureTest extends TestCase { - public function test_it_stops_when_a_task_fail() : void + public function test_it_stops_when_a_task_fail(): void { self::expectException(Throwable::class); @@ -46,7 +46,7 @@ public function test_it_stops_when_a_task_fail() : void $strategy = new StopOnFailure(); - $strategy->execute(static function () use ($createEmail, $createFolder) : void { + $strategy->execute(static function () use ($createEmail, $createFolder): void { $createEmail->run([]); $createFolder->run([]); diff --git a/tests/TaskManagerTest.php b/tests/TaskManagerTest.php index 82c361c..5653d80 100644 --- a/tests/TaskManagerTest.php +++ b/tests/TaskManagerTest.php @@ -24,14 +24,14 @@ namespace Tests\CustomerGauge\TaskManager; use CustomerGauge\TaskManager\InvalidTaskAttribute; -use CustomerGauge\TaskManager\Task; use CustomerGauge\TaskManager\Reversible; +use CustomerGauge\TaskManager\Task; use CustomerGauge\TaskManager\TaskManager; use PHPUnit\Framework\TestCase; class TaskManagerTest extends TestCase { - public function test_it_can_run_tasks() : void + public function test_it_can_run_tasks(): void { $createEmail = $this->createMock(Task::class); $createFolder = $this->createMock(Task::class); @@ -50,7 +50,7 @@ public function test_it_can_run_tasks() : void $manager->run([]); } - public function test_it_can_manage_attributes() : void + public function test_it_can_manage_attributes(): void { $createEmail = $this->createMock(Task::class); $createFolder = $this->createMock(Task::class); @@ -75,7 +75,7 @@ public function test_it_can_manage_attributes() : void $manager->run([]); } - public function test_task_can_not_use_same_key_in_attributes() : void + public function test_task_can_not_use_same_key_in_attributes(): void { $this->expectException(InvalidTaskAttribute::class); @@ -96,7 +96,7 @@ public function test_task_can_not_use_same_key_in_attributes() : void $manager->run([]); } - public function test_task_can_be_revertable() : void + public function test_task_can_be_revertable(): void { $createEmail = $this->createMock(ReversibleTask::class); $createFolder = $this->createMock(ReversibleTask::class);