4 * This file is part of the Mink package.
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\Mink\Exception;
13 use Behat\Mink\Driver\DriverInterface;
14 use Behat\Mink\Session;
17 * Exception thrown for failed expectations.
19 * Some specialized child classes are available to customize the error rendering.
21 * @author Konstantin Kudryashov <ever.zet@gmail.com>
23 class ExpectationException extends Exception
29 * Initializes exception.
31 * @param string $message optional message
32 * @param DriverInterface|Session $driver driver instance (or session for BC)
33 * @param \Exception|null $exception expectation exception
35 public function __construct($message, $driver, \Exception $exception = null)
37 if ($driver instanceof Session) {
38 @trigger_error('Passing a Session object to the ExpectationException constructor is deprecated as of Mink 1.7. Pass the driver instead.', E_USER_DEPRECATED);
40 $this->session = $driver;
41 $this->driver = $driver->getDriver();
42 } elseif (!$driver instanceof DriverInterface) {
43 // Trigger an exception as we cannot typehint a disjunction
44 throw new \InvalidArgumentException('The ExpectationException constructor expects a DriverInterface or a Session.');
46 $this->driver = $driver;
49 if (!$message && null !== $exception) {
50 $message = $exception->getMessage();
53 parent::__construct($message, 0, $exception);
57 * Returns exception message with additional context info.
61 public function __toString()
64 $pageText = $this->pipeString($this->trimString($this->getContext())."\n");
65 $string = sprintf("%s\n\n%s%s", $this->getMessage(), $this->getResponseInfo(), $pageText);
66 } catch (\Exception $e) {
67 return $this->getMessage();
74 * Gets the context rendered for this exception.
78 protected function getContext()
80 return $this->trimBody($this->driver->getContent());
86 * @return DriverInterface
88 protected function getDriver()
94 * Returns exception session.
98 * @deprecated since 1.7, to be removed in 2.0. Use getDriver and the driver API instead.
100 protected function getSession()
102 if (null === $this->session) {
103 throw new \LogicException(sprintf('The deprecated method %s cannot be used when passing a driver in the constructor', __METHOD__));
106 @trigger_error(sprintf('The method %s is deprecated as of Mink 1.7 and will be removed in 2.0. Use getDriver and the driver API instead.'));
108 return $this->session;
112 * Prepends every line in a string with pipe (|).
114 * @param string $string
118 protected function pipeString($string)
120 return '| '.strtr($string, array("\n" => "\n| "));
124 * Removes response header/footer, letting only <body /> content.
126 * @param string $string response content
130 protected function trimBody($string)
132 $string = preg_replace(array('/^.*<body>/s', '/<\/body>.*$/s'), array('<body>', '</body>'), $string);
138 * Trims string to specified number of chars.
140 * @param string $string response content
141 * @param int $count trim count
145 protected function trimString($string, $count = 1000)
147 $string = trim($string);
149 if ($count < mb_strlen($string)) {
150 return mb_substr($string, 0, $count - 3).'...';
157 * Returns response information string.
161 protected function getResponseInfo()
163 $driver = basename(str_replace('\\', '/', get_class($this->driver)));
167 $info .= 'HTTP/1.1 '.$this->driver->getStatusCode().' | ';
168 } catch (UnsupportedDriverActionException $e) {
169 // Ignore the status code when not supported
171 $info .= $this->driver->getCurrentUrl().' | '.$driver." ]\n|\n";