diff --git a/app/config.php b/app/config.php index fdf9896b..6f741f1d 100644 --- a/app/config.php +++ b/app/config.php @@ -203,9 +203,9 @@ }), CodePatcher::class => factory(function (ContainerInterface $c) { $patch = (new Patch) - ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'ini_set("display_errors", 1);')) + ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'ini_set("display_errors", 0);')) ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'error_reporting(E_ALL);')) - ->withInsertion(new Insertion(Insertion ::TYPE_BEFORE, 'date_default_timezone_set("Europe/London");')); + ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'date_default_timezone_set("Europe/London");')); return new CodePatcher($c->get(Parser::class), new Standard, $patch); }), diff --git a/composer.lock b/composer.lock index 93372587..6905b95d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "3235a8dc2d974f4b27bc4cd545ed37fb", + "hash": "d12a566491d807f91315a39b604ff0ac", "content-hash": "21f1705d07a93a8b7f249bd23a0755df", "packages": [ { @@ -665,7 +665,7 @@ }, { "name": "symfony/filesystem", - "version": "v3.0.5", + "version": "v3.0.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -714,7 +714,7 @@ }, { "name": "symfony/process", - "version": "v3.0.5", + "version": "v3.0.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -870,16 +870,16 @@ }, { "name": "composer/composer", - "version": "1.1.0-RC", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "94c2a21fe51016758212fa0aebd8add36757f354" + "reference": "48156b0fd9888bf528fbe9c9cba6963223cdd584" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/94c2a21fe51016758212fa0aebd8add36757f354", - "reference": "94c2a21fe51016758212fa0aebd8add36757f354", + "url": "https://api.github.com/repos/composer/composer/zipball/48156b0fd9888bf528fbe9c9cba6963223cdd584", + "reference": "48156b0fd9888bf528fbe9c9cba6963223cdd584", "shasum": "" }, "require": { @@ -943,7 +943,7 @@ "dependency", "package" ], - "time": "2016-04-29 16:32:14" + "time": "2016-05-17 11:25:44" }, { "name": "composer/semver", @@ -1343,16 +1343,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "3.3.1", + "version": "3.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2431befdd451fac43fbcde94d1a92fb3b8b68f86" + "reference": "44cd8e3930e431658d1a5de7d282d5cb37837fd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2431befdd451fac43fbcde94d1a92fb3b8b68f86", - "reference": "2431befdd451fac43fbcde94d1a92fb3b8b68f86", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/44cd8e3930e431658d1a5de7d282d5cb37837fd5", + "reference": "44cd8e3930e431658d1a5de7d282d5cb37837fd5", "shasum": "" }, "require": { @@ -1402,7 +1402,7 @@ "testing", "xunit" ], - "time": "2016-04-08 08:14:53" + "time": "2016-05-27 16:24:29" }, { "name": "phpunit/php-file-iterator", @@ -1494,21 +1494,24 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, "type": "library", "autoload": { "classmap": [ @@ -1531,7 +1534,7 @@ "keywords": [ "timer" ], - "time": "2015-06-21 08:01:12" + "time": "2016-05-12 18:03:57" }, { "name": "phpunit/php-token-stream", @@ -1584,16 +1587,16 @@ }, { "name": "phpunit/phpunit", - "version": "5.3.2", + "version": "5.3.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "2c6da3536035617bae3fe3db37283c9e0eb63ab3" + "reference": "00dd95ffb48805503817ced06399017df315fe5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2c6da3536035617bae3fe3db37283c9e0eb63ab3", - "reference": "2c6da3536035617bae3fe3db37283c9e0eb63ab3", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00dd95ffb48805503817ced06399017df315fe5c", + "reference": "00dd95ffb48805503817ced06399017df315fe5c", "shasum": "" }, "require": { @@ -1655,7 +1658,7 @@ "testing", "xunit" ], - "time": "2016-04-12 16:20:08" + "time": "2016-05-11 13:28:45" }, { "name": "phpunit/phpunit-mock-objects", @@ -1914,16 +1917,16 @@ }, { "name": "sebastian/environment", - "version": "1.3.6", + "version": "1.3.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "2292b116f43c272ff4328083096114f84ea46a56" + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/2292b116f43c272ff4328083096114f84ea46a56", - "reference": "2292b116f43c272ff4328083096114f84ea46a56", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", + "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", "shasum": "" }, "require": { @@ -1960,7 +1963,7 @@ "environment", "hhvm" ], - "time": "2016-05-04 07:59:13" + "time": "2016-05-17 03:18:57" }, { "name": "sebastian/exporter", @@ -2481,7 +2484,7 @@ }, { "name": "symfony/console", - "version": "v3.0.5", + "version": "v3.0.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", @@ -2541,7 +2544,7 @@ }, { "name": "symfony/finder", - "version": "v3.0.5", + "version": "v3.0.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -2590,16 +2593,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.1.1", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "1289d16209491b584839022f29257ad859b8532d" + "reference": "dff51f72b0706335131b00a7f49606168c582594" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", - "reference": "1289d16209491b584839022f29257ad859b8532d", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594", + "reference": "dff51f72b0706335131b00a7f49606168c582594", "shasum": "" }, "require": { @@ -2611,7 +2614,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -2645,11 +2648,11 @@ "portable", "shim" ], - "time": "2016-01-20 09:13:37" + "time": "2016-05-18 14:26:46" }, { "name": "symfony/yaml", - "version": "v3.0.5", + "version": "v3.0.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", diff --git a/src/Exception/CodeExecutionException.php b/src/Exception/CodeExecutionException.php index ec238831..c92cf512 100644 --- a/src/Exception/CodeExecutionException.php +++ b/src/Exception/CodeExecutionException.php @@ -12,14 +12,50 @@ */ class CodeExecutionException extends RuntimeException { + + /** + * @var string + */ + private $actual; + /** + * @var string + */ + private $errors; + + /** + * CodeExecutionException constructor. + * @param string $reason + * @param string $actual + * @param string $errors + */ + public function __construct($reason, $actual = null, $errors = null) + { + $this->message = $reason; + $this->actual = $actual; + $this->errors = $errors; + } + /** * @param Process $process * @return static */ public static function fromProcess(Process $process) { - $message = 'PHP Code failed to execute. Error: "%s"'; - $processOutput = $process->getErrorOutput() ? $process->getErrorOutput() : $process->getOutput(); - return new static(sprintf($message, $processOutput)); + $message = "PHP Code failed to execute. Error: \n%s"; + $processOutput = $process->getOutput(); + $processErrorOutput = $process->getErrorOutput(); + return new static( + sprintf($message, $processErrorOutput ?: $processOutput), $processOutput, $processErrorOutput + ); + } + + public function getActual() + { + return $this->actual; + } + + public function getErrors() + { + return $this->errors; } } diff --git a/src/ExerciseRunner/CgiRunner.php b/src/ExerciseRunner/CgiRunner.php index a306d793..d2f98d32 100644 --- a/src/ExerciseRunner/CgiRunner.php +++ b/src/ExerciseRunner/CgiRunner.php @@ -98,7 +98,7 @@ private function checkRequest(RequestInterface $request, $fileName) try { $event = $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.verify.user-execute.pre', $request)); - $userResponse = $this->executePhpFile($fileName, $event->getRequest(), 'user'); + list($userResponse, $userWarnings) = $this->executePhpFile($fileName, $event->getRequest(), 'user'); } catch (CodeExecutionException $e) { $this->eventDispatcher->dispatch(new Event('cgi.verify.user-execute.fail', ['exception' => $e])); return Failure::fromNameAndCodeExecutionFailure($this->getName(), $e); @@ -109,8 +109,15 @@ private function checkRequest(RequestInterface $request, $fileName) $solutionHeaders = $this->getHeaders($solutionResponse); $userHeaders = $this->getHeaders($userResponse); - if ($solutionBody !== $userBody || $solutionHeaders !== $userHeaders) { - return new CgiOutRequestFailure($request, $solutionBody, $userBody, $solutionHeaders, $userHeaders); + if ($solutionBody !== $userBody || $solutionHeaders !== $userHeaders || $userWarnings) { + return new CgiOutRequestFailure( + $request, + $solutionBody, + $userBody, + $solutionHeaders, + $userHeaders, + $userWarnings + ); } return new Success($this->getName()); @@ -153,7 +160,11 @@ private function executePhpFile($fileName, RequestInterface $request, $type) $output = "HTTP/1.0 200 OK\r\n" . $output; } - return ResponseSerializer::fromString($output); + return ( + $type == 'user' ? + [ResponseSerializer::fromString($output), $process->getErrorOutput()] + : ResponseSerializer::fromString($output) + ); } /** diff --git a/src/ExerciseRunner/CliRunner.php b/src/ExerciseRunner/CliRunner.php index 0cdf95b4..c9207b97 100644 --- a/src/ExerciseRunner/CliRunner.php +++ b/src/ExerciseRunner/CliRunner.php @@ -2,7 +2,6 @@ namespace PhpSchool\PhpWorkshop\ExerciseRunner; -use PhpSchool\PhpWorkshop\Event\CliEvent; use PhpSchool\PhpWorkshop\Event\CliExecuteEvent; use PhpSchool\PhpWorkshop\Event\Event; use PhpSchool\PhpWorkshop\Event\EventDispatcher; @@ -11,7 +10,6 @@ use PhpSchool\PhpWorkshop\Exercise\CliExercise; use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; -use PhpSchool\PhpWorkshop\ExerciseCheck\StdOutExerciseCheck; use PhpSchool\PhpWorkshop\Output\OutputInterface; use PhpSchool\PhpWorkshop\Result\Failure; use PhpSchool\PhpWorkshop\Result\ResultInterface; @@ -71,8 +69,11 @@ private function executePhpFile($fileName, ArrayObject $args, $type) if (!$process->isSuccessful()) { throw CodeExecutionException::fromProcess($process); } - - return $process->getOutput(); + return ( + $type == 'user' ? + [$process->getOutput(), $process->getErrorOutput()] + : $process->getOutput() + ); } /** @@ -110,13 +111,28 @@ public function verify($fileName) try { $event = $this->eventDispatcher->dispatch(new CliExecuteEvent('cli.verify.user-execute.pre', $args)); - $userOutput = $this->executePhpFile($fileName, $event->getArgs(), 'user'); + list($userOutput, $userWarnings) = $this->executePhpFile($fileName, $event->getArgs(), 'user'); } catch (CodeExecutionException $e) { $this->eventDispatcher->dispatch(new Event('cli.verify.user-execute.fail', ['exception' => $e])); - return Failure::fromNameAndCodeExecutionFailure($this->getName(), $e); + return Failure::fromNameAndCodeExecutionFailure( + $this->getName(), + $e, + $solutionOutput, + $e->getActual(), + $e->getErrors() + ); } - if ($solutionOutput === $userOutput) { - return new Success($this->getName()); + if ($solutionOutput === $userOutput || !empty($userWarnings)) { + if (!empty($userWarnings)) { + return StdOutFailure::fromNameAndWarnings( + $this->getName(), + $solutionOutput, + $userOutput, + $userWarnings + ); + } else { + return new Success($this->getName()); + } } return StdOutFailure::fromNameAndOutput($this->getName(), $solutionOutput, $userOutput); diff --git a/src/Result/CgiOutRequestFailure.php b/src/Result/CgiOutRequestFailure.php index 77e0085f..510ff2ce 100644 --- a/src/Result/CgiOutRequestFailure.php +++ b/src/Result/CgiOutRequestFailure.php @@ -36,25 +36,33 @@ class CgiOutRequestFailure implements FailureInterface */ private $actualHeaders; + /** + * @var string|null + */ + private $warnings; + /** * @param RequestInterface $request * @param string $expectedOutput * @param string $actualOutput * @param array $expectedHeaders * @param array $actualHeaders + * @param string|null $warnings */ public function __construct( RequestInterface $request, $expectedOutput, $actualOutput, array $expectedHeaders, - array $actualHeaders + array $actualHeaders, + $warnings = null ) { $this->request = $request; $this->expectedOutput = $expectedOutput; $this->actualOutput = $actualOutput; $this->expectedHeaders = $expectedHeaders; $this->actualHeaders = $actualHeaders; + $this->warnings = $warnings; } /** @@ -128,4 +136,12 @@ public function getCheckName() { return 'Request Failure'; } + + /** + * @return string|null + */ + public function getWarnings() + { + return $this->warnings; + } } diff --git a/src/Result/Failure.php b/src/Result/Failure.php index 9b6b219d..cbefcab4 100644 --- a/src/Result/Failure.php +++ b/src/Result/Failure.php @@ -18,6 +18,21 @@ class Failure implements FailureInterface */ private $reason; + /** + * @var string|null + */ + private $expectedOutput; + + /** + * @var string|null + */ + private $actualOutput; + + /** + * @var string|null + */ + private $errors; + /** * @var string */ @@ -26,11 +41,16 @@ class Failure implements FailureInterface /** * @param string $name * @param string|null $reason + * @param string|null $expectedOutput + * @param string|null $actualOutput */ - public function __construct($name, $reason = null) + public function __construct($name, $reason = null, $expectedOutput = null, $actualOutput = null, $errors = null) { - $this->name = $name; - $this->reason = $reason; + $this->name = $name; + $this->reason = $reason; + $this->expectedOutput = $expectedOutput; + $this->actualOutput = $actualOutput; + $this->errors = $errors; } /** @@ -56,11 +76,19 @@ public static function fromCheckAndReason(CheckInterface $check, $reason) /** * @param string $name * @param CodeExecutionException $e + * @param string|null $expectedOutput + * @param string|null $actualOutput + * @param string|null $errors * @return static */ - public static function fromNameAndCodeExecutionFailure($name, CodeExecutionException $e) - { - return new static($name, $e->getMessage()); + public static function fromNameAndCodeExecutionFailure( + $name, + CodeExecutionException $e, + $expectedOutput = null, + $actualOutput = null, + $errors = null + ) { + return new static($name, $e->getMessage(), $expectedOutput, $actualOutput, $errors); } /** @@ -92,4 +120,28 @@ public function getReason() { return $this->reason; } + + /** + * @return string|null + */ + public function getExpectedOutput() + { + return $this->expectedOutput; + } + + /** + * @return string|null + */ + public function getActualOutput() + { + return $this->actualOutput; + } + + /** + * @return string|null + */ + public function getErrors() + { + return $this->errors; + } } diff --git a/src/Result/StdOutFailure.php b/src/Result/StdOutFailure.php index 30d84f3c..c0da3701 100644 --- a/src/Result/StdOutFailure.php +++ b/src/Result/StdOutFailure.php @@ -26,16 +26,22 @@ class StdOutFailure implements FailureInterface */ private $actualOutput; + /** + * @var string + */ + private $warnings; + /** * @param string $name * @param string $expectedOutput * @param string $actualOutput */ - public function __construct($name, $expectedOutput, $actualOutput) + public function __construct($name, $expectedOutput, $actualOutput, $warnings = null) { $this->name = $name; $this->expectedOutput = $expectedOutput; $this->actualOutput = $actualOutput; + $this->warnings = $warnings; } /** @@ -49,6 +55,18 @@ public static function fromNameAndOutput($name, $expectedOutput, $actualOutput) return new static($name, $expectedOutput, $actualOutput); } + /** + * @param string $name + * @param $expectedOutput + * @param $actualOutput + * @param $warnings + * @return static + */ + public static function fromNameAndWarnings($name, $expectedOutput, $actualOutput, $warnings) + { + return new static($name, $expectedOutput, $actualOutput, $warnings); + } + /** * @param CheckInterface $check * @param $expectedOutput @@ -83,4 +101,12 @@ public function getActualOutput() { return $this->actualOutput; } + + /** + * @return string + */ + public function getWarnings() + { + return $this->warnings; + } } diff --git a/src/ResultRenderer/FailureRenderer.php b/src/ResultRenderer/FailureRenderer.php index 5c4cdac2..743b1bfe 100644 --- a/src/ResultRenderer/FailureRenderer.php +++ b/src/ResultRenderer/FailureRenderer.php @@ -30,6 +30,35 @@ public function __construct(Failure $result) */ public function render(ResultsRenderer $renderer) { - return ' ' . $this->result->getReason() . "\n"; + if ($this->result->getExpectedOutput()) { + return sprintf( + " %s\n%s\n\n %s\n%s\n" . ($this->result->getErrors() ? "\n %s\n%s\n" : ""), + $renderer->style("ACTUAL", ['bold', 'underline', 'yellow']), + $this->indent($renderer->style(sprintf('"%s"', $this->result->getActualOutput()), 'red')), + $renderer->style("EXPECTED", ['yellow', 'bold', 'underline']), + $this->indent($renderer->style(sprintf('"%s"', $this->result->getExpectedOutput()), 'red')), + $renderer->style("ERRORS/WARNINGS", ['yellow', 'bold', 'underline']), + $this->indent($renderer->style(sprintf('%s', $this->result->getErrors()), 'red')) + ); + } else { + return ' ' . $this->result->getReason() . "\n"; + } + } + + /** + * @param string $string + * @return string + */ + private function indent($string) + { + return implode( + "\n", + array_map( + function ($line) { + return sprintf(" %s", $line); + }, + explode("\n", $string) + ) + ); } } diff --git a/src/ResultRenderer/OutputFailureRenderer.php b/src/ResultRenderer/OutputFailureRenderer.php index db2c08a3..174e5dda 100644 --- a/src/ResultRenderer/OutputFailureRenderer.php +++ b/src/ResultRenderer/OutputFailureRenderer.php @@ -32,11 +32,13 @@ public function __construct(StdOutFailure $result) public function render(ResultsRenderer $renderer) { return sprintf( - " %s\n%s\n\n %s\n%s\n", + " %s\n%s\n\n %s\n%s\n" . ($this->result->getWarnings() ? "\n %s\n%s\n" : ""), $renderer->style("ACTUAL", ['bold', 'underline', 'yellow']), $this->indent($renderer->style(sprintf('"%s"', $this->result->getActualOutput()), 'red')), $renderer->style("EXPECTED", ['yellow', 'bold', 'underline']), - $this->indent($renderer->style(sprintf('"%s"', $this->result->getExpectedOutput()), 'red')) + $this->indent($renderer->style(sprintf('"%s"', $this->result->getExpectedOutput()), 'red')), + $renderer->style("WARNINGS", ['yellow', 'bold', 'underline']), + $this->indent($renderer->style(sprintf('"%s"', $this->result->getWarnings()), 'red')) ); } diff --git a/test/CodePatcherTest.php b/test/CodePatcherTest.php index d4b7149a..ff978964 100644 --- a/test/CodePatcherTest.php +++ b/test/CodePatcherTest.php @@ -26,12 +26,12 @@ class CodePatcherTest extends PHPUnit_Framework_TestCase public function testDefaultPatchIsAppliedIfAvailable() { $patch = (new Patch) - ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'ini_set("display_errors", 1);')); + ->withInsertion(new Insertion(Insertion::TYPE_BEFORE, 'ini_set("display_errors", 0);')); $patcher = new CodePatcher((new ParserFactory)->create(ParserFactory::PREFER_PHP7), new Standard, $patch); $exercise = $this->getMock(ExerciseInterface::class); - $expected = "assertEquals($expected, $patcher->patch($exercise, 'getMock(); $process - ->expects($this->exactly(2)) + ->expects($this->exactly(1)) ->method('getErrorOutput') ->will($this->returnValue('Error Output')); $e = CodeExecutionException::fromProcess($process); - $this->assertEquals('PHP Code failed to execute. Error: "Error Output"', $e->getMessage()); + $this->assertEquals("PHP Code failed to execute. Error: \nError Output", $e->getMessage()); } public function testFromProcessUsesStdOutputIfErrorOutputEmpty() @@ -51,6 +51,6 @@ public function testFromProcessUsesStdOutputIfErrorOutputEmpty() ->will($this->returnValue('Std Output')); $e = CodeExecutionException::fromProcess($process); - $this->assertEquals('PHP Code failed to execute. Error: "Std Output"', $e->getMessage()); + $this->assertEquals("PHP Code failed to execute. Error: \nStd Output", $e->getMessage()); } } diff --git a/test/ExerciseRunner/CgiRunnerTest.php b/test/ExerciseRunner/CgiRunnerTest.php index dd5f37b2..0b529f88 100644 --- a/test/ExerciseRunner/CgiRunnerTest.php +++ b/test/ExerciseRunner/CgiRunnerTest.php @@ -65,7 +65,8 @@ public function testVerifyThrowsExceptionIfSolutionFailsExecution() ->method('getRequests') ->will($this->returnValue([$request])); - $regex = "/^PHP Code failed to execute\\. Error: \"PHP Parse error: syntax error, unexpected end of file in/"; + $regex = + "/^PHP Code failed to execute\\. Error: \\nPHP Parse error: syntax error, unexpected end of file in/"; $this->setExpectedExceptionRegExp(SolutionExecutionException::class, $regex); $this->runner->verify(''); } @@ -167,7 +168,7 @@ public function testVerifyReturnsFailureIfUserSolutionFailsToExecute() $result = iterator_to_array($failure)[0]; $this->assertInstanceOf(Failure::class, $result); - $failureMsg = "/^PHP Code failed to execute. Error: \"PHP Parse error: syntax error, unexpected end of file"; + $failureMsg = "/^PHP Code failed to execute. Error: \\nPHP Parse error: syntax error, unexpected end of file"; $failureMsg .= " in/"; $this->assertRegExp($failureMsg, $result->getReason()); } diff --git a/test/ExerciseRunner/CliRunnerTest.php b/test/ExerciseRunner/CliRunnerTest.php index 203544ae..953d382e 100644 --- a/test/ExerciseRunner/CliRunnerTest.php +++ b/test/ExerciseRunner/CliRunnerTest.php @@ -58,7 +58,7 @@ public function testVerifyThrowsExceptionIfSolutionFailsExecution() ->method('getArgs') ->will($this->returnValue([])); - $regex = "/^PHP Code failed to execute\\. Error: \"PHP Parse error: syntax error, unexpected end of file"; + $regex = "/^PHP Code failed to execute\\. Error: \\nPHP Parse error: syntax error, unexpected end of file"; $regex .= ", expecting ',' or ';'/"; $this->setExpectedExceptionRegExp(SolutionExecutionException::class, $regex); $this->runner->verify(''); @@ -98,7 +98,7 @@ public function testVerifyReturnsFailureIfUserSolutionFailsToExecute() $failure = $this->runner->verify(__DIR__ . '/../res/cli/user-error.php'); - $failureMsg = "/^PHP Code failed to execute. Error: \"PHP Parse error: syntax error, "; + $failureMsg = "/^PHP Code failed to execute. Error: \\nPHP Parse error: syntax error, "; $failureMsg .= "unexpected end of file, expecting ',' or ';'/"; $this->assertInstanceOf(Failure::class, $failure); @@ -155,7 +155,7 @@ public function testRunPassesOutputAndReturnsFailureIfScriptFails() ->method('getArgs') ->will($this->returnValue([1, 2, 3])); - $this->expectOutputRegex('/PHP Parse error: syntax error, unexpected end of file, expecting \',\' or \';\' /'); + $this->expectOutputRegex("/PHP Parse error: syntax error, unexpected end of file, expecting ',' or ';' /"); $success = $this->runner->run(__DIR__ . '/../res/cli/user-error.php', $output); $this->assertFalse($success);