From f64f44f20bd70d6d064dd88908d20ad2c40c770b Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 15 Nov 2023 22:49:51 +0100 Subject: [PATCH 1/2] feat: install netlogix/coding-guidelines-php --- composer.json | 5 ++++- ecs.php | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 ecs.php diff --git a/composer.json b/composer.json index c958cac..4db05c6 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,8 @@ }, "require-dev": { "phpunit/phpunit": "*", - "infection/infection": "*" + "infection/infection": "*", + "netlogix/coding-guidelines-php": "^1.0" }, "config": { "allow-plugins": { @@ -28,6 +29,8 @@ } }, "scripts": { + "lint": "ecs check", + "lint-fix": "ecs check --fix", "test": "phpunit", "infection": "infection", "test-coverage": "XDEBUG_MODE=coverage phpunit --coverage-html=coverage" diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..07470a0 --- /dev/null +++ b/ecs.php @@ -0,0 +1,17 @@ +configure($ecsConfig); + + $ecsConfig->paths( + [ + __DIR__ . '/src', + __DIR__ . '/tests', + ] + ); +}; From da9634a7da2a1413c562b0f7e06fd2c06be47aa1 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 15 Nov 2023 22:50:06 +0100 Subject: [PATCH 2/2] refactor: apply ecs --- src/ResettableTaskPoolInterface.php | 8 +++--- src/Task.php | 18 ++++++------ src/TaskGraph.php | 27 ++++++++++-------- src/TaskInterface.php | 14 ++++----- src/TaskPool.php | 28 ++++++++++-------- src/TaskPoolInterface.php | 12 +++++--- tests/Unit/TaskGraphTest.php | 25 +++++++++------- tests/Unit/TaskPoolTest.php | 44 ++++++++++++++++++----------- tests/Unit/TaskTest.php | 3 +- 9 files changed, 105 insertions(+), 74 deletions(-) diff --git a/src/ResettableTaskPoolInterface.php b/src/ResettableTaskPoolInterface.php index 95d8b73..d151a8f 100644 --- a/src/ResettableTaskPoolInterface.php +++ b/src/ResettableTaskPoolInterface.php @@ -1,10 +1,10 @@ $dependencies */ - function __construct( + public function __construct( private readonly string $name, - private readonly array $dependencies = [] - ) - { - if (array_filter($dependencies, fn($i) => !is_string($i))) { - throw new \InvalidArgumentException('Dependencies must be strings'); + private readonly array $dependencies = [] + ) { + if (array_filter($dependencies, fn ($i) => !is_string($i))) { + throw new InvalidArgumentException('Dependencies must be strings'); } } @@ -40,12 +40,13 @@ public function getDependencies(): array */ public function checkDependencies(array $resolvedTasks): bool { - return [] == array_diff($this->getDependencies(), $resolvedTasks); + return [] === array_diff($this->getDependencies(), $resolvedTasks); } public function resolve(): self { $this->resolved = true; + return $this; } @@ -57,6 +58,7 @@ public function isResolved(): bool public function reset(): self { $this->resolved = false; + return $this; } } diff --git a/src/TaskGraph.php b/src/TaskGraph.php index dd6a22f..863e1ef 100644 --- a/src/TaskGraph.php +++ b/src/TaskGraph.php @@ -1,23 +1,25 @@ > - * @throws \Exception + * @return Generator> */ - public function getIterator(): \Generator + public function getIterator(): Generator { $tasksToResolve = []; @@ -41,17 +43,18 @@ public function getIterator(): \Generator !$this->hasResolvableTasks($tasksToResolve, $resolvedTasks) && !empty($tasksToResolve) ) { - throw new \Exception("Dependency cycle detected. Cannot resolve dependencies."); + throw new Exception("Dependency cycle detected. Cannot resolve dependencies."); } } } private function hasResolvableTasks(iterable $tasksToResolve, array $resolvedTasks): bool { - return $this->getResolvableTasks($tasksToResolve, $resolvedTasks)->valid(); + return $this->getResolvableTasks($tasksToResolve, $resolvedTasks) + ->valid(); } - private function getResolvableTasks(iterable $tasksToResolve, array $resolvedTasks): \Generator + private function getResolvableTasks(iterable $tasksToResolve, array $resolvedTasks): Generator { foreach ($tasksToResolve as $taskName) { $task = $this->tasks->getTask($taskName); @@ -64,7 +67,7 @@ private function getResolvableTasks(iterable $tasksToResolve, array $resolvedTas public function resetPool(): self { if (!($this->tasks instanceof ResettableTaskPoolInterface)) { - throw new \InvalidArgumentException('TaskPool is not resettable'); + throw new InvalidArgumentException('TaskPool is not resettable'); } $this->tasks->reset(); diff --git a/src/TaskInterface.php b/src/TaskInterface.php index 09dfc94..1def9d2 100644 --- a/src/TaskInterface.php +++ b/src/TaskInterface.php @@ -1,26 +1,26 @@ addTask($task); } } - function addTask(TaskInterface $task): self + public function addTask(TaskInterface $task): self { if (isset($this->tasks[$task->getName()])) { - throw new \InvalidArgumentException('Task already exists'); + throw new InvalidArgumentException('Task already exists'); } $this->tasks[$task->getName()] = $task; @@ -26,22 +30,24 @@ function addTask(TaskInterface $task): self return $this; } - function getTask(string $name): TaskInterface + public function getTask(string $name): TaskInterface { if (!isset($this->tasks[$name])) { - throw new \InvalidArgumentException(sprintf('Task "%s" does not exist', $name)); + throw new InvalidArgumentException(sprintf('Task "%s" does not exist', $name)); } + return $this->tasks[$name]; } - function getIterator(): \Traversable + public function getIterator(): Traversable { - return new \ArrayIterator($this->tasks); + return new ArrayIterator($this->tasks); } - function reset(): self + public function reset(): self { - array_map(fn($t) => $t->reset(), $this->tasks); + array_map(fn ($t) => $t->reset(), $this->tasks); + return $this; } } diff --git a/src/TaskPoolInterface.php b/src/TaskPoolInterface.php index 90ae5be..1f295a4 100644 --- a/src/TaskPoolInterface.php +++ b/src/TaskPoolInterface.php @@ -1,14 +1,18 @@ + * @return Traversable */ - function getIterator(): \Traversable; + public function getIterator(): Traversable; - function getTask(string $name): TaskInterface; + public function getTask(string $name): TaskInterface; } diff --git a/tests/Unit/TaskGraphTest.php b/tests/Unit/TaskGraphTest.php index 99592c1..54aa1a4 100644 --- a/tests/Unit/TaskGraphTest.php +++ b/tests/Unit/TaskGraphTest.php @@ -1,8 +1,12 @@ expects($this->once())->method('reset'); + $taskPool->expects($this->once()) + ->method('reset'); $graph = new TaskGraph($taskPool); $graph->resetPool(); @@ -23,7 +28,7 @@ public function testReset(): void public function testResetException(): void { $taskPool = self::createMock(TaskPoolInterface::class); - self::expectException(\InvalidArgumentException::class); + self::expectException(InvalidArgumentException::class); $graph = new TaskGraph($taskPool); $graph->resetPool(); } @@ -33,13 +38,15 @@ public function testResolveDependencies(): void $tasks = [ 'TaskA' => new Task('TaskA'), 'TaskB' => new Task('TaskB', ['TaskC']), - 'TaskC' => new Task('TaskC', ['TaskA']) + 'TaskC' => new Task('TaskC', ['TaskA']), ]; $taskPool = self::createMock(TaskPoolInterface::class); - $taskPool->method('getIterator')->willReturn(new \ArrayIterator($tasks)); - $taskPool->method('getTask')->willReturnCallback(fn($name) => $tasks[$name]); + $taskPool->method('getIterator') + ->willReturn(new ArrayIterator($tasks)); + $taskPool->method('getTask') + ->willReturnCallback(fn ($name) => $tasks[$name]); $graph = new TaskGraph($taskPool); @@ -56,14 +63,12 @@ public function testResolveDependencies(): void public function testResolveCycle(): void { - $this->expectException(\Exception::class); + $this->expectException(Exception::class); $taskPool = self::createMock(TaskPoolInterface::class); - $taskPool->method('getIterator')->willReturn(new \ArrayIterator([ - new Task('TaskB', ['TaskA']), - new Task('TaskA', ['TaskB']) - ])); + $taskPool->method('getIterator') + ->willReturn(new ArrayIterator([new Task('TaskB', ['TaskA']), new Task('TaskA', ['TaskB'])])); foreach ((new TaskGraph($taskPool))->getIterator() as $tasks) { foreach ($tasks as $task) { diff --git a/tests/Unit/TaskPoolTest.php b/tests/Unit/TaskPoolTest.php index 53e1f5a..d438030 100644 --- a/tests/Unit/TaskPoolTest.php +++ b/tests/Unit/TaskPoolTest.php @@ -4,78 +4,88 @@ namespace Netlogix\DependencyResolver; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; +use Traversable; class TaskPoolTest extends TestCase { - function testCanInstantiate(): void + public function testCanInstantiate(): void { $taskPool = new TaskPool(); $this->assertInstanceOf(TaskPoolInterface::class, $taskPool); - $this->assertInstanceOf(\Traversable::class, $taskPool); + $this->assertInstanceOf(Traversable::class, $taskPool); } - function testAddTask(): void + public function testAddTask(): void { $taskPool = new TaskPool(); $task = self::createMock(TaskInterface::class); - $task->method('getName')->willReturn('TaskA'); + $task->method('getName') + ->willReturn('TaskA'); $taskPool->addTask($task); $this->assertSame($task, $taskPool->getTask('TaskA')); } - function testAddTaskException(): void + public function testAddTaskException(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $taskPool = new TaskPool(); $task = self::createMock(TaskInterface::class); - $task->method('getName')->willReturn('TaskA'); + $task->method('getName') + ->willReturn('TaskA'); $taskPool->addTask($task); $taskPool->addTask($task); } - function testGetTask(): void + public function testGetTask(): void { $taskPool = new TaskPool(); $task = self::createMock(TaskInterface::class); - $task->method('getName')->willReturn('TaskA'); + $task->method('getName') + ->willReturn('TaskA'); $taskPool->addTask($task); $this->assertSame($task, $taskPool->getTask('TaskA')); } - function testGetTaskException(): void + public function testGetTaskException(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $taskPool = new TaskPool(); $taskPool->getTask('TaskB'); } - function testGetIterator(): void + public function testGetIterator(): void { $task = self::createMock(TaskInterface::class); - $task->method('getName')->willReturn('TaskA'); + $task->method('getName') + ->willReturn('TaskA'); $taskPool = new TaskPool([$task]); - $this->assertSame(['TaskA' => $task], iterator_to_array($taskPool)); + $this->assertSame([ + 'TaskA' => $task, + ], iterator_to_array($taskPool)); } - function testReset(): void + public function testReset(): void { $taskPool = new TaskPool(); $task = self::createMock(TaskInterface::class); - $task->method('getName')->willReturn('TaskA'); - $task->expects($this->once())->method('reset'); + $task->method('getName') + ->willReturn('TaskA'); + $task->expects($this->once()) + ->method('reset'); $taskPool->addTask($task); $taskPool->reset(); diff --git a/tests/Unit/TaskTest.php b/tests/Unit/TaskTest.php index 3d55944..29ccf22 100644 --- a/tests/Unit/TaskTest.php +++ b/tests/Unit/TaskTest.php @@ -4,6 +4,7 @@ namespace Netlogix\DependencyResolver; +use InvalidArgumentException; use PHPUnit\Framework\TestCase; class TaskTest extends TestCase @@ -50,7 +51,7 @@ public function testReset(): void public function testConstructWithInvalidDependencies(): void { - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); new Task('TaskA', [1, 'TaskC']); } }