4 * This file is part of the Behat Testwork.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Testwork\Call\Handler;
13 use Behat\Testwork\Argument\Validator;
14 use Behat\Testwork\Call\Call;
15 use Behat\Testwork\Call\CallResult;
16 use Behat\Testwork\Call\Exception\CallErrorException;
20 * Handles calls in the current runtime.
22 * @author Konstantin Kudryashov <ever.zet@gmail.com>
24 final class RuntimeCallHandler implements CallHandler
29 private $errorReportingLevel;
33 private $obStarted = false;
40 * Initializes executor.
42 * @param integer $errorReportingLevel
44 public function __construct($errorReportingLevel = E_ALL)
46 $this->errorReportingLevel = $errorReportingLevel;
47 $this->validator = new Validator();
53 public function supportsCall(Call $call)
61 public function handleCall(Call $call)
63 $this->startErrorAndOutputBuffering($call);
64 $result = $this->executeCall($call);
65 $this->stopErrorAndOutputBuffering();
71 * Used as a custom error handler when step is running.
73 * @see set_error_handler()
75 * @param integer $level
76 * @param string $message
78 * @param integer $line
82 * @throws CallErrorException
84 public function handleError($level, $message, $file, $line)
86 if ($this->errorLevelIsNotReportable($level)) {
90 throw new CallErrorException($level, $message, $file, $line);
94 * Executes single call.
100 private function executeCall(Call $call)
102 $reflection = $call->getCallee()->getReflection();
103 $callable = $call->getBoundCallable();
104 $arguments = $call->getArguments();
105 $return = $exception = null;
108 $this->validator->validateArguments($reflection, $arguments);
109 $return = call_user_func_array($callable, $arguments);
110 } catch (Exception $caught) {
111 $exception = $caught;
114 $stdOut = $this->getBufferedStdOut();
116 return new CallResult($call, $return, $exception, $stdOut);
120 * Returns buffered stdout.
122 * @return null|string
124 private function getBufferedStdOut()
126 return ob_get_length() ? ob_get_contents() : null;
130 * Starts error handler and stdout buffering.
134 private function startErrorAndOutputBuffering(Call $call)
136 $errorReporting = $call->getErrorReportingLevel() ? : $this->errorReportingLevel;
137 set_error_handler(array($this, 'handleError'), $errorReporting);
138 $this->obStarted = ob_start();
142 * Stops error handler and stdout buffering.
144 private function stopErrorAndOutputBuffering()
146 if ($this->obStarted) {
149 restore_error_handler();
153 * Checks if provided error level is not reportable.
155 * @param integer $level
159 private function errorLevelIsNotReportable($level)
161 return !(error_reporting() & $level);