Example #1
0
 /**
  * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with
  * the information from the request objects returned from the exercise. The exercise can return multiple
  * requests so the solution will be invoked for however many requests there are.
  *
  * Running only runs the student's solution, the reference solution is not run and no verification is performed,
  * the output of the student's solution is written directly to the output.
  *
  * Events dispatched (for each request):
  *
  * * cgi.run.student-execute.pre
  * * cgi.run.student.executing
  *
  * @param Input $input The command line arguments passed to the command.
  * @param OutputInterface $output A wrapper around STDOUT.
  * @return bool If the solution was successfully executed, eg. exit code was 0.
  */
 public function run(Input $input, OutputInterface $output)
 {
     $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.start', $this->exercise, $input));
     $success = true;
     foreach ($this->exercise->getRequests() as $i => $request) {
         $event = $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student-execute.pre', $request));
         $process = $this->getProcess($input->getArgument('program'), $event->getRequest());
         $output->writeTitle("Request");
         $output->emptyLine();
         $output->write($this->requestRenderer->renderRequest($request));
         $output->writeTitle("Output");
         $output->emptyLine();
         $process->start();
         $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student.executing', $request, ['output' => $output]));
         $process->wait(function ($outputType, $outputBuffer) use($output) {
             $output->write($outputBuffer);
         });
         $output->emptyLine();
         if (!$process->isSuccessful()) {
             $success = false;
         }
         $output->lineBreak();
     }
     $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.finish', $this->exercise, $input));
     return $success;
 }
 /**
  * Render the details of each failed request including the mismatching headers and body.
  *
  * @param ResultsRenderer $renderer
  * @return string
  */
 public function render(ResultsRenderer $renderer)
 {
     $results = array_filter($this->result->getResults(), function (ResultInterface $result) {
         return $result instanceof FailureInterface;
     });
     $output = '';
     if (count($results)) {
         $output .= $renderer->center("Some requests to your solution produced incorrect output!\n");
     }
     foreach ($results as $key => $request) {
         $output .= $renderer->lineBreak();
         $output .= "\n";
         $output .= $renderer->style(sprintf('Request %d', $key + 1), ['bold', 'underline', 'blue']);
         $output .= ' ' . $renderer->style(' FAILED ', ['bg_red', 'bold']) . "\n\n";
         $output .= "Request Details:\n\n";
         $output .= $this->requestRenderer->renderRequest($request->getRequest()) . "\n";
         $output .= $renderer->renderResult($request) . "\n";
     }
     return $output;
 }