Dustin Wilson
3 years ago
15 changed files with 68 additions and 453 deletions
@ -1,79 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* @license MIT |
|
||||
* Copyright 2017, Dustin Wilson, J. King et al. |
|
||||
* See LICENSE and AUTHORS files for details |
|
||||
*/ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace MensBeam\HTML\DOM; |
|
||||
|
|
||||
/** |
|
||||
* Getters and setters in PHP sucks. Instead of having getter and setter |
|
||||
* function types for classes we instead have the __get and __set magic methods |
|
||||
* to handle all properties. Not only are they unwieldy to use when you have |
|
||||
* many properties they also become difficult to handle when inheriting where |
|
||||
* traits are involved. This trait attempts to create hackish getter and setter |
|
||||
* functions that can be extended by simple inheritance. |
|
||||
*/ |
|
||||
trait MagicProperties { |
|
||||
public function __get(string $name) { |
|
||||
$methodName = $this->getMagicPropertyMethodName($name); |
|
||||
if ($methodName === null) { |
|
||||
throw new Exception(Exception::NONEXISTENT_PROPERTY, $name); |
|
||||
} |
|
||||
return call_user_func([ $this, $methodName ]); |
|
||||
} |
|
||||
|
|
||||
public function __isset(string $name): bool { |
|
||||
return ($this->getMagicPropertyMethodName($name) !== null); |
|
||||
} |
|
||||
|
|
||||
public function __set(string $name, $value) { |
|
||||
$methodName = $this->getMagicPropertyMethodName($name, false); |
|
||||
if ($methodName !== null) { |
|
||||
call_user_func([ $this, $methodName ], $value); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if ($this->getMagicPropertyMethodName($name) !== null) { |
|
||||
throw new Exception(Exception::READONLY_PROPERTY, $name); |
|
||||
} else { |
|
||||
throw new Exception(Exception::NONEXISTENT_PROPERTY, $name); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public function __unset(string $name) { |
|
||||
$methodName = $this->getMagicPropertyMethodName($name, false); |
|
||||
if ($methodName === null) { |
|
||||
throw new Exception(Exception::READONLY_PROPERTY, $name); |
|
||||
} |
|
||||
|
|
||||
call_user_func([ $this, $methodName ], null); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
// Method_exists is case-insensitive because methods are case-insensitive in |
|
||||
// PHP. Properties in PHP 8 are sensitive, so let's use reflection to check |
|
||||
// against the actual name to get a case sensitive match like methods should be! |
|
||||
private function getMagicPropertyMethodName(string $name, bool $get = true): ?string { |
|
||||
static $protectedMethodsList = null; |
|
||||
|
|
||||
$methodName = "__" . (($get) ? 'get' : 'set') . "_{$name}"; |
|
||||
if (method_exists($this, $methodName)) { |
|
||||
if ($protectedMethodsList === null) { |
|
||||
$reflector = new \ReflectionClass($this); |
|
||||
// Magic property methods are protected |
|
||||
$protectedMethodsList = $reflector->getMethods(\ReflectionMethod::IS_PROTECTED); |
|
||||
} |
|
||||
|
|
||||
foreach ($protectedMethodsList as $method) { |
|
||||
if ($method->name === $methodName) { |
|
||||
return $methodName; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return null; |
|
||||
} |
|
||||
} |
|
@ -1,17 +0,0 @@ |
|||||
module.exports = ctx => ({ |
|
||||
//map: ctx.options.map,
|
|
||||
parser: 'postcss-scss', |
|
||||
//syntax: 'postcss-scss',
|
|
||||
plugins: { |
|
||||
'postcss-import': { root: ctx.file.dirname }, |
|
||||
'postcss-discard-comments': {}, |
|
||||
'postcss-sassy-mixins': {}, |
|
||||
'postcss-custom-media': {preserve: false}, |
|
||||
'postcss-media-minmax': {}, |
|
||||
'postcss-custom-properties': {preserve: false}, |
|
||||
'postcss-color-function': {}, |
|
||||
'postcss-nested': {}, |
|
||||
'autoprefixer': {}, |
|
||||
'postcss-csso': {}, |
|
||||
} |
|
||||
}) |
|
@ -1,49 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* @license MIT |
|
||||
* Copyright 2017, Dustin Wilson, J. King et al. |
|
||||
* See LICENSE and AUTHORS files for details |
|
||||
*/ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace MensBeam\HTML\DOM\TestCase; |
|
||||
|
|
||||
use MensBeam\HTML\DOM\{ |
|
||||
DOMException, |
|
||||
Exception |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* @covers \MensBeam\HTML\DOM\DOMException |
|
||||
* @covers \MensBeam\HTML\DOM\Exception |
|
||||
*/ |
|
||||
class TestException extends \PHPUnit\Framework\TestCase { |
|
||||
public function provideConstructorFailures(): iterable { |
|
||||
return [ |
|
||||
[ function() { |
|
||||
$d = new DOMException(2112); |
|
||||
}, Exception::INVALID_CODE ], |
|
||||
[ function() { |
|
||||
$d = new Exception(2112); |
|
||||
}, Exception::INVALID_CODE ], |
|
||||
[ function() { |
|
||||
throw new DOMException(DOMException::NOT_FOUND, 'FAIL'); |
|
||||
}, Exception::INCORRECT_PARAMETERS_FOR_MESSAGE ], |
|
||||
[ function() { |
|
||||
throw new Exception(Exception::UNKNOWN_ERROR, 'FAIL'); |
|
||||
}, Exception::INCORRECT_PARAMETERS_FOR_MESSAGE ], |
|
||||
]; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* @dataProvider provideConstructorFailures |
|
||||
* @covers \MensBeam\HTML\DOM\DOMException::__construct |
|
||||
* @covers \MensBeam\HTML\DOM\Exception::__construct |
|
||||
*/ |
|
||||
public function testConstructorFailures(\Closure $closure, int $errorCode): void { |
|
||||
$this->expectException(Exception::class); |
|
||||
$this->expectExceptionCode($errorCode); |
|
||||
$closure(); |
|
||||
} |
|
||||
} |
|
@ -1,79 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* @license MIT |
|
||||
* Copyright 2017, Dustin Wilson, J. King et al. |
|
||||
* See LICENSE and AUTHORS files for details |
|
||||
*/ |
|
||||
|
|
||||
declare(strict_types=1); |
|
||||
namespace MensBeam\HTML\DOM\TestCase; |
|
||||
|
|
||||
use MensBeam\HTML\DOM\{ |
|
||||
Document, |
|
||||
Exception, |
|
||||
MagicProperties |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
/** @covers \MensBeam\HTML\DOM\MagicProperties */ |
|
||||
class TestMagicProperties extends \PHPUnit\Framework\TestCase { |
|
||||
public function provideFailures(): iterable { |
|
||||
return [ |
|
||||
[ function() { |
|
||||
$d = new Document(); |
|
||||
$d->omgWTFBBQ; |
|
||||
}, Exception::NONEXISTENT_PROPERTY ], |
|
||||
[ function() { |
|
||||
$d = new Document(); |
|
||||
$d->omgWTFBBQ = 'ook'; |
|
||||
}, Exception::NONEXISTENT_PROPERTY ], |
|
||||
[ function() { |
|
||||
$d = new Document(); |
|
||||
$d->xpath = 'ook'; |
|
||||
}, Exception::READONLY_PROPERTY ], |
|
||||
[ function() { |
|
||||
$d = new Document(); |
|
||||
unset($d->xpath); |
|
||||
}, Exception::READONLY_PROPERTY ] |
|
||||
]; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* @dataProvider provideFailures |
|
||||
* @covers \MensBeam\HTML\DOM\MagicProperties::__get |
|
||||
* @covers \MensBeam\HTML\DOM\MagicProperties::__set |
|
||||
* @covers \MensBeam\HTML\DOM\MagicProperties::__unset |
|
||||
*/ |
|
||||
public function testFailures(\Closure $closure, int $errorCode): void { |
|
||||
$this->expectException(Exception::class); |
|
||||
$this->expectExceptionCode($errorCode); |
|
||||
$closure(); |
|
||||
} |
|
||||
|
|
||||
/** @covers \MensBeam\HTML\DOM\MagicProperties::__isset */ |
|
||||
public function testIsset(): void { |
|
||||
$d = new Document(); |
|
||||
$this->assertTrue(isset($d->body)); |
|
||||
} |
|
||||
|
|
||||
/** @covers \MensBeam\HTML\DOM\MagicProperties::__unset */ |
|
||||
public function testUnset(): void { |
|
||||
// Nothing allows setting values to null yet, so make one |
|
||||
$d = new class { |
|
||||
use MagicProperties; |
|
||||
protected ?string $_ook = 'ook'; |
|
||||
|
|
||||
|
|
||||
protected function __get_ook(): ?string { |
|
||||
return $this->_ook; |
|
||||
} |
|
||||
|
|
||||
protected function __set_ook(?string $value): void { |
|
||||
$this->_ook = $value; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
unset($d->ook); |
|
||||
$this->assertNull($d->ook); |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue