Dustin Wilson
3 months ago
commit
f3645a5f77
11 changed files with 1955 additions and 0 deletions
@ -0,0 +1,76 @@ |
|||
# Project-specific |
|||
/test*.* |
|||
/test/ |
|||
/test/* |
|||
|
|||
# General |
|||
*.DS_Store |
|||
.AppleDouble |
|||
.LSOverride |
|||
|
|||
# Icon must end with two \r |
|||
Icon |
|||
|
|||
|
|||
# Thumbnails |
|||
._* |
|||
|
|||
# Files that might appear in the root of a volume |
|||
.DocumentRevisions-V100 |
|||
.fseventsd |
|||
.Spotlight-V100 |
|||
.TemporaryItems |
|||
.Trashes |
|||
.VolumeIcon.icns |
|||
.com.apple.timemachine.donotpresent |
|||
|
|||
# Directories potentially created on remote AFP share |
|||
.AppleDB |
|||
.AppleDesktop |
|||
Network Trash Folder |
|||
Temporary Items |
|||
.apdisk |
|||
|
|||
# Windows thumbnail cache files |
|||
Thumbs.db |
|||
ehthumbs.db |
|||
ehthumbs_vista.db |
|||
|
|||
# Dump file |
|||
*.stackdump |
|||
|
|||
# Folder config file |
|||
Desktop.ini |
|||
|
|||
# Recycle Bin used on file shares |
|||
$RECYCLE.BIN/ |
|||
|
|||
# Windows Installer files |
|||
*.cab |
|||
*.msi |
|||
*.msm |
|||
*.msp |
|||
|
|||
# Windows shortcuts |
|||
*.lnk |
|||
|
|||
*~ |
|||
|
|||
# temporary files which can be created if a process still has a handle open of a deleted file |
|||
.fuse_hidden* |
|||
|
|||
# KDE directory preferences |
|||
.directory |
|||
|
|||
# Linux trash folder which might appear on any partition or disk |
|||
.Trash-* |
|||
|
|||
# .nfs files are created when an open file is removed but is still being accessed |
|||
.nfs* |
|||
|
|||
/vendor/ |
|||
/vendor-bin/*/vendor |
|||
/tests/html5lib-tests |
|||
/tests/.phpunit.*cache |
|||
/tests/coverage |
|||
cachegrind.out.* |
@ -0,0 +1,4 @@ |
|||
Project leads |
|||
------------- |
|||
Dustin Wilson https://dustinwilson.com/ |
|||
J. King https://jkingweb.ca/ |
@ -0,0 +1,22 @@ |
|||
Copyright (c) 2024 Dustin Wilson, J. King |
|||
|
|||
Permission is hereby granted, free of charge, to any person |
|||
obtaining a copy of this software and associated documentation |
|||
files (the "Software"), to deal in the Software without |
|||
restriction, including without limitation the rights to use, |
|||
copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the |
|||
Software is furnished to do so, subject to the following |
|||
conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be |
|||
included in all copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|||
OTHER DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,37 @@ |
|||
# Self-Sealing Callable # |
|||
|
|||
> You won't find a better Self-Sealing Callable in this sector! |
|||
|
|||
_Self-Sealing Callable_ is a class that implements `__invoke()` which can enable and disable itself. When registering shutdown functions in PHP it's not possible to unregister them. This class exists to be used in this case. By calling `SelfSealingCallable->disable()` it will return `false` when invoked, allowing retroactive disabling of the shutdown handler. |
|||
|
|||
|
|||
## Requirements ## |
|||
|
|||
* PHP 8.1 |
|||
|
|||
|
|||
## Installation ## |
|||
|
|||
```shell |
|||
composer require mensbeam/self-sealing-callable |
|||
``` |
|||
|
|||
|
|||
## Usage ## |
|||
|
|||
It's pretty simple: |
|||
|
|||
```php |
|||
use MensBeam\SelfSealingCallable; |
|||
|
|||
$callable = new SelfSealingCallable(fn() => 'ook'); |
|||
$ook = $callable(); |
|||
// 'ook' |
|||
$callable->disable(); |
|||
$ook = $callable(); |
|||
// false |
|||
$callable->enable(); |
|||
$ook = $callable(); |
|||
// 'ook' |
|||
|
|||
``` |
@ -0,0 +1,23 @@ |
|||
{ |
|||
"name": "mensbeam/self-sealing-callable", |
|||
"description": "You won't find a better Self-Sealing Callable in this sector!", |
|||
"type": "library", |
|||
"license": "MIT", |
|||
"autoload": { |
|||
"psr-4": { |
|||
"MensBeam\\": "lib/" |
|||
} |
|||
}, |
|||
"authors": [ |
|||
{ |
|||
"name": "Dustin Wilson", |
|||
"email": "dustin@dustinwilson.com" |
|||
} |
|||
], |
|||
"require": { |
|||
"php": ">=8.1" |
|||
}, |
|||
"require-dev": { |
|||
"phpunit/phpunit": "^11.0" |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,42 @@ |
|||
<?php |
|||
/** |
|||
* @license MIT |
|||
* Copyright 2024 Dustin Wilson, et al. |
|||
* See LICENSE and AUTHORS files for details |
|||
*/ |
|||
|
|||
declare(strict_types=1); |
|||
namespace MensBeam; |
|||
|
|||
|
|||
class SelfSealingCallable { |
|||
protected \Closure $callable; |
|||
protected bool $enabled; |
|||
|
|||
|
|||
|
|||
|
|||
public function __construct(callable $callable) { |
|||
$this->callable = \Closure::fromCallable($callable); |
|||
$this->enabled = true; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
public function __invoke(): mixed { |
|||
if ($this->enabled === false) { |
|||
return false; |
|||
} |
|||
|
|||
return ($this->callable)(); |
|||
} |
|||
|
|||
public function disable() { |
|||
$this->enabled = false; |
|||
} |
|||
|
|||
public function enable() { |
|||
$this->enabled = true; |
|||
} |
|||
} |
@ -0,0 +1,38 @@ |
|||
#!/usr/bin/env php |
|||
<?php |
|||
/** |
|||
* @license MIT |
|||
* Copyright 2022 Dustin Wilson, et al. |
|||
* See LICENSE and AUTHORS files for details |
|||
*/ |
|||
|
|||
$dir = ini_get('extension_dir'); |
|||
$php = escapeshellarg(\PHP_BINARY); |
|||
$code = escapeshellarg(__DIR__ . '/lib'); |
|||
|
|||
|
|||
array_shift($argv); |
|||
foreach ($argv as $k => $v) { |
|||
if (in_array($v, ['--coverage', '--coverage-html'])) { |
|||
$argv[$k] = '--coverage-html tests/coverage'; |
|||
} |
|||
} |
|||
|
|||
$cmd = [ |
|||
$php, |
|||
'-d opcache.enable_cli=0', |
|||
]; |
|||
|
|||
if (!extension_loaded('xdebug')) { |
|||
$cmd[] = '-d zend_extension=xdebug.so'; |
|||
} |
|||
|
|||
$cmd = implode(' ', [ |
|||
...$cmd, |
|||
'-d xdebug.mode=coverage,develop,trace', |
|||
escapeshellarg(__DIR__ . '/vendor/bin/phpunit'), |
|||
'--configuration tests/phpunit.xml', |
|||
...$argv, |
|||
'--display-deprecations' |
|||
]); |
|||
passthru($cmd); |
@ -0,0 +1,18 @@ |
|||
<?php |
|||
declare(strict_types=1); |
|||
namespace MensBeam\SelfSealingCallable\Test; |
|||
|
|||
ini_set('memory_limit', '2G'); |
|||
ini_set('zend.assertions', '1'); |
|||
ini_set('assert.exception', 'true'); |
|||
error_reporting(\E_ALL); |
|||
define('CWD', dirname(__DIR__)); |
|||
require_once CWD . '/vendor/autoload.php'; |
|||
|
|||
if (function_exists('xdebug_set_filter')) { |
|||
if (defined('XDEBUG_PATH_INCLUDE')) { |
|||
xdebug_set_filter(\XDEBUG_FILTER_CODE_COVERAGE, \XDEBUG_PATH_INCLUDE, [ CWD . '/lib/' ]); |
|||
} else { |
|||
xdebug_set_filter(\XDEBUG_FILTER_CODE_COVERAGE, \XDEBUG_PATH_WHITELIST, [ CWD . '/lib/' ]); |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
<?php |
|||
/** |
|||
* @license MIT |
|||
* Copyright 2024 Dustin Wilson, et al. |
|||
* See LICENSE and AUTHORS files for details |
|||
*/ |
|||
|
|||
declare(strict_types=1); |
|||
namespace MensBeam\SelfSealingCallable\Test; |
|||
use MensBeam\SelfSealingCallable; |
|||
use PHPUnit\Framework\{ |
|||
TestCase, |
|||
Attributes\CoversClass, |
|||
Attributes\DataProvider |
|||
}; |
|||
|
|||
|
|||
#[CoversClass('MensBeam\SelfSealingCallable')] |
|||
class TestSelfSealingCallable extends TestCase { |
|||
public function testInvocation(): void { |
|||
$c = new SelfSealingCallable(fn() => 'ook'); |
|||
$this->assertSame('ook', $c()); |
|||
$c->disable(); |
|||
$this->assertFalse($c()); |
|||
$c->enable(); |
|||
$this->assertSame('ook', $c()); |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" |
|||
beStrictAboutOutputDuringTests="true" |
|||
beStrictAboutTestsThatDoNotTestAnything="true" |
|||
bootstrap="bootstrap.php" |
|||
cacheDirectory=".phpunit.cache" |
|||
colors="true" |
|||
executionOrder="defects" |
|||
requireCoverageMetadata="true" |
|||
> |
|||
<testsuites> |
|||
<testsuite name="Main"> |
|||
<directory prefix="Test" suffix=".php">./cases</directory> |
|||
</testsuite> |
|||
</testsuites> |
|||
<coverage/> |
|||
<source> |
|||
<include> |
|||
<directory suffix=".php">../lib</directory> |
|||
</include> |
|||
</source> |
|||
</phpunit> |
Loading…
Reference in new issue