From dcce570a9b57aaec02570afc6e34f47a927835b5 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Sat, 11 May 2024 10:34:52 +0200 Subject: [PATCH] Update PHP8 appreciate for new workshop version --- .docker/runtime/Dockerfile | 14 ++ .docker/runtime/docker-compose.yml | 14 ++ composer.json | 2 +- composer.lock | 137 +++++++++--------- src/Exercise/AMatchMadeInHeaven.php | 22 ++- src/Exercise/ASafeSpaceForNulls.php | 17 ++- src/Exercise/AllMixedUp.php | 24 +-- src/Exercise/CautionWithCatches.php | 22 ++- src/Exercise/HaveTheLastSay.php | 36 ++--- src/Exercise/InfiniteDivisions.php | 26 ++-- src/Exercise/LordOfTheStrings.php | 26 ++-- src/Exercise/PhpGetsAPromotion.php | 12 +- src/Exercise/StringifyToDemystify.php | 25 ++-- src/Exercise/TheAttributesOfSuccess.php | 50 ++++--- src/Exercise/TheReturnOfStatic.php | 16 +- src/Exercise/ThrowAnExpression.php | 22 +-- src/Exercise/UniteTheTypes.php | 14 +- test/Exercise/LordOfTheStringsTest.php | 2 +- .../lord-of-the-strings/solution-no-code.php | 1 - .../solution-no-composer.php | 3 + 20 files changed, 283 insertions(+), 202 deletions(-) create mode 100644 .docker/runtime/Dockerfile create mode 100644 .docker/runtime/docker-compose.yml delete mode 100644 test/solutions/lord-of-the-strings/solution-no-code.php create mode 100644 test/solutions/lord-of-the-strings/solution-no-composer.php diff --git a/.docker/runtime/Dockerfile b/.docker/runtime/Dockerfile new file mode 100644 index 0000000..dc8e93f --- /dev/null +++ b/.docker/runtime/Dockerfile @@ -0,0 +1,14 @@ +FROM php:8.3-alpine as build + +RUN apk add --no-cache $PHPIZE_DEPS && \ + apk add --no-cache linux-headers + +RUN docker-php-ext-install sockets + +FROM php:8.3-alpine as final + +COPY --from=build /usr/local/lib/php /usr/local/lib/php +COPY --from=build /usr/local/etc/php /usr/local/etc/php + +RUN apk add git +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer \ No newline at end of file diff --git a/.docker/runtime/docker-compose.yml b/.docker/runtime/docker-compose.yml new file mode 100644 index 0000000..8ea2906 --- /dev/null +++ b/.docker/runtime/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.8' + +services: + runtime: + image: php8appreciate-runtime + build: + context: . + dockerfile: Dockerfile + + volumes: + - type: bind + source: ${SOLUTION} + target: '/solution' + diff --git a/composer.json b/composer.json index 7c702d9..3b2d862 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ ], "require": { "php": "^8.0", - "php-school/php-workshop": "dev-master" + "php-school/php-workshop": "dev-05-09-remove_temporary_solution_mapper" }, "require-dev": { "phpunit/phpunit": "^9", diff --git a/composer.lock b/composer.lock index 5f88a06..551b9a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "861a3809372ea7552bbd417ed292aff9", + "content-hash": "7bd3b34dc505a0982f14fe5cf1e61f63", "packages": [ { "name": "beberlei/assert", @@ -734,21 +734,21 @@ }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v4.19.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", @@ -784,9 +784,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" }, - "time": "2023-12-10T21:03:43+00:00" + "time": "2024-03-17T08:10:35+00:00" }, { "name": "php-di/invoker", @@ -1126,16 +1126,16 @@ }, { "name": "php-school/php-workshop", - "version": "dev-master", + "version": "dev-05-09-remove_temporary_solution_mapper", "source": { "type": "git", "url": "https://github.com/php-school/php-workshop.git", - "reference": "11911b2157e80480a8cc272b56f417f5ba4903bf" + "reference": "f9f53dc3e7d27dfc6fa5f48e556ce2bf4130f504" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-school/php-workshop/zipball/11911b2157e80480a8cc272b56f417f5ba4903bf", - "reference": "11911b2157e80480a8cc272b56f417f5ba4903bf", + "url": "https://api.github.com/repos/php-school/php-workshop/zipball/f9f53dc3e7d27dfc6fa5f48e556ce2bf4130f504", + "reference": "f9f53dc3e7d27dfc6fa5f48e556ce2bf4130f504", "shasum": "" }, "require": { @@ -1165,7 +1165,6 @@ "squizlabs/php_codesniffer": "^3.7", "yoast/phpunit-polyfills": "^0.2.0" }, - "default-branch": true, "type": "library", "autoload": { "files": [ @@ -1204,9 +1203,9 @@ ], "support": { "issues": "https://github.com/php-school/php-workshop/issues", - "source": "https://github.com/php-school/php-workshop/tree/master" + "source": "https://github.com/php-school/php-workshop/tree/05-09-remove_temporary_solution_mapper" }, - "time": "2024-03-10T13:04:10+00:00" + "time": "2024-05-11T08:25:54+00:00" }, { "name": "php-school/terminal", @@ -1367,20 +1366,20 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -1404,7 +1403,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -1416,9 +1415,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -1569,16 +1568,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -1587,7 +1586,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1616,7 +1615,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -1632,26 +1631,27 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/filesystem", - "version": "v6.4.3", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "78dde75f8f6dbbca4ec436a4b0087f7af02076d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/78dde75f8f6dbbca4ec436a4b0087f7af02076d4", + "reference": "78dde75f8f6dbbca4ec436a4b0087f7af02076d4", "shasum": "" }, "require": { "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "symfony/polyfill-mbstring": "~1.8", + "symfony/process": "^5.4|^6.4" }, "type": "library", "autoload": { @@ -1679,7 +1679,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + "source": "https://github.com/symfony/filesystem/tree/v6.4.7" }, "funding": [ { @@ -1695,7 +1695,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-04-18T09:22:46+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1858,16 +1858,16 @@ }, { "name": "symfony/process", - "version": "v6.4.4", + "version": "v6.4.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "710e27879e9be3395de2b98da3f52a946039f297" + "reference": "cdb1c81c145fd5aa9b0038bab694035020943381" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", - "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "url": "https://api.github.com/repos/symfony/process/zipball/cdb1c81c145fd5aa9b0038bab694035020943381", + "reference": "cdb1c81c145fd5aa9b0038bab694035020943381", "shasum": "" }, "require": { @@ -1899,7 +1899,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.4" + "source": "https://github.com/symfony/process/tree/v6.4.7" }, "funding": [ { @@ -1915,7 +1915,7 @@ "type": "tidelift" } ], - "time": "2024-02-20T12:31:00+00:00" + "time": "2024-04-18T09:22:46+00:00" } ], "packages-dev": [ @@ -2168,16 +2168,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.60", + "version": "1.10.67", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe" + "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/16ddbe776f10da6a95ebd25de7c1dbed397dc493", + "reference": "16ddbe776f10da6a95ebd25de7c1dbed397dc493", "shasum": "" }, "require": { @@ -2220,13 +2220,9 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2024-03-07T13:30:19+00:00" + "time": "2024-04-16T07:22:02+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2549,16 +2545,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.17", + "version": "9.6.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd" + "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", + "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", "shasum": "" }, "require": { @@ -2632,7 +2628,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.17" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" }, "funding": [ { @@ -2648,7 +2644,7 @@ "type": "tidelift" } ], - "time": "2024-02-23T13:14:51+00:00" + "time": "2024-04-05T04:35:58+00:00" }, { "name": "sebastian/cli-parser", @@ -3452,16 +3448,16 @@ }, { "name": "sebastian/resource-operations", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", "shasum": "" }, "require": { @@ -3473,7 +3469,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -3494,8 +3490,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" }, "funding": [ { @@ -3503,7 +3498,7 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-03-14T16:00:52+00:00" }, { "name": "sebastian/type", @@ -3616,16 +3611,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.9.0", + "version": "3.9.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480", + "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480", "shasum": "" }, "require": { @@ -3692,7 +3687,7 @@ "type": "open_collective" } ], - "time": "2024-02-16T15:06:51+00:00" + "time": "2024-04-23T20:25:34+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/Exercise/AMatchMadeInHeaven.php b/src/Exercise/AMatchMadeInHeaven.php index e8fc17c..b6f7473 100644 --- a/src/Exercise/AMatchMadeInHeaven.php +++ b/src/Exercise/AMatchMadeInHeaven.php @@ -9,14 +9,14 @@ use PhpParser\NodeVisitorAbstract; use PhpParser\Parser; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; -use PhpSchool\PhpWorkshop\Exercise\BaseExerciseTrait; use PhpSchool\PhpWorkshop\Exercise\CliExercise; -use PhpSchool\PhpWorkshop\Exercise\DefaultExercise; -use PhpSchool\PhpWorkshop\Exercise\ExerciseAssets; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -24,6 +24,8 @@ use PhpSchool\PhpWorkshop\Solution\SingleFileSolution; use PhpSchool\PhpWorkshop\Solution\SolutionInterface; +use function PhpSchool\PhpWorkshop\collect; + class AMatchMadeInHeaven extends AbstractExercise implements ExerciseInterface, CliExercise, @@ -44,8 +46,10 @@ public function getDescription(): string return 'PHP 8\'s Match Expression'; } - public function getArgs(): array + public function defineTestScenario(): CliScenario { + $environment = new CliScenario(); + $runs = [ ['enter'], ['esc'], @@ -55,7 +59,11 @@ public function getArgs(): array shuffle($runs); - return $runs; + foreach ($runs as $run) { + $environment->withExecution($run); + } + + return $environment; } public function getInitialCode(): SolutionInterface @@ -65,9 +73,9 @@ public function getInitialCode(): SolutionInterface ); } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); if (null === $statements || empty($statements)) { return Failure::fromNameAndReason($this->getName(), 'No code was found'); diff --git a/src/Exercise/ASafeSpaceForNulls.php b/src/Exercise/ASafeSpaceForNulls.php index e2b1434..d8887a8 100644 --- a/src/Exercise/ASafeSpaceForNulls.php +++ b/src/Exercise/ASafeSpaceForNulls.php @@ -17,15 +17,17 @@ use PhpParser\NodeFinder; use PhpParser\Parser; use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\FileComparisonExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; -use PhpSchool\PhpWorkshop\Input\Input; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -59,14 +61,15 @@ public function getType(): ExerciseType return new ExerciseType(ExerciseType::CLI); } - public function getArgs(): array + public function getRequiredChecks(): array { - return []; + return [FileComparisonCheck::class]; } - public function configure(ExerciseDispatcher $dispatcher): void + public function defineTestScenario(): CliScenario { - $dispatcher->requireCheck(FileComparisonCheck::class); + return (new CliScenario()) + ->withExecution(); } public function getPatch(): Patch @@ -171,10 +174,10 @@ public function getPatch(): Patch }); } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); $ageFetch = $this->findNullSafePropFetch($statements, 'user', 'age'); $addressFetch = $this->findAllNullSafePropertyFetch($statements, 'user', 'address'); diff --git a/src/Exercise/AllMixedUp.php b/src/Exercise/AllMixedUp.php index c4cd217..d1bcfe8 100644 --- a/src/Exercise/AllMixedUp.php +++ b/src/Exercise/AllMixedUp.php @@ -14,15 +14,20 @@ use PhpParser\Parser; use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\FileComparisonExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\RunnerContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; @@ -58,15 +63,9 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array { - $dispatcher->requireCheck(FunctionRequirementsCheck::class); - $dispatcher->requireCheck(FileComparisonCheck::class); - } - - public function getArgs(): array - { - return []; + return [FunctionRequirementsCheck::class, FileComparisonCheck::class]; } public function getPatch(): Patch @@ -134,10 +133,10 @@ public function getBannedFunctions(): array return []; } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var Function_|null $logger */ $logger = (new NodeFinder())->findFirst($statements, function (\PhpParser\Node $node) { @@ -170,4 +169,9 @@ public function check(Input $input): ResultInterface return new Success($this->getName()); } + + public function defineTestScenario(): CliScenario + { + return (new CliScenario())->withExecution(); + } } diff --git a/src/Exercise/CautionWithCatches.php b/src/Exercise/CautionWithCatches.php index 81efd45..ed1f8f0 100644 --- a/src/Exercise/CautionWithCatches.php +++ b/src/Exercise/CautionWithCatches.php @@ -10,12 +10,17 @@ use PhpParser\NodeFinder; use PhpParser\Parser; use PhpSchool\PhpWorkshop\CodeInsertion; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; @@ -49,16 +54,10 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function getArgs(): array - { - $this->password = $this->faker->password(); - return [[$this->password]]; - } - - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var TryCatch|null $tryCatch */ $tryCatch = (new NodeFinder())->findFirstInstanceOf($statements, TryCatch::class); @@ -87,4 +86,11 @@ function verify_password(string \$password) { return (new Patch())->withInsertion($passwordVerifyInsertion); } + + public function defineTestScenario(): CliScenario + { + $this->password = $this->faker->password(); + + return (new CliScenario())->withExecution([$this->password]); + } } diff --git a/src/Exercise/HaveTheLastSay.php b/src/Exercise/HaveTheLastSay.php index 42b5b31..94a7c6d 100644 --- a/src/Exercise/HaveTheLastSay.php +++ b/src/Exercise/HaveTheLastSay.php @@ -8,13 +8,19 @@ use PhpParser\NodeFinder; use PhpParser\Parser; use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\Exercise\TemporaryDirectoryTrait; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\RunnerContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\FailureInterface; @@ -45,10 +51,8 @@ public function getDescription(): string return 'Use named arguments to specify the last to a specific parameter'; } - public function getArgs(): array + public function defineTestScenario(): CliScenario { - $file = $this->getTemporaryPath(); - $countries = [ ['UK', 'London'], ['Austria', 'Vienna'], @@ -62,14 +66,15 @@ public function getArgs(): array ['Belarus', 'Minsk'], ]; - file_put_contents( - $file, - collect($this->getRandomCountries($countries))->map(fn ($row) => implode("|", $row))->implode("\n") - ); + $fileContent = collect($this->getRandomCountries($countries)) + ->map(fn ($row) => implode("|", $row)) + ->implode("\n"); - return [ - [$file] - ]; + $fileName = sprintf('countries-%s.csv', bin2hex(random_bytes(4))); + + return (new CliScenario()) + ->withExecution(["./$fileName"]) + ->withFile($fileName, $fileContent); } /** @@ -84,11 +89,6 @@ private function getRandomCountries(array $countries): array ); } - public function tearDown(): void - { - unlink($this->getTemporaryPath()); - } - public function getType(): ExerciseType { return ExerciseType::CLI(); @@ -104,16 +104,16 @@ public function getBannedFunctions(): array return []; } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); if (null === $statements || empty($statements)) { return Failure::fromNameAndReason($this->getName(), 'No code was found'); } $check = new FunctionRequirementsCheck($this->parser); - $result = $check->check($this, $input); + $result = $check->check($context); if ($result instanceof FailureInterface) { return $result; diff --git a/src/Exercise/InfiniteDivisions.php b/src/Exercise/InfiniteDivisions.php index 454c0c4..e0a64d6 100644 --- a/src/Exercise/InfiniteDivisions.php +++ b/src/Exercise/InfiniteDivisions.php @@ -12,13 +12,17 @@ use PhpParser\NodeFinder; use PhpParser\Parser; use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\RunnerContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -49,25 +53,25 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array { - $dispatcher->requireCheck(FunctionRequirementsCheck::class); + return [FunctionRequirementsCheck::class]; } - public function getArgs(): array + public function defineTestScenario(): CliScenario { - return [ - [ + return (new CliScenario()) + ->withExecution([ (string) $this->faker->randomFloat(3, 10, 100), '0' - ], - [ + ]) + ->withExecution([ (string) $this->faker->randomFloat(3, 10, 100), (string) $this->faker->randomFloat(3, 0, 10) - ] - ]; + ]); } + public function getRequiredFunctions(): array { return ['fdiv', 'round']; @@ -78,10 +82,10 @@ public function getBannedFunctions(): array return []; } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); $finder = new NodeFinder(); diff --git a/src/Exercise/LordOfTheStrings.php b/src/Exercise/LordOfTheStrings.php index ea72642..1d70cd5 100644 --- a/src/Exercise/LordOfTheStrings.php +++ b/src/Exercise/LordOfTheStrings.php @@ -5,13 +5,17 @@ use Faker\Generator; use PhpSchool\PhpWorkshop\Check\ComposerCheck; use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\ComposerExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\RunnerContext; use PhpSchool\PhpWorkshop\Solution\DirectorySolution; use PhpSchool\PhpWorkshop\Solution\SolutionInterface; @@ -40,18 +44,12 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array { - $dispatcher->requireCheck(FunctionRequirementsCheck::class); - $dispatcher->requireCheck(ComposerCheck::class); + return [FunctionRequirementsCheck::class, ComposerCheck::class]; } - public function getSolution(): SolutionInterface - { - return DirectorySolution::fromDirectory(__DIR__ . '/../../exercises/lord-of-the-strings/solution'); - } - - public function getArgs(): array + public function defineTestScenario(): CliScenario { /** @var string $word */ $word = $this->faker->words(1, true); @@ -67,9 +65,13 @@ public function getArgs(): array 'nowhere' => $sentence }; - return [ - [$word, $sentence] - ]; + return (new CliScenario()) + ->withExecution([$word, $sentence]); + } + + public function getSolution(): SolutionInterface + { + return DirectorySolution::fromDirectory(__DIR__ . '/../../exercises/lord-of-the-strings/solution'); } public function insertWordInSentenceRandomly(string $word, string $sentence): string diff --git a/src/Exercise/PhpGetsAPromotion.php b/src/Exercise/PhpGetsAPromotion.php index d269028..a1c7c69 100644 --- a/src/Exercise/PhpGetsAPromotion.php +++ b/src/Exercise/PhpGetsAPromotion.php @@ -13,7 +13,9 @@ use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -57,15 +59,15 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function getArgs(): array + public function defineTestScenario(): CliScenario { - return []; + return (new CliScenario())->withExecution(); } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var Class_|null $classNode */ $classNode = (new NodeFinder())->findFirstInstanceOf($statements, Class_::class); @@ -73,7 +75,7 @@ public function check(Input $input): ResultInterface return Failure::fromNameAndReason($this->getName(), 'No class was found'); } - (static fn () => require $input->getRequiredArgument('program'))(); + (static fn () => require $context->getEntryPoint())(); /** @var class-string $className */ $reflectionClass = new ReflectionClass($className); diff --git a/src/Exercise/StringifyToDemystify.php b/src/Exercise/StringifyToDemystify.php index bf84cf6..e419728 100644 --- a/src/Exercise/StringifyToDemystify.php +++ b/src/Exercise/StringifyToDemystify.php @@ -17,10 +17,12 @@ use PhpSchool\PhpWorkshop\Exercise\CgiExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CgiScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; @@ -55,17 +57,16 @@ public function getType(): ExerciseType return ExerciseType::CGI(); } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array { - $dispatcher->requireCheck(FunctionRequirementsCheck::class); + return [FunctionRequirementsCheck::class]; } - /** - * @return array - */ - public function getRequests(): array + public function defineTestScenario(): CgiScenario { - return array_map( + $environment = new CgiScenario(); + + $requests = array_map( fn () => new Request( 'POST', 'https://phpschool.io/api', @@ -74,6 +75,12 @@ public function getRequests(): array ), array_fill(0, random_int(3, 6), null) ); + + foreach ($requests as $request) { + $environment->withExecution($request); + } + + return $environment; } /** @@ -132,10 +139,10 @@ public function getBannedFunctions(): array return []; } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var Stmt[] $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var Class_|null $classStmt */ $classStmt = (new NodeFinder())->findFirstInstanceOf($statements, Class_::class); diff --git a/src/Exercise/TheAttributesOfSuccess.php b/src/Exercise/TheAttributesOfSuccess.php index 934f4f7..fde0079 100644 --- a/src/Exercise/TheAttributesOfSuccess.php +++ b/src/Exercise/TheAttributesOfSuccess.php @@ -18,15 +18,18 @@ use PhpParser\Parser; use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\FileComparisonExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\FunctionRequirementsExerciseCheck; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -57,10 +60,29 @@ public function getDescription(): string return 'PHP 8\'s Attributes'; } - public function configure(ExerciseDispatcher $dispatcher): void + public function getRequiredChecks(): array { - $dispatcher->requireCheck(FileComparisonCheck::class); - $dispatcher->requireCheck(FunctionRequirementsCheck::class); + return [ + FileComparisonCheck::class, + FunctionRequirementsCheck::class + ]; + } + + public function defineTestScenario(): CliScenario + { + return (new CliScenario()) + ->withExecution([ + json_encode( + [ + 'id' => random_int(0, 100), + 'comment' => $this->faker->sentence(4), + 'rating' => $this->faker->numberBetween(0, 5), + 'reviewer' => $this->faker->userName(), + 'date' => $this->faker->date('d-m-Y') + ], + JSON_THROW_ON_ERROR + ) + ]); } public function getInitialCode(): SolutionInterface @@ -83,28 +105,10 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function getArgs(): array - { - return [ - [ - json_encode( - [ - 'id' => random_int(0, 100), - 'comment' => $this->faker->sentence(4), - 'rating' => $this->faker->numberBetween(0, 5), - 'reviewer' => $this->faker->userName(), - 'date' => $this->faker->date('d-m-Y') - ], - JSON_THROW_ON_ERROR - ) - ] - ]; - } - - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var Class_|null $classStmt */ $classStmt = (new NodeFinder())->findFirst($statements, function (Node $node) { diff --git a/src/Exercise/TheReturnOfStatic.php b/src/Exercise/TheReturnOfStatic.php index ab9d8b6..106fe61 100644 --- a/src/Exercise/TheReturnOfStatic.php +++ b/src/Exercise/TheReturnOfStatic.php @@ -12,12 +12,19 @@ use PhpParser\Node\Stmt\Function_; use PhpParser\NodeFinder; use PhpParser\Parser; +use PhpSchool\PhpWorkshop\Check\FileComparisonCheck; +use PhpSchool\PhpWorkshop\Check\FunctionRequirementsCheck; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -57,15 +64,16 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function getArgs(): array + public function defineTestScenario(): CliScenario { - return []; + return (new CliScenario()) + ->withExecution([]); } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); $finder = new NodeFinder(); diff --git a/src/Exercise/ThrowAnExpression.php b/src/Exercise/ThrowAnExpression.php index 0848a21..7b0caa3 100644 --- a/src/Exercise/ThrowAnExpression.php +++ b/src/Exercise/ThrowAnExpression.php @@ -10,13 +10,16 @@ use PhpParser\Node\Stmt\If_; use PhpParser\NodeFinder; use PhpParser\Parser; +use PhpSchool\PhpWorkshop\Environment\CgiTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CgiExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\ProvidesInitialCode; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CgiScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; @@ -51,18 +54,10 @@ public function getType(): ExerciseType return ExerciseType::CGI(); } - public function getRequests(): array - { - return [ - (new Request('GET', 'https://top-secret.com/forbidden')), - (new Request('GET', 'https://top-secret.com/blog')) - ]; - } - - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var If_|null $if */ $if = (new NodeFinder())->findFirstInstanceOf($statements, If_::class); @@ -97,4 +92,11 @@ public function getPatch(): Patch return (new Patch()) ->withTransformer(new Patch\WrapInTryCatch(\InvalidArgumentException::class)); } + + public function defineTestScenario(): CgiScenario + { + return (new CgiScenario()) + ->withExecution(new Request('GET', 'https://top-secret.com/forbidden')) + ->withExecution(new Request('GET', 'https://top-secret.com/blog')); + } } diff --git a/src/Exercise/UniteTheTypes.php b/src/Exercise/UniteTheTypes.php index 0d7db46..beb1531 100644 --- a/src/Exercise/UniteTheTypes.php +++ b/src/Exercise/UniteTheTypes.php @@ -9,12 +9,17 @@ use PhpParser\NodeFinder; use PhpParser\Parser; use PhpSchool\PhpWorkshop\CodeInsertion; +use PhpSchool\PhpWorkshop\Environment\CliTestEnvironment; use PhpSchool\PhpWorkshop\Exercise\AbstractExercise; use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; +use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; use PhpSchool\PhpWorkshop\Exercise\SubmissionPatchable; use PhpSchool\PhpWorkshop\ExerciseCheck\SelfCheck; +use PhpSchool\PhpWorkshop\ExerciseDispatcher; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\CliContext; +use PhpSchool\PhpWorkshop\ExerciseRunner\Context\ExecutionContext; use PhpSchool\PhpWorkshop\Input\Input; use PhpSchool\PhpWorkshop\Patch; use PhpSchool\PhpWorkshop\Result\Failure; @@ -47,7 +52,7 @@ public function getType(): ExerciseType return ExerciseType::CLI(); } - public function getArgs(): array + public function defineTestScenario(): CliScenario { $numbers = array_map( function (): string { @@ -59,7 +64,8 @@ function (): string { range(0, random_int(5, 15)) ); - return [$numbers]; + return (new CliScenario()) + ->withExecution($numbers); } public function getPatch(): Patch @@ -82,10 +88,10 @@ public function getPatch(): Patch ->withInsertion($casterInsertion); } - public function check(Input $input): ResultInterface + public function check(ExecutionContext $context): ResultInterface { /** @var array $statements */ - $statements = $this->parser->parse((string) file_get_contents($input->getRequiredArgument('program'))); + $statements = $this->parser->parse((string) file_get_contents($context->getEntryPoint())); /** @var Function_|null $adder */ $adder = (new NodeFinder())->findFirst($statements, function (\PhpParser\Node $node) { diff --git a/test/Exercise/LordOfTheStringsTest.php b/test/Exercise/LordOfTheStringsTest.php index e4d671c..2cc9f62 100644 --- a/test/Exercise/LordOfTheStringsTest.php +++ b/test/Exercise/LordOfTheStringsTest.php @@ -23,7 +23,7 @@ public function getExerciseClass(): string public function testWithNoComposerFile(): void { - $this->runExercise('solution-no-code.php'); + $this->runExercise('solution-no-composer.php'); $this->assertVerifyWasNotSuccessful(); $this->assertResultsHasFailureAndMatches(ComposerFailure::class, function (ComposerFailure $composerFailure) { diff --git a/test/solutions/lord-of-the-strings/solution-no-code.php b/test/solutions/lord-of-the-strings/solution-no-code.php deleted file mode 100644 index b3d9bbc..0000000 --- a/test/solutions/lord-of-the-strings/solution-no-code.php +++ /dev/null @@ -1 +0,0 @@ -