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