TestCase::restoreConstant()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Mougrim\PhpunitSoftMocks;
4
5
use Badoo\SoftMocks;
0 ignored issues
show
Bug introduced by
The type Badoo\SoftMocks was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
7
/**
8
 * @author Mougrim <[email protected]>
9
 */
10
class TestCase extends \PHPUnit_Framework_TestCase
11
{
12
    /** @var \ReflectionClass[] */
13
    private $reflectionClasses = [];
14
    private $closuresClass;
15
16 7
    protected function tearDown()
17
    {
18 7
        $this->restoreAll();
19 7
        parent::tearDown();
20
    }
21
22
    /**
23
     * @param callable|string $name
24
     * @param callable $function
25
     */
26 1
    public function redefineFunction($name, callable $function)
27
    {
28 1
        SoftMocks::redefineFunction($name, '', $function);
29
    }
30
31
    /**
32
     * @param callable|string $name
33
     */
34 1
    public function restoreFunction($name)
35
    {
36 1
        SoftMocks::restoreFunction($name);
37
    }
38
39 2
    public function redefineConstant($name, $value)
40
    {
41 2
        SoftMocks::redefineConstant($name, $value);
42
    }
43
44 2
    public function restoreConstant($name)
45
    {
46 2
        SoftMocks::restoreConstant($name);
47
    }
48
49 2
    public function removeConstant($name)
50
    {
51 2
        SoftMocks::removeConstant($name);
52
    }
53
54 1
    public function redefineClassConstant($class, $name, $value)
55
    {
56 1
        $this->redefineConstant($class.'::'.$name, $value);
57
    }
58
59 1
    public function restoreClassConstant($class, $name)
60
    {
61 1
        $this->restoreConstant($class.'::'.$name);
62
    }
63
64 1
    public function removeClassConstant($class, $name)
65
    {
66 1
        $this->removeConstant($class.'::'.$name);
67
    }
68
69 2
    public function restoreAllConstants()
70
    {
71 2
        SoftMocks::restoreAllConstants();
72
    }
73
74
    /**
75
     * Only user-defined method redefinition is supported.
76
     *
77
     * @param callable|array $classAndMethod [$class, $method] $class - a class name or a trait name
78
     * @param callable $function
79
     *
80
     * @throws \ReflectionException
81
     */
82 4
    public function redefineMethod(array $classAndMethod, callable $function)
83
    {
84 4
        list($class, $name) = $classAndMethod;
85 4
        if (!isset($this->reflectionClasses[$class])) {
86 4
            $this->reflectionClasses[$class] = new \ReflectionClass($class);
87
        }
88 4
        $reflection = $this->reflectionClasses[$class];
89 4
        $method = $reflection->getMethod($name);
90 4
        $closuresClass = $this->getClosuresClass();
91 4
        $closuresClass::${'closures'}[$class][$name] = $function;
92 4
        $bindCode = "\$this, {$class}::class";
93 4
        if ($method->isStatic()) {
94 2
            $bindCode = "null, {$class}::class";
95
        }
96 4
        $code = <<<PHP
97
\$function = {$closuresClass}::\$closures['{$class}']['{$name}'];
98
if (\$function instanceof \Closure) {
99
    \$function = \$function->bindTo({$bindCode});
100
}
101
return call_user_func_array(\$function, \$params);
102
103
PHP;
104 4
        SoftMocks::redefineMethod($class, $name, '', $code);
105
    }
106
107 4
    private function getClosuresClass()
108
    {
109 4
        if ($this->closuresClass === null) {
110 4
            $namespace = __NAMESPACE__;
111 4
            $className = str_replace('.', '_', uniqid('ClosuresClass_', true));
112
113 4
            $code = <<<PHP
114
namespace {$namespace};
115
class {$className}
116
{
117
    public static \$closures = [];
118
}
119
PHP;
120
121 4
            eval($code);
122
123 4
            $this->closuresClass = $namespace.'\\'.$className;
124
        }
125
126 4
        return $this->closuresClass;
127
    }
128
129
    /**
130
     * @param callable|array $classAndMethod [$class, $method] $class - a class name or a trait name
131
     */
132 3
    public function restoreMethod(array $classAndMethod)
133
    {
134 3
        list($class, $name) = $classAndMethod;
135 3
        SoftMocks::restoreMethod($class, $name);
136 3
        $closuresClass = $this->getClosuresClass();
137 3
        unset($closuresClass::${'closures'}[$class][$name]);
138
    }
139
140 4
    public function callOriginal(callable $callable, array $params)
141
    {
142 4
        return SoftMocks::callOriginal($callable, $params);
143
    }
144
145 7
    public function restoreAll()
146
    {
147 7
        SoftMocks::restoreAll();
148 7
        if ($this->closuresClass) {
149 4
            $closuresClass = $this->closuresClass;
150 7
            $closuresClass::${'closures'} = [];
151
        }
152
    }
153
}
154