UnitTestFixture::assertNull()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
/**
3
 * Scabbia2 Testing Component
4
 * https://github.com/eserozvataf/scabbia2
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @link        https://github.com/eserozvataf/scabbia2-testing for the canonical source repository
10
 * @copyright   2010-2016 Eser Ozvataf. (http://eser.ozvataf.com/)
11
 * @license     http://www.apache.org/licenses/LICENSE-2.0 - Apache License, Version 2.0
12
 */
13
14
namespace Scabbia\Testing;
15
16
use ReflectionClass;
17
18
/**
19
 * Base class for fixtures which is going to be constructed to host unit testing
20
 * methods inside
21
 *
22
 * @package     Scabbia\Testing
23
 * @author      Eser Ozvataf <[email protected]>
24
 * @since       2.0.0
25
 */
26
abstract class UnitTestFixture
27
{
28
    /** @type bool @isFailed Indicates test fixture is failed or not */
29
    public $isFailed = false;
30
    /** @type array @testStack Track of the unit which is currently testing */
31
    public $testStack = [];
32
    /** @type array @testReport Output of test results */
33
    public $testReport = [];
34
    /** @type null|array $testExpectations The set of outcomes which is going to be tested */
35
    public $testExpectations = null;
36
37
38
    /**
39
     * Begin testing all methods of the fixture
40
     *
41
     * @return void
42
     */
43
    public function test()
44
    {
45
        $tMe = new ReflectionClass($this);
46
        $tMethods = $tMe->getMethods(\ReflectionMethod::IS_PUBLIC);
47
48
        $tReservedMethods = ["setUp", "tearDown"];
49
50
        /** @type \ReflectionMethod $tMethod */
51
        foreach ($tMethods as $tMethod) {
52
            if ($tMethod->class !== $tMe->name || in_array($tMethod->name, $tReservedMethods)) {
53
                continue;
54
            }
55
56
            $this->testUnit(sprintf("%s->%s()", $tMe->name, $tMethod->name), [$this, $tMethod->name]);
57
        }
58
    }
59
60
    /**
61
     * Tests the specified method of the fixture
62
     *
63
     * @param $uName        string      Name of the method
64
     * @param $uCallback    callable    Target method
65
     *
66
     * @return void
67
     */
68
    public function testUnit($uName, /* callable */ $uCallback)
69
    {
70
        $this->testStack[] = ["name" => $uName, "callback" => $uCallback];
71
72
        $tException = null;
73
74
        $this->testExpectations = [
75
            "ignoreException" => [],
76
            "expectException" => [],
77
78
            "result" => null
79
        ];
80
        $this->setUp();
81
        try {
82
            call_user_func($uCallback);
83
        } catch (\Exception $ex) {
84
            $tException = $ex;
85
        }
86
        $this->tearDown();
87
88
        if ($tException !== null) {
89
            /** @type string $tExpectation */
90
            foreach ($this->testExpectations["ignoreException"] as $tExpectation) {
91
                if (!is_a($tException, $tExpectation)) {
92
                    continue;
93
                }
94
95
                $this->testAddReport(
96
                    "ignoreException",
97
                    false,
98
                    get_class($tException) . ": " . $tException->getMessage()
99
                );
100
                $tException = null;
101
                break;
102
            }
103
        }
104
105
        $tExpectations = $this->testExpectations["expectException"];
106
        /** @type string $tExpectationKey */
107
        /** @type string $tExpectation */
108
        foreach ($tExpectations as $tExpectationKey => $tExpectation) {
109
            if ($tException !== null && is_a($tException, $tExpectation)) {
110
                unset($tExpectations[$tExpectationKey]);
111
                $this->testAddReport(
112
                    "expectException",
113
                    false,
114
                    get_class($tException) . ": " . $tException->getMessage()
115
                );
116
                $tException = null;
117
            }
118
        }
119
120
        /** @type string $tExpectation */
121
        foreach ($tExpectations as $tExpectation) {
122
            $this->testAddReport("expectException", true, $tExpectation);
123
        }
124
125
        if ($tException !== null) {
126
            $this->testAddReport("exception", true, get_class($tException) . ": " . $tException->getMessage());
127
        }
128
129
        if ($this->testExpectations["result"] !== null) {
130
            if ($this->testExpectations["result"][0] === "skip") {
131
                $this->testAddReport("skip", false, $this->testExpectations["result"][1]);
132
                $this->isFailed = false;
133
            } elseif ($this->testExpectations["result"][0] === "fail") {
134
                $this->testAddReport("fail", true, $this->testExpectations["result"][1]);
135
                $this->isFailed = true;
136
            }
137
        }
138
139
        array_pop($this->testStack);
140
    }
141
142
    /**
143
     * Adds test output to the final report
144
     *
145
     * @param $uOperation   string      Name of the operation
146
     * @param $uIsFailed    bool        Is test failed or not?
147
     * @param $uMessage     mixed       Message (optional)
148
     *
149
     * @return void
150
     */
151
    public function testAddReport($uOperation, $uIsFailed, $uMessage = null)
152
    {
153
        $tScope = end($this->testStack);
154
155
        if (!isset($this->testReport[$tScope["name"]])) {
156
            $this->testReport[$tScope["name"]] = [];
157
        }
158
159
        $this->testReport[$tScope["name"]][] = [
160
            "operation" => $uOperation,
161
            "failed" => $uIsFailed,
162
            "message" => $uMessage
163
        ];
164
165
        if ($uIsFailed) {
166
            $this->isFailed = true;
167
        }
168
    }
169
170
    /**
171
     * SetUp method of the fixture
172
     *
173
     * This method is being executed when the test is started.
174
     *
175
     * @return void
176
     */
177
    protected function setUp()
178
    {
179
180
    }
181
182
    /**
183
     * TearDown method of the fixture
184
     *
185
     * This method is being executed when the test is finished.
186
     *
187
     * @return void
188
     */
189
    protected function tearDown()
190
    {
191
192
    }
193
194
    /**
195
     * Tests if given condition is **not** true
196
     *
197
     * @param $uCondition   bool    The condition
198
     * @param $uMessage     mixed   Message (optional)
199
     *
200
     * @return void
201
     */
202
    public function assertTrue($uCondition, $uMessage = null)
203
    {
204
        $this->testAddReport("assertTrue", $uCondition, $uMessage);
205
    }
206
207
    /**
208
     * Tests if given condition is **not** false
209
     *
210
     * @param $uCondition   bool    The condition
211
     * @param $uMessage     mixed   Message (optional)
212
     *
213
     * @return void
214
     */
215
    public function assertFalse($uCondition, $uMessage = null)
216
    {
217
        $this->testAddReport("assertFalse", !$uCondition, $uMessage);
218
    }
219
220
    /**
221
     * Tests if given condition is **not** null
222
     *
223
     * @param $uVariable    bool    The condition
224
     * @param $uMessage     mixed   Message (optional)
225
     *
226
     * @return void
227
     */
228
    public function assertNull($uVariable, $uMessage = null)
229
    {
230
        $this->testAddReport("assertNull", $uVariable === null, $uMessage);
231
    }
232
233
    /**
234
     * Tests if given condition is null
235
     *
236
     * @param $uVariable    bool    The condition
237
     * @param $uMessage     mixed   Message (optional)
238
     *
239
     * @return void
240
     */
241
    public function assertNotNull($uVariable, $uMessage = null)
242
    {
243
        $this->testAddReport("assertNotNull", $uVariable !== null, $uMessage);
244
    }
245
246
    /**
247
     * Tests if given variable derived from given class
248
     *
249
     * @param $uVariable    mixed   The variable
250
     * @param $uClassName   mixed   Class name
251
     * @param $uMessage     mixed   Message (optional)
252
     *
253
     * @return void
254
     */
255
    public function assertInstanceOf($uVariable, $uClassName, $uMessage = null)
256
    {
257
        $this->testAddReport("assertInstanceOf", $uVariable instanceof $uClassName, $uMessage);
258
    }
259
260
    /**
261
     * Tests if given variables have the same type and value
262
     *
263
     * @param $uVariable1   mixed   First variable
264
     * @param $uVariable2   mixed   Second variable
265
     * @param $uMessage     mixed   Message (optional)
266
     *
267
     * @return void
268
     */
269
    public function assertSame($uVariable1, $uVariable2, $uMessage = null)
270
    {
271
        $this->testAddReport("assertSame", $uVariable1 !== $uVariable2, $uMessage);
272
    }
273
274
    /**
275
     * Tests if given variables have the same value
276
     *
277
     * @param $uVariable1   mixed   First variable
278
     * @param $uVariable2   mixed   Second variable
279
     * @param $uMessage     mixed   Message (optional)
280
     *
281
     * @return void
282
     */
283
    public function assertEquals($uVariable1, $uVariable2, $uMessage = null)
284
    {
285
        $this->testAddReport("assertEquals", $uVariable1 != $uVariable2, $uMessage);
286
    }
287
288
    /**
289
     * Tests if given variable is a substring of another given variable
290
     *
291
     * @param $uVariable1   mixed   First variable
292
     * @param $uVariable2   mixed   Second variable
293
     * @param $uMessage     mixed   Message (optional)
294
     *
295
     * @return void
296
     */
297
    public function assertContains($uVariable1, $uVariable2, $uMessage = null)
298
    {
299
        if (is_scalar($uVariable2)) {
300
            $this->testAddReport("assertContains", strpos($uVariable1, $uVariable2) === false, $uMessage);
301
            return;
302
        }
303
304
        $this->testAddReport("assertContains", !in_array($uVariable1, $uVariable2, true), $uMessage);
305
    }
306
307
    /**
308
     * Tests if will testing unit throw specified exception or not
309
     *
310
     * @param $uExceptionType    string     Name of the exception type
311
     *
312
     * @return void
313
     */
314
    public function expectException($uExceptionType)
315
    {
316
        $this->testExpectations["expectException"][] = $uExceptionType;
317
    }
318
319
    /**
320
     * Ignores if testing unit throws specified exception during test
321
     *
322
     * @param $uExceptionType    string     Name of the exception type
323
     *
324
     * @return void
325
     */
326
    public function ignoreException($uExceptionType)
327
    {
328
        $this->testExpectations["ignoreException"][] = $uExceptionType;
329
    }
330
331
    /**
332
     * Marks current unit test as skipped
333
     *
334
     * @param $uMessage     mixed   Message (optional)
335
     *
336
     * @return void
337
     */
338
    public function markTestSkipped($uMessage = null)
339
    {
340
        $this->testExpectations["result"] = ["skip", $uMessage];
341
    }
342
343
    /**
344
     * Marks current unit test as failed
345
     *
346
     * @param $uMessage     mixed   Message (optional)
347
     *
348
     * @return void
349
     */
350
    public function fail($uMessage = null)
351
    {
352
        $this->testExpectations["result"] = ["fail", $uMessage];
353
    }
354
}
355