1: <?php
2:
3: /**
4: * This file is part of expect package.
5: *
6: * (c) Noritaka Horio <holy.shared.design@gmail.com>
7: *
8: * This source file is subject to the MIT license that is bundled
9: * with this source code in the file LICENSE.
10: */
11: namespace expect\matcher;
12:
13: use Exception;
14: use expect\FailedMessage;
15:
16: /**
17: * Verify whether an exception is thrown.
18: *
19: * <code>
20: * $matcher = new ToThrow('RuntimeException');
21: * $matcher->match(function() { throw new RuntimeException() }); //return true
22: *
23: * $matcher->match(function() { throw new Exception() }); //return false
24: * <code>
25: *
26: * @author Noritaka Horio <holy.shared.design@gmail.com>
27: * @copyright Noritaka Horio <holy.shared.design@gmail.com>
28: */
29: final class ToThrow implements ReportableMatcher
30: {
31: /**
32: * @var callable
33: */
34: private $actual;
35:
36: /**
37: * @var string
38: */
39: private $expected;
40:
41: /**
42: * @var Exception|null
43: */
44: private $thrownException;
45:
46: /**
47: * Create a new matcher.
48: *
49: * @param string $expected
50: */
51: public function __construct($expected)
52: {
53: $this->expected = $expected;
54: }
55:
56: /**
57: * {@inheritdoc}
58: */
59: public function match($actual)
60: {
61: $this->actual = $actual;
62:
63: try {
64: $actual();
65: } catch (Exception $exception) {
66: $this->thrownException = $exception;
67: }
68:
69: return $this->thrownException instanceof $this->expected;
70: }
71:
72: /**
73: * {@inheritdoc}
74: */
75: public function reportFailed(FailedMessage $message)
76: {
77: $explanation = 'none thrown';
78:
79: if ($this->thrownException) {
80: $class = get_class($this->thrownException);
81: $explanation = "got $class";
82: }
83:
84: $message->appendText('Expected ')
85: ->appendText($this->expected)
86: ->appendText(' to be thrown, ')
87: ->appendText($explanation);
88: }
89:
90: /**
91: * {@inheritdoc}
92: */
93: public function reportNegativeFailed(FailedMessage $message)
94: {
95: $message->appendText('Expected ')
96: ->appendText($this->expected)
97: ->appendText(' not to be thrown');
98: }
99: }
100: