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 @@
-