Skip to content

Commit

Permalink
Merge pull request #15 from assertwell/feature/runkit-proxy
Browse files Browse the repository at this point in the history
Introduce a Runkit support class
  • Loading branch information
stevegrunwell authored Oct 26, 2020
2 parents 2df1431 + 0e214b4 commit 582f8db
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 28 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
"@test:analysis"
],
"test:analysis": [
"phpstan analyse"
"simple-phpunit --version",
"phpstan analyse -c phpstan.neon.dist"
],
"test:coverage": [
"phpdbg -qrr -d memory_limit=-1 ./vendor/bin/simple-phpunit --colors=always --testdox --coverage-html=tests/coverage"
Expand Down
33 changes: 18 additions & 15 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@ parameters:
paths:
- src
- tests

bootstrapFiles:
- vendor/bin/.phpunit/phpunit/vendor/autoload.php

ignoreErrors:
# PHPUnit framework classes are provided by symfony/phpunit-bridge.
# Don't require return type hinting in tests.
-
message: '#^Class PHPUnit\\Framework\\.+ not found\.$#'
path: *
message: '#Method \S+ has no return typehint specified\.#'
path: tests/*

# Strings are a valid callable type.
-
message: '#Parameter \#1 \$function of function call_user_func_array expects callable\(\): mixed, string given\.#'
path: src/Support/Runkit.php
10 changes: 9 additions & 1 deletion src/Concerns/Runkit.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ trait Runkit
* Mark a test as skipped if Runkit is not available.
*
* @throws \PHPUnit\Framework\SkippedTestError
*
* @param string $message Optional. A message to include if the SkippedTestError exception
* is thrown. Default is empty.
*
* @return void
*/
protected function requiresRunkit($message = '')
{
Expand All @@ -22,9 +27,12 @@ protected function requiresRunkit($message = '')

/**
* Determine whether or not Runkit is available in the current environment.
*
* @return bool
*/
protected function isRunkitAvailable()
{
return function_exists('runkit_constant_redefine');
return function_exists('runkit7_constant_redefine')
|| function_exists('runkit_constant_redefine');
}
}
17 changes: 13 additions & 4 deletions src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace AssertWell\PHPUnitGlobalState;

use AssertWell\PHPUnitGlobalState\Exceptions\RedefineException;
use AssertWell\PHPUnitGlobalState\Support\Runkit;

trait Constants
{
Expand All @@ -17,6 +18,8 @@ trait Constants

/**
* @before
*
* @return void
*/
protected function resetConstants()
{
Expand All @@ -28,20 +31,22 @@ protected function resetConstants()

/**
* @after
*
* @return void
*/
protected function restoreConstants()
{
foreach ($this->_constants['updated'] as $name => $value) {
if (defined($name)) {
runkit_constant_redefine($name, $value);
Runkit::constant_redefine($name, $value);
} else {
define($name, $value);
}
}

foreach ($this->_constants['created'] as $name) {
if (defined($name)) {
runkit_constant_remove($name);
Runkit::constant_remove($name);
}
}
}
Expand All @@ -55,6 +60,8 @@ protected function restoreConstants()
*
* @param string $name The constant name.
* @param mixed $value The scalar value to store in the constant.
*
* @return self
*/
protected function setConstant($name, $value = null)
{
Expand All @@ -66,7 +73,7 @@ protected function setConstant($name, $value = null)
}

try {
runkit_constant_redefine($name, $value);
Runkit::constant_redefine($name, $value);
} catch (\Exception $e) {
throw new RedefineException(sprintf(
'Unable to redefine constant "%s" with value "%s".',
Expand All @@ -86,6 +93,8 @@ protected function setConstant($name, $value = null)
* Delete a constant.
*
* @param string $name The constant name.
*
* @return self
*/
protected function deleteConstant($name)
{
Expand All @@ -99,7 +108,7 @@ protected function deleteConstant($name)
$this->_constants['updated'][$name] = constant($name);
}

runkit_constant_remove($name);
Runkit::constant_remove($name);

return $this;
}
Expand Down
8 changes: 8 additions & 0 deletions src/EnvironmentVariables.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ trait EnvironmentVariables

/**
* @before
*
* @return void
*/
protected function resetEnvironmentVariableRegistry()
{
Expand All @@ -21,6 +23,8 @@ protected function resetEnvironmentVariableRegistry()

/**
* @after
*
* @return void
*/
protected function restoreEnvironmentVariables()
{
Expand All @@ -37,6 +41,8 @@ protected function restoreEnvironmentVariables()
* @param string $variable The environment variable name.
* @param mixed $value The value to store in the environment variable. Passing NULL will
* delete the environment variable.
*
* @return self
*/
protected function setEnvironmentVariable($variable, $value = null)
{
Expand All @@ -53,6 +59,8 @@ protected function setEnvironmentVariable($variable, $value = null)
* Delete an environment variable.
*
* @param string $variable The variable name.
*
* @return self
*/
protected function deleteEnvironmentVariable($variable)
{
Expand Down
6 changes: 6 additions & 0 deletions src/GlobalVariables.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ trait GlobalVariables

/**
* @before
*
* @return void
*/
protected function resetGlobalVariables()
{
Expand All @@ -22,6 +24,8 @@ protected function resetGlobalVariables()

/**
* @after
*
* @return void
*/
protected function restoreGlobalVariables()
{
Expand All @@ -42,6 +46,8 @@ protected function restoreGlobalVariables()
* @param string $variable The global variable name.
* @param mixed $value The new, temporary value. Passing NULL will unset the given
* $variable, if it exists.
*
* @return void
*/
protected function setGlobalVariable($variable, $value)
{
Expand Down
58 changes: 58 additions & 0 deletions src/Support/Runkit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/**
* A utility class to ensure we're calling the runkit7_* functions when available, as the runkit_*
* versions are deprecated in newer versions of PHP.
*/

namespace AssertWell\PHPUnitGlobalState\Support;

/**
* phpcs:disable Generic.Files.LineLength.TooLong
* @method static bool constant_add(string $constname, mixed $value, int $newVisibility = NULL)
* @method static bool constant_redefine(string $constname, mixed $value, int $newVisibility = NULL)
* @method static bool constant_remove(string $constname)
* @method static bool function_add(string $funcname, string $arglist, string $code, bool $return_by_reference = NULL, string $doc_comment = NULL, string $return_type, bool $is_strict = NULL)
* @method static bool function_copy(string $funcname, string $targetname)
* @method static bool function_redefine(string $funcname, string $arglist, string $code, bool $return_by_reference = NULL, string $doc_comment = NULL, string $return_type = NULL, bool $is_strict)
* @method static bool function_remove(string $funcname)
* @method static bool function_rename(string $funcname, string $newname)
* @method static bool import(string $filename, int $flags = NULL)
* @method static bool method_add(string $classname, string $methodname, string $args, string $code, int $flags = RUNKIT7_ACC_PUBLIC, string $doc_comment = NULL, string $return_type = NULL, bool $is_strict = NULL)
* @method static bool method_copy(string $dClass, string $dMethod, string $sClass, string $sMethod = NULL)
* @method static bool method_redefine(string $classname, string $methodname, string $args, string $code, int $flags = RUNKIT7_ACC_PUBLIC, string $doc_comment = NULL, string $return_type, bool $is_strict = NULL)
* @method static bool method_remove(string $classname, string $methodname)
* @method static bool method_rename(string $classname, string $methodname, string $newname)
* @method static int object_id(object $obj)
* @method static array superglobals()
* @method static array zval_inspect(string $value)
* phpcs:enable Generic.Files.LineLength.TooLong
*/
class Runkit
{
/**
* Dynamically alias methods to the underlying Runkit functions.
*
* @throws \BadFunctionCallException if the underlying function does not exist.
*
* @param string $name The method name.
* @param mixed[] $args Method arguments.
*
* @return mixed The return value of the corresponding runkit(7)_* functions.
*/
public static function __callStatic($name, array $args = [])
{
if (function_exists('runkit7_' . $name)) {
return call_user_func_array('runkit7_' . $name, $args);
}

if (function_exists('runkit_' . $name)) {
return call_user_func_array('runkit_' . $name, $args);
}

throw new \BadFunctionCallException(sprintf(
'Runkit7 does not include a runkit7_%1$s() function.',
$name
));
}
}
8 changes: 4 additions & 4 deletions tests/ConstantsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static function defineConstants()
*/
public function setConstant_should_be_able_to_handle_newly_defined_constants()
{
$this->requiresRunkit('This test depends on runkit being unavailable.');
$this->requiresRunkit('This test depends on runkit being available.');

$this->assertFalse(defined('SOME_CONSTANT'));

Expand All @@ -48,7 +48,7 @@ public function setConstant_should_be_able_to_handle_newly_defined_constants()
*/
public function setConstant_should_be_able_to_redefine_existing_constants()
{
$this->requiresRunkit('This test depends on runkit being unavailable.');
$this->requiresRunkit('This test depends on runkit being available.');

$this->setConstant('EXISTING_CONSTANT', 'some other value');
$this->assertSame('some other value', constant('EXISTING_CONSTANT'));
Expand All @@ -67,7 +67,7 @@ public function setConstant_should_be_able_to_redefine_existing_constants()
*/
public function setConstant_should_throw_an_exception_if_it_cannot_redefine_a_constant()
{
$this->requiresRunkit('This test depends on runkit being unavailable.');
$this->requiresRunkit('This test depends on runkit being available.');

$this->expectException(RedefineException::class);
$this->setConstant('EXISTING_CONSTANT', (object) ['some' => 'object']);
Expand All @@ -85,7 +85,7 @@ public function setConstant_should_throw_an_exception_if_it_cannot_redefine_a_co
*/
public function deleteConstant_should_remove_an_existing_constant()
{
$this->requiresRunkit('This test depends on runkit being unavailable.');
$this->requiresRunkit('This test depends on runkit being available.');

$this->deleteConstant('DELETE_THIS_CONSTANT');
$this->assertFalse(defined('DELETE_THIS_CONSTANT'));
Expand Down

0 comments on commit 582f8db

Please sign in to comment.