Skip to content

Commit f8a4512

Browse files
committed
exercise runner docs
1 parent 957e75a commit f8a4512

File tree

3 files changed

+106
-25
lines changed

3 files changed

+106
-25
lines changed

src/ExerciseRunner/CgiRunner.php

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
use PhpSchool\PhpWorkshop\Result\Success;
1818
use Psr\Http\Message\RequestInterface;
1919
use Psr\Http\Message\ResponseInterface;
20+
use RuntimeException;
2021
use Symfony\Component\Process\Process;
2122
use Zend\Diactoros\Response\Serializer as ResponseSerializer;
2223

2324
/**
24-
* Class CgiRunner
25+
* The `CGI` runner. This runner executes solutions as if they were behind a web-server. They populate the `$_SERVER`,
26+
* `$_GET` & `$_POST` super globals with information based of the request objects returned from the exercise.
27+
*
2528
* @author Aydin Hassan <aydin@hotmail.co.uk>
2629
*/
2730
class CgiRunner implements ExerciseRunnerInterface
@@ -38,8 +41,13 @@ class CgiRunner implements ExerciseRunnerInterface
3841
private $eventDispatcher;
3942

4043
/**
41-
* @param CgiExercise $exercise
42-
* @param EventDispatcher $eventDispatcher
44+
* Requires the exercise instance and an event dispatcher. This runner requires the `php-cgi` binary to
45+
* be available. It will check for it's existence in the system's $PATH variable or the same
46+
* folder that the CLI php binary lives in.
47+
*
48+
* @param CgiExercise $exercise The exercise to be invoked.
49+
* @param EventDispatcher $eventDispatcher The event dispatcher.
50+
* @throws RuntimeException If the `php-cgi` binary cannot be found.
4351
*/
4452
public function __construct(CgiExercise $exercise, EventDispatcher $eventDispatcher)
4553
{
@@ -52,15 +60,15 @@ public function __construct(CgiExercise $exercise, EventDispatcher $eventDispatc
5260
// Try one more time, relying on being in the php binary's directory (where it should be on Windows)
5361
system(sprintf('%s --version %s', $newPath, $silence), $stillFailedToRun);
5462
if ($stillFailedToRun) {
55-
throw new \RuntimeException(
63+
throw new RuntimeException(
5664
'Could not load php-cgi binary. Please install php-cgi using your package manager.'
5765
);
5866
}
5967
}
6068
} else {
6169
@system('php-cgi --version > /dev/null 2>&1', $failedToRun);
6270
if ($failedToRun) {
63-
throw new \RuntimeException(
71+
throw new RuntimeException(
6472
'Could not load php-cgi binary. Please install php-cgi using your package manager.'
6573
);
6674
}
@@ -192,8 +200,21 @@ private function getProcess($fileName, RequestInterface $request)
192200
}
193201

194202
/**
195-
* @param string $fileName
196-
* @return ResultInterface
203+
* Verifies a solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
204+
* the information from the request objects returned from the exercise. The exercise can return multiple
205+
* requests so the solution will be invoked for however many requests there are.
206+
*
207+
* Events dispatched (for each request):
208+
*
209+
* * cgi.verify.reference-execute.pre
210+
* * cgi.verify.reference.executing
211+
* * cgi.verify.reference-execute.fail (if the reference solution fails to execute)
212+
* * cgi.verify.student-execute.pre
213+
* * cgi.verify.student.executing
214+
* * cgi.verify.student-execute.fail (if the student's solution fails to execute)
215+
*
216+
* @param string $fileName The absolute path to the student's solution.
217+
* @return ResultInterface The result of the check.
197218
*/
198219
public function verify($fileName)
199220
{
@@ -209,9 +230,21 @@ function (RequestInterface $request) use ($fileName) {
209230
}
210231

211232
/**
212-
* @param string $fileName
213-
* @param OutputInterface $output
214-
* @return bool
233+
* Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
234+
* the information from the request objects returned from the exercise. The exercise can return multiple
235+
* requests so the solution will be invoked for however many requests there are.
236+
*
237+
* Running only runs the student's solution, the reference solution is not run and no verification is performed,
238+
* the output of the student's solution is written directly to the output.
239+
*
240+
* Events dispatched (for each request):
241+
*
242+
* * cgi.run.student-execute.pre
243+
* * cgi.run.student.executing
244+
*
245+
* @param string $fileName The absolute path to the student's solution.
246+
* @param OutputInterface $output A wrapper around STDOUT.
247+
* @return bool If the solution was successfully executed, eg. exit code was 0.
215248
*/
216249
public function run($fileName, OutputInterface $output)
217250
{

src/ExerciseRunner/CliRunner.php

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@
2121
use Symfony\Component\Process\Process;
2222

2323
/**
24-
* Class CliRunner
24+
* The `CLI` runner. This runner executes solutions as PHP CLI scripts, passing the arguments
25+
* from the exercise as command line arguments to the solution. The solution will be invoked like:
26+
*
27+
* ```bash
28+
* php my-solution.php arg1 arg2 arg3
29+
* ```
30+
*
2531
* @author Aydin Hassan <aydin@hotmail.co.uk>
2632
*/
2733
class CliRunner implements ExerciseRunnerInterface
@@ -37,8 +43,10 @@ class CliRunner implements ExerciseRunnerInterface
3743
private $eventDispatcher;
3844

3945
/**
40-
* @param CliExercise $exercise
41-
* @param EventDispatcher $eventDispatcher
46+
* Requires the exercise instance and an event dispatcher.
47+
*
48+
* @param CliExercise $exercise The exercise to be invoked.
49+
* @param EventDispatcher $eventDispatcher The event dispatcher.
4250
*/
4351
public function __construct(CliExercise $exercise, EventDispatcher $eventDispatcher)
4452
{
@@ -76,7 +84,7 @@ private function executePhpFile($fileName, ArrayObject $args, $type)
7684
}
7785

7886
/**
79-
* @param string $fileName
87+
* @param string $fileName
8088
* @param ArrayObject $args
8189
*
8290
* @return Process
@@ -88,8 +96,20 @@ private function getPhpProcess($fileName, ArrayObject $args)
8896
}
8997

9098
/**
91-
* @param string $fileName
92-
* @return ResultInterface
99+
* Verifies a solution by invoking PHP from the CLI passing the arguments gathered from the exercise
100+
* as command line arguments to PHP.
101+
*
102+
* Events dispatched:
103+
*
104+
* * cli.verify.reference-execute.pre
105+
* * cli.verify.reference.executing
106+
* * cli.verify.reference-execute.fail (if the reference solution fails to execute)
107+
* * cli.verify.student-execute.pre
108+
* * cli.verify.student.executing
109+
* * cli.verify.student-execute.fail (if the student's solution fails to execute)
110+
*
111+
* @param string $fileName The absolute path to the student's solution.
112+
* @return ResultInterface The result of the check.
93113
*/
94114
public function verify($fileName)
95115
{
@@ -123,9 +143,20 @@ public function verify($fileName)
123143
}
124144

125145
/**
126-
* @param string $fileName
127-
* @param OutputInterface $output
128-
* @return bool
146+
* Runs a student's solution by invoking PHP from the CLI passing the arguments gathered from the exercise
147+
* as command line arguments to PHP.
148+
*
149+
* Running only runs the student's solution, the reference solution is not run and no verification is performed,
150+
* the output of the student's solution is written directly to the output.
151+
*
152+
* Events dispatched:
153+
*
154+
* * cli.run.student-execute.pre
155+
* * cli.run.student.executing
156+
*
157+
* @param string $fileName The absolute path to the student's solution.
158+
* @param OutputInterface $output A wrapper around STDOUT.
159+
* @return bool If the solution was successfully executed, eg. exit code was 0.
129160
*/
130161
public function run($fileName, OutputInterface $output)
131162
{

src/ExerciseRunner/ExerciseRunnerInterface.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,44 @@
77
use PhpSchool\PhpWorkshop\Result\ResultInterface;
88

99
/**
10-
* Interface ExerciseRunnerInterface
10+
* This interface describes how an exercise runner should work. Each exercise type
11+
* maps to an exercise runner.
12+
*
1113
* @package PhpSchool\PhpWorkshop\ExerciseRunner
1214
* @author Aydin Hassan <aydin@hotmail.co.uk>
1315
*/
1416
interface ExerciseRunnerInterface
1517
{
1618
/**
19+
* Get the name of the exercise runner.
20+
*
1721
* @return string
1822
*/
1923
public function getName();
2024

2125
/**
22-
* @param string $fileName
23-
* @return ResultInterface
26+
* Verify a solution to an exercise. Verification involves executing the reference solution
27+
* and the student's solution and comparing their output. If the output is the same
28+
* an instance of `PhpSchool\PhpWorkshop\Result\SuccessInterface` should be returned, if the output
29+
* is not the same, or something else went wrong then an instance of
30+
* `\PhpSchool\PhpWorkshop\Result\FailureInterface` should be returned.
31+
*
32+
* Other things that could go wrong include the student's solution returning a non-zero
33+
* exit code, or an notice/warning being exhibited.
34+
*
35+
* @param string $fileName The absolute path to the student's solution.
36+
* @return ResultInterface The result of the check.
2437
*/
2538
public function verify($fileName);
2639

2740
/**
28-
* @param string $fileName
29-
* @param OutputInterface $output
30-
* @return bool
41+
* Run a solution to an exercise. This simply run's the student's solution with the correct input from the exercise
42+
* (such as the CLI arguments) and prints the output directly. This allows the student to have the environment
43+
* setup for them including getting a different set of arguments each time (if the exercise supports that).
44+
*
45+
* @param string $fileName The absolute path to the student's solution.
46+
* @param OutputInterface $output A wrapper around STDOUT.
47+
* @return bool If the solution was successfully executed, eg. exit code was 0.
3148
*/
3249
public function run($fileName, OutputInterface $output);
3350
}

0 commit comments

Comments
 (0)