From 234fde1013799379cefe3b4c9587a509a2443c5f Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Sun, 5 May 2024 21:15:43 +0200 Subject: [PATCH] Seperate listeners and checks --- src/Exercise/AbstractExercise.php | 14 ++++++---- src/Exercise/ExerciseInterface.php | 15 ++++++---- src/ExerciseDispatcher.php | 8 +++--- test/Asset/CgiExerciseImpl.php | 9 +++++- test/Asset/CliExerciseImpl.php | 9 +++++- test/Asset/CliExerciseMissingInterface.php | 7 +++++ test/Asset/ComposerExercise.php | 9 ++++-- test/Asset/ExerciseWithInitialCode.php | 14 +++++++--- test/Asset/FileComparisonExercise.php | 14 +++++++--- test/Asset/FunctionRequirementsExercise.php | 17 +++++++---- test/Asset/PatchableExercise.php | 10 +++++-- test/Asset/ProvidesSolutionExercise.php | 16 +++++++---- test/Check/DatabaseCheckTest.php | 31 ++++++--------------- test/Exercise/AbstractExerciseTest.php | 7 +++-- 14 files changed, 115 insertions(+), 65 deletions(-) diff --git a/src/Exercise/AbstractExercise.php b/src/Exercise/AbstractExercise.php index ff790419..87a0b241 100644 --- a/src/Exercise/AbstractExercise.php +++ b/src/Exercise/AbstractExercise.php @@ -4,6 +4,8 @@ namespace PhpSchool\PhpWorkshop\Exercise; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\ExerciseDispatcher; use PhpSchool\PhpWorkshop\Solution\SingleFileSolution; use PhpSchool\PhpWorkshop\Solution\SolutionInterface; @@ -78,12 +80,14 @@ public static function normaliseName(string $name): string } /** - * This method is implemented as empty by default, if you want to add additional checks or listen - * to events, you should override this method. - * - * @param ExerciseDispatcher $dispatcher + * @return list */ - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void { } } diff --git a/src/Exercise/ExerciseInterface.php b/src/Exercise/ExerciseInterface.php index 2a969359..10443374 100644 --- a/src/Exercise/ExerciseInterface.php +++ b/src/Exercise/ExerciseInterface.php @@ -4,6 +4,7 @@ namespace PhpSchool\PhpWorkshop\Exercise; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\ExerciseDispatcher; /** @@ -34,14 +35,16 @@ public function getType(): ExerciseType; public function getProblem(): string; /** - * This is where the exercise specifies the extra checks it may require. It is also - * possible to grab the event dispatcher from the exercise dispatcher and listen to any - * events. This method is automatically invoked just before verifying/running an student's solution - * to an exercise. + * Subscribe to events triggered throughout the verification process + */ + public function defineListeners(EventDispatcher $dispatcher): void; + + /** + * This is where the exercise specifies the extra checks it may require. * - * @param ExerciseDispatcher $dispatcher + * @return array */ - public function configure(ExerciseDispatcher $dispatcher): void; + public function getRequiredChecks(): array; /** * A short description of the exercise. diff --git a/src/ExerciseDispatcher.php b/src/ExerciseDispatcher.php index 6d9348a6..112fd68b 100644 --- a/src/ExerciseDispatcher.php +++ b/src/ExerciseDispatcher.php @@ -129,11 +129,11 @@ public function requireCheck(string $requiredCheck): void */ public function verify(ExerciseInterface $exercise, Input $input): ResultAggregator { - $exercise->configure($this); - $runner = $this->runnerManager->getRunner($exercise); - foreach ($runner->getRequiredChecks() as $requiredCheck) { + $exercise->defineListeners($this->eventDispatcher); + + foreach ([...$runner->getRequiredChecks(), ...$exercise->getRequiredChecks()] as $requiredCheck) { $this->requireCheck($requiredCheck); } @@ -181,7 +181,7 @@ public function verify(ExerciseInterface $exercise, Input $input): ResultAggrega */ public function run(ExerciseInterface $exercise, Input $input, OutputInterface $output): bool { - $exercise->configure($this); + $exercise->defineListeners($this->eventDispatcher); /** @var PhpLintCheck $lint */ $lint = $this->checkRepository->getByClass(PhpLintCheck::class); diff --git a/test/Asset/CgiExerciseImpl.php b/test/Asset/CgiExerciseImpl.php index 45c78005..d8c23c96 100644 --- a/test/Asset/CgiExerciseImpl.php +++ b/test/Asset/CgiExerciseImpl.php @@ -2,6 +2,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\CgiExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; @@ -62,7 +64,12 @@ public function getType(): ExerciseType return ExerciseType::CGI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void { } } diff --git a/test/Asset/CliExerciseImpl.php b/test/Asset/CliExerciseImpl.php index df157189..0fcc9e32 100644 --- a/test/Asset/CliExerciseImpl.php +++ b/test/Asset/CliExerciseImpl.php @@ -2,6 +2,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; @@ -66,7 +68,12 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void { } } diff --git a/test/Asset/CliExerciseMissingInterface.php b/test/Asset/CliExerciseMissingInterface.php index 5edd2200..21c8d482 100644 --- a/test/Asset/CliExerciseMissingInterface.php +++ b/test/Asset/CliExerciseMissingInterface.php @@ -2,6 +2,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; @@ -31,4 +33,9 @@ public function getType(): ExerciseType { return ExerciseType::CLI(); } + + public function getRequiredChecks(): array + { + return []; + } } diff --git a/test/Asset/ComposerExercise.php b/test/Asset/ComposerExercise.php index 622a7de8..e7365893 100644 --- a/test/Asset/ComposerExercise.php +++ b/test/Asset/ComposerExercise.php @@ -3,6 +3,7 @@ namespace PhpSchool\PhpWorkshopTest\Asset; use PhpSchool\PhpWorkshop\Check\ComposerCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\ExerciseCheck\ComposerExerciseCheck; @@ -53,8 +54,12 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array + { + return [ComposerCheck::class]; + } + + public function defineListeners(EventDispatcher $dispatcher): void { - $dispatcher->requireCheck(ComposerCheck::class); } } diff --git a/test/Asset/ExerciseWithInitialCode.php b/test/Asset/ExerciseWithInitialCode.php index 398b3785..49282605 100644 --- a/test/Asset/ExerciseWithInitialCode.php +++ b/test/Asset/ExerciseWithInitialCode.php @@ -2,6 +2,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; @@ -41,13 +43,17 @@ public function getType(): ExerciseType // TODO: Implement getType() method. } - public function configure(ExerciseDispatcher $dispatcher): void + public function getInitialCode(): SolutionInterface { - // TODO: Implement configure() method. + return SingleFileSolution::fromFile(__DIR__ . '/initial-code/init-solution.php'); } - public function getInitialCode(): SolutionInterface + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void { - return SingleFileSolution::fromFile(__DIR__ . '/initial-code/init-solution.php'); } } diff --git a/test/Asset/FileComparisonExercise.php b/test/Asset/FileComparisonExercise.php index b4ecd9c1..8627a37c 100644 --- a/test/Asset/FileComparisonExercise.php +++ b/test/Asset/FileComparisonExercise.php @@ -3,6 +3,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; use PhpSchool\PhpWorkshop\Check\ComposerCheck; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\ExerciseCheck\FileComparisonExerciseCheck; @@ -66,13 +68,17 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getFilesToCompare(): array { - $dispatcher->requireCheck(ComposerCheck::class); + return $this->files; } - public function getFilesToCompare(): array + public function getRequiredChecks(): array + { + return [FileComparisonCheck::class]; + } + + public function defineListeners(EventDispatcher $dispatcher): void { - return $this->files; } } diff --git a/test/Asset/FunctionRequirementsExercise.php b/test/Asset/FunctionRequirementsExercise.php index 927d6f56..4e243a3f 100644 --- a/test/Asset/FunctionRequirementsExercise.php +++ b/test/Asset/FunctionRequirementsExercise.php @@ -3,6 +3,9 @@ namespace PhpSchool\PhpWorkshopTest\Asset; use PhpSchool\PhpWorkshop\Check\ComposerCheck; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; @@ -45,11 +48,6 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void - { - $dispatcher->requireCheck(ComposerCheck::class); - } - /** * @return string[] */ @@ -65,4 +63,13 @@ public function getBannedFunctions(): array { return ['file']; } + + public function getRequiredChecks(): array + { + return [FunctionRequirementsCheck::class]; + } + + public function defineListeners(EventDispatcher $dispatcher): void + { + } } diff --git a/test/Asset/PatchableExercise.php b/test/Asset/PatchableExercise.php index 51a9d601..c232113e 100644 --- a/test/Asset/PatchableExercise.php +++ b/test/Asset/PatchableExercise.php @@ -2,6 +2,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; @@ -45,8 +47,12 @@ public function getType(): ExerciseType // TODO: Implement getType() method. } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void { - // TODO: Implement configure() method. } } diff --git a/test/Asset/ProvidesSolutionExercise.php b/test/Asset/ProvidesSolutionExercise.php index b86f8dd9..503e1bf8 100644 --- a/test/Asset/ProvidesSolutionExercise.php +++ b/test/Asset/ProvidesSolutionExercise.php @@ -4,6 +4,8 @@ namespace PhpSchool\PhpWorkshopTest\Asset; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesSolution; @@ -28,11 +30,6 @@ public function getProblem(): string // TODO: Implement getProblem() method. } - public function configure(ExerciseDispatcher $dispatcher): void - { - // TODO: Implement configure() method. - } - public function getDescription(): string { // TODO: Implement getDescription() method. @@ -47,4 +44,13 @@ public function getSolution(): SolutionInterface { return SingleFileSolution::fromFile(__DIR__ . '/provided-solution/solution.php'); } + + public function getRequiredChecks(): array + { + return []; + } + + public function defineListeners(EventDispatcher $dispatcher): void + { + } } diff --git a/test/Check/DatabaseCheckTest.php b/test/Check/DatabaseCheckTest.php index 14629e90..da96cd7f 100644 --- a/test/Check/DatabaseCheckTest.php +++ b/test/Check/DatabaseCheckTest.php @@ -131,10 +131,8 @@ public function testIfPDOThrowsExceptionItCleansUp(): void $this->exercise ->expects($this->once()) - ->method('configure') - ->willReturnCallback(function (ExerciseDispatcher $dispatcher) { - $dispatcher->requireCheck(DatabaseCheck::class); - }); + ->method('getRequiredChecks') + ->willReturn([DatabaseCheck::class]); $this->exercise ->expects($this->once()) @@ -172,10 +170,8 @@ public function testSuccessIsReturnedIfDatabaseVerificationPassed(): void $this->exercise ->expects($this->once()) - ->method('configure') - ->willReturnCallback(function (ExerciseDispatcher $dispatcher) { - $dispatcher->requireCheck(DatabaseCheck::class); - }); + ->method('getRequiredChecks') + ->willReturn([DatabaseCheck::class]); $this->exercise ->expects($this->once()) @@ -207,13 +203,6 @@ public function testRunExercise(): void ->method('getArgs') ->willReturn([]); - $this->exercise - ->expects($this->once()) - ->method('configure') - ->willReturnCallback(function (ExerciseDispatcher $dispatcher) { - $dispatcher->requireCheck(DatabaseCheck::class); - }); - $this->checkRepository->registerCheck($this->check); $results = new ResultAggregator(); @@ -248,10 +237,8 @@ public function testFailureIsReturnedIfDatabaseVerificationFails(): void $this->exercise ->expects($this->once()) - ->method('configure') - ->willReturnCallback(function (ExerciseDispatcher $dispatcher) { - $dispatcher->requireCheck(DatabaseCheck::class); - }); + ->method('getRequiredChecks') + ->willReturn([DatabaseCheck::class]); $this->exercise ->expects($this->once()) @@ -296,10 +283,8 @@ public function testAlteringDatabaseInSolutionDoesNotEffectDatabaseInUserSolutio $this->exercise ->expects($this->once()) - ->method('configure') - ->willReturnCallback(function (ExerciseDispatcher $dispatcher) { - $dispatcher->requireCheck(DatabaseCheck::class); - }); + ->method('getRequiredChecks') + ->willReturn([DatabaseCheck::class]); $this->exercise ->expects($this->once()) diff --git a/test/Exercise/AbstractExerciseTest.php b/test/Exercise/AbstractExerciseTest.php index 6b2d722c..c500b0f7 100644 --- a/test/Exercise/AbstractExerciseTest.php +++ b/test/Exercise/AbstractExerciseTest.php @@ -2,6 +2,7 @@ namespace PhpSchool\PhpWorkshopTest\Exercise; +use PhpSchool\PhpWorkshop\Event\EventDispatcher; use PhpSchool\PhpWorkshop\ExerciseDispatcher; use PhpSchool\PhpWorkshop\Solution\SolutionFile; use PhpSchool\PhpWorkshop\Solution\SolutionInterface; @@ -65,11 +66,11 @@ public function problemProvider(): array ]; } - public function testConfigureDoesNothing(): void + public function testDefineListenersDoesNothing(): void { - $dispatcher = $this->createMock(ExerciseDispatcher::class); + $dispatcher = $this->createMock(EventDispatcher::class); $exercise = new AbstractExerciseImpl('Array We Go'); - $this->assertNull($exercise->configure($dispatcher)); + $this->assertNull($exercise->defineListeners($dispatcher)); } }