Skip to content

Commit 6453c48

Browse files
committed
To avoid users from having to deal with conflict resolution, do away with the Runkit trait in favor of more static methods on the Runkit support class
1 parent b38ecb3 commit 6453c48

File tree

11 files changed

+188
-220
lines changed

11 files changed

+188
-220
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"Tests\\": "tests/"
4545
},
4646
"files": [
47-
"tests/Support/functions.php"
47+
"tests/stubs/functions.php"
4848
]
4949
},
5050
"config": {

phpstan.neon.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ parameters:
2424
paths:
2525
- tests/FixtureTest.php
2626
- tests/FunctionsTest.php
27+
28+
-
29+
message: '#Call to an undefined static method \S+#'
30+
path: tests/Support/RunkitTest.php

src/Concerns/Runkit.php

Lines changed: 0 additions & 79 deletions
This file was deleted.

src/Constants.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
trait Constants
99
{
10-
use Concerns\Runkit;
11-
1210
/**
1311
* All constants being handled by this trait.
1412
*
@@ -43,6 +41,8 @@ protected function restoreConstants()
4341

4442
unset($this->constants['created'][$key]);
4543
}
44+
45+
Runkit::reset();
4646
}
4747

4848
/**
@@ -59,7 +59,9 @@ protected function restoreConstants()
5959
*/
6060
protected function setConstant($name, $value = null)
6161
{
62-
$this->requiresRunkit('setConstant() requires Runkit be available, skipping.');
62+
if (! Runkit::isAvailable()) {
63+
$this->markTestSkipped('setConstant() requires Runkit be available, skipping.');
64+
}
6365

6466
if (defined($name)) {
6567
if (! isset($this->constants['updated'][$name])) {
@@ -96,7 +98,9 @@ protected function deleteConstant($name)
9698
return $this;
9799
}
98100

99-
$this->requiresRunkit('deleteConstant() requires Runkit be available, skipping.');
101+
if (! Runkit::isAvailable()) {
102+
$this->markTestSkipped('deleteConstant() requires Runkit be available, skipping.');
103+
}
100104

101105
if (! isset($this->constants[$name])) {
102106
$this->constants['updated'][$name] = constant($name);

src/Functions.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
trait Functions
1010
{
11-
use Concerns\Runkit;
12-
1311
/**
1412
* All functions being handled by this trait.
1513
*
@@ -41,6 +39,8 @@ protected function restoreFunctions()
4139

4240
array_map([Runkit::class, 'function_remove'], $this->functions['defined']);
4341
$this->functions['defined'] = [];
42+
43+
Runkit::reset();
4444
}
4545

4646
/**
@@ -64,7 +64,9 @@ protected function defineFunction($name, \Closure $closure)
6464
));
6565
}
6666

67-
$this->requiresRunkit('defineFunction() requires Runkit be available, skipping.');
67+
if (! Runkit::isAvailable()) {
68+
$this->markTestSkipped('defineFunction() requires Runkit be available, skipping.');
69+
}
6870

6971
if (! Runkit::function_add($name, $closure)) {
7072
throw new RunkitException(sprintf('Unable to define function %1$s().', $name));
@@ -91,11 +93,13 @@ protected function redefineFunction($name, \Closure $closure)
9193
return $this->defineFunction($name, $closure);
9294
}
9395

94-
$this->requiresRunkit('redefineFunction() requires Runkit be available, skipping.');
96+
if (! Runkit::isAvailable()) {
97+
$this->markTestSkipped('redefineFunction() requires Runkit be available, skipping.');
98+
}
9599

96100
// Back up the original version of the function.
97101
if (! isset($this->functions['redefined'][$name])) {
98-
$namespaced = $this->runkitNamespace($name);
102+
$namespaced = Runkit::makeNamespaced($name);
99103

100104
if (! Runkit::function_rename($name, $namespaced)) {
101105
throw new RunkitException(sprintf('Unable to back up %1$s(), aborting.', $name));
@@ -126,7 +130,7 @@ protected function deleteFunction($name)
126130
return $this;
127131
}
128132

129-
$namespaced = $this->runkitNamespace($name);
133+
$namespaced = Runkit::makeNamespaced($name);
130134

131135
if (! Runkit::function_rename($name, $namespaced)) {
132136
throw new RunkitException(sprintf('Unable to back up %1$s(), aborting.', $name));

src/Support/Runkit.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
*/
3333
class Runkit
3434
{
35+
/**
36+
* A namespace used to move things out of the way for the duration of a test.
37+
*
38+
* @var string
39+
*/
40+
private static $namespace;
41+
3542
/**
3643
* Dynamically alias methods to the underlying Runkit functions.
3744
*
@@ -57,4 +64,61 @@ public static function __callStatic($name, array $args = [])
5764
$name
5865
));
5966
}
67+
68+
/**
69+
* Determine whether or not Runkit is available in the current environment.
70+
*
71+
* @return bool
72+
*/
73+
public static function isAvailable()
74+
{
75+
return function_exists('runkit7_constant_redefine')
76+
|| function_exists('runkit_constant_redefine');
77+
}
78+
79+
/**
80+
* Get the current runkit namespace.
81+
*
82+
* If the property is currently empty, one will be created.
83+
*
84+
* @return string The namespace (with trailing backslash) where we're moving functions,
85+
* constants, etc. during tests.
86+
*/
87+
public static function getNamespace()
88+
{
89+
if (empty(self::$namespace)) {
90+
self::$namespace = uniqid(__NAMESPACE__ . '\\runkit_') . '\\';
91+
}
92+
93+
return self::$namespace;
94+
}
95+
96+
/**
97+
* Namespace the given reference.
98+
*
99+
* @param string $var The item to be moved into the temporary test namespace.
100+
*
101+
* @return string The newly-namespaced item.
102+
*/
103+
public static function makeNamespaced($var)
104+
{
105+
// Strip leading backslashes.
106+
if (0 === mb_strpos($var, '\\')) {
107+
$var = mb_substr($var, 1);
108+
}
109+
110+
return self::getNamespace() . $var;
111+
}
112+
113+
/**
114+
* Reset static properties.
115+
*
116+
* This is helpful to run before tests in case self::$namespace gets polluted.
117+
*
118+
* @return void
119+
*/
120+
public static function reset()
121+
{
122+
self::$namespace = '';
123+
}
60124
}

tests/Concerns/RunkitTest.php

Lines changed: 0 additions & 98 deletions
This file was deleted.

0 commit comments

Comments
 (0)