1<?php
2
3/**
4 * Hoa
5 *
6 *
7 * @license
8 *
9 * New BSD License
10 *
11 * Copyright © 2007-2017, Hoa community. All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *     * Redistributions of source code must retain the above copyright
16 *       notice, this list of conditions and the following disclaimer.
17 *     * Redistributions in binary form must reproduce the above copyright
18 *       notice, this list of conditions and the following disclaimer in the
19 *       documentation and/or other materials provided with the distribution.
20 *     * Neither the name of the Hoa nor the names of its contributors may be
21 *       used to endorse or promote products derived from this software without
22 *       specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37namespace Hoa\Exception\Test\Unit;
38
39use Hoa\Exception\Idle as SUT;
40use Hoa\Test;
41
42/**
43 * Class \Hoa\Exception\Test\Unit\Idle.
44 *
45 * Test suite of the idle exception.
46 *
47 * @copyright  Copyright © 2007-2017 Hoa community
48 * @license    New BSD License
49 */
50class Idle extends Test\Unit\Suite
51{
52    public function case_is_a_real_exception()
53    {
54        $this
55            ->when($result = new SUT('foo'))
56            ->then
57                ->object($result)
58                    ->isInstanceOf('Exception');
59    }
60
61    public function case_get_backtrace()
62    {
63        $this
64            ->given($exception = new SUT('foo'))
65            ->when($result = $exception->getBacktrace())
66            ->then
67                ->array($result)
68                    ->hasKey(0)
69                ->array($result[0])
70                    ->hasKey('file')
71                    ->hasKey('line')
72                    ->hasKey('function')
73                    ->hasKey('class')
74                    ->hasKey('type')
75                    ->hasKey('args');
76    }
77
78    public function case_get_previous_throw()
79    {
80        $this
81            ->given(
82                $previous  = new SUT('previous'),
83                $exception = new SUT('foo', 0, [], $previous)
84            )
85            ->when($result = $exception->getPreviousThrow())
86            ->then
87                ->object($result)
88                    ->isIdenticalTo($previous);
89    }
90
91    public function case_get_arguments()
92    {
93        $this
94            ->given($exception = new SUT('foo', 0, ['arg', 42, null]))
95            ->when($result = $exception->getArguments())
96            ->then
97                ->array($result)
98                    ->isEqualTo(['arg', 42, '(null)']);
99    }
100
101    public function case_get_arguments_from_a_string()
102    {
103        $this
104            ->given($exception = new SUT('foo', 0, 'arg'))
105            ->when($result = $exception->getArguments())
106            ->then
107                ->array($result)
108                    ->isEqualTo(['arg']);
109    }
110
111    public function case_get_raw_message()
112    {
113        $this
114            ->given(
115                $message   = 'foo %s',
116                $exception = new SUT($message)
117            )
118            ->when($result = $exception->getRawMessage())
119            ->then
120                ->string($result)
121                    ->isEqualTo($message);
122    }
123
124    public function case_get_formatted_message()
125    {
126        $this
127            ->given(
128                $message   = 'foo %s',
129                $exception = new SUT($message, 0, 'bar')
130            )
131            ->when($result = $exception->getFormattedMessage())
132            ->then
133                ->string($result)
134                    ->isEqualTo($exception->getMessage())
135                    ->isEqualTo('foo bar');
136    }
137
138    public function case_get_from_object()
139    {
140        $this
141            ->given($exception = new SUT('foo'))
142            ->when($result = $exception->getFrom())
143            ->then
144                ->string($result)
145                    ->isEqualTo(__METHOD__ . '()');
146    }
147
148    public function case_raise()
149    {
150        $this
151            ->given($exception = new SUT('foo'), $line = __LINE__)
152            ->when($result = $exception->raise())
153            ->then
154                ->string($result)
155                    ->isEqualTo(
156                        __METHOD__ . '(): (0) foo' . "\n" .
157                        'in ' . __FILE__ . ' at line ' . $line . '.'
158                    );
159    }
160
161    public function case_raise_with_previous()
162    {
163        $this
164            ->given(
165                $previous  = new SUT('previous'), $previousLine = __LINE__,
166                $exception = new SUT('foo', 0, [], $previous), $line = __LINE__
167            )
168            ->when($result = $exception->raise(true))
169            ->then
170                ->string($result)
171                    ->isEqualTo(
172                        __METHOD__ . '(): (0) foo' . "\n" .
173                        'in ' . __FILE__ . ' at line ' . $line . '.' . "\n\n" .
174                        '    ⬇' . "\n\n" .
175                        'Nested exception (' . get_class($previous) . '):' . "\n" .
176                        __METHOD__ . '(): (0) previous' . "\n" .
177                        'in ' . __FILE__ . ' at line ' . $previousLine . '.'
178                    );
179    }
180
181    public function case_uncaught()
182    {
183        $this
184            ->given(
185                $this->function->ob_get_level = 0,
186                $exception = new SUT('foo'), $line = __LINE__
187            )
188            ->when($result = SUT::uncaught($exception))
189            ->then
190                ->variable($result)
191                    ->isNull()
192                ->output
193                    ->isEqualTo(
194                        'Uncaught exception (' . get_class($exception) . '):' . "\n" .
195                        __METHOD__ . '(): (0) foo' . "\n" .
196                        'in ' . __FILE__ . ' at line ' . $line . '.'
197                    );
198    }
199
200    public function case_uncaught_not_Hoa()
201    {
202        $this
203            ->exception(function () {
204                SUT::uncaught(new \Exception('foo'));
205            })
206                ->isInstanceOf('Exception')
207            ->output
208                ->isEmpty();
209    }
210
211    public function case_to_string()
212    {
213        $this
214            ->given($exception = new SUT('foo'))
215            ->when($result = $exception->__toString())
216            ->then
217                ->string($result)
218                    ->isEqualTo($exception->raise());
219    }
220
221    public function case_disable_uncaught_handler()
222    {
223        $this
224            ->given(
225                $this->function->restore_exception_handler = function () use (&$called) {
226                    $called = true;
227
228                    return null;
229                }
230            )
231            ->when($result = SUT::enableUncaughtHandler(false))
232            ->then
233                ->variable($result)
234                    ->isNull()
235                ->boolean($called)
236                    ->isTrue();
237    }
238
239    public function case_enable_uncaught_handler()
240    {
241        $self = $this;
242
243        $this
244            ->given(
245                $this->function->set_exception_handler = function ($handler) use ($self, &$called) {
246                    $called = true;
247
248                    $self
249                        ->object($handler)
250                            ->isInstanceOf('Closure')
251                        ->let($reflection = new \ReflectionObject($handler))
252                        ->array($invokeParameters = $reflection->getMethod('__invoke')->getParameters())
253                            ->hasSize(1)
254                        ->string($invokeParameters[0]->getName())
255                            ->isEqualTo('exception');
256
257                    return null;
258                }
259            )
260            ->when($result = SUT::enableUncaughtHandler())
261            ->then
262                ->variable($result)
263                    ->isNull()
264                ->boolean($called)
265                    ->isTrue();
266    }
267}
268