diff --git a/composer.json b/composer.json index 4df72391..a0e76d97 100644 --- a/composer.json +++ b/composer.json @@ -53,10 +53,6 @@ } }, "scripts" : { - "test": [ - "phpunit", - "@cs" - ], "cs" : [ "phpcs src --standard=PSR2", "phpcs test --standard=PSR2" diff --git a/src/Application.php b/src/Application.php index a8d0adae..ff9acdea 100644 --- a/src/Application.php +++ b/src/Application.php @@ -4,16 +4,16 @@ use Assert\Assertion; use DI\ContainerBuilder; -use PhpSchool\PhpWorkshop\Check\CheckInterface; use PhpSchool\PhpWorkshop\Check\CheckRepository; use PhpSchool\PhpWorkshop\Exception\MissingArgumentException; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Factory\ResultRendererFactory; use PhpSchool\PhpWorkshop\Output\OutputInterface; -use PhpSchool\PhpWorkshop\ResultRenderer\ResultRendererInterface; /** - * Class Application + * This is the main application class, this takes care of bootstrapping, routing and + * output. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -45,7 +45,7 @@ final class Application private $diConfigFile; /** - * @var string + * @var string|null */ private $logo = null; @@ -60,8 +60,11 @@ final class Application private $bgColour = 'black'; /** - * @param string $workshopTitle - * @param $diConfigFile + * It should be instantiated with the title of + * the workshop and the path to the DI configuration file. + * + * @param string $workshopTitle The workshop title - this is used throughout the application + * @param string $diConfigFile The absolute path to the DI configuration file */ public function __construct($workshopTitle, $diConfigFile) { @@ -73,7 +76,10 @@ public function __construct($workshopTitle, $diConfigFile) } /** - * @param string $check + * Register a custom check with the application. Exercises will only be able to use the check + * if it has been registered here. + * + * @param string $check The FQCN of the check */ public function addCheck($check) { @@ -81,7 +87,10 @@ public function addCheck($check) } /** - * @param string $exercise + * Register an exercise with the application. Only exercises registered here will + * be displayed in the exercise menu. + * + * @param string $exercise The FQCN of the check */ public function addExercise($exercise) { @@ -104,7 +113,10 @@ public function addResult($resultClass, $resultRendererClass) } /** - * @param string $logo + * Add an ASCII art logo to the application. This will be displayed at the top of them menu. It will be + * automatically padded to sit in the middle. + * + * @param string $logo The logo */ public function setLogo($logo) { @@ -113,7 +125,10 @@ public function setLogo($logo) } /** - * @param string $colour + * Modify the foreground color of the workshop menu + * Can be any of: black, red, green, yellow, blue, magenta, cyan, white + * + * @param string $colour The colour */ public function setFgColour($colour) { @@ -122,7 +137,10 @@ public function setFgColour($colour) } /** - * @param string $colour + * Modify the background color of the workshop menu + * Can be any of: black, red, green, yellow, blue, magenta, cyan, white + * + * @param string $colour The colour */ public function setBgColour($colour) { @@ -131,7 +149,10 @@ public function setBgColour($colour) } /** - * Run the app + * Executes the framework, invoking the specified command. + * The return value is the exit code. 0 for success, anything else is a failure. + * + * @return int The exit code */ public function run() { diff --git a/src/Check/CheckInterface.php b/src/Check/CheckInterface.php index a1f84f1a..0c3764a4 100644 --- a/src/Check/CheckInterface.php +++ b/src/Check/CheckInterface.php @@ -3,7 +3,8 @@ namespace PhpSchool\PhpWorkshop\Check; /** - * Class CheckInterface + * Base Interface for Checks. + * * @package PhpSchool\PhpWorkshop\Comparator * @author Aydin Hassan */ @@ -18,7 +19,7 @@ public function getName(); /** * This returns the interface the exercise should implement - * when requiring this check + * when requiring this check. It should be the FQCN of the interface. * * @return string */ diff --git a/src/Check/CheckRepository.php b/src/Check/CheckRepository.php index 51dd81d2..68f431fe 100644 --- a/src/Check/CheckRepository.php +++ b/src/Check/CheckRepository.php @@ -2,11 +2,12 @@ namespace PhpSchool\PhpWorkshop\Check; -use PhpSchool\CliMenu\Exception\InvalidTerminalException; use PhpSchool\PhpWorkshop\Exception\InvalidArgumentException; /** - * Class CheckRepository + * This class is the repository containing all the available checks + * for the workshop framework. + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ @@ -18,7 +19,7 @@ class CheckRepository private $checks = []; /** - * @param CheckInterface[] $checks + * @param CheckInterface[] $checks An array of checks available to the workshop framework. */ public function __construct(array $checks = []) { @@ -28,7 +29,9 @@ public function __construct(array $checks = []) } /** - * @param CheckInterface $check + * Add a new check to the repository. + * + * @param CheckInterface $check The check instance to add. */ public function registerCheck(CheckInterface $check) { @@ -36,6 +39,8 @@ public function registerCheck(CheckInterface $check) } /** + * Get all of the checks in the repository. + * * @return array */ public function getAll() @@ -44,9 +49,11 @@ public function getAll() } /** - * @param string $class - * @return CheckInterface - * @throws InvalidArgumentException + * Get a check instance via it's class name. + * + * @param string $class The class name of the check instance. + * @return CheckInterface The instance. + * @throws InvalidArgumentException If an instance of the check does not exist. */ public function getByClass($class) { @@ -58,6 +65,8 @@ public function getByClass($class) } /** + * Query whether a check instance exists in this repository via its class name. + * * @param string $class * @return bool */ diff --git a/src/Check/CodeParseCheck.php b/src/Check/CodeParseCheck.php index 37b4441c..810422dd 100644 --- a/src/Check/CodeParseCheck.php +++ b/src/Check/CodeParseCheck.php @@ -13,7 +13,9 @@ use PhpSchool\PhpWorkshop\Result\Success; /** - * Class CodeParseCheck + * This check attempts to parse a student's solution and returns + * a success or failure based on the result of the parsing. + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ @@ -34,6 +36,8 @@ public function __construct(Parser $parser) } /** + * Return the check's name + * * @return string */ public function getName() @@ -42,9 +46,13 @@ public function getName() } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultInterface + * This check grabs the contents of the student's solution and + * attempts to parse it with `nikic/php-parser`. If any exceptions are thrown + * by the parser, it is treated as a failure. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { @@ -61,6 +69,8 @@ public function check(ExerciseInterface $exercise, $fileName) } /** + * This check can run on any exercise type. + * * @param ExerciseType $exerciseType * @return bool */ @@ -70,7 +80,6 @@ public function canRun(ExerciseType $exerciseType) } /** - * * @return string */ public function getExerciseInterface() @@ -79,6 +88,8 @@ public function getExerciseInterface() } /** + * This check should be run before executing the student's solution, as, if it cannot be parsed + * it probably cannot be executed. * * @return string */ diff --git a/src/Check/ComposerCheck.php b/src/Check/ComposerCheck.php index 0a5af4f2..8a6c9ea6 100644 --- a/src/Check/ComposerCheck.php +++ b/src/Check/ComposerCheck.php @@ -11,13 +11,17 @@ use PhpSchool\PhpWorkshop\Result\Success; /** - * Class ComposerCheck + * This check looks for a set of composer packages specified by the exercise + * in the students `composer.lock` file. + * * @author Aydin Hassan */ class ComposerCheck implements SimpleCheckInterface { /** + * Return the check's name + * * @return string */ public function getName() @@ -26,9 +30,13 @@ public function getName() } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultInterface + * This check parses the `composer.lock` file and checks that the student + * installed a set of required packages. If they did not a failure is returned, otherwise, + * a success is returned. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { @@ -63,6 +71,8 @@ public function check(ExerciseInterface $exercise, $fileName) } /** + * This check can run on any exercise type. + * * @param ExerciseType $exerciseType * @return bool */ @@ -81,6 +91,7 @@ public function getExerciseInterface() } /** + * This check can run before because if it fails, there is no point executing the solution. * * @return string */ diff --git a/src/Check/DatabaseCheck.php b/src/Check/DatabaseCheck.php index 2575bd4f..3b96041f 100644 --- a/src/Check/DatabaseCheck.php +++ b/src/Check/DatabaseCheck.php @@ -7,8 +7,6 @@ use PhpSchool\PhpWorkshop\Event\CliExecuteEvent; use PhpSchool\PhpWorkshop\Event\Event; use PhpSchool\PhpWorkshop\Event\EventDispatcher; -use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; -use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\TemporaryDirectoryTrait; use PhpSchool\PhpWorkshop\ExerciseCheck\DatabaseExerciseCheck; use PhpSchool\PhpWorkshop\Result\Failure; @@ -16,7 +14,11 @@ use Symfony\Component\Process\Process; /** - * Class DatabaseCheck + * This check sets up a database and a `PDO` object. It prepends the database DSN as a CLI argument to the student's + * solution so they can connect to the database. The `PDO` object is passed to the exercise before and after the + * student's solution has been executed, allowing you to first seed the database and then verify the contents of the + * database. + * * @author Aydin Hassan */ class DatabaseCheck implements ListenableCheckInterface @@ -49,7 +51,7 @@ class DatabaseCheck implements ListenableCheckInterface private $solutionDsn; /** - * + * Setup paths and DSN's. */ public function __construct() { @@ -71,7 +73,6 @@ public function getName() } /** - * * @return string */ public function getExerciseInterface() @@ -80,6 +81,9 @@ public function getExerciseInterface() } /** + * Here we attach to various events to seed, verify and inject the DSN's + * to the student & reference solution programs's CLI arguments. + * * @param EventDispatcher $eventDispatcher */ public function attach(EventDispatcher $eventDispatcher) diff --git a/src/Check/FileExistsCheck.php b/src/Check/FileExistsCheck.php index ecc7b898..43f882d1 100644 --- a/src/Check/FileExistsCheck.php +++ b/src/Check/FileExistsCheck.php @@ -9,13 +9,16 @@ use PhpSchool\PhpWorkshop\Result\Success; /** - * Class FileExistsCheck + * This check verifies that the student's solution file actually exists. + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ class FileExistsCheck implements SimpleCheckInterface { /** + * Return the check's name. + * * @return string */ public function getName() @@ -24,9 +27,11 @@ public function getName() } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultInterface + * Simply check that the file exists. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { @@ -38,6 +43,8 @@ public function check(ExerciseInterface $exercise, $fileName) } /** + * This check can run on any exercise type. + * * @param ExerciseType $exerciseType * @return bool */ @@ -56,6 +63,7 @@ public function getExerciseInterface() } /** + * This check must run before executing the solution becuase it may not exist. * * @return string */ diff --git a/src/Check/FunctionRequirementsCheck.php b/src/Check/FunctionRequirementsCheck.php index 88e12fee..bb467fd0 100644 --- a/src/Check/FunctionRequirementsCheck.php +++ b/src/Check/FunctionRequirementsCheck.php @@ -16,7 +16,9 @@ use PhpSchool\PhpWorkshop\Result\Success; /** - * Class FunctionRequirementsCheck + * This check verifies that the student's solution contains usages of some required functions + * and also does not use certain functions (specified by the exercise). + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ @@ -37,6 +39,8 @@ public function __construct(Parser $parser) } /** + * Return the check's name. + * * @return string */ public function getName() @@ -45,9 +49,13 @@ public function getName() } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultInterface + * Parse the students solution and check that there are usages of + * required functions and that banned functions are not used. The requirements + * are pulled from the exercise. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { @@ -92,6 +100,8 @@ public function check(ExerciseInterface $exercise, $fileName) } /** + * This check can run on any exercise type. + * * @param ExerciseType $exerciseType * @return bool */ @@ -101,7 +111,6 @@ public function canRun(ExerciseType $exerciseType) } /** - * * @return string */ public function getExerciseInterface() @@ -110,6 +119,9 @@ public function getExerciseInterface() } /** + * This is performed after executing the student's solution because the solution may produce the correct + * output, but do it in a way that was not correct for the task. This way the student can see the program works + * but missed some requirements. * * @return string */ diff --git a/src/Check/ListenableCheckInterface.php b/src/Check/ListenableCheckInterface.php index 3092ff45..64aa12dc 100644 --- a/src/Check/ListenableCheckInterface.php +++ b/src/Check/ListenableCheckInterface.php @@ -5,13 +5,17 @@ use PhpSchool\PhpWorkshop\Event\EventDispatcher; /** - * Interface ListenableCheckInterface + * The interface for advanced listener checks which can execute logic at any dispatched event. + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ interface ListenableCheckInterface extends CheckInterface { /** + * Attach to events throughout the running/verifying process. Inject verifiers + * and listeners. + * * @param EventDispatcher $eventDispatcher */ public function attach(EventDispatcher $eventDispatcher); diff --git a/src/Check/PhpLintCheck.php b/src/Check/PhpLintCheck.php index bb3d0483..9955c28a 100644 --- a/src/Check/PhpLintCheck.php +++ b/src/Check/PhpLintCheck.php @@ -9,7 +9,9 @@ use Symfony\Component\Process\Process; /** - * Class PhpLintCheck + * This check attempts to lint a student's solution and returns + * a success or failure based on the result of the linting. + * * @package PhpSchool\PhpWorkshop\Check * @author Aydin Hassan */ @@ -17,6 +19,8 @@ class PhpLintCheck implements SimpleCheckInterface { /** + * Return the check's name + * * @return string */ public function getName() @@ -25,9 +29,11 @@ public function getName() } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return Failure|Success + * Simply check the student's solution can be linted with `php -l`. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName) { @@ -42,6 +48,8 @@ public function check(ExerciseInterface $exercise, $fileName) } /** + * This check can run on any exercise type. + * * @param ExerciseType $exerciseType * @return bool */ @@ -51,7 +59,6 @@ public function canRun(ExerciseType $exerciseType) } /** - * * @return string */ public function getExerciseInterface() @@ -60,6 +67,8 @@ public function getExerciseInterface() } /** + * This check should be run before executing the student's solution, as, if it cannot be linted + * it probably cannot be executed. * * @return string */ diff --git a/src/Check/SimpleCheckInterface.php b/src/Check/SimpleCheckInterface.php index 7d4e7b9d..044ee798 100644 --- a/src/Check/SimpleCheckInterface.php +++ b/src/Check/SimpleCheckInterface.php @@ -7,7 +7,9 @@ use PhpSchool\PhpWorkshop\Result\ResultInterface; /** - * Class CheckInterface + * The interface for simple checks, checks that execute at one defined point, before or after + * output verification. + * * @package PhpSchool\PhpWorkshop\Comparator * @author Aydin Hassan */ @@ -36,14 +38,22 @@ interface SimpleCheckInterface extends CheckInterface public function canRun(ExerciseType $exerciseType); /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultInterface + * The check is ran against an exercise and a filename which + * will point to the student's solution. + * + * If the check is successful then an instance of + * `PhpSchool\PhpWorkshop\Result\SuccessInterface` should be returned. If the check is not + * successful then an instance of `PhpSchool\PhpWorkshop\Result\FailureInterface` + * should be returned. + * + * @param ExerciseInterface $exercise The exercise to check against. + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check(ExerciseInterface $exercise, $fileName); /** - * either static::CHECK_BEFORE | static::CHECK_AFTER + * Either `static::CHECK_BEFORE` | `static::CHECK_AFTER`. * * @return string */ diff --git a/src/CodeInsertion.php b/src/CodeInsertion.php index 79ae3907..567cf97c 100644 --- a/src/CodeInsertion.php +++ b/src/CodeInsertion.php @@ -5,13 +5,24 @@ use Assert\Assertion; /** - * Class CodeInsertion. + * This class is a simple DTO to represent a code insertion which should + * be performed on a students solution. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ class CodeInsertion { + /** + * Denotes that the block of code this insertion + * represents, should be inserted at the top of the solution. + */ const TYPE_BEFORE = 'before'; + + /** + * Denotes that the block of code this insertion + * represents, should be inserted at the bottom of the solution. + */ const TYPE_AFTER = 'after'; /** @@ -33,6 +44,9 @@ class CodeInsertion private $code; /** + * Accepts the type of insertion, either `static::TYPE_BEFORE` or `static::TYPE_AFTER` + * and a string containing the code to be inserted. + * * @param string $type * @param string $code */ @@ -46,6 +60,8 @@ public function __construct($type, $code) } /** + * Get the type of insertion, either `static::TYPE_BEFORE` or `static::TYPE_AFTER`. + * * @return string */ public function getType() @@ -54,6 +70,8 @@ public function getType() } /** + * Get a string containing the code be inserted. + * * @return string */ public function getCode() diff --git a/src/CodePatcher.php b/src/CodePatcher.php index a0240df8..af29e6c7 100644 --- a/src/CodePatcher.php +++ b/src/CodePatcher.php @@ -12,7 +12,10 @@ use PhpSchool\PhpWorkshop\Exercise\SubmissionPatcher; /** - * Class CodePatcher + * Service to apply patches to a student's solution. Accepts a default patch via the constructor. + * Patches are pulled from the exercise (if it implements `SubmissionPatchable`) and applied to the + * given code. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -34,6 +37,13 @@ class CodePatcher private $defaultPatch; /** + * This service requires an instance of `Parser` and `Standard`. These services allow + * to parse code to an AST and to print code from an AST. + * + * The service also accepts a default patch. This allows a workshop to apply a patch + * to every single student solution. This is used (by default) to modify various ini + * settings, such as increasing the error reporting level. + * * @param Parser $parser * @param Standard $printer * @param Patch $defaultPatch @@ -46,6 +56,13 @@ public function __construct(Parser $parser, Standard $printer, Patch $defaultPat } /** + * Accepts an exercise and a string containing the students solution to the exercise. + * + * If there is a default patch, the students solution is patched with that. + * + * If the exercise implements `SubmissionPatchable` then the patch is pulled from it and applied to + * the students solution. + * * @param ExerciseInterface $exercise * @param string $code * @return string diff --git a/src/Command/CreditsCommand.php b/src/Command/CreditsCommand.php index 96b2fa10..7f6a58cb 100644 --- a/src/Command/CreditsCommand.php +++ b/src/Command/CreditsCommand.php @@ -6,7 +6,8 @@ use PhpSchool\PhpWorkshop\Output\OutputInterface; /** - * Class CreditsCommand + * A command to display the framework and workshop credits. + * * @package PhpSchool\PhpWorkshop\Command * @author Aydin Hassan * @author Michael Woodward @@ -66,6 +67,7 @@ private function writeContributors(array $contributors) } /** + * * @return int|void */ public function __invoke() diff --git a/src/CommandDefinition.php b/src/CommandDefinition.php index d4ee33f5..1f5689cc 100644 --- a/src/CommandDefinition.php +++ b/src/CommandDefinition.php @@ -3,7 +3,10 @@ namespace PhpSchool\PhpWorkshop; /** - * Class CommandDefinition + * Represents a command in the workshop framework. Simply consists of a + * command name, required arguments and either a service name or callable to + * execute when the command is run. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -15,7 +18,7 @@ class CommandDefinition private $name; /** - * @var array + * @var string[] */ private $args; @@ -25,11 +28,9 @@ class CommandDefinition private $commandCallable; /** - * CommandDefinition constructor. - * - * @param string $name - * @param array $args - * @param string|callable $commandCallable + * @param string $name The name of the command (this is how the student would invoke the command from the cli) + * @param string[] $args A list of required arguments. This must be an array of strings. + * @param string|callable $commandCallable The name of a callable container entry or an actual PHP callable. */ public function __construct($name, array $args, $commandCallable) { @@ -39,6 +40,8 @@ public function __construct($name, array $args, $commandCallable) } /** + * Get the name of the command. + * * @return string */ public function getName() @@ -47,6 +50,8 @@ public function getName() } /** + * Get the list of required arguments. + * * @return array */ public function getRequiredArgs() @@ -55,6 +60,8 @@ public function getRequiredArgs() } /** + * Get the callable associated with this command. + * * @return string|callable */ public function getCommandCallable() diff --git a/src/CommandRouter.php b/src/CommandRouter.php index c2daea63..78028a3a 100644 --- a/src/CommandRouter.php +++ b/src/CommandRouter.php @@ -8,7 +8,10 @@ use SebastianBergmann\Environment\Runtime; /** - * Class CommandRouter + * Parses $argv (or passed array) and attempts to find a command + * which is suitable for what was typed on the cli. It then executes the callable + * associated with that command definition. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -26,14 +29,20 @@ class CommandRouter private $defaultCommand; /** - * @var \Interop\Container\ContainerInterface + * @var ContainerInterface */ private $container; /** - * @param CommandDefinition[] $commands - * @param $default - * @param \Interop\Container\ContainerInterface $container + * Accepts an array of `CommandDefinition`'s which represent the application. Also takes a default + * (name of one of the commands) which will be used if the workshop was invoked with no arguments. + * + * Also accepts an instance of the container so it can look for services in there which may by defined + * as the callable for one of the command definitions. + * + * @param CommandDefinition[] $commands An array of command definitions + * @param string $default The default command to use (if the workshop was invoked with no arguments) + * @param ContainerInterface $container An instance of the container */ public function __construct(array $commands, $default, ContainerInterface $container) { @@ -61,6 +70,18 @@ private function addCommand(CommandDefinition $c) } /** + * Attempts to route the command. Parses `$argv` (or a given array), extracting the command name and + * arguments. Using the command name, the command definition is looked up. + * + * The number of arguments are validated against the required arguments for the command + * (specified by the definition) + * + * We get the callable from the command definition, or if it is the name of a service, we lookup the service + * in the container and validate that it is a callable. + * + * Finally, the callable is invoked with the arguments passed from the cli. The return value of + * callable is returned (if it is an integer, if not zero (success) is returned). + * * @param array $args * @return int * @throws CliRouteNotExists diff --git a/src/ComposerUtil/LockFileParser.php b/src/ComposerUtil/LockFileParser.php index 8e76843c..3e6e6547 100644 --- a/src/ComposerUtil/LockFileParser.php +++ b/src/ComposerUtil/LockFileParser.php @@ -5,7 +5,8 @@ use PhpSchool\PhpWorkshop\Exception\InvalidArgumentException; /** - * Class LockFileParser + * Utility for reading installed package versions from a `composer.lock` file. + * * @author Aydin Hassan */ class LockFileParser @@ -16,8 +17,8 @@ class LockFileParser private $contents; /** - * @param string $lockFilePath - * @throws InvalidArgumentException + * @param string $lockFilePath The absolute path to the `composer.lock` file. + * @throws InvalidArgumentException If the file does not exist. */ public function __construct($lockFilePath) { @@ -29,6 +30,15 @@ public function __construct($lockFilePath) } /** + * Get an array of installed packages from the `composer.lock` file including their versions. + * + * ```php + * [ + * ['name' => 'my/package', 'version' => '1.0.0'], + * ['name' => 'my/second-package', 'version' => '1.1.0'], + * ]; + * ``` + * * @return array */ public function getInstalledPackages() @@ -42,6 +52,8 @@ public function getInstalledPackages() } /** + * Check if a package name has been installed in any version. + * * @param string $packageName * @return bool */ diff --git a/src/Event/CgiExecuteEvent.php b/src/Event/CgiExecuteEvent.php index 6b78c370..821de0c2 100644 --- a/src/Event/CgiExecuteEvent.php +++ b/src/Event/CgiExecuteEvent.php @@ -6,7 +6,9 @@ use Psr\Http\Message\RequestInterface; /** - * Class CgiExecuteEvent + * An event to represent events which occur throughout the verification and running process in + * `\PhpSchool\PhpWorkshop\ExerciseRunner\CgiRunner`. + * * @package PhpSchool\PhpWorkshop\Event * @author Aydin Hassan */ @@ -19,9 +21,9 @@ class CgiExecuteEvent extends Event private $request; /** - * @param string $name - * @param RequestInterface $request - * @param array $parameters + * @param string $name The event name. + * @param RequestInterface $request The request that will be performed. + * @param array $parameters The event parameters. */ public function __construct($name, RequestInterface $request, array $parameters = []) { @@ -31,6 +33,8 @@ public function __construct($name, RequestInterface $request, array $parameters } /** + * Add a header to the request. + * * @param string $header * @param string|string[] $value */ @@ -40,6 +44,8 @@ public function addHeaderToRequest($header, $value) } /** + * Modify the request via a callback. The callback should return the newly modified request. + * * @param callable $callback */ public function modifyRequest(callable $callback) @@ -48,6 +54,8 @@ public function modifyRequest(callable $callback) } /** + * Get the request. + * * @return RequestInterface */ public function getRequest() diff --git a/src/Event/CliExecuteEvent.php b/src/Event/CliExecuteEvent.php index 0743519c..96a33037 100644 --- a/src/Event/CliExecuteEvent.php +++ b/src/Event/CliExecuteEvent.php @@ -6,7 +6,9 @@ use PhpSchool\PhpWorkshop\Utils\ArrayObject; /** - * Class CliEvent + * An event to represent events which occur throughout the verification and running process in + * `\PhpSchool\PhpWorkshop\ExerciseRunner\CliRunner`. + * * @package PhpSchool\PhpWorkshop\Event * @author Aydin Hassan */ @@ -18,9 +20,9 @@ class CliExecuteEvent extends Event private $args; /** - * @param string $name - * @param ArrayObject $args - * @param array $parameters + * @param string $name The event name. + * @param ArrayObject $args The arguments that should be/have been passed to the program. + * @param array $parameters The event parameters. */ public function __construct($name, ArrayObject $args, array $parameters = []) { @@ -30,6 +32,8 @@ public function __construct($name, ArrayObject $args, array $parameters = []) } /** + * Prepend an argument to the list of arguments to be passed to the program. + * * @param string $arg */ public function prependArg($arg) @@ -39,6 +43,8 @@ public function prependArg($arg) } /** + * Append an argument to the list of arguments to be passed to the program. + * * @param string $arg */ public function appendArg($arg) @@ -48,6 +54,8 @@ public function appendArg($arg) } /** + * Get the arguments to be passed to the program. + * * @return ArrayObject */ public function getArgs() diff --git a/src/Event/Event.php b/src/Event/Event.php index 2986c3ac..83b14546 100644 --- a/src/Event/Event.php +++ b/src/Event/Event.php @@ -5,7 +5,8 @@ use PhpSchool\PhpWorkshop\Exception\InvalidArgumentException; /** - * Class CliEvent + * A generic `PhpSchool\PhpWorkshop\Event\EventInterface` implementation. + * * @package PhpSchool\PhpWorkshop\Event * @author Aydin Hassan */ @@ -22,8 +23,8 @@ class Event implements EventInterface protected $parameters; /** - * @param string $name - * @param array $parameters + * @param string $name The event name. + * @param array $parameters The event parameters. */ public function __construct($name, array $parameters = []) { @@ -32,6 +33,8 @@ public function __construct($name, array $parameters = []) } /** + * Get the name of this event. + * * @return string */ public function getName() @@ -40,6 +43,8 @@ public function getName() } /** + * Get an array of parameters that were triggered with this event. + * * @return mixed[] */ public function getParameters() @@ -48,8 +53,11 @@ public function getParameters() } /** - * @param string $name - * @return mixed + * Get a parameter by it's name. + * + * @param string $name The name of the parameter. + * @return mixed The value. + * @throws InvalidArgumentException If the parameter by name does not exist. */ public function getParameter($name) { diff --git a/src/Event/EventDispatcher.php b/src/Event/EventDispatcher.php index ec5291d1..21bc7c2c 100644 --- a/src/Event/EventDispatcher.php +++ b/src/Event/EventDispatcher.php @@ -6,7 +6,8 @@ use PhpSchool\PhpWorkshop\ResultAggregator; /** - * Class EventDispatcher + * An event dispatcher implementation. + * * @package PhpSchool\PhpWorkshop\EventManager * @author Aydin Hassan */ @@ -31,6 +32,8 @@ public function __construct(ResultAggregator $resultAggregator) } /** + * Dispatch an event. Can be any event object which implements `PhpSchool\PhpWorkshop\Event\EventInterface`. + * * @param EventInterface $event * @return EventInterface */ @@ -46,7 +49,10 @@ public function dispatch(EventInterface $event) } /** - * @param string $eventNames + * Attach a callback to an event name. `$eventNames` can be an array of event names in order to attach the same + * callback to multiple events or it can just be one event name as a string. + * + * @param string|array $eventNames * @param callable $callback */ public function listen($eventNames, callable $callback) @@ -74,7 +80,11 @@ private function attachListener($eventName, callable $callback) } /** - * @param string $eventName + * Insert a verifier callback which will execute at the given event name much like normal listeners. + * A verifier should return an object which implements `PhpSchool\PhpWorkshop\Result\FailureInterface` + * or `PhpSchool\PhpWorkshop\Result\SuccessInterface`. This result object will be added to the result aggregator. + * + * @param string|array $eventName * @param callable $verifier */ public function insertVerifier($eventName, callable $verifier) diff --git a/src/Event/EventInterface.php b/src/Event/EventInterface.php index 08852526..669b9604 100644 --- a/src/Event/EventInterface.php +++ b/src/Event/EventInterface.php @@ -3,25 +3,33 @@ namespace PhpSchool\PhpWorkshop\Event; /** - * Class CliEvent + * An event representation. + * * @package PhpSchool\PhpWorkshop\Event * @author Aydin Hassan */ interface EventInterface { /** + * Get the name of this event. + * * @return string */ public function getName(); /** + * Get an array of parameters that were triggered with this event. + * * @return mixed[] */ public function getParameters(); /** - * @param string $name - * @return mixed + * Get a parameter by it's name. + * + * @param string $name The name of the parameter. + * @return mixed The value. + * @throws InvalidArgumentException If the parameter by name does not exist. */ public function getParameter($name); } diff --git a/src/Exception/CheckNotApplicableException.php b/src/Exception/CheckNotApplicableException.php index a17601cc..c6b4e985 100644 --- a/src/Exception/CheckNotApplicableException.php +++ b/src/Exception/CheckNotApplicableException.php @@ -7,15 +7,19 @@ use RuntimeException; /** - * Class CheckNotApplicableException + * Represents the situation when a workshop developer tries to use a check in an exercise which has + * a type not supported by the check. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ class CheckNotApplicableException extends RuntimeException { /** - * @param CheckInterface $check - * @param ExerciseInterface $exercise + * Static constructor to create an instance from the check & exercise. + * + * @param CheckInterface $check The check Instance. + * @param ExerciseInterface $exercise The exercise Instance. * @return static */ public static function fromCheckAndExercise(CheckInterface $check, ExerciseInterface $exercise) diff --git a/src/Exception/CliRouteNotExistsException.php b/src/Exception/CliRouteNotExistsException.php index 111d1d45..41d1ba86 100644 --- a/src/Exception/CliRouteNotExistsException.php +++ b/src/Exception/CliRouteNotExistsException.php @@ -5,14 +5,15 @@ use RuntimeException; /** - * Class CliRouteNotExistsException + * Represents the situation where a command is called which does not exist in the framework. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ class CliRouteNotExistsException extends RuntimeException { /** - * @param string $routeName + * @param string $routeName The name of the command which was typed. */ public function __construct($routeName) { diff --git a/src/Exception/CodeExecutionException.php b/src/Exception/CodeExecutionException.php index ec238831..94c92ef6 100644 --- a/src/Exception/CodeExecutionException.php +++ b/src/Exception/CodeExecutionException.php @@ -6,14 +6,17 @@ use Symfony\Component\Process\Process; /** - * Class CodeExecutionException + * Represents the situation where some PHP code could not be executed successfully. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ class CodeExecutionException extends RuntimeException { /** - * @param Process $process + * Static constructor to create an instance from a failed `Symfony\Component\Process\Process` instance. + * + * @param Process $process The `Symfony\Component\Process\Process` instance which failed. * @return static */ public static function fromProcess(Process $process) diff --git a/src/Exception/ExerciseNotConfiguredException.php b/src/Exception/ExerciseNotConfiguredException.php index f909f7f8..bf08747f 100644 --- a/src/Exception/ExerciseNotConfiguredException.php +++ b/src/Exception/ExerciseNotConfiguredException.php @@ -6,15 +6,19 @@ use RuntimeException; /** - * Class ExerciseNotConfiguredException + * Represents the situation where an exercise requires a check but does not implement + * the correct interface enforced by the check. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ class ExerciseNotConfiguredException extends RuntimeException { /** - * @param ExerciseInterface $exercise - * @param $interface + * Static constructor to create an instance from the exercise and interface name. + * + * @param ExerciseInterface $exercise The exercise instance. + * @param $interface The FQCN of the interface. * @return static */ public static function missingImplements(ExerciseInterface $exercise, $interface) diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index f0696a4c..920368a9 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -3,13 +3,16 @@ namespace PhpSchool\PhpWorkshop\Exception; /** - * Class InvalidArgumentException + * Represents invalid argument exceptions. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ class InvalidArgumentException extends \InvalidArgumentException { /** + * Static constructor to create from the expected type & the actual value. + * * @param string $expected * @param mixed $actual * @return static @@ -26,6 +29,8 @@ public static function typeMisMatch($expected, $actual) } /** + * Static constructor to create from when a parameter should be one of a set of allowed values, but was not. + * * @param string $parameterName * @param mixed[] $allowedValues * @param mixed $actualValue @@ -47,7 +52,7 @@ public static function notValidParameter($parameterName, array $allowedValues, $ * @param $value * @return string */ - public static function stringify($value) + private static function stringify($value) { if (is_object($value)) { return get_class($value); diff --git a/src/Exception/MissingArgumentException.php b/src/Exception/MissingArgumentException.php index 0febaf9c..8af5b7d5 100644 --- a/src/Exception/MissingArgumentException.php +++ b/src/Exception/MissingArgumentException.php @@ -5,7 +5,8 @@ use RuntimeException; /** - * Class MissingArgumentException + * Represents the situation where a command was called without required parameters. + * * @package PhpSchool\PhpWorkshop\Exception * @author Aydin Hassan */ @@ -17,8 +18,10 @@ class MissingArgumentException extends RuntimeException private $missingArguments = []; /** - * @param $commandName - * @param array $missingArguments + * Create the exception, requires the command name and missing arguments. + * + * @param string $commandName The command name. + * @param array $missingArguments An array of missing arguments (strings). */ public function __construct($commandName, array $missingArguments) { @@ -33,6 +36,8 @@ public function __construct($commandName, array $missingArguments) } /** + * Retrieve the list of missing arguments. + * * @return array */ public function getMissingArguments() diff --git a/src/Exception/SolutionExecutionException.php b/src/Exception/SolutionExecutionException.php index 71eccdef..988126fc 100644 --- a/src/Exception/SolutionExecutionException.php +++ b/src/Exception/SolutionExecutionException.php @@ -5,7 +5,8 @@ use RuntimeException; /** - * Class SolutionExecutionException + * Represents the situation where a reference solution cannot be executed (this should only really happen during + * workshop development). * @author Aydin Hassan */ class SolutionExecutionException extends RuntimeException diff --git a/src/Exercise/AbstractExercise.php b/src/Exercise/AbstractExercise.php index 34e8c50c..16cd0e6f 100644 --- a/src/Exercise/AbstractExercise.php +++ b/src/Exercise/AbstractExercise.php @@ -8,7 +8,9 @@ use ReflectionClass; /** - * Class AbstractExercise + * This abstract class implements many of the methods described in `PhpSchool\PhpWorkshop\Exercise\ExerciseInterface`. + * It serves as a good base for an exercise, providing useful defaults for many of the methods. + * * @package PhpSchool\PhpWorkshop\Exercise * @author Aydin Hassan */ @@ -16,11 +18,20 @@ abstract class AbstractExercise { /** + * Get the name of the exercise, like `Hello World!`. + * * @return string */ abstract public function getName(); /** + * This returns a single file solution named `solution.php` which + * should exist in `workshop-root/exercises//solution/`. + * + * This method can be overwritten if the solution consists of multiple files, + * see [Directory Solution](https://www.phpschool.io/docs/reference/exercise-solutions#directory-solution) for + * more details. + * * @return SolutionInterface */ public function getSolution() @@ -37,6 +48,9 @@ public function getSolution() } /** + * This returns the problem file path, which is assumed to exist in + * `workshop-root/exercises//problem/` as a file named `problem.md`. + * * @return string */ public function getProblem() @@ -47,7 +61,10 @@ public function getProblem() } /** - * @return null + * Allows to perform some cleanup after the exercise solution's have been executed, for example + * remove files, close DB connections. + * + * @return void */ public function tearDown() { @@ -63,6 +80,9 @@ private function normaliseName($name) } /** + * 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 */ public function configure(ExerciseDispatcher $dispatcher) diff --git a/src/Exercise/CgiExercise.php b/src/Exercise/CgiExercise.php index aa443fa3..bcc16358 100644 --- a/src/Exercise/CgiExercise.php +++ b/src/Exercise/CgiExercise.php @@ -5,13 +5,17 @@ use Psr\Http\Message\RequestInterface; /** - * Interface CgiExercise + * This interface describes the additional methods a CGI type exercise should implement. + * * @package PhpSchool\PhpWorkshop\Exercise */ interface CgiExercise { /** - * @return RequestInterface[] + * This method should return an array of PSR-7 requests, which will be forwarded to the student's + * solution. + * + * @return RequestInterface[] An array of PSR-7 requests. */ public function getRequests(); } diff --git a/src/Exercise/CliExercise.php b/src/Exercise/CliExercise.php index a88db368..a8df0d4d 100644 --- a/src/Exercise/CliExercise.php +++ b/src/Exercise/CliExercise.php @@ -2,16 +2,18 @@ namespace PhpSchool\PhpWorkshop\Exercise; -use Psr\Http\Message\RequestInterface; - /** - * Interface CliExercise + * This interface describes the additional methods a CLI type exercise should implement. + * * @package PhpSchool\PhpWorkshop\Exercise */ interface CliExercise { /** - * @return string[] + * This method should return an array of strings which will be passed to the student's solution + * as command line arguments. + * + * @return string[] An array of string arguments. */ public function getArgs(); } diff --git a/src/Exercise/ExerciseInterface.php b/src/Exercise/ExerciseInterface.php index 28fe2d45..518a2f68 100644 --- a/src/Exercise/ExerciseInterface.php +++ b/src/Exercise/ExerciseInterface.php @@ -6,45 +6,64 @@ use PhpSchool\PhpWorkshop\Solution\SolutionInterface; /** - * Class ExerciseInterface + * This interface describes all of the methods an exercise + * should implement. + * * @package PhpSchool\PhpWorkshop\Exercise * @author Aydin Hassan */ - interface ExerciseInterface { /** + * Get the name of the exercise, like `Hello World!`. + * * @return string */ public function getName(); /** + * Return the type of exercise. This is an ENUM. See `PhpSchool\PhpWorkshop\Exercise\ExerciseType`. + * * @return ExerciseType */ public function getType(); /** + * 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. + * * @param ExerciseDispatcher $dispatcher */ public function configure(ExerciseDispatcher $dispatcher); /** + * A short description of the exercise. + * * @return string */ public function getDescription(); /** + * Get the exercise solution. + * * @return SolutionInterface */ public function getSolution(); /** + * Get the absolute path to the markdown file which contains the exercise problem. + * * @return string */ public function getProblem(); /** + * Allows to perform some cleanup after the exercise solution's have been executed, for example + * remove files, close DB connections. + * * @return void */ public function tearDown(); diff --git a/src/Exercise/ExerciseType.php b/src/Exercise/ExerciseType.php index 3b665a82..f29644e6 100644 --- a/src/Exercise/ExerciseType.php +++ b/src/Exercise/ExerciseType.php @@ -7,7 +7,13 @@ use PhpSchool\PhpWorkshop\ExerciseRunner\CliRunner; /** - * Class ExerciseType + * This class is a ENUM which represents the types that exercises can be. Instantiation looks like: + * + * ```php + * $typeCli = ExerciseType::CLI(); + * $typeCgi = ExerciseType::CGI(); + * ``` + * * @package PhpSchool\PhpWorkshop\Exercise * @author Aydin Hassan */ diff --git a/src/Exercise/SubmissionPatchable.php b/src/Exercise/SubmissionPatchable.php index 1dbe26e5..e3fe30e3 100644 --- a/src/Exercise/SubmissionPatchable.php +++ b/src/Exercise/SubmissionPatchable.php @@ -5,13 +5,20 @@ use PhpSchool\PhpWorkshop\Patch; /** - * Interface SubmissionPatchable + * This interface, when implemented by an exercise, tells the workshop framework that the exercise + * would like to patch the student's solution. This might include adding code to the top of the file like + * injecting variables. The exercise should implement the `getPatch()` method and it should return a `Patch`. + * See [Patching Exercise Submissions](https://www.phpschool.io/docs/reference/patching-exercise-solutions) for + * more details. + * * @package PhpSchool\PhpWorkshop\Exercise * @author Aydin Hassan */ interface SubmissionPatchable { /** + * Get the patch. + * * @return Patch */ public function getPatch(); diff --git a/src/Exercise/TemporaryDirectoryTrait.php b/src/Exercise/TemporaryDirectoryTrait.php index 075c6fac..39d92915 100644 --- a/src/Exercise/TemporaryDirectoryTrait.php +++ b/src/Exercise/TemporaryDirectoryTrait.php @@ -3,16 +3,21 @@ namespace PhpSchool\PhpWorkshop\Exercise; /** - * Class TemporaryDirectoryTrait + * Helper trait to use in exercises to get a temporary path + * for IO stuff. + * * @package PhpSchool\PhpWorkshop\Exercise * @author Aydin Hassan */ trait TemporaryDirectoryTrait { /** - * @return string + * Get a temporary directory to use in exercises, takes in to account + * the class-name. + * + * @return string The absolute path to the temporary directory. */ - protected function getTemporaryPath() + public function getTemporaryPath() { return sprintf( '%s/%s', diff --git a/src/ExerciseCheck/ComposerExerciseCheck.php b/src/ExerciseCheck/ComposerExerciseCheck.php index 94cb8c47..63ff97f1 100644 --- a/src/ExerciseCheck/ComposerExerciseCheck.php +++ b/src/ExerciseCheck/ComposerExerciseCheck.php @@ -3,13 +3,18 @@ namespace PhpSchool\PhpWorkshop\ExerciseCheck; /** - * Interface ComposerExerciseCheck + * This interface should be implemented when you require the check `PhpSchool\PhpWorkshop\Check\ComposerCheck` in your + * exercise. + * * @package PhpSchool\PhpWorkshop\ExerciseCheck */ interface ComposerExerciseCheck { /** - * @return array + * Returns an array of composer package names that student's solution should + * have required via composer. + * + * @return array An array of composer package names. */ public function getRequiredPackages(); } diff --git a/src/ExerciseCheck/DatabaseExerciseCheck.php b/src/ExerciseCheck/DatabaseExerciseCheck.php index aeb51a2e..18423983 100644 --- a/src/ExerciseCheck/DatabaseExerciseCheck.php +++ b/src/ExerciseCheck/DatabaseExerciseCheck.php @@ -5,20 +5,30 @@ use PDO; /** - * Interface DatabaseExerciseCheck + * This interface should be implemented when you require the check `PhpSchool\PhpWorkshop\Check\DatabaseCheck` in your + * exercise. + * * @package PhpSchool\PhpWorkshop\ExerciseCheck */ interface DatabaseExerciseCheck { /** - * @param PDO $db - * @return bool + * This method allows your exercise to seed the database *before* the solution's are executed. You can do anything + * you normally could with a `PDO` object. + * + * @param PDO $db A `PDO` instance pointing to the database which will be accessible to the student's solution. + * @return void */ - public function verify(PDO $db); + public function seed(PDO $db); /** - * @param PDO $db - * @return void + * This method allows your exercise to verify the state of database *after* the student's solution has been + * executed. You can count rows in tables, check for the existence of tables & rows and of course anything else + * you can do with a `PDO` object. The method should return a boolean indicating whether the verification + * was successful or not. + * + * @param PDO $db A `PDO` instance pointing to the database which was accessible by the student's solution. + * @return bool The result of the verification. */ - public function seed(PDO $db); + public function verify(PDO $db); } diff --git a/src/ExerciseCheck/FunctionRequirementsExerciseCheck.php b/src/ExerciseCheck/FunctionRequirementsExerciseCheck.php index 596170fd..089c8c8a 100644 --- a/src/ExerciseCheck/FunctionRequirementsExerciseCheck.php +++ b/src/ExerciseCheck/FunctionRequirementsExerciseCheck.php @@ -3,18 +3,26 @@ namespace PhpSchool\PhpWorkshop\ExerciseCheck; /** - * Interface FunctionRequirementsExerciseCheck + * This interface should be implemented when you require the check + * `PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck` in your exercise. + * * @package PhpSchool\PhpWorkshop\ExerciseCheck */ interface FunctionRequirementsExerciseCheck { /** - * @return string[] + * Returns an array of function names that the student's solution should use. The solution + * will be parsed and checked for usages of these functions. + * + * @return string[] An array of function names that *should* be used. */ public function getRequiredFunctions(); /** - * @return string[] + * Returns an array of function names that the student's solution should not use. The solution + * will be parsed and checked for usages of these functions. + * + * @return string[] An array of function names that *should not* be used. */ public function getBannedFunctions(); } diff --git a/src/ExerciseCheck/SelfCheck.php b/src/ExerciseCheck/SelfCheck.php index 13b64f69..9cedcfc6 100644 --- a/src/ExerciseCheck/SelfCheck.php +++ b/src/ExerciseCheck/SelfCheck.php @@ -5,15 +5,24 @@ use PhpSchool\PhpWorkshop\Result\ResultInterface; /** - * Class SelfCheck + * When implemented in an exercise, this interface allows for an exercise to check it's self. + * That is, perform additional verifications in the actual exercise class + * itself. See [Self Checking Exercises](https://www.phpschool.io/docs/reference/self-checking-exercises) for more + * information. + * + * Self checking runs *after* the student's solution has been run/verified. + * * @package PhpSchool\PhpWorkshop\ExerciseCheck * @author Aydin Hassan */ interface SelfCheck { /** - * @param string $fileName - * @return ResultInterface + * The method is passed the absolute file path to the student's solution and should return a result + * object which indicates the success or not of the check. + * + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function check($fileName); } diff --git a/src/ExerciseDispatcher.php b/src/ExerciseDispatcher.php index c33e8ad3..5a65b81d 100644 --- a/src/ExerciseDispatcher.php +++ b/src/ExerciseDispatcher.php @@ -19,7 +19,9 @@ use Symfony\Component\Process\Process; /** - * Class ExerciseDispatcher + * This class is used to verify/run a student's solution to an exercise. It routes to the correct + * runner based on the exercise type. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -56,7 +58,7 @@ class ExerciseDispatcher private $checkRepository; /** - * @param RunnerFactory $runnerFactory + * @param RunnerFactory $runnerFactory Factory capable of building an exercise runner based on the exercise type. * @param ResultAggregator $resultAggregator * @param EventDispatcher $eventDispatcher * @param CheckRepository $checkRepository @@ -74,8 +76,12 @@ public function __construct( } /** - * @param string $requiredCheck - * @throws InvalidArgumentException + * Queue a specific check to be run when the exercise is verified. When the exercise is verified + * the check specified as the first argument will also be executed. Throws an `InvalidArgumentException` + * if the check does not exist in the `CheckRepository`. + * + * @param string $requiredCheck The name of the required check. + * @throws InvalidArgumentException If the check does not exist. */ public function requireCheck($requiredCheck) { @@ -112,11 +118,15 @@ public function requireCheck($requiredCheck) } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @return ResultAggregator - * @throws CheckNotApplicableException - * @throws ExerciseNotConfiguredException + * Verify a students solution against a specific exercise. Runs queued checks based on their position. Invokes the + * correct runner for the exercise based on the exercise type. Various events are triggered throughout the process. + * + * @param ExerciseInterface $exercise The exercise instance. + * @param string $fileName The absolute file name of the students solution. + * @return ResultAggregator Contains all the results injected via the runner, checks and events. + * @throws CheckNotApplicableException If the check is not applicable to the exercise type. + * @throws ExerciseNotConfiguredException If the exercise does not implement the correct interface based on + * the checks required. */ public function verify(ExerciseInterface $exercise, $fileName) { @@ -156,10 +166,14 @@ public function verify(ExerciseInterface $exercise, $fileName) } /** - * @param ExerciseInterface $exercise - * @param string $fileName - * @param OutputInterface $output - * @return bool + * Run a student's solution against a specific exercise. Does not invoke checks. Invokes the + * correct runner for the exercise based on the exercise type. Various events are triggered throughout the process. + * The output of the solution is written directly to the `OutputInterface` instance. + * + * @param ExerciseInterface $exercise The exercise instance. + * @param string $fileName The absolute file name of the students solution. + * @param OutputInterface $output An output instance capable of writing to stdout. + * @return bool Whether the solution ran successfully or not. */ public function run(ExerciseInterface $exercise, $fileName, OutputInterface $output) { @@ -198,6 +212,8 @@ private function validateChecks(array $checks, ExerciseInterface $exercise) } /** + * Retrieve the `EventDispatcher` instance. + * * @return EventDispatcher */ public function getEventDispatcher() diff --git a/src/ExerciseRenderer.php b/src/ExerciseRenderer.php index 45967f7c..843f03af 100644 --- a/src/ExerciseRenderer.php +++ b/src/ExerciseRenderer.php @@ -7,7 +7,9 @@ use PhpSchool\PhpWorkshop\Output\OutputInterface; /** - * Class ExerciseRenderer + * This class is used to render the exercise problem to the student, it also sets the current exercise + * on to the user state object. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ diff --git a/src/ExerciseRepository.php b/src/ExerciseRepository.php index a6e949f6..7a78f7ef 100644 --- a/src/ExerciseRepository.php +++ b/src/ExerciseRepository.php @@ -4,11 +4,13 @@ use ArrayIterator; use Countable; +use InvalidArgumentException; use IteratorAggregate; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; /** - * Class ExerciseRepository + * Exercise repository, use to locate individual/all exercises by certain criteria. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -20,6 +22,8 @@ class ExerciseRepository implements IteratorAggregate, Countable private $exercises; /** + * Requires an array of `ExerciseInterface` instances. + * * @param ExerciseInterface[] $exercises */ public function __construct(array $exercises) @@ -31,6 +35,8 @@ public function __construct(array $exercises) } /** + * Retrieve all of the exercises as an array. + * * @return ExerciseInterface[] */ public function findAll() @@ -39,8 +45,12 @@ public function findAll() } /** + * Find an exercise by it's name. If it does not exist + * an `InvalidArgumentException` exception is thrown. + * * @param string $name * @return ExerciseInterface + * @throws InvalidArgumentException */ public function findByName($name) { @@ -50,10 +60,12 @@ public function findByName($name) } } - throw new \InvalidArgumentException(sprintf('Exercise with name: "%s" does not exist', $name)); + throw new InvalidArgumentException(sprintf('Exercise with name: "%s" does not exist', $name)); } /** + * Get the names of each exercise as an array. + * * @return array */ public function getAllNames() @@ -64,6 +76,8 @@ public function getAllNames() } /** + * Get the number of exercises contained within the repository. + * * @return int */ public function count() @@ -72,6 +86,8 @@ public function count() } /** + * Allow to iterate over the repository with `foreach`. + * * @return ArrayIterator */ public function getIterator() diff --git a/src/ExerciseRunner/CgiRunner.php b/src/ExerciseRunner/CgiRunner.php index 371990eb..3d923028 100644 --- a/src/ExerciseRunner/CgiRunner.php +++ b/src/ExerciseRunner/CgiRunner.php @@ -17,11 +17,14 @@ use PhpSchool\PhpWorkshop\Result\Success; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use RuntimeException; use Symfony\Component\Process\Process; use Zend\Diactoros\Response\Serializer as ResponseSerializer; /** - * Class CgiRunner + * The `CGI` runner. This runner executes solutions as if they were behind a web-server. They populate the `$_SERVER`, + * `$_GET` & `$_POST` super globals with information based of the request objects returned from the exercise. + * * @author Aydin Hassan */ class CgiRunner implements ExerciseRunnerInterface @@ -38,8 +41,13 @@ class CgiRunner implements ExerciseRunnerInterface private $eventDispatcher; /** - * @param CgiExercise $exercise - * @param EventDispatcher $eventDispatcher + * Requires the exercise instance and an event dispatcher. This runner requires the `php-cgi` binary to + * be available. It will check for it's existence in the system's $PATH variable or the same + * folder that the CLI php binary lives in. + * + * @param CgiExercise $exercise The exercise to be invoked. + * @param EventDispatcher $eventDispatcher The event dispatcher. + * @throws RuntimeException If the `php-cgi` binary cannot be found. */ public function __construct(CgiExercise $exercise, EventDispatcher $eventDispatcher) { @@ -52,7 +60,7 @@ public function __construct(CgiExercise $exercise, EventDispatcher $eventDispatc // Try one more time, relying on being in the php binary's directory (where it should be on Windows) system(sprintf('%s --version %s', $newPath, $silence), $stillFailedToRun); if ($stillFailedToRun) { - throw new \RuntimeException( + throw new RuntimeException( 'Could not load php-cgi binary. Please install php-cgi using your package manager.' ); } @@ -60,7 +68,7 @@ public function __construct(CgiExercise $exercise, EventDispatcher $eventDispatc } else { @system('php-cgi --version > /dev/null 2>&1', $failedToRun); if ($failedToRun) { - throw new \RuntimeException( + throw new RuntimeException( 'Could not load php-cgi binary. Please install php-cgi using your package manager.' ); } @@ -192,8 +200,21 @@ private function getProcess($fileName, RequestInterface $request) } /** - * @param string $fileName - * @return ResultInterface + * Verifies a solution by invoking PHP via the `php-cgi` binary, populating all the super globals with + * the information from the request objects returned from the exercise. The exercise can return multiple + * requests so the solution will be invoked for however many requests there are. + * + * Events dispatched (for each request): + * + * * cgi.verify.reference-execute.pre + * * cgi.verify.reference.executing + * * cgi.verify.reference-execute.fail (if the reference solution fails to execute) + * * cgi.verify.student-execute.pre + * * cgi.verify.student.executing + * * cgi.verify.student-execute.fail (if the student's solution fails to execute) + * + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function verify($fileName) { @@ -209,9 +230,21 @@ function (RequestInterface $request) use ($fileName) { } /** - * @param string $fileName - * @param OutputInterface $output - * @return bool + * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with + * the information from the request objects returned from the exercise. The exercise can return multiple + * requests so the solution will be invoked for however many requests there are. + * + * Running only runs the student's solution, the reference solution is not run and no verification is performed, + * the output of the student's solution is written directly to the output. + * + * Events dispatched (for each request): + * + * * cgi.run.student-execute.pre + * * cgi.run.student.executing + * + * @param string $fileName The absolute path to the student's solution. + * @param OutputInterface $output A wrapper around STDOUT. + * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run($fileName, OutputInterface $output) { diff --git a/src/ExerciseRunner/CliRunner.php b/src/ExerciseRunner/CliRunner.php index cfce1b45..c0f8e569 100644 --- a/src/ExerciseRunner/CliRunner.php +++ b/src/ExerciseRunner/CliRunner.php @@ -21,7 +21,13 @@ use Symfony\Component\Process\Process; /** - * Class CliRunner + * The `CLI` runner. This runner executes solutions as PHP CLI scripts, passing the arguments + * from the exercise as command line arguments to the solution. The solution will be invoked like: + * + * ```bash + * php my-solution.php arg1 arg2 arg3 + * ``` + * * @author Aydin Hassan */ class CliRunner implements ExerciseRunnerInterface @@ -37,8 +43,10 @@ class CliRunner implements ExerciseRunnerInterface private $eventDispatcher; /** - * @param CliExercise $exercise - * @param EventDispatcher $eventDispatcher + * Requires the exercise instance and an event dispatcher. + * + * @param CliExercise $exercise The exercise to be invoked. + * @param EventDispatcher $eventDispatcher The event dispatcher. */ public function __construct(CliExercise $exercise, EventDispatcher $eventDispatcher) { @@ -76,7 +84,7 @@ private function executePhpFile($fileName, ArrayObject $args, $type) } /** - * @param string $fileName + * @param string $fileName * @param ArrayObject $args * * @return Process @@ -88,8 +96,20 @@ private function getPhpProcess($fileName, ArrayObject $args) } /** - * @param string $fileName - * @return ResultInterface + * Verifies a solution by invoking PHP from the CLI passing the arguments gathered from the exercise + * as command line arguments to PHP. + * + * Events dispatched: + * + * * cli.verify.reference-execute.pre + * * cli.verify.reference.executing + * * cli.verify.reference-execute.fail (if the reference solution fails to execute) + * * cli.verify.student-execute.pre + * * cli.verify.student.executing + * * cli.verify.student-execute.fail (if the student's solution fails to execute) + * + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function verify($fileName) { @@ -123,9 +143,20 @@ public function verify($fileName) } /** - * @param string $fileName - * @param OutputInterface $output - * @return bool + * Runs a student's solution by invoking PHP from the CLI passing the arguments gathered from the exercise + * as command line arguments to PHP. + * + * Running only runs the student's solution, the reference solution is not run and no verification is performed, + * the output of the student's solution is written directly to the output. + * + * Events dispatched: + * + * * cli.run.student-execute.pre + * * cli.run.student.executing + * + * @param string $fileName The absolute path to the student's solution. + * @param OutputInterface $output A wrapper around STDOUT. + * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run($fileName, OutputInterface $output) { diff --git a/src/ExerciseRunner/ExerciseRunnerInterface.php b/src/ExerciseRunner/ExerciseRunnerInterface.php index ba213873..c5ccbb3a 100644 --- a/src/ExerciseRunner/ExerciseRunnerInterface.php +++ b/src/ExerciseRunner/ExerciseRunnerInterface.php @@ -7,27 +7,44 @@ use PhpSchool\PhpWorkshop\Result\ResultInterface; /** - * Interface ExerciseRunnerInterface + * This interface describes how an exercise runner should work. Each exercise type + * maps to an exercise runner. + * * @package PhpSchool\PhpWorkshop\ExerciseRunner * @author Aydin Hassan */ interface ExerciseRunnerInterface { /** + * Get the name of the exercise runner. + * * @return string */ public function getName(); /** - * @param string $fileName - * @return ResultInterface + * Verify a solution to an exercise. Verification involves executing the reference solution + * and the student's solution and comparing their output. If the output is the same + * an instance of `PhpSchool\PhpWorkshop\Result\SuccessInterface` should be returned, if the output + * is not the same, or something else went wrong then an instance of + * `\PhpSchool\PhpWorkshop\Result\FailureInterface` should be returned. + * + * Other things that could go wrong include the student's solution returning a non-zero + * exit code, or a notice/warning being exhibited. + * + * @param string $fileName The absolute path to the student's solution. + * @return ResultInterface The result of the check. */ public function verify($fileName); /** - * @param string $fileName - * @param OutputInterface $output - * @return bool + * Run a solution to an exercise. This simply run's the student's solution with the correct input from the exercise + * (such as the CLI arguments) and prints the output directly. This allows the student to have the environment + * setup for them including getting a different set of arguments each time (if the exercise supports that). + * + * @param string $fileName The absolute path to the student's solution. + * @param OutputInterface $output A wrapper around STDOUT. + * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run($fileName, OutputInterface $output); } diff --git a/src/MarkdownRenderer.php b/src/MarkdownRenderer.php index 2febfed3..e5057e25 100644 --- a/src/MarkdownRenderer.php +++ b/src/MarkdownRenderer.php @@ -6,23 +6,28 @@ use AydinHassan\CliMdRenderer\CliRenderer; /** - * Class MarkdownRenderer + * Utility to render a markdown string to a string formatted with ANSI escape codes for output + * on the console. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ class MarkdownRenderer { /** - * @var \League\CommonMark\DocParser + * @var DocParser */ private $docParser; /** - * @var \AydinHassan\CliMdRenderer\CliRenderer + * @var CliRenderer */ private $cliRenderer; /** + * Should be constructed with an instance of `DocParser` with parses the markdown to an AST. + * `CliRenderer` renders the AST to a string formatted for the console. + * * @param DocParser $docParser * @param CliRenderer $cliRenderer */ @@ -33,6 +38,9 @@ public function __construct(DocParser $docParser, CliRenderer $cliRenderer) } /** + * Expects a string of markdown and returns a string which has been formatted for + * displaying on the console. + * * @param string $markdown * @return string */ diff --git a/src/Output/OutputInterface.php b/src/Output/OutputInterface.php index ba9ff26f..95381fe0 100644 --- a/src/Output/OutputInterface.php +++ b/src/Output/OutputInterface.php @@ -13,41 +13,57 @@ interface OutputInterface { /** + * Write a string as an error. Should be decorated in someway + * which highlights the severity. + * * @param string $error */ public function printError($error); /** + * Write a string to the output. + * * @param string $content */ public function write($content); /** + * Write an array of strings, each on a new line. + * * @param array $lines */ public function writeLines(array $lines); /** + * Write a string terminated with a newline. + * * @param string $line */ public function writeLine($line); /** - * Write empty line + * Write an empty line. */ public function emptyLine(); /** + * Write a line break. + * * @return string */ public function lineBreak(); /** + * Write a title section. Should be decorated in a way which makes + * the title stand out. + * * @param string $title */ public function writeTitle($title); /** + * Write a PSR-7 request. + * * @param RequestInterface $request */ public function writeRequest(RequestInterface $request); diff --git a/src/Output/StdOutput.php b/src/Output/StdOutput.php index b7025e4b..fb9dd672 100644 --- a/src/Output/StdOutput.php +++ b/src/Output/StdOutput.php @@ -48,6 +48,9 @@ public function printError($error) } /** + * Write a title section. Should be decorated in a way which makes + * the title stand out. + * * @param string $title */ public function writeTitle($title) @@ -56,6 +59,8 @@ public function writeTitle($title) } /** + * Write a string to the output. + * * @param string $content */ public function write($content) @@ -64,6 +69,8 @@ public function write($content) } /** + * Write an array of strings, each on a new line. + * * @param array $lines */ public function writeLines(array $lines) @@ -74,6 +81,8 @@ public function writeLines(array $lines) } /** + * Write a string terminated with a newline. + * * @param string $line */ public function writeLine($line) @@ -82,7 +91,7 @@ public function writeLine($line) } /** - * Write empty line + * Write an empty line. */ public function emptyLine() { @@ -90,6 +99,8 @@ public function emptyLine() } /** + * Write a line break. + * * @return string */ public function lineBreak() @@ -98,6 +109,8 @@ public function lineBreak() } /** + * Write a PSR-7 request. + * * @param RequestInterface $request */ public function writeRequest(RequestInterface $request) diff --git a/src/Patch.php b/src/Patch.php index 9036e3f1..55745359 100644 --- a/src/Patch.php +++ b/src/Patch.php @@ -5,7 +5,13 @@ use Closure; /** - * Class Patch + * This class is responsible for storing the modifications that should + * be made to a PHP file. That includes insertions and transformers. + * A transformer is a simple closure which should receives an AST + * representation of the student's solution and it should return the modified AST. + * An insertion is a block of code that can be inserted at the top or bottom of + * the students solution. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -17,6 +23,8 @@ class Patch private $modifications = []; /** + * Add a new `CodeInsertion`. `Patch` is immutable so a new instance is returned. + * * @param CodeInsertion $insertion * @return static */ @@ -28,8 +36,10 @@ public function withInsertion(CodeInsertion $insertion) } /** + * Add a new transformer (`Closure`). `Patch` is immutable so a new instance is returned. + * * @param Closure $closure - * @return Patch + * @return static */ public function withTransformer(Closure $closure) { @@ -39,6 +49,8 @@ public function withTransformer(Closure $closure) } /** + * Retrieve all the modifications including insertions (`CodeInsertion`'s) & transformers (`Closure`'s) + * * @return array */ public function getModifiers() diff --git a/src/Result/CgiOutRequestFailure.php b/src/Result/CgiOutRequestFailure.php index 77e0085f..a067eb8b 100644 --- a/src/Result/CgiOutRequestFailure.php +++ b/src/Result/CgiOutRequestFailure.php @@ -5,7 +5,9 @@ use Psr\Http\Message\RequestInterface; /** - * Class CgiOutRequestFailure + * A failure result representing the situation where the output of a student's solution did not match the + * expected output in the context of a HTTP request. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ @@ -58,6 +60,8 @@ public function __construct( } /** + * Get the request object associated with this failure. + * * @return RequestInterface */ public function getRequest() @@ -66,6 +70,8 @@ public function getRequest() } /** + * Is the output different? + * * @return bool */ public function bodyDifferent() @@ -74,6 +80,8 @@ public function bodyDifferent() } /** + * Are the headers different? + * * @return bool */ public function headersDifferent() @@ -82,6 +90,8 @@ public function headersDifferent() } /** + * Are the headers & body different? + * * @return bool */ public function headersAndBodyDifferent() @@ -90,6 +100,8 @@ public function headersAndBodyDifferent() } /** + * Get the expected output. + * * @return string */ public function getExpectedOutput() @@ -98,6 +110,8 @@ public function getExpectedOutput() } /** + * Get the actual output. + * * @return string */ public function getActualOutput() @@ -106,6 +120,8 @@ public function getActualOutput() } /** + * Get the array of expected headers. + * * @return array */ public function getExpectedHeaders() @@ -114,6 +130,8 @@ public function getExpectedHeaders() } /** + * Get the array of actual headers. + * * @return array */ public function getActualHeaders() diff --git a/src/Result/CgiOutResult.php b/src/Result/CgiOutResult.php index 1f74996d..0ae86e60 100644 --- a/src/Result/CgiOutResult.php +++ b/src/Result/CgiOutResult.php @@ -2,11 +2,12 @@ namespace PhpSchool\PhpWorkshop\Result; -use PhpSchool\PhpWorkshop\Check\CheckInterface; use PhpSchool\PhpWorkshop\ResultAggregator; /** - * Class CgiOutFailure + * A result which encompasses all the results for each individual request made during + * the CGI verification process. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ @@ -18,8 +19,8 @@ class CgiOutResult extends ResultAggregator implements ResultInterface private $name; /** - * @param string $name - * @param array $requestResults + * @param string $name The name of the check that produced this result. + * @param array $requestResults An array of results representing each request. */ public function __construct($name, array $requestResults) { @@ -31,6 +32,8 @@ public function __construct($name, array $requestResults) /** + * Get the name of the check that this result was produced from, most likely the CGI Runner. + * * @return string */ public function getCheckName() diff --git a/src/Result/Failure.php b/src/Result/Failure.php index 9b6b219d..c0f81c91 100644 --- a/src/Result/Failure.php +++ b/src/Result/Failure.php @@ -7,7 +7,8 @@ use PhpSchool\PhpWorkshop\Exception\CodeExecutionException; /** - * Class Failure + * Default implementation of `PhpSchool\PhpWorkshop\Result\FailureInterface`. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -24,8 +25,11 @@ class Failure implements FailureInterface private $name; /** - * @param string $name - * @param string|null $reason + * Create an instance from the name of the check that produces this result + * and the reason for the failure. + * + * @param string $name The name of the check that produced this result. + * @param string|null $reason The reason (if any) of the failure. */ public function __construct($name, $reason = null) { @@ -34,9 +38,11 @@ public function __construct($name, $reason = null) } /** - * @param string $name - * @param $reason - * @return static + * Named constructor, for added code legibility. + * + * @param string $name The name of the check that produced this result. + * @param string|null $reason The reason (if any) of the failure. + * @return static The result. */ public static function fromNameAndReason($name, $reason) { @@ -44,9 +50,11 @@ public static function fromNameAndReason($name, $reason) } /** - * @param CheckInterface $check - * @param string $reason - * @return static + * Static constructor to create from an instance of `PhpSchool\PhpWorkshop\Check\CheckInterface`. + * + * @param CheckInterface $check The check instance. + * @param string $reason The reason (if any) of the failure. + * @return static The result. */ public static function fromCheckAndReason(CheckInterface $check, $reason) { @@ -54,9 +62,11 @@ public static function fromCheckAndReason(CheckInterface $check, $reason) } /** - * @param string $name - * @param CodeExecutionException $e - * @return static + * Static constructor to create from a `PhpSchool\PhpWorkshop\Exception\CodeExecutionException` exception. + * + * @param string $name The name of the check that produced this result. + * @param CodeExecutionException $e The exception. + * @return static The result. */ public static function fromNameAndCodeExecutionFailure($name, CodeExecutionException $e) { @@ -64,10 +74,13 @@ public static function fromNameAndCodeExecutionFailure($name, CodeExecutionExcep } /** - * @param CheckInterface $check - * @param ParseErrorException $e - * @param string $file - * @return static + * Static constructor to create from a `PhpParser\Error` exception. Many checks will need to parse the student's + * solution, so this serves as a helper to create a consistent failure. + * + * @param CheckInterface $check The check that attempted to parse the solution. + * @param ParseErrorException $e The parse exception. + * @param string $file The absolute path to the solution. + * @return static The result. */ public static function fromCheckAndCodeParseFailure(CheckInterface $check, ParseErrorException $e, $file) { @@ -78,6 +91,8 @@ public static function fromCheckAndCodeParseFailure(CheckInterface $check, Parse } /** + * Get the name of the check that this result was produced from. + * * @return string */ public function getCheckName() @@ -86,6 +101,8 @@ public function getCheckName() } /** + * Get the reason, or `null` if there is no reason. + * * @return string|null */ public function getReason() diff --git a/src/Result/FailureInterface.php b/src/Result/FailureInterface.php index 8ba3efb7..9c0aefa2 100644 --- a/src/Result/FailureInterface.php +++ b/src/Result/FailureInterface.php @@ -3,7 +3,9 @@ namespace PhpSchool\PhpWorkshop\Result; /** - * Interface FailureInterface + * This interface represents a failure. Any result implementing this interface will + * be treated as a failure. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ diff --git a/src/Result/FunctionRequirementsFailure.php b/src/Result/FunctionRequirementsFailure.php index 8fb581cc..b5e47380 100644 --- a/src/Result/FunctionRequirementsFailure.php +++ b/src/Result/FunctionRequirementsFailure.php @@ -5,7 +5,9 @@ use PhpSchool\PhpWorkshop\Check\CheckInterface; /** - * Class FunctionRequirementsFailure + * A failure result representing the situation where there were function usage requirements + * and they were not met. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ @@ -24,9 +26,9 @@ class FunctionRequirementsFailure implements FailureInterface private $missingFunctions; /** - * @param CheckInterface $check - * @param array $bannedFunctions - * @param array $missingFunctions + * @param CheckInterface $check The check that produced this result. + * @param array $bannedFunctions A list of functions that were used, but were banned. + * @param array $missingFunctions A list of functions that were not used, but were required. */ public function __construct(CheckInterface $check, array $bannedFunctions, array $missingFunctions) { @@ -36,6 +38,8 @@ public function __construct(CheckInterface $check, array $bannedFunctions, array } /** + * Get the list of functions that were used, but were banned. + * * @return array */ public function getBannedFunctions() @@ -44,6 +48,8 @@ public function getBannedFunctions() } /** + * Get the list of functions that were not used, but were required. + * * @return array */ public function getMissingFunctions() diff --git a/src/Result/ResultInterface.php b/src/Result/ResultInterface.php index 7575feae..c8ac6acc 100644 --- a/src/Result/ResultInterface.php +++ b/src/Result/ResultInterface.php @@ -3,12 +3,17 @@ namespace PhpSchool\PhpWorkshop\Result; /** - * Interface ResultInterface + * The base result interface, on it's own does not mean much, instead the + * interfaces `PhpSchool\PhpWorkshop\Result\SuccessInterface` & `PhpSchool\PhpWorkshop\Result\FailureInterface` + * should be used. + * * @package PhpSchool\PhpWorkshop\Result */ interface ResultInterface { /** + * Get the name of the check that this result was produced from. + * * @return string */ public function getCheckName(); diff --git a/src/Result/ResultTrait.php b/src/Result/ResultTrait.php index e53e6a8d..2325544a 100644 --- a/src/Result/ResultTrait.php +++ b/src/Result/ResultTrait.php @@ -5,7 +5,9 @@ use PhpSchool\PhpWorkshop\Check\CheckInterface; /** - * Trait ResultTrait + * Helper to proxy the `getCheckName()` method through to the `PhpSchool\PhpWorkshop\Check\CheckInterface` + * instance. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ @@ -17,6 +19,9 @@ trait ResultTrait private $check; /** + * Get the check name from the underlying check. Assumes that the `check` property has been + * assigned an instance of `PhpSchool\PhpWorkshop\Check\CheckInterface`. + * * @return string */ public function getCheckName() diff --git a/src/Result/StdOutFailure.php b/src/Result/StdOutFailure.php index 30d84f3c..e54b1b01 100644 --- a/src/Result/StdOutFailure.php +++ b/src/Result/StdOutFailure.php @@ -5,7 +5,9 @@ use PhpSchool\PhpWorkshop\Check\CheckInterface; /** - * Class StdOutFailure + * A failure result representing the situation where the output of a solution does not match + * that of the expected output. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ @@ -27,9 +29,9 @@ class StdOutFailure implements FailureInterface private $actualOutput; /** - * @param string $name - * @param string $expectedOutput - * @param string $actualOutput + * @param string $name The name of the check that produced this result. + * @param string $expectedOutput The expected output. + * @param string $actualOutput The actual output. */ public function __construct($name, $expectedOutput, $actualOutput) { @@ -39,10 +41,12 @@ public function __construct($name, $expectedOutput, $actualOutput) } /** - * @param string $name - * @param $expectedOutput - * @param $actualOutput - * @return static + * Named constructor, for added code legibility. + * + * @param string $name The name of the check that produced this result. + * @param string $expectedOutput The expected output. + * @param string $actualOutput The actual output. + * @return static The result. */ public static function fromNameAndOutput($name, $expectedOutput, $actualOutput) { @@ -50,10 +54,12 @@ public static function fromNameAndOutput($name, $expectedOutput, $actualOutput) } /** - * @param CheckInterface $check - * @param $expectedOutput - * @param $actualOutput - * @return static + * Static constructor to create from an instance of `PhpSchool\PhpWorkshop\Check\CheckInterface`. + * + * @param CheckInterface $check The check instance. + * @param string $expectedOutput The expected output. + * @param string $actualOutput The actual output. + * @return static The result. */ public static function fromCheckAndOutput(CheckInterface $check, $expectedOutput, $actualOutput) { @@ -61,6 +67,8 @@ public static function fromCheckAndOutput(CheckInterface $check, $expectedOutput } /** + * Get the name of the check that this result was produced from. + * * @return string */ public function getCheckName() @@ -69,6 +77,8 @@ public function getCheckName() } /** + * Get the expected output. + * * @return string */ public function getExpectedOutput() @@ -77,6 +87,8 @@ public function getExpectedOutput() } /** + * Get the actual output. + * * @return string */ public function getActualOutput() diff --git a/src/Result/Success.php b/src/Result/Success.php index d1030e7c..a598c210 100644 --- a/src/Result/Success.php +++ b/src/Result/Success.php @@ -5,16 +5,20 @@ use PhpSchool\PhpWorkshop\Check\CheckInterface; /** - * Class Fail + * Default implementation of `PhpSchool\PhpWorkshop\Result\SuccessInterface`. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ class Success implements SuccessInterface { + /** + * @var string + */ private $name; /** - * @param string $name + * @param string $name The name of the check that produced this result. */ public function __construct($name) { @@ -22,8 +26,10 @@ public function __construct($name) } /** - * @param CheckInterface $check - * @return static + * Static constructor to create from an instance of `PhpSchool\PhpWorkshop\Check\CheckInterface`. + * + * @param CheckInterface $check The check instance. + * @return static The result. */ public static function fromCheck(CheckInterface $check) { @@ -31,6 +37,8 @@ public static function fromCheck(CheckInterface $check) } /** + * Get the name of the check that this result was produced from. + * * @return string */ public function getCheckName() diff --git a/src/Result/SuccessInterface.php b/src/Result/SuccessInterface.php index 260c81d0..ff1a1d2a 100644 --- a/src/Result/SuccessInterface.php +++ b/src/Result/SuccessInterface.php @@ -3,7 +3,9 @@ namespace PhpSchool\PhpWorkshop\Result; /** - * Interface SuccessInterface + * This interface represents a success. Any result implementing this interface will + * be treated as a success. + * * @package PhpSchool\PhpWorkshop\Result * @author Aydin Hassan */ diff --git a/src/ResultAggregator.php b/src/ResultAggregator.php index 8e442929..a85fa568 100644 --- a/src/ResultAggregator.php +++ b/src/ResultAggregator.php @@ -9,7 +9,9 @@ use PhpSchool\PhpWorkshop\Result\ResultInterface; /** - * Class ResultAggregator + * This class is a container to hold all the results produced + * throughout the verification of a students solution. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -21,6 +23,8 @@ class ResultAggregator implements IteratorAggregate private $results = []; /** + * Add a new result. + * * @param ResultInterface $result */ public function add(ResultInterface $result) @@ -29,6 +33,9 @@ public function add(ResultInterface $result) } /** + * Computes whether the results are considered a success. If there are any results which implement + * `FailureInterface` then the combined result is considered as a fail. + * * @return bool */ public function isSuccessful() @@ -44,6 +51,8 @@ public function isSuccessful() } /** + * Get an iterator in order to `foreach` the results. + * * @return ArrayIterator */ public function getIterator() diff --git a/src/ResultRenderer/CgiOutResultRenderer.php b/src/ResultRenderer/CgiOutResultRenderer.php index 53c9e0de..178a3793 100644 --- a/src/ResultRenderer/CgiOutResultRenderer.php +++ b/src/ResultRenderer/CgiOutResultRenderer.php @@ -6,10 +6,10 @@ use PhpSchool\PhpWorkshop\Result\CgiOutResult; use PhpSchool\PhpWorkshop\Result\FailureInterface; use PhpSchool\PhpWorkshop\Result\ResultInterface; -use PhpSchool\PhpWorkshop\Result\SuccessInterface; /** - * Class CgiOutResultRenderer + * Renderer for `PhpSchool\PhpWorkshop\Result\CgiOutResult`. + * * @package PhpSchool\PhpWorkshop\ResultRenderer */ class CgiOutResultRenderer implements ResultRendererInterface @@ -21,7 +21,7 @@ class CgiOutResultRenderer implements ResultRendererInterface private $result; /** - * @param CgiOutResult $result + * @param CgiOutResult $result The result. */ public function __construct(CgiOutResult $result) { @@ -29,6 +29,8 @@ public function __construct(CgiOutResult $result) } /** + * Render the details of each failed request including the mismatching headers and body. + * * @param ResultsRenderer $renderer * @return string */ diff --git a/src/ResultRenderer/FailureRenderer.php b/src/ResultRenderer/FailureRenderer.php index 5c4cdac2..716e5a11 100644 --- a/src/ResultRenderer/FailureRenderer.php +++ b/src/ResultRenderer/FailureRenderer.php @@ -6,7 +6,8 @@ use PhpSchool\PhpWorkshop\Result\ResultInterface; /** - * Class FailureRenderer + * Renderer for `PhpSchool\PhpWorkshop\Result\Failure`. + * * @package PhpSchool\PhpWorkshop\ResultRenderer */ class FailureRenderer implements ResultRendererInterface @@ -17,7 +18,7 @@ class FailureRenderer implements ResultRendererInterface private $result; /** - * @param Failure $result + * @param Failure $result The failure. */ public function __construct(Failure $result) { @@ -25,6 +26,8 @@ public function __construct(Failure $result) } /** + * Simply print the reason. + * * @param ResultsRenderer $renderer * @return string */ diff --git a/src/ResultRenderer/FunctionRequirementsFailureRenderer.php b/src/ResultRenderer/FunctionRequirementsFailureRenderer.php index b141fdd4..24a8a3ee 100644 --- a/src/ResultRenderer/FunctionRequirementsFailureRenderer.php +++ b/src/ResultRenderer/FunctionRequirementsFailureRenderer.php @@ -5,7 +5,8 @@ use PhpSchool\PhpWorkshop\Result\FunctionRequirementsFailure; /** - * Class FunctionRequirementsFailureRenderer + * Renderer for `PhpSchool\PhpWorkshop\Result\FunctionRequirementsFailure`. + * * @package PhpSchool\PhpWorkshop\ResultRenderer * @author Aydin Hassan */ @@ -17,7 +18,7 @@ class FunctionRequirementsFailureRenderer implements ResultRendererInterface private $result; /** - * @param FunctionRequirementsFailure $result + * @param FunctionRequirementsFailure $result The failure. */ public function __construct(FunctionRequirementsFailure $result) { @@ -25,6 +26,8 @@ public function __construct(FunctionRequirementsFailure $result) } /** + * Print a list of the missing, required functions & print a list of used but banned functions. + * * @param ResultsRenderer $renderer * @return string */ diff --git a/src/ResultRenderer/OutputFailureRenderer.php b/src/ResultRenderer/OutputFailureRenderer.php index db2c08a3..d0b295fb 100644 --- a/src/ResultRenderer/OutputFailureRenderer.php +++ b/src/ResultRenderer/OutputFailureRenderer.php @@ -6,7 +6,8 @@ use PhpSchool\PhpWorkshop\Result\StdOutFailure; /** - * Class OutputFailureRenderer + * Renderer for `PhpSchool\PhpWorkshop\Result\StdOutFailure`. + * * @package PhpSchool\PhpWorkshop\ResultRenderer */ class OutputFailureRenderer implements ResultRendererInterface @@ -18,7 +19,7 @@ class OutputFailureRenderer implements ResultRendererInterface private $result; /** - * @param StdOutFailure $result + * @param StdOutFailure $result The failure. */ public function __construct(StdOutFailure $result) { @@ -26,6 +27,8 @@ public function __construct(StdOutFailure $result) } /** + * Print the actual and expected output. + * * @param ResultsRenderer $renderer * @return string */ diff --git a/src/ResultRenderer/ResultRendererInterface.php b/src/ResultRenderer/ResultRendererInterface.php index 68bfb841..2ac4b5c7 100644 --- a/src/ResultRenderer/ResultRendererInterface.php +++ b/src/ResultRenderer/ResultRendererInterface.php @@ -2,18 +2,25 @@ namespace PhpSchool\PhpWorkshop\ResultRenderer; -use PhpSchool\PhpWorkshop\Result\ResultInterface; - /** - * Interface ResultRendererInterface + * The interface, result renderers should adhere to. + * * @package PhpSchool\PhpWorkshop\ResultRenderer + * @author Aydin Hassan */ interface ResultRendererInterface { /** - * @param ResultsRenderer $renderer - * @return string + * This method should return a string representation of the result, + * formatted for output on the command line. + * + * The `PhpSchool\PhpWorkshop\ResultRenderer\ResultsRenderer` method has + * various helpers to render line breaks, colour output and can also render child + * results. + * + * @param ResultsRenderer $renderer The main renderer instance. + * @return string The string representation of the result. */ public function render(ResultsRenderer $renderer); } diff --git a/src/ResultRenderer/ResultsRenderer.php b/src/ResultRenderer/ResultsRenderer.php index 14eac63a..f2d6cdf1 100644 --- a/src/ResultRenderer/ResultsRenderer.php +++ b/src/ResultRenderer/ResultsRenderer.php @@ -15,7 +15,8 @@ use PhpSchool\PhpWorkshop\UserState; /** - * Class ResultsRenderer + * Renderer which renders a `PhpSchool\PhpWorkshop\ResultAggregator` and writes it the output. + * * @package PhpSchool\PhpWorkshop\ResultRenderer */ class ResultsRenderer @@ -51,11 +52,11 @@ class ResultsRenderer private $resultRendererFactory; /** - * @param $appName - * @param Color $color - * @param TerminalInterface $terminal - * @param ExerciseRepository $exerciseRepository - * @param SyntaxHighlighter $syntaxHighlighter + * @param string $appName The name of the binary to run this workshop. + * @param Color $color A instance of `Color` used to colour strings with ANSI escape codes. + * @param TerminalInterface $terminal A helper to get information regarding the current terminal. + * @param ExerciseRepository $exerciseRepository The exercise repository. + * @param SyntaxHighlighter $syntaxHighlighter A PHP syntax highlighter for the terminal, uses ANSI escape codes. */ public function __construct( $appName, @@ -74,10 +75,13 @@ public function __construct( } /** - * @param ResultAggregator $results - * @param ExerciseInterface $exercise - * @param UserState $userState - * @param OutputInterface $output + * Render the result set to the output and statistics on the number of exercises completed and + * remaining. + * + * @param ResultAggregator $results The result set. + * @param ExerciseInterface $exercise The exercise instance that was just attempted. + * @param UserState $userState The current state of the student's progress. + * @param OutputInterface $output The output instance. */ public function render( ResultAggregator $results, @@ -201,8 +205,11 @@ private function styleArray(array $lines, array $styles) } /** + * Style/colour a string. + * Can be any of: black, red, green, yellow, blue, magenta, cyan, white, bold, italic, underline. + * * @param string $string - * @param array|string $colourOrStyle + * @param array|string $colourOrStyle A single style as a string or multiple styles as an array. * * @return string * @@ -222,8 +229,10 @@ public function style($string, $colourOrStyle) } /** - * @param ResultInterface $result - * @return string + * Render a result. Attempt to find the correct renderer via the result renderer factory. + * + * @param ResultInterface $result The result. + * @return string The string representation of the result. */ public function renderResult(ResultInterface $result) { @@ -231,6 +240,8 @@ public function renderResult(ResultInterface $result) } /** + * Draw a line break across the terminal. + * * @return string */ public function lineBreak() diff --git a/src/Solution/DirectorySolution.php b/src/Solution/DirectorySolution.php index 818c704d..9fa185b2 100644 --- a/src/Solution/DirectorySolution.php +++ b/src/Solution/DirectorySolution.php @@ -8,7 +8,8 @@ use RecursiveIteratorIterator; /** - * Class DirectorySolution + * Solution which can contain multiple files, the file to execute is defined as the entry point. + * * @author Aydin Hassan * @author Michael Woodward */ @@ -31,10 +32,14 @@ class DirectorySolution implements SolutionInterface private $baseDirectory; /** - * @param string $directory - * @param string $entryPoint - * @param array $exclusions - * @throws InvalidArgumentException + * Build an instance from a given directory. Requires a file name to be used as the entry point, + * and optionally can take an array of files to exclude from the solution. For example you may want to + * ignore some dot files or `composer.lock`. + * + * @param string $directory The directory to search for files. + * @param string $entryPoint The relative path from the directory of the entry point file. + * @param array $exclusions An array of file names to exclude from the folder. + * @throws InvalidArgumentException If the entry point does not exist in the folder. */ public function __construct($directory, $entryPoint, array $exclusions = []) { @@ -72,17 +77,22 @@ public function __construct($directory, $entryPoint, array $exclusions = []) } /** - * @param string $directory - * @param array $exclusions - * @param string $entryPoint + * Static constructor to build an instance from a directory. + * + * @param string $directory The directory to search for files. + * @param array $exclusions An array of file names to exclude from the folder. + * @param string $entryPoint The relative path from the directory of the entry point file. * @return static */ public static function fromDirectory($directory, array $exclusions = [], $entryPoint = 'solution.php') { return new static($directory, $entryPoint, array_merge($exclusions, ['composer.lock', 'vendor'])); } - + /** + * Get the entry point. This is the PHP file that PHO would execute in order to run the + * program. This should be the absolute path. + * * @return string */ public function getEntryPoint() @@ -91,7 +101,9 @@ public function getEntryPoint() } /** - * @return string[] + * Get all the files which are contained with the solution. + * + * @return SolutionFile[] */ public function getFiles() { @@ -99,6 +111,8 @@ public function getFiles() } /** + * Get the absolute path to the directory containing the solution. + * * @return string */ public function getBaseDirectory() @@ -107,6 +121,8 @@ public function getBaseDirectory() } /** + * Check whether there is a `composer.lock` file in the base directory. + * * @return bool */ public function hasComposerFile() diff --git a/src/Solution/SingleFileSolution.php b/src/Solution/SingleFileSolution.php index f44da739..eb074cc9 100644 --- a/src/Solution/SingleFileSolution.php +++ b/src/Solution/SingleFileSolution.php @@ -5,7 +5,8 @@ use InvalidArgumentException; /** - * Class SingleFileSolution + * Solution to use when the solution only consists of one file. + * * @author Aydin Hassan */ class SingleFileSolution implements SolutionInterface @@ -17,8 +18,8 @@ class SingleFileSolution implements SolutionInterface private $file; /** - * @param string $file - * @throws InvalidArgumentException + * @param string $file The absolute path of the reference solution. + * @throws InvalidArgumentException If the file does not exist. */ public function __construct($file) { @@ -26,15 +27,21 @@ public function __construct($file) } /** - * @param string $file + * Static constructor to build an instance from an absolute file path. + * + * @param string $file The absolute path of the reference solution. * @return static + * @throws InvalidArgumentException If the file does not exist. */ public static function fromFile($file) { return new static($file); } - + /** + * Get the entry point. This is the PHP file that php would execute in order to run the + * program. This should be the absolute path. + * * @return string */ public function getEntryPoint() @@ -43,7 +50,9 @@ public function getEntryPoint() } /** - * @return string[] + * Get all the files which are contained with the solution. + * + * @return SolutionFile[] */ public function getFiles() { @@ -51,6 +60,8 @@ public function getFiles() } /** + * Get the absolute path to the directory containing the solution. + * * @return string */ public function getBaseDirectory() @@ -59,6 +70,9 @@ public function getBaseDirectory() } /** + * Single file solutions can never have composer files as there must be at least + * one `php` file. + * * @return bool */ public function hasComposerFile() diff --git a/src/Solution/SolutionFile.php b/src/Solution/SolutionFile.php index bc995f22..b8afe4c9 100644 --- a/src/Solution/SolutionFile.php +++ b/src/Solution/SolutionFile.php @@ -5,7 +5,8 @@ use InvalidArgumentException; /** - * Class SolutionFile + * This class represents a file on the file system which is part of the reference solution. + * * @package PhpSchool\PhpWorkshop\Solution * @author Aydin Hassan */ @@ -22,9 +23,9 @@ class SolutionFile private $baseDirectory; /** - * @param string $relativePath - * @param string $baseDirectory - * @throws InvalidArgumentException + * @param string $relativePath The relative path from the base directory. + * @param string $baseDirectory The base directory of the solution. + * @throws InvalidArgumentException If the file does not exist. */ public function __construct($relativePath, $baseDirectory) { @@ -37,6 +38,9 @@ public function __construct($relativePath, $baseDirectory) } /** + * Static constructor to create an instance from a file path. + * Will assume the base directory should be the immediate parent of the file. + * * @param string $file * @return static */ @@ -46,6 +50,8 @@ public static function fromFile($file) } /** + * Get the absolute path of the file. + * * @return string */ private function getAbsolutePath() @@ -54,6 +60,8 @@ private function getAbsolutePath() } /** + * Get the relative path of the file from the base directory. + * * @return string */ public function getRelativePath() @@ -62,6 +70,8 @@ public function getRelativePath() } /** + * Get the base directory of the file. + * * @return string */ public function getBaseDirectory() @@ -70,6 +80,8 @@ public function getBaseDirectory() } /** + * Get the contents of the file. + * * @return string */ public function getContents() @@ -78,6 +90,8 @@ public function getContents() } /** + * Proxy to the absolute path. + * * @return string */ public function __toString() diff --git a/src/Solution/SolutionInterface.php b/src/Solution/SolutionInterface.php index c8b7b7d8..a1528f15 100644 --- a/src/Solution/SolutionInterface.php +++ b/src/Solution/SolutionInterface.php @@ -3,27 +3,37 @@ namespace PhpSchool\PhpWorkshop\Solution; /** - * Interface SolutionInterface + * Interface for reference solution representations. + * * @author Aydin Hassan */ interface SolutionInterface { /** + * Get the entry point. This is the PHP file that php would execute in order to run the + * program. This should be the absolute path. + * * @return string */ public function getEntryPoint(); /** + * Get all the files which are contained with the solution. + * * @return SolutionFile[] */ public function getFiles(); /** + * Get the absolute path to the directory containing the solution. + * * @return string */ public function getBaseDirectory(); /** + * Whether or not the solution has a `composer.json` & `composer.lock` file. + * * @return bool */ public function hasComposerFile(); diff --git a/src/UserState.php b/src/UserState.php index 66c533aa..39055b5b 100644 --- a/src/UserState.php +++ b/src/UserState.php @@ -3,7 +3,9 @@ namespace PhpSchool\PhpWorkshop; /** - * Class UserState + * This class represents the current state of the user. Which exercises she/he has completed and + * which is the current exercise being attempted. + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -21,8 +23,11 @@ class UserState private $completedExercises; /** - * @param string $currentExercise - * @param array $completedExercises + * Take an array of completed exercises (the exercise names) and a string containing the current + * exercise. + * + * @param array $completedExercises An array of exercise names. + * @param string $currentExercise Can be null in-case the student did not start an exercise yet. */ public function __construct(array $completedExercises = [], $currentExercise = null) { @@ -31,6 +36,8 @@ public function __construct(array $completedExercises = [], $currentExercise = n } /** + * Mark an exercise as completed. Should be the exercise name. + * * @param string $exercise */ public function addCompletedExercise($exercise) @@ -41,6 +48,8 @@ public function addCompletedExercise($exercise) } /** + * Set the current exercise. Should be the exercise name. + * * @param string $exercise */ public function setCurrentExercise($exercise) @@ -49,6 +58,8 @@ public function setCurrentExercise($exercise) } /** + * Get the current exercise name. + * * @return string */ public function getCurrentExercise() @@ -57,6 +68,8 @@ public function getCurrentExercise() } /** + * Get an array of the completed exercises (the exercise names). + * * @return array */ public function getCompletedExercises() @@ -65,6 +78,8 @@ public function getCompletedExercises() } /** + * Check whether the student is actually assigned an exercise. + * * @return bool */ public function isAssignedExercise() @@ -73,6 +88,8 @@ public function isAssignedExercise() } /** + * Check whether the student has completed an exercise by the exercise name. + * * @param string $exercise * @return bool */ diff --git a/src/UserStateSerializer.php b/src/UserStateSerializer.php index 00ced83a..ea24a222 100644 --- a/src/UserStateSerializer.php +++ b/src/UserStateSerializer.php @@ -3,7 +3,8 @@ namespace PhpSchool\PhpWorkshop; /** - * Class UserStateSerializer + * Reads and persists the `UserState` instance to storage (file based). + * * @package PhpSchool\PhpWorkshop * @author Aydin Hassan */ @@ -35,9 +36,9 @@ class UserStateSerializer private $exerciseRepository; /** - * @param string $saveFileDirectory - * @param string $workshopName - * @param ExerciseRepository $exerciseRepository + * @param string $saveFileDirectory The path of the directory where the save file should be stored. + * @param string $workshopName The name of the current workshop. + * @param ExerciseRepository $exerciseRepository The repository of exercises. */ public function __construct($saveFileDirectory, $workshopName, ExerciseRepository $exerciseRepository) { @@ -51,8 +52,9 @@ public function __construct($saveFileDirectory, $workshopName, ExerciseRepositor } /** - * @param UserState $state + * Save the students state for this workshop to disk. * + * @param UserState $state * @return int */ public function serialize(UserState $state) @@ -72,6 +74,8 @@ public function serialize(UserState $state) } /** + * Read a students state for this workshop from the disk. + * * @return UserState */ public function deSerialize() @@ -130,7 +134,7 @@ public function deSerialize() * at the same time. Therefore we must try to migrate that data in to the new namespaced * format in order to preserve users save data. * - * We can only migrate data when using the workshop the data was originally saved from + * We can only migrate data when using the workshop the data was originally saved from. * * @param string $legacySaveFile * @return null|UserState diff --git a/src/Utils/ArrayObject.php b/src/Utils/ArrayObject.php index 6a4d0fdc..d62ef31e 100644 --- a/src/Utils/ArrayObject.php +++ b/src/Utils/ArrayObject.php @@ -7,7 +7,8 @@ use IteratorAggregate; /** - * Class ArrayObject + * Utility collection class. + * * @package PhpSchool\PhpWorkshop\Utils * @author Aydin Hassan */ @@ -20,18 +21,19 @@ class ArrayObject implements IteratorAggregate, Countable private $array; /** - * @param array|mixed... $array + * Accepts an array of items. + * + * @param array $array */ - public function __construct($array) + public function __construct(array $array) { - if (func_num_args() > 1) { - $this->array = func_get_args(); - } else { - $this->array = $array; - } + $this->array = $array; } /** + * Run a callable function over each item in the array using the result + * to construct a new instance of `ArrayObject`. + * * @param callable $callback * @return static */ @@ -41,6 +43,8 @@ public function map(callable $callback) } /** + * Implode each item together using the provided glue. + * * @param string $glue * @return string */ @@ -50,6 +54,8 @@ public function implode($glue) } /** + * Add a new item on to the beginning of the collection. A new instance is returned. + * * @param mixed $value * @return static */ @@ -59,6 +65,8 @@ public function prepend($value) } /** + * Add a new item to the end of the collection. A new instance is returned. + * * @param mixed $value * @return static */ @@ -68,6 +76,8 @@ public function append($value) } /** + * Return an iterator containing all the items. Allows to `foreach` over. + * * @return ArrayIterator */ public function getIterator() @@ -76,6 +86,8 @@ public function getIterator() } /** + * Get all the items in the array. + * * @return array */ public function getArrayCopy() @@ -84,6 +96,8 @@ public function getArrayCopy() } /** + * Get the number of items in the collection. + * * @return int */ public function count() diff --git a/test/Exception/InvalidArgumentExceptionTest.php b/test/Exception/InvalidArgumentExceptionTest.php index 8736ffa9..caaec5cf 100644 --- a/test/Exception/InvalidArgumentExceptionTest.php +++ b/test/Exception/InvalidArgumentExceptionTest.php @@ -37,7 +37,10 @@ public function testExceptionFromNotValidParameterConstructor() */ public function testStringify($value, $expected) { - $this->assertEquals(InvalidArgumentException::stringify($value), $expected); + $rM = new \ReflectionMethod(InvalidArgumentException::class, 'stringify'); + $rM->setAccessible(true); + + $this->assertEquals($rM->invoke(null, $value), $expected); } /** diff --git a/test/Util/ArrayObjectTest.php b/test/Util/ArrayObjectTest.php index 244da700..8076485e 100644 --- a/test/Util/ArrayObjectTest.php +++ b/test/Util/ArrayObjectTest.php @@ -58,10 +58,4 @@ public function testGetArrayCopy() $arrayObject = new ArrayObject([1, 2, 3]); $this->assertSame([1, 2, 3], $arrayObject->getArrayCopy()); } - - public function testGetArrayCopyWithVariadicConstruction() - { - $arrayObject = new ArrayObject(1, 2, 3); - $this->assertSame([1, 2, 3], $arrayObject->getArrayCopy()); - } }