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..b38f58a --- /dev/null +++ b/.docker/runtime/docker-compose.yml @@ -0,0 +1,14 @@ +services: + runtime: + image: php8appreciate-runtime + build: + context: . + dockerfile: Dockerfile + + user: ${UID}:${GID} + + volumes: + - type: bind + source: ${SOLUTION} + target: '/solution' + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b09072..d7a821d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,8 @@ jobs: - name: Run phpunit tests run: | mkdir -p build/logs - vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml + PROCESS_FACTORY=host vendor/bin/phpunit + PROCESS_FACTORY=docker vendor/bin/phpunit --coverage-clover ./build/logs/clover.xml - name: Run phpcs run: composer cs diff --git a/composer.json b/composer.json index 7c702d9..5fd1fb9 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-docker-fixes" }, "require-dev": { "phpunit/phpunit": "^9", diff --git a/composer.lock b/composer.lock index 5f88a06..695d33d 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": "2d8b0aef87879a02fc704a8f524de907", "packages": [ { "name": "beberlei/assert", @@ -138,22 +138,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -164,9 +164,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -244,7 +244,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -260,20 +260,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:35:24+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", "shasum": "" }, "require": { @@ -281,7 +281,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", "extra": { @@ -327,7 +327,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.0.3" }, "funding": [ { @@ -343,20 +343,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:19:20+00:00" + "time": "2024-07-18T10:29:17+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", "shasum": "" }, "require": { @@ -371,8 +371,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -443,7 +443,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.7.0" }, "funding": [ { @@ -459,7 +459,7 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:05:35+00:00" + "time": "2024-07-18T11:15:46+00:00" }, { "name": "kevinlebrun/colors.php", @@ -518,26 +518,27 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.3.3", + "version": "v1.3.4", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "3dbf8a8e914634c48d389c1234552666b3d43754" + "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754", - "reference": "3dbf8a8e914634c48d389c1234552666b3d43754", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/61b87392d986dc49ad5ef64e75b1ff5fee24ef81", + "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81", "shasum": "" }, "require": { "php": "^7.3|^8.0" }, "require-dev": { - "nesbot/carbon": "^2.61", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", + "nesbot/carbon": "^2.61|^3.0", "pestphp/pest": "^1.21.3", "phpstan/phpstan": "^1.8.2", - "symfony/var-dumper": "^5.4.11" + "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0" }, "type": "library", "extra": { @@ -574,7 +575,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2023-11-08T14:08:06+00:00" + "time": "2024-08-02T07:48:17+00:00" }, { "name": "league/commonmark", @@ -734,21 +735,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 +785,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 +1127,16 @@ }, { "name": "php-school/php-workshop", - "version": "dev-master", + "version": "dev-docker-fixes", "source": { "type": "git", "url": "https://github.com/php-school/php-workshop.git", - "reference": "11911b2157e80480a8cc272b56f417f5ba4903bf" + "reference": "73febf8c62d982cd74896df9266522dc2a5153b5" }, "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/73febf8c62d982cd74896df9266522dc2a5153b5", + "reference": "73febf8c62d982cd74896df9266522dc2a5153b5", "shasum": "" }, "require": { @@ -1158,15 +1159,20 @@ "symfony/process": "^4.0 | ^5.0 | ^6.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.8", "composer/composer": "^2.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.8", "phpunit/phpunit": "^8.5", - "squizlabs/php_codesniffer": "^3.7", "yoast/phpunit-polyfills": "^0.2.0" }, - "default-branch": true, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { "files": [ "src/Event/functions.php", @@ -1204,9 +1210,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/docker-fixes" }, - "time": "2024-03-10T13:04:10+00:00" + "time": "2024-09-04T11:22:50+00:00" }, { "name": "php-school/terminal", @@ -1367,20 +1373,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 +1410,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 +1422,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 +1575,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 +1593,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1616,7 +1622,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,20 +1638,20 @@ "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.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b51ef8059159330b74a4d52f68e671033c0fe463", + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463", "shasum": "" }, "require": { @@ -1653,6 +1659,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -1679,7 +1688,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.9" }, "funding": [ { @@ -1695,20 +1704,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-06-28T09:49:33+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -1758,7 +1767,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -1774,20 +1783,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -1838,7 +1847,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -1854,20 +1863,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/process", - "version": "v6.4.4", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "710e27879e9be3395de2b98da3f52a946039f297" + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", - "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "url": "https://api.github.com/repos/symfony/process/zipball/8d92dd79149f29e89ee0f480254db595f6a6a2c5", + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5", "shasum": "" }, "require": { @@ -1899,7 +1908,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.8" }, "funding": [ { @@ -1915,7 +1924,7 @@ "type": "tidelift" } ], - "time": "2024-02-20T12:31:00+00:00" + "time": "2024-05-31T14:49:08+00:00" } ], "packages-dev": [ @@ -1991,16 +2000,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -2008,11 +2017,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -2038,7 +2048,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -2046,7 +2056,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "phar-io/manifest", @@ -2168,16 +2178,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.60", + "version": "1.12.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe" + "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe", - "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", + "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", "shasum": "" }, "require": { @@ -2220,45 +2230,41 @@ { "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-09-05T16:09:28+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "9.2.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -2267,7 +2273,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { @@ -2296,7 +2302,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, "funding": [ { @@ -2304,7 +2310,7 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-08-22T04:23:01+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2549,45 +2555,45 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.17", + "version": "9.6.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd" + "reference": "49d7820565836236411f5dc002d16dd689cde42f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd", - "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49d7820565836236411f5dc002d16dd689cde42f", + "reference": "49d7820565836236411f5dc002d16dd689cde42f", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", + "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-code-coverage": "^9.2.31", + "phpunit/php-file-iterator": "^3.0.6", "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.7", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -2632,7 +2638,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.20" }, "funding": [ { @@ -2648,7 +2654,7 @@ "type": "tidelift" } ], - "time": "2024-02-23T13:14:51+00:00" + "time": "2024-07-10T11:45:39+00:00" }, { "name": "sebastian/cli-parser", @@ -3452,16 +3458,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 +3479,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -3494,8 +3500,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 +3508,7 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-03-14T16:00:52+00:00" }, { "name": "sebastian/type", @@ -3616,16 +3621,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.9.0", + "version": "3.10.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" + "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017" }, "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/86e5f5dd9a840c46810ebe5ff1885581c42a3017", + "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017", "shasum": "" }, "require": { @@ -3692,7 +3697,7 @@ "type": "open_collective" } ], - "time": "2024-02-16T15:06:51+00:00" + "time": "2024-07-21T23:26:44+00:00" }, { "name": "theseer/tokenizer", diff --git a/phpunit.xml b/phpunit.xml index 5200ada..eac0d7d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,4 +9,7 @@ ./test ./test/solutions + + + 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..117a66a 100644 --- a/src/Exercise/ASafeSpaceForNulls.php +++ b/src/Exercise/ASafeSpaceForNulls.php @@ -21,11 +21,11 @@ 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 +59,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 +172,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..a970347 100644 --- a/src/Exercise/LordOfTheStrings.php +++ b/src/Exercise/LordOfTheStrings.php @@ -9,6 +9,7 @@ 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; @@ -40,18 +41,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 +62,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..d5950ce 100644 --- a/src/Exercise/ThrowAnExpression.php +++ b/src/Exercise/ThrowAnExpression.php @@ -15,8 +15,10 @@ 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 +53,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 +91,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/ASafeSpaceForNullsTest.php b/test/Exercise/ASafeSpaceForNullsTest.php index 5a8aa4e..98023c5 100644 --- a/test/Exercise/ASafeSpaceForNullsTest.php +++ b/test/Exercise/ASafeSpaceForNullsTest.php @@ -20,11 +20,6 @@ public function getApplication(): Application return require __DIR__ . '/../../app/bootstrap.php'; } - public function tearDown(): void - { - $this->removeSolutionAsset('users.csv'); - } - public function testFailureWhenAgeAccessedWithoutNullSafe(): void { $this->runExercise('no-null-safe-age.php'); @@ -73,6 +68,23 @@ public function testFailureWhenAddressLine1AccessedWithoutNullSafe(): void ); } + + public function testFailureWhenCsvNotCorrect(): void + { + $this->runExercise('csv-wrong.php'); + + $this->assertVerifyWasNotSuccessful(); + + $this->assertResultsHasFailureAndMatches( + FileComparisonFailure::class, + function (FileComparisonFailure $failure) { + self::assertEquals('users.csv', $failure->getFileName()); + + return true; + } + ); + } + public function testFailureWhenAddressLine2AccessedWithoutNullSafe(): void { $this->runExercise('no-null-safe-address-line2.php'); @@ -97,22 +109,6 @@ public function testFailureWhenCsvNotExported(): void ); } - public function testFailureWhenCsvNotCorrect(): void - { - $this->runExercise('csv-wrong.php'); - - $this->assertVerifyWasNotSuccessful(); - - $this->assertResultsHasFailureAndMatches( - FileComparisonFailure::class, - function (FileComparisonFailure $failure) { - self::assertEquals('users.csv', $failure->getFileName()); - - return true; - } - ); - } - public function testWithCorrectSolution(): void { $this->runExercise('correct-solution.php'); diff --git a/test/Exercise/AllMixedUpTest.php b/test/Exercise/AllMixedUpTest.php index bc5f34c..8d8bad8 100644 --- a/test/Exercise/AllMixedUpTest.php +++ b/test/Exercise/AllMixedUpTest.php @@ -21,12 +21,6 @@ public function getApplication(): Application return require __DIR__ . '/../../app/bootstrap.php'; } - public function tearDown(): void - { - $this->removeSolutionAsset('param.log'); - parent::tearDown(); - } - public function testSuccessfulSolution(): void { $this->runExercise('solution-correct.php'); diff --git a/test/Exercise/LordOfTheStringsTest.php b/test/Exercise/LordOfTheStringsTest.php index e4d671c..60ce21e 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) { @@ -36,7 +36,7 @@ public function testWithNoComposerFile(): void public function testWithNoCode(): void { - $this->runExercise('no-code/solution.php'); + $this->runExercise('no-code/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -45,7 +45,7 @@ public function testWithNoCode(): void public function testUsingBannedFunction(): void { - $this->runExercise('banned-functions/solution.php'); + $this->runExercise('banned-functions/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -73,7 +73,7 @@ function (FunctionRequirementsFailure $failure) { public function testWithCorrectSolution(): void { - $this->runExercise('correct-solution/solution.php'); + $this->runExercise('correct-solution/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasSuccessful(); } diff --git a/test/Exercise/TheAttributesOfSuccessTest.php b/test/Exercise/TheAttributesOfSuccessTest.php index 7e480d7..6c1e42a 100644 --- a/test/Exercise/TheAttributesOfSuccessTest.php +++ b/test/Exercise/TheAttributesOfSuccessTest.php @@ -24,7 +24,7 @@ public function getApplication(): Application public function testSuccessfulSolution(): void { - $this->runExercise('correct-solution/solution.php'); + $this->runExercise('correct-solution/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasSuccessful(); $this->assertOutputWasCorrect(); @@ -32,7 +32,7 @@ public function testSuccessfulSolution(): void public function testSuccessfulSolutionWithPromotedProperty(): void { - $this->runExercise('correct-solution-promoted/solution.php'); + $this->runExercise('correct-solution-promoted/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasSuccessful(); $this->assertOutputWasCorrect(); @@ -40,7 +40,7 @@ public function testSuccessfulSolutionWithPromotedProperty(): void public function testModifyingExternalCodeFails(): void { - $this->runExercise('modified-external-code/solution.php'); + $this->runExercise('modified-external-code/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); $this->assertOutputWasCorrect(); @@ -57,7 +57,7 @@ function (FileComparisonFailure $failure) { public function testNotCallingDeserializeFails(): void { - $this->runExercise('no-deserialize-call/solution.php'); + $this->runExercise('no-deserialize-call/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); $this->assertOutputWasIncorrect(); @@ -73,7 +73,7 @@ function (FunctionRequirementsFailure $failure) { public function testNotDumpingObjectFails(): void { - $this->runExercise('no-var-dump/solution.php'); + $this->runExercise('no-var-dump/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); $this->assertOutputWasIncorrect(); @@ -89,7 +89,7 @@ function (FunctionRequirementsFailure $failure) { public function testWhenOutputIsIncorrectComparisonFails(): void { - $this->runExercise('incorrect-output/solution.php'); + $this->runExercise('incorrect-output/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); $this->assertOutputWasIncorrect(); @@ -102,7 +102,7 @@ public function testWhenOutputIsIncorrectComparisonFails(): void public function testWhenNoClassNamedReviewDefined(): void { - $this->runExercise('no-review-class/solution.php'); + $this->runExercise('no-review-class/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -111,7 +111,7 @@ public function testWhenNoClassNamedReviewDefined(): void public function testWhenNoMethodNamedObfuscateReviewerDefined(): void { - $this->runExercise('no-obfuscate-method/solution.php'); + $this->runExercise('no-obfuscate-method/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -120,7 +120,7 @@ public function testWhenNoMethodNamedObfuscateReviewerDefined(): void public function testWhenNoAttributeDefinedOnObfuscateReviewerMethod(): void { - $this->runExercise('no-attributes/solution.php'); + $this->runExercise('no-attributes/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -129,7 +129,7 @@ public function testWhenNoAttributeDefinedOnObfuscateReviewerMethod(): void public function testWhenNoAttributedNamedObfuscateUsedOnMethod(): void { - $this->runExercise('no-attribute-named-obfuscate/solution.php'); + $this->runExercise('no-attribute-named-obfuscate/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -141,7 +141,7 @@ public function testWhenNoAttributedNamedObfuscateUsedOnMethod(): void public function testWhenNoArgumentsPassedToObfuscateAttribute(): void { - $this->runExercise('no-arguments-obfuscate-attribute/solution.php'); + $this->runExercise('no-arguments-obfuscate-attribute/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -153,7 +153,7 @@ public function testWhenNoArgumentsPassedToObfuscateAttribute(): void public function testWhenIncorrectPropertyPassedToObfuscateAttribute(): void { - $this->runExercise('invalid-arg-obfuscate-attribute/solution.php'); + $this->runExercise('invalid-arg-obfuscate-attribute/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -165,7 +165,7 @@ public function testWhenIncorrectPropertyPassedToObfuscateAttribute(): void public function testWhenObfuscateAttributeNotDefined(): void { - $this->runExercise('no-obfuscate-class/solution.php'); + $this->runExercise('no-obfuscate-class/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -174,7 +174,7 @@ public function testWhenObfuscateAttributeNotDefined(): void public function testWhenObfuscateHasNoAttributes(): void { - $this->runExercise('obfuscate-no-attributes/solution.php'); + $this->runExercise('obfuscate-no-attributes/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -183,7 +183,7 @@ public function testWhenObfuscateHasNoAttributes(): void public function testWhenObfuscateAttributeIncorrectlyDefined(): void { - $this->runExercise('obfuscate-attribute-incorrect/solution.php'); + $this->runExercise('obfuscate-attribute-incorrect/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -192,7 +192,7 @@ public function testWhenObfuscateAttributeIncorrectlyDefined(): void public function testWhenObfuscateAttributeHasNoFlags(): void { - $this->runExercise('obfuscate-attribute-no-flags/solution.php'); + $this->runExercise('obfuscate-attribute-no-flags/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -201,7 +201,7 @@ public function testWhenObfuscateAttributeHasNoFlags(): void public function testWhenObfuscateAttributeConfigurationIsWrong(): void { - $this->runExercise('obfuscate-attribute-wrong-target/solution.php'); + $this->runExercise('obfuscate-attribute-wrong-target/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); @@ -213,7 +213,7 @@ public function testWhenObfuscateAttributeConfigurationIsWrong(): void public function testWhenObfuscateAttributeHasNoPublicPropertyNamedKey(): void { - $this->runExercise('no-public-property-named-key/solution.php'); + $this->runExercise('no-public-property-named-key/solution.php', self::DIRECTORY_SOLUTION); $this->assertVerifyWasNotSuccessful(); diff --git a/test/Exercise/ThrowAnExpressionTest.php b/test/Exercise/ThrowAnExpressionTest.php index 03d0666..161748d 100644 --- a/test/Exercise/ThrowAnExpressionTest.php +++ b/test/Exercise/ThrowAnExpressionTest.php @@ -34,7 +34,7 @@ public function testThrowingWrongException(): void self::assertInstanceOf(Success::class, $output->getResults()[1]); self::assertMatchesRegularExpression( - '/Fatal error: Uncaught Exception: Access denied!/', + '/Fatal error:\s+Uncaught Exception: Access denied!/', $output->getResults()[0]->getReason() ); 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 @@ -