Completed
Push — master ( a850c8...d9e568 )
by Sergey
13:40
created

TestCase::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Common tests stuff
4
 *
5
 * @see       https://github.com/sergeymakinen/tests
6
 * @copyright Copyright (c) 2017 Sergey Makinen (https://makinen.ru)
7
 * @license   https://github.com/sergeymakinen/tests/blob/master/LICENSE MIT License
8
 */
9
10
namespace SergeyMakinen\Tests;
11
12
use PHPUnit\Framework\Exception;
13
use PHPUnit\Util\InvalidArgumentHelper;
14
15
abstract class TestCase extends \PHPUnit\Framework\TestCase
16
{
17
    /**
18
     * @var string
19
     */
20
    private $expectedException;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
21
22
    /**
23
     * @inheritDoc
24
     */
25 2
    protected function tearDown()
26
    {
27 2
        parent::tearDown();
28 2
        $this->expectedException = null;
29 2
    }
30
31
    /**
32
     * Returns whether the class' parent method exists.
33
     *
34
     * @param string $name
35
     * @return bool
36
     *
37
     * @internal
38
     */
39 1
    protected function isParentMethod($name)
40
    {
41 1
        return is_callable('parent::' . $name);
42
    }
43
44
    /**
45
     * Returns a test double for the specified class.
46
     *
47
     * @param string $originalClassName
48
     * @return \PHPUnit_Framework_MockObject_MockObject
49
     */
50
    protected function createMock($originalClassName)
51
    {
52
        if ($this->isParentMethod(__FUNCTION__)) {
53
            return parent::createMock($originalClassName);
54
        }
55
56
        return $this
57
            ->getMockBuilder($originalClassName)
58
            ->disableOriginalConstructor()
59
            ->disableOriginalClone()
60
            ->disableArgumentCloning()
61
            ->getMock();
62
    }
63
64
    /**
65
     * Sets an exception expected.
66
     *
67
     * @param string $exception
68
     * @throws Exception|\PHPUnit_Framework_Exception
69
     */
70 2
    public function expectException($exception)
71
    {
72 2
        if ($this->isParentMethod(__FUNCTION__)) {
73
            parent::expectException($exception);
74
            return;
75
        }
76
77 2
        if (!is_string($exception)) {
78 1
            if (class_exists('PHPUnit\Util\InvalidArgumentHelper')) {
79
                throw InvalidArgumentHelper::factory(1, 'string');
80
            } else {
81 1
                throw \PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
82
            }
83
        }
84
85 1
        $this->expectedException = $exception;
86 1
        $this->setExpectedException($this->expectedException);
0 ignored issues
show
Bug introduced by
The method setExpectedException() does not exist on SergeyMakinen\Tests\TestCase. Did you maybe mean setExpectedExceptionFromAnnotation()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
87 1
    }
88
89
    /**
90
     * Sets an exception code expected.
91
     *
92
     * @param int|string $code
93
     * @throws Exception|\PHPUnit_Framework_Exception
94
     */
95 2
    public function expectExceptionCode($code)
96
    {
97 2
        if ($this->isParentMethod(__FUNCTION__)) {
98
            parent::expectExceptionCode($code);
99
            return;
100
        }
101
102 2
        if (!is_int($code) && !is_string($code)) {
103 1
            if (class_exists('PHPUnit\Util\InvalidArgumentHelper')) {
104
                throw InvalidArgumentHelper::factory(1, 'integer or string');
105
            } else {
106 1
                throw \PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer or string');
107
            }
108
        }
109
110 1
        $this->setExpectedException($this->expectedException, '', $code);
0 ignored issues
show
Bug introduced by
The method setExpectedException() does not exist on SergeyMakinen\Tests\TestCase. Did you maybe mean setExpectedExceptionFromAnnotation()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
111 1
    }
112
113
    /**
114
     * Returns the reflected property.
115
     *
116
     * @param object|string $object
117
     * @param string $name
118
     * @return \ReflectionProperty
119
     */
120 2
    protected function getProperty($object, $name)
121
    {
122 2
        $class = new \ReflectionClass($object);
123 2
        while (!$class->hasProperty($name)) {
124 2
            $class = $class->getParentClass();
125 2
        }
126 2
        return $class->getProperty($name);
127
    }
128
129
    /**
130
     * Returns the private/protected property by its name.
131
     *
132
     * @param object|string $object
133
     * @param string $name
134
     * @return mixed
135
     */
136 2
    protected function getInaccessibleProperty($object, $name)
137
    {
138 2
        $property = $this->getProperty($object, $name);
139 2
        $property->setAccessible(true);
140 2
        return $property->getValue(is_object($object) ? $object : null);
141
    }
142
143
    /**
144
     * Sets the private/protected property value by its name.
145
     *
146
     * @param object|string $object
147
     * @param string $name
148
     * @param mixed $value
149
     */
150 2
    protected function setInaccessibleProperty($object, $name, $value)
151
    {
152 2
        $property = $this->getProperty($object, $name);
153 2
        $property->setAccessible(true);
154 2
        $property->setValue(is_object($object) ? $object : null, $value);
155 2
    }
156
157
    /**
158
     * Invokes the private/protected method by its name and returns its result.
159
     *
160
     * @param object|string $object
161
     * @param string $name
162
     * @param array $args
163
     * @return mixed
164
     */
165 2
    protected function invokeInaccessibleMethod($object, $name, array $args = [])
166
    {
167 2
        $method = new \ReflectionMethod($object, $name);
168 2
        $method->setAccessible(true);
169 2
        return $method->invokeArgs(is_object($object) ? $object : null, $args);
170
    }
171
}
172