Skip to content

Commit 234fde1

Browse files
committed
Seperate listeners and checks
1 parent 88d8200 commit 234fde1

14 files changed

+115
-65
lines changed

Diff for: src/Exercise/AbstractExercise.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace PhpSchool\PhpWorkshop\Exercise;
66

7+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
8+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
79
use PhpSchool\PhpWorkshop\ExerciseDispatcher;
810
use PhpSchool\PhpWorkshop\Solution\SingleFileSolution;
911
use PhpSchool\PhpWorkshop\Solution\SolutionInterface;
@@ -78,12 +80,14 @@ public static function normaliseName(string $name): string
7880
}
7981

8082
/**
81-
* This method is implemented as empty by default, if you want to add additional checks or listen
82-
* to events, you should override this method.
83-
*
84-
* @param ExerciseDispatcher $dispatcher
83+
* @return list<class-string>
8584
*/
86-
public function configure(ExerciseDispatcher $dispatcher): void
85+
public function getRequiredChecks(): array
86+
{
87+
return [];
88+
}
89+
90+
public function defineListeners(EventDispatcher $dispatcher): void
8791
{
8892
}
8993
}

Diff for: src/Exercise/ExerciseInterface.php

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace PhpSchool\PhpWorkshop\Exercise;
66

7+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
78
use PhpSchool\PhpWorkshop\ExerciseDispatcher;
89

910
/**
@@ -34,14 +35,16 @@ public function getType(): ExerciseType;
3435
public function getProblem(): string;
3536

3637
/**
37-
* This is where the exercise specifies the extra checks it may require. It is also
38-
* possible to grab the event dispatcher from the exercise dispatcher and listen to any
39-
* events. This method is automatically invoked just before verifying/running an student's solution
40-
* to an exercise.
38+
* Subscribe to events triggered throughout the verification process
39+
*/
40+
public function defineListeners(EventDispatcher $dispatcher): void;
41+
42+
/**
43+
* This is where the exercise specifies the extra checks it may require.
4144
*
42-
* @param ExerciseDispatcher $dispatcher
45+
* @return array<class-string>
4346
*/
44-
public function configure(ExerciseDispatcher $dispatcher): void;
47+
public function getRequiredChecks(): array;
4548

4649
/**
4750
* A short description of the exercise.

Diff for: src/ExerciseDispatcher.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ public function requireCheck(string $requiredCheck): void
129129
*/
130130
public function verify(ExerciseInterface $exercise, Input $input): ResultAggregator
131131
{
132-
$exercise->configure($this);
133-
134132
$runner = $this->runnerManager->getRunner($exercise);
135133

136-
foreach ($runner->getRequiredChecks() as $requiredCheck) {
134+
$exercise->defineListeners($this->eventDispatcher);
135+
136+
foreach ([...$runner->getRequiredChecks(), ...$exercise->getRequiredChecks()] as $requiredCheck) {
137137
$this->requireCheck($requiredCheck);
138138
}
139139

@@ -181,7 +181,7 @@ public function verify(ExerciseInterface $exercise, Input $input): ResultAggrega
181181
*/
182182
public function run(ExerciseInterface $exercise, Input $input, OutputInterface $output): bool
183183
{
184-
$exercise->configure($this);
184+
$exercise->defineListeners($this->eventDispatcher);
185185

186186
/** @var PhpLintCheck $lint */
187187
$lint = $this->checkRepository->getByClass(PhpLintCheck::class);

Diff for: test/Asset/CgiExerciseImpl.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

5+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
57
use PhpSchool\PhpWorkshop\Exercise\CgiExercise;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
79
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
@@ -62,7 +64,12 @@ public function getType(): ExerciseType
6264
return ExerciseType::CGI();
6365
}
6466

65-
public function configure(ExerciseDispatcher $dispatcher): void
67+
public function getRequiredChecks(): array
68+
{
69+
return [];
70+
}
71+
72+
public function defineListeners(EventDispatcher $dispatcher): void
6673
{
6774
}
6875
}

Diff for: test/Asset/CliExerciseImpl.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

5+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
57
use PhpSchool\PhpWorkshop\Exercise\CliExercise;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
79
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
@@ -66,7 +68,12 @@ public function getType(): ExerciseType
6668
return ExerciseType::CLI();
6769
}
6870

69-
public function configure(ExerciseDispatcher $dispatcher): void
71+
public function getRequiredChecks(): array
72+
{
73+
return [];
74+
}
75+
76+
public function defineListeners(EventDispatcher $dispatcher): void
7077
{
7178
}
7279
}

Diff for: test/Asset/CliExerciseMissingInterface.php

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

5+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
57
use PhpSchool\PhpWorkshop\Exercise\AbstractExercise;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
79
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
@@ -31,4 +33,9 @@ public function getType(): ExerciseType
3133
{
3234
return ExerciseType::CLI();
3335
}
36+
37+
public function getRequiredChecks(): array
38+
{
39+
return [];
40+
}
3441
}

Diff for: test/Asset/ComposerExercise.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

55
use PhpSchool\PhpWorkshop\Check\ComposerCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
67
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
78
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
89
use PhpSchool\PhpWorkshop\ExerciseCheck\ComposerExerciseCheck;
@@ -53,8 +54,12 @@ public function getType(): ExerciseType
5354
return ExerciseType::CLI();
5455
}
5556

56-
public function configure(ExerciseDispatcher $dispatcher): void
57+
public function getRequiredChecks(): array
58+
{
59+
return [ComposerCheck::class];
60+
}
61+
62+
public function defineListeners(EventDispatcher $dispatcher): void
5763
{
58-
$dispatcher->requireCheck(ComposerCheck::class);
5964
}
6065
}

Diff for: test/Asset/ExerciseWithInitialCode.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

5+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
57
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
79
use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode;
@@ -41,13 +43,17 @@ public function getType(): ExerciseType
4143
// TODO: Implement getType() method.
4244
}
4345

44-
public function configure(ExerciseDispatcher $dispatcher): void
46+
public function getInitialCode(): SolutionInterface
4547
{
46-
// TODO: Implement configure() method.
48+
return SingleFileSolution::fromFile(__DIR__ . '/initial-code/init-solution.php');
4749
}
4850

49-
public function getInitialCode(): SolutionInterface
51+
public function getRequiredChecks(): array
52+
{
53+
return [];
54+
}
55+
56+
public function defineListeners(EventDispatcher $dispatcher): void
5057
{
51-
return SingleFileSolution::fromFile(__DIR__ . '/initial-code/init-solution.php');
5258
}
5359
}

Diff for: test/Asset/FileComparisonExercise.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

55
use PhpSchool\PhpWorkshop\Check\ComposerCheck;
6+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
7+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
79
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
810
use PhpSchool\PhpWorkshop\ExerciseCheck\FileComparisonExerciseCheck;
@@ -66,13 +68,17 @@ public function getType(): ExerciseType
6668
return ExerciseType::CLI();
6769
}
6870

69-
public function configure(ExerciseDispatcher $dispatcher): void
71+
public function getFilesToCompare(): array
7072
{
71-
$dispatcher->requireCheck(ComposerCheck::class);
73+
return $this->files;
7274
}
7375

74-
public function getFilesToCompare(): array
76+
public function getRequiredChecks(): array
77+
{
78+
return [FileComparisonCheck::class];
79+
}
80+
81+
public function defineListeners(EventDispatcher $dispatcher): void
7582
{
76-
return $this->files;
7783
}
7884
}

Diff for: test/Asset/FunctionRequirementsExercise.php

+12-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

55
use PhpSchool\PhpWorkshop\Check\ComposerCheck;
6+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
7+
use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck;
8+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
69
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
710
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
811
use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck;
@@ -45,11 +48,6 @@ public function getType(): ExerciseType
4548
return ExerciseType::CLI();
4649
}
4750

48-
public function configure(ExerciseDispatcher $dispatcher): void
49-
{
50-
$dispatcher->requireCheck(ComposerCheck::class);
51-
}
52-
5351
/**
5452
* @return string[]
5553
*/
@@ -65,4 +63,13 @@ public function getBannedFunctions(): array
6563
{
6664
return ['file'];
6765
}
66+
67+
public function getRequiredChecks(): array
68+
{
69+
return [FunctionRequirementsCheck::class];
70+
}
71+
72+
public function defineListeners(EventDispatcher $dispatcher): void
73+
{
74+
}
6875
}

Diff for: test/Asset/PatchableExercise.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PhpSchool\PhpWorkshopTest\Asset;
44

5+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
6+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
57
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
68
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
79
use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable;
@@ -45,8 +47,12 @@ public function getType(): ExerciseType
4547
// TODO: Implement getType() method.
4648
}
4749

48-
public function configure(ExerciseDispatcher $dispatcher): void
50+
public function getRequiredChecks(): array
51+
{
52+
return [];
53+
}
54+
55+
public function defineListeners(EventDispatcher $dispatcher): void
4956
{
50-
// TODO: Implement configure() method.
5157
}
5258
}

Diff for: test/Asset/ProvidesSolutionExercise.php

+11-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace PhpSchool\PhpWorkshopTest\Asset;
66

7+
use PhpSchool\PhpWorkshop\Check\FileComparisonCheck;
8+
use PhpSchool\PhpWorkshop\Event\EventDispatcher;
79
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
810
use PhpSchool\PhpWorkshop\Exercise\ExerciseType;
911
use PhpSchool\PhpWorkshop\Exercise\ProvidesSolution;
@@ -28,11 +30,6 @@ public function getProblem(): string
2830
// TODO: Implement getProblem() method.
2931
}
3032

31-
public function configure(ExerciseDispatcher $dispatcher): void
32-
{
33-
// TODO: Implement configure() method.
34-
}
35-
3633
public function getDescription(): string
3734
{
3835
// TODO: Implement getDescription() method.
@@ -47,4 +44,13 @@ public function getSolution(): SolutionInterface
4744
{
4845
return SingleFileSolution::fromFile(__DIR__ . '/provided-solution/solution.php');
4946
}
47+
48+
public function getRequiredChecks(): array
49+
{
50+
return [];
51+
}
52+
53+
public function defineListeners(EventDispatcher $dispatcher): void
54+
{
55+
}
5056
}

Diff for: test/Check/DatabaseCheckTest.php

+8-23
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,8 @@ public function testIfPDOThrowsExceptionItCleansUp(): void
131131

132132
$this->exercise
133133
->expects($this->once())
134-
->method('configure')
135-
->willReturnCallback(function (ExerciseDispatcher $dispatcher) {
136-
$dispatcher->requireCheck(DatabaseCheck::class);
137-
});
134+
->method('getRequiredChecks')
135+
->willReturn([DatabaseCheck::class]);
138136

139137
$this->exercise
140138
->expects($this->once())
@@ -172,10 +170,8 @@ public function testSuccessIsReturnedIfDatabaseVerificationPassed(): void
172170

173171
$this->exercise
174172
->expects($this->once())
175-
->method('configure')
176-
->willReturnCallback(function (ExerciseDispatcher $dispatcher) {
177-
$dispatcher->requireCheck(DatabaseCheck::class);
178-
});
173+
->method('getRequiredChecks')
174+
->willReturn([DatabaseCheck::class]);
179175

180176
$this->exercise
181177
->expects($this->once())
@@ -207,13 +203,6 @@ public function testRunExercise(): void
207203
->method('getArgs')
208204
->willReturn([]);
209205

210-
$this->exercise
211-
->expects($this->once())
212-
->method('configure')
213-
->willReturnCallback(function (ExerciseDispatcher $dispatcher) {
214-
$dispatcher->requireCheck(DatabaseCheck::class);
215-
});
216-
217206
$this->checkRepository->registerCheck($this->check);
218207

219208
$results = new ResultAggregator();
@@ -248,10 +237,8 @@ public function testFailureIsReturnedIfDatabaseVerificationFails(): void
248237

249238
$this->exercise
250239
->expects($this->once())
251-
->method('configure')
252-
->willReturnCallback(function (ExerciseDispatcher $dispatcher) {
253-
$dispatcher->requireCheck(DatabaseCheck::class);
254-
});
240+
->method('getRequiredChecks')
241+
->willReturn([DatabaseCheck::class]);
255242

256243
$this->exercise
257244
->expects($this->once())
@@ -296,10 +283,8 @@ public function testAlteringDatabaseInSolutionDoesNotEffectDatabaseInUserSolutio
296283

297284
$this->exercise
298285
->expects($this->once())
299-
->method('configure')
300-
->willReturnCallback(function (ExerciseDispatcher $dispatcher) {
301-
$dispatcher->requireCheck(DatabaseCheck::class);
302-
});
286+
->method('getRequiredChecks')
287+
->willReturn([DatabaseCheck::class]);
303288

304289
$this->exercise
305290
->expects($this->once())

0 commit comments

Comments
 (0)