diff --git a/composer.json b/composer.json index f31e02219d..080a4a55dd 100644 --- a/composer.json +++ b/composer.json @@ -6,15 +6,11 @@ "type": "library", "license": "GPL-3.0", "authors": [ - { - "name": "Konstantin Arkhipov" - }, - { - "name": "Anton Lebedevich" - } + { "name": "Konstantin Arkhipov" }, + { "name": "Anton Lebedevich" } ], "require": { - "php": ">=7.3.0" + "php": ">=7.4" }, "conflict": { "ext-http": "*" diff --git a/global.inc.php.tpl b/global.inc.php.tpl index 13f61f3109..ff30c99a66 100644 --- a/global.inc.php.tpl +++ b/global.inc.php.tpl @@ -11,7 +11,7 @@ // sample system-wide configuration file -function error2Exception($code, $string, $file, $line, $context) +function error2Exception($code, $string, $file, $line) { throw new \OnPHP\Core\Exception\BaseException($string, $code); } diff --git a/src/Core/Base/Aliased.php b/src/Core/Base/Aliased.php index 5bc96a1c6c..c6bdf3a8b5 100644 --- a/src/Core/Base/Aliased.php +++ b/src/Core/Base/Aliased.php @@ -18,5 +18,4 @@ interface Aliased { public function getAlias(); -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/Core/Base/Assert.php b/src/Core/Base/Assert.php index e6e78948a6..4f05fde6fa 100644 --- a/src/Core/Base/Assert.php +++ b/src/Core/Base/Assert.php @@ -1,5 +1,4 @@ $second)) throw new WrongArgumentException( @@ -239,7 +373,13 @@ public static function isGreater($first, $second, $message = null) ); } - public static function isLesserOrEqual($first, $second, $message = null) + /** + * @param $first + * @param $second + * @param string|null $message + * @throws WrongArgumentException + */ + public static function isLesserOrEqual($first, $second, string $message = null): void { if (!($first <= $second)) throw new WrongArgumentException( @@ -247,7 +387,13 @@ public static function isLesserOrEqual($first, $second, $message = null) ); } - public static function isGreaterOrEqual($first, $second, $message = null) + /** + * @param $first + * @param $second + * @param string|null $message + * @throws WrongArgumentException + */ + public static function isGreaterOrEqual($first, $second, string $message = null): void { if (!($first >= $second)) throw new WrongArgumentException( @@ -255,15 +401,27 @@ public static function isGreaterOrEqual($first, $second, $message = null) ); } - public static function isInstance($first, $second, $message = null) + /** + * @param $first + * @param $second + * @param string|null $message + * @throws WrongArgumentException + */ + public static function isInstance($first, $second, string $message = null): void { if (!ClassUtils::isInstanceOf($first, $second)) throw new WrongArgumentException( $message.', '.self::dumpOppositeArguments($first, $second) ); } - - public static function isSameClasses($left, $right, $message = null) + + /** + * @param $left + * @param $right + * @param string|null $message + * @throws WrongArgumentException + */ + public static function isSameClasses($left, $right, string $message = null) { if (!ClassUtils::isSameClassNames($left, $right)) throw new WrongArgumentException( @@ -271,7 +429,12 @@ public static function isSameClasses($left, $right, $message = null) ); } - public static function classExists($className, $message = null) + /** + * @param $className + * @param string|null $message + * @throws ClassNotFoundException + */ + public static function classExists($className, string $message = null): void { if (!class_exists($className, true)) throw new ClassNotFoundException( @@ -279,7 +442,14 @@ public static function classExists($className, $message = null) ); } - public static function methodExists($object, $method, $message = null) + /** + * Checks if the class method exists + * @param $object An object instance or a class name + * @param string $method The method name + * @param string|null $message + * @throws WrongArgumentException + */ + public static function methodExists($object, string $method, string $message = null): void { if (!method_exists($object, $method)) throw new WrongArgumentException( @@ -287,12 +457,21 @@ public static function methodExists($object, $method, $message = null) ); } - public static function isUnreachable($message = 'unreachable code reached') + /** + * @param string $message + * @throws WrongArgumentException + */ + public static function isUnreachable(string $message = 'unreachable code reached'): void { throw new WrongArgumentException($message); } - public static function isObject($object, $message = null) + /** + * @param mixed $object + * @param string|null $message + * @throws WrongArgumentException + */ + public static function isObject($object, string $message = null): void { if (!is_object($object)) throw new WrongArgumentException( @@ -300,9 +479,11 @@ public static function isObject($object, $message = null) ); } - /// exceptionless methods - //@{ - public static function checkInteger($value) + /** + * @param mixed $value + * @return bool + */ + public static function checkInteger($value): bool { return ( is_numeric($value) @@ -311,7 +492,11 @@ public static function checkInteger($value) ); } - public static function checkFloat($value) + /** + * @param mixed $value + * @return bool + */ + public static function checkFloat($value): bool { return ( is_numeric($value) @@ -319,22 +504,34 @@ public static function checkFloat($value) ); } - public static function checkScalar($value) + /** + * @param mixed $value + * @return bool + */ + public static function checkScalar($value): bool { return is_scalar($value); } - public static function dumpArgument($argument) + /** + * @param mixed $argument + * @return string + */ + public static function dumpArgument($argument): string { return 'argument: ['.print_r($argument, true).']'; } - public static function dumpOppositeArguments($first, $second) + /** + * Dump two arguments as string + * @param mixed $first + * @param mixed $second + * @return string + */ + public static function dumpOppositeArguments($first, $second): string { return 'arguments: ['.print_r($first, true).'] ' .'vs. ['.print_r($second, true).'] '; } - //@} -} -?> +} \ No newline at end of file diff --git a/src/Core/Base/Singleton.php b/src/Core/Base/Singleton.php index 9abacb3cb1..3d5325cf3b 100644 --- a/src/Core/Base/Singleton.php +++ b/src/Core/Base/Singleton.php @@ -21,21 +21,22 @@ **/ abstract class Singleton { - private static $instances = array(); + private static array $instances = []; protected function __construct() {/* you can't create me */} - /// @example singleton.php - final public static function getInstance( - $class, $args = null /* , ... */ - ) + /** + * @param string $class + * @param ...$args + * @return object + * @throws MissingElementException + * @throws \OnPHP\Core\Exception\WrongArgumentException + */ + final public static function getInstance(string $class, ...$args): object { if (!isset(self::$instances[$class])) { // for Singleton::getInstance('class_name', $arg1, ...) calling - if (2 < func_num_args()) { - $args = func_get_args(); - array_shift($args); - + if (1 < count($args)) { // emulation of ReflectionClass->newInstanceWithoutConstructor $object = unserialize( @@ -50,12 +51,11 @@ final public static function getInstance( try { $object = $args - ? new $class($args) + ? new $class(...$args) : new $class(); - } catch (\ArgumentCountError $e) { + } catch (\ArgumentCountError $exception) { throw new MissingElementException('Too few arguments to __constructor'); } - } Assert::isTrue( @@ -69,12 +69,19 @@ final public static function getInstance( return self::$instances[$class]; } - final public static function getAllInstances() + /** + * @return object[] + */ + final public static function getAllInstances(): array { return self::$instances; } - /* void */ final public static function dropInstance($class) + /** + * @param string $class + * @throws MissingElementException + */ + final public static function dropInstance(string $class): void { if (!isset(self::$instances[$class])) throw new MissingElementException('knows nothing about '.$class); @@ -82,7 +89,6 @@ final public static function getAllInstances() unset(self::$instances[$class]); } - final private function __clone() {/* do not clone me */} - final private function __sleep() {/* restless class */} -} -?> + final public function __clone() {/* do not clone me */} + final public function __sleep() {/* restless class */} +} \ No newline at end of file diff --git a/src/Core/Base/StaticFactory.php b/src/Core/Base/StaticFactory.php index 7f8790b1ab..484b539d18 100644 --- a/src/Core/Base/StaticFactory.php +++ b/src/Core/Base/StaticFactory.php @@ -20,5 +20,4 @@ abstract class StaticFactory { final private function __construct() {/*_*/} -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/Core/Cache/BaseAggregateCache.php b/src/Core/Cache/BaseAggregateCache.php index 8e1d471fbd..b1744c4f1f 100644 --- a/src/Core/Cache/BaseAggregateCache.php +++ b/src/Core/Cache/BaseAggregateCache.php @@ -114,7 +114,10 @@ public function get($key) { $label = $this->guessLabel($key); - if ($this->peers[$label]['object']->isAlive()) { + if ( + ($peer = ($this->peers[$label]['object'] ?? null)) !== null + && $peer->isAlive() + ) { return $this->peers[$label]['object']->get($key); } else { $this->checkAlive(); diff --git a/src/Core/Cache/CyclicAggregateCache.php b/src/Core/Cache/CyclicAggregateCache.php index eb1dd849e2..1caab74263 100644 --- a/src/Core/Cache/CyclicAggregateCache.php +++ b/src/Core/Cache/CyclicAggregateCache.php @@ -72,7 +72,7 @@ protected function guessLabel($key) next($this->peers); } - if ($point <= ($firstPeer['mountPoint'] + $this->summaryWeight)) { + if ($point <= (($firstPeer['mountPoint'] ?? 0) + $this->summaryWeight)) { reset($this->peers); return key($this->peers); diff --git a/src/Core/DB/PgSQL.php b/src/Core/DB/PgSQL.php index d6ee2ad44f..edb37978f3 100644 --- a/src/Core/DB/PgSQL.php +++ b/src/Core/DB/PgSQL.php @@ -105,7 +105,6 @@ public function setDbEncoding() /** * query methods **/ - public function queryRaw($queryString) { try { @@ -113,7 +112,7 @@ public function queryRaw($queryString) } catch (BaseException $e) { // manual parsing, since pg_send_query() and // pg_get_result() is too slow in our case - list($error, ) = explode("\n", pg_errormessage($this->link)); + list($error, ) = explode("\n", pg_last_error($this->link)); $code = substr($error, 8, 5); if ($code == PostgresError::UNIQUE_VIOLATION) { diff --git a/src/Core/Exception/ClassNotFoundException.php b/src/Core/Exception/ClassNotFoundException.php index 7f45ca811d..6d27afd86a 100644 --- a/src/Core/Exception/ClassNotFoundException.php +++ b/src/Core/Exception/ClassNotFoundException.php @@ -15,5 +15,4 @@ * @ingroup Exceptions * @ingroup Module **/ -final class ClassNotFoundException extends BaseException {/*_*/} -?> +final class ClassNotFoundException extends BaseException {/*_*/} \ No newline at end of file diff --git a/src/Main/Markup/Html/HtmlAssembler.php b/src/Main/Markup/Html/HtmlAssembler.php index 2143e1b97f..a6a0c45217 100644 --- a/src/Main/Markup/Html/HtmlAssembler.php +++ b/src/Main/Markup/Html/HtmlAssembler.php @@ -123,7 +123,7 @@ private static function getAttributes(SgmlOpenTag $tag) $quotedValue = null; else // FIXME: is multibyte safe? - $quotedValue = '="'.str_replace('"', '"', $value).'"'; + $quotedValue = '="'.preg_replace('/\"/u', '"', $value).'"'; $attributes[] = $name.$quotedValue; } diff --git a/src/Main/Markup/Html/SgmlIgnoredTag.php b/src/Main/Markup/Html/SgmlIgnoredTag.php index b7ac23d713..3a8df5cc75 100644 --- a/src/Main/Markup/Html/SgmlIgnoredTag.php +++ b/src/Main/Markup/Html/SgmlIgnoredTag.php @@ -70,12 +70,12 @@ public function getEndMark() public function isComment() { - return $this->id == '!--'; + return $this->getId() == '!--'; } public function isExternal() { - return ($this->id && $this->id[0] == '?'); + return mb_substr($this->getId() ?? '', 0, 1) == '?'; } } ?> \ No newline at end of file diff --git a/src/Main/UnifiedContainer/ManyToManyLinkedFull.php b/src/Main/UnifiedContainer/ManyToManyLinkedFull.php index c9b62f5ebe..edeb88b330 100644 --- a/src/Main/UnifiedContainer/ManyToManyLinkedFull.php +++ b/src/Main/UnifiedContainer/ManyToManyLinkedFull.php @@ -22,7 +22,7 @@ final class ManyToManyLinkedFull extends ManyToManyLinkedWorker /** * @return ManyToManyLinkedFull **/ - public function sync($insert, $update = array(), $delete) + public function sync($insert, $update = [], $delete = []) { $dao = $this->container->getDao(); diff --git a/src/Main/UnifiedContainer/ManyToManyLinkedLazy.php b/src/Main/UnifiedContainer/ManyToManyLinkedLazy.php index 496dfc80b6..4d5efda5fb 100644 --- a/src/Main/UnifiedContainer/ManyToManyLinkedLazy.php +++ b/src/Main/UnifiedContainer/ManyToManyLinkedLazy.php @@ -26,7 +26,7 @@ final class ManyToManyLinkedLazy extends ManyToManyLinkedWorker * @throws WrongArgumentException * @return ManyToManyLinkedLazy **/ - public function sync($insert, $update = array(), $delete) + public function sync($insert, $update = [], $delete = []) { Assert::isTrue($update === array()); diff --git a/src/Main/UnifiedContainer/OneToManyLinkedFull.php b/src/Main/UnifiedContainer/OneToManyLinkedFull.php index df6a226a2e..2b14c4507d 100644 --- a/src/Main/UnifiedContainer/OneToManyLinkedFull.php +++ b/src/Main/UnifiedContainer/OneToManyLinkedFull.php @@ -34,7 +34,7 @@ public function makeFetchQuery() /** * @return OneToManyLinkedFull **/ - public function sync($insert, $update = array(), $delete) + public function sync($insert, $update = [], $delete = []) { $uc = $this->container; $dao = $uc->getDao(); diff --git a/src/Main/UnifiedContainer/OneToManyLinkedLazy.php b/src/Main/UnifiedContainer/OneToManyLinkedLazy.php index 0660259d1f..7e08a22949 100644 --- a/src/Main/UnifiedContainer/OneToManyLinkedLazy.php +++ b/src/Main/UnifiedContainer/OneToManyLinkedLazy.php @@ -41,7 +41,7 @@ public function makeFetchQuery() * @throws WrongArgumentException * @return OneToManyLinkedLazy **/ - public function sync($insert, $update = array(), $delete) + public function sync($insert, $update = [], $delete = []) { Assert::isTrue($update === array()); diff --git a/src/Main/UnifiedContainer/UnifiedContainerWorker.php b/src/Main/UnifiedContainer/UnifiedContainerWorker.php index 8586e79ade..d617ee7cb3 100644 --- a/src/Main/UnifiedContainer/UnifiedContainerWorker.php +++ b/src/Main/UnifiedContainer/UnifiedContainerWorker.php @@ -31,7 +31,7 @@ abstract class UnifiedContainerWorker protected $container = null; abstract public function makeFetchQuery(); - abstract public function sync($insert, $update = array(), $delete); + abstract public function sync($insert, $update = [], $delete = []); public function __construct(UnifiedContainer $uc) { diff --git a/src/Main/Util/ArrayUtils.php b/src/Main/Util/ArrayUtils.php index 5e48d71616..afefe9d55c 100644 --- a/src/Main/Util/ArrayUtils.php +++ b/src/Main/Util/ArrayUtils.php @@ -14,6 +14,7 @@ use OnPHP\Core\Base\Assert; use OnPHP\Core\Base\Identifiable; use OnPHP\Core\Base\StaticFactory; +use OnPHP\Core\Exception\WrongArgumentException; use OnPHP\Main\Base\Comparator; /** @@ -38,6 +39,9 @@ public static function regularizeList($ids, $objects) return $result; } + /** + * @todo - добавить третий аргумент для аналогии с array_column + */ public static function convertObjectList($list = null, $getter = 'getId') { $out = array(); @@ -51,34 +55,40 @@ public static function convertObjectList($list = null, $getter = 'getId') return $out; } - public static function getIdsArray($objectsList) + /** + * @param array $objectsList + * @return Identifiable[] + * @throws WrongArgumentException + */ + public static function getIdsArray(array $objectsList): array { - $out = array(); - - if (!$objectsList) - return $out; - - Assert::isInstance( - current($objectsList), Identifiable::class, - 'only identifiable lists accepted' - ); - - foreach ($objectsList as $object) - $out[] = $object->getId(); + if (empty($objectsList)) { + return []; + } - return $out; + return array_map(function ($objectItem) { + Assert::isInstance($objectItem, Identifiable::class,'only identifiable lists accepted'); + return $objectItem->getId(); + }, $objectsList); } - public static function &convertToPlainList($list, $key) + /** + * @param array $list + * @param mixed $key + * @return array + */ + public static function convertToPlainList(array $list, $key): array { - $out = array(); - - foreach ($list as $obj) - $out[] = $obj[$key]; - - return $out; + return array_filter( + array_column($list, $key) + ); } + /** + * @param $array + * @param $var + * @return mixed|null + */ public static function getArrayVar(&$array, $var) { if (isset($array[$var]) && !empty($array[$var])) { @@ -89,29 +99,32 @@ public static function getArrayVar(&$array, $var) return null; } - public static function columnFromSet($column, $array) + /** + * @param $column + * @param array $array + * @return array + * @deprecated by [[self::convertToPlainList]] + */ + public static function columnFromSet($column, array $array): array { - Assert::isArray($array); - $result = array(); - - foreach ($array as $row) - if (isset($row[$column])) - $result[] = $row[$column]; - - return $result; + return array_filter( + array_column($array, $column) + ); } - public static function mergeUnique(/* ... */) + /** + * @param array ...$arguments + * @return array + * @throws WrongArgumentException + */ + public static function mergeUnique(...$arguments): array { - $arguments = func_get_args(); - - Assert::isArray(reset($arguments)); + array_map(function ($array) { + Assert::isArray($array); + }, $arguments); return array_unique( - call_user_func_array( - 'array_merge', - $arguments - ) + array_merge(...$arguments) ); } diff --git a/src/Main/Util/ClassUtils.php b/src/Main/Util/ClassUtils.php index 4f24ad8c19..a9cbf93b1d 100644 --- a/src/Main/Util/ClassUtils.php +++ b/src/Main/Util/ClassUtils.php @@ -11,6 +11,8 @@ namespace OnPHP\Main\Util; +use ReflectionClass; +use ReflectionException; use OnPHP\Core\Base\Assert; use OnPHP\Core\Base\StaticFactory; use OnPHP\Core\Exception\ClassNotFoundException; @@ -21,14 +23,22 @@ **/ final class ClassUtils extends StaticFactory { -// const CLASS_NAME_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'; - const CLASS_NAME_PATTERN = '(\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+'; // new one with namespaces - - /* void */ public static function copyProperties($source, $destination) + const CLASS_NAME_PATTERN = '(\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+'; + + /** + * Copy only public and protected object properties fetch + * allowed by get... methods and set by set... methods. + * Be careful, private properties from parent class not copied! + * @param object $source + * @param object $destination + * @throws WrongArgumentException + * @throws ReflectionException + */ + public static function copyProperties(object $source, object $destination): void { - Assert::isEqual(get_class($source), get_class($destination)); + Assert::isSameClasses(get_class($source), get_class($destination)); - $class = new \ReflectionClass($source); + $class = new ReflectionClass($source); foreach ($class->getProperties() as $property) { $name = ucfirst($property->getName()); @@ -36,33 +46,45 @@ final class ClassUtils extends StaticFactory $setter = 'set'.$name; if ( - ($class->hasMethod($getter)) - && ($class->hasMethod($setter)) + !method_exists($source, $getter) + || !is_callable([$source, $getter]) + || !method_exists($destination, $setter) + || !is_callable([$destination, $setter]) ) { + continue; + } - $sourceValue = $source->$getter(); - - if ($sourceValue === null) { - - $setMethood = $class->getMethod($setter); - $parameterList = $setMethood->getParameters(); - $firstParameter = $parameterList[0]; - - if ($firstParameter->allowsNull()) - $destination->$setter($sourceValue); + $sourceValue = $source->$getter(); + if ($sourceValue !== null) { + $destination->$setter($sourceValue); + } else { + $dropper = 'drop'.$name; - } else { + if ( + ($firstArg = $class->getMethod($setter)->getParameters()[0] ?? null) !== null + && $firstArg->allowsNull() === true + ) { $destination->$setter($sourceValue); + } elseif ( + method_exists($destination, $dropper) + && is_callable([$destination, $dropper]) + ) { + $destination->$dropper(); } } } } - /* void */ public static function copyNotNullProperties($source, $destination) + /** + * @param object $source + * @param object $destination + * @throws WrongArgumentException + */ + public static function copyNotNullProperties(object $source, object $destination): void { - Assert::isTrue(get_class($source) == get_class($destination)); + Assert::isEqual(get_class($source), get_class($destination)); - $class = new \ReflectionClass($source); + $class = new ReflectionClass($source); foreach ($class->getProperties() as $property) { $name = ucfirst($property->getName()); @@ -70,21 +92,27 @@ final class ClassUtils extends StaticFactory $setter = 'set'.$name; if ( - ($class->hasMethod($getter)) - && ($class->hasMethod($setter)) + method_exists($source, $getter) + && is_callable([$source, $getter]) + && method_exists($destination, $setter) + && is_callable([$destination, $setter]) + && ($value = $source->$getter()) !== null ) { - $value = $source->$getter(); - if ($value !== null) - $destination->$setter($value); + $destination->$setter($value); } } } - /* void */ public static function fillNullProperties($source, $destination) + /** + * @param object $source + * @param object $destination + * @throws WrongArgumentException + */ + public static function fillNullProperties(object $source, object $destination): void { - Assert::isTrue(get_class($source) == get_class($destination)); + Assert::isEqual(get_class($source), get_class($destination)); - $class = new \ReflectionClass($source); + $class = new ReflectionClass($source); foreach ($class->getProperties() as $property) { $name = ucfirst($property->getName()); @@ -92,31 +120,40 @@ final class ClassUtils extends StaticFactory $setter = 'set'.$name; if ( - ($class->hasMethod($getter)) - && ($class->hasMethod($setter)) + method_exists($source, $getter) + && is_callable([$source, $getter]) + && method_exists($destination, $setter) + && is_callable([$destination, $setter]) + && null === $destination->$getter() + && ( + null !== ($sourceValue = $source->$getter()) + ) ) { - $destinationValue = $destination->$getter(); - $sourceValue = $source->$getter(); - - if ( - ($destinationValue === null) - && ($sourceValue !== null) - ) { - $destination->$setter($sourceValue); - } + $destination->$setter($sourceValue); } } } - public static function isClassName($className) + /** + * @param mixed $className + * @return bool + */ + public static function isClassName($className): bool { - if (!is_string($className)) + if (!is_string($className)) { return false; + } - return preg_match('/^'.self::CLASS_NAME_PATTERN.'$/', $className) > 0; + return preg_match('/^'.self::CLASS_NAME_PATTERN.'$/', $className) === 1; } - - public static function isSameClassNames($left, $right) + + /** + * @param mixed $left + * @param mixed $right + * @return bool + * @throws WrongArgumentException + */ + public static function isSameClassNames($left, $right): bool { if ( ( @@ -131,92 +168,111 @@ public static function isSameClassNames($left, $right) return '\\'.ltrim($left, '\\') == '\\'.ltrim($right, '\\'); } - throw new WrongArgumentException('strange class given'); + throw new WrongArgumentException( + 'strange class given ' + . Assert::dumpOppositeArguments($left, $right) + ); } - /// to avoid dependency on SPL's class_implements - public static function isClassImplements($what) + /** + * @param mixed $what + * @param bool $autoload + * @return array + * @throws ClassNotFoundException + * @todo remove use function class_implemets in future, it`s removed in PHP 8 + */ + public static function isClassImplements($what, bool $autoload = true): array { static $classImplements = null; - if (!$classImplements) { - if (!function_exists('class_implements')) { - $classImplements = create_function( - '$what', - ' - $info = new \ReflectionClass($what); - return $info->getInterfaceNames(); - ' - ); - } else { + if (null === $classImplements) { + if (function_exists('class_implements')) { $classImplements = 'class_implements'; + } else { + $classImplements = function ($what, bool $autoload) { + $interfacesList = (new ReflectionClass($what)) + ->getInterfaceNames(); + return array_combine($interfacesList, $interfacesList); + }; } } - return $classImplements($what, true); + try { + $implements = $classImplements($what, $autoload); + } catch(\Throwable $exception) { + throw new ClassNotFoundException($what); + } + + return is_array($implements) ? $implements : []; } - public static function isInstanceOf($object, $class) + /** + * @param mixed $object + * @param mixed $class + * @return bool + * @throws WrongArgumentException + */ + public static function isInstanceOf($object, $class): bool { if (is_object($class)) { - $className = get_class($class); - } elseif (is_string($class)) { - $className = $class; - } else { - throw new WrongArgumentException('strange class given'); - } - - $className = '\\'.ltrim($className, '\\'); - - if (is_string($object)) { - $object = '\\'.ltrim($object, '\\'); - - if (self::isClassName($object)) { - if ($object == $className) { - return true; - } elseif (is_subclass_of($object, $className)) { - return true; - } else { - return in_array( - $class, - self::isClassImplements($object) - ); - } + if (is_object($object)) { + return $object instanceof $class; + } elseif (is_string($object)) { + return is_a($object, get_class($class), true); } - } elseif (is_object($object)) { - return $object instanceof $className; + } elseif ( + is_string($class) + && (is_object($object) || is_string($object)) + ) { + return is_a($object, $class, true); } - - throw new WrongArgumentException('strange object given'); + + Assert::isUnreachable('strange object or class given ' . Assert::dumpOppositeArguments($object, $class)); } - public static function callStaticMethod($methodSignature /* , ... */) + /** + * @param mixed $methodSignature + * @param ...$arguments + * @return mixed + * @throws ClassNotFoundException + * @throws WrongArgumentException + */ + public static function callStaticMethod($methodSignature, ...$arguments) { - $agruments = func_get_args(); - array_shift($agruments); - return call_user_func_array( self::checkStaticMethod($methodSignature), - $agruments + $arguments ); } - public static function checkStaticMethod($methodSignature) + /** + * @param mixed $methodSignature + * @return array + * @throws ClassNotFoundException + * @throws WrongArgumentException + */ + public static function checkStaticMethod($methodSignature): array { if (is_array($methodSignature)) { $nameParts = $methodSignature; - } else { + } elseif (is_string($methodSignature)) { $nameParts = explode('::', $methodSignature); + } else { + Assert::isUnreachable('Incorrect method signature ' . Assert::dumpArgument($methodSignature)); } - Assert::isEqual(count($nameParts), 2, 'Incorrect method signature'); + Assert::isEqual( + count($nameParts), + 2, + 'Incorrect method signature ' . Assert::dumpArgument($methodSignature) + ); list($className, $methodName) = $nameParts; try { - $class = new \ReflectionClass($className); - } catch (\ReflectionException $e) { + $class = new ReflectionClass($className); + } catch (ReflectionException $exception) { throw new ClassNotFoundException($className); } @@ -226,7 +282,6 @@ public static function checkStaticMethod($methodSignature) ); $method = $class->getMethod($methodName); - Assert::isTrue( $method->isStatic(), "method is not static '{$className}::{$methodName}'" @@ -239,28 +294,4 @@ public static function checkStaticMethod($methodSignature) return $nameParts; } - - /* void */ public static function preloadAllClasses() - { - foreach (explode(PATH_SEPARATOR, get_include_path()) as $directory) { - foreach ( - glob( - $directory.DIRECTORY_SEPARATOR.'/*'.EXT_CLASS, - GLOB_NOSORT - ) - as $file - ) { - $className = basename($file, EXT_CLASS); - - if ( - !class_exists($className) - && !interface_exists($className) - && !(function_exists('trait_exists') && trait_exists($className)) - ) { - include $file; - } - } - } - } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/Meta/Pattern/GenerationPattern.php b/src/Meta/Pattern/GenerationPattern.php index 8817e72a4c..b4dfc81a0f 100644 --- a/src/Meta/Pattern/GenerationPattern.php +++ b/src/Meta/Pattern/GenerationPattern.php @@ -28,6 +28,6 @@ public function daoExists(); public function tableExists(); /// forcing patterns to be singletones - public static function getInstance($class /*, $args = null*/); + public static function getInstance(string $class, ...$args): object; } ?> \ No newline at end of file diff --git a/tests/AllTests.php b/tests/AllTests.php index 22705d6f46..947b4d60db 100644 --- a/tests/AllTests.php +++ b/tests/AllTests.php @@ -47,7 +47,8 @@ final class AllTests public static function suite() { - $suite = new TestSuite('onPHP-'.ONPHP_VERSION); + $testSuiteName = 'onPHP-'.ONPHP_VERSION; + $suite = new TestSuite($testSuiteName); // meta, DB and DAOs ordered tests portion if (self::$dbs && self::checkRun()) { @@ -108,12 +109,18 @@ public static function suite() } foreach (self::$paths as $testPath) { - foreach (glob($testPath.'*Test'.EXT_CLASS, GLOB_BRACE) as $file) { - $suite->addTestFile($file); + /** Попробовать убрать ключ GLOB_BRACE, тем более он доступен не на всех системах */ + if (($files = glob($testPath.'*Test'.EXT_CLASS, GLOB_BRACE)) !== false) { + $suite->addTestFiles($files); } } - - return $suite; + + $listSuites = new \PHPUnit\Framework\TestSuite($testSuiteName); + for($i = 0; $i < count(self::$workers); $i++) { + $listSuites->addTestSuite(clone $suite); + } + + return $listSuites; } protected static function checkRun() diff --git a/tests/Core/Base/AliasedTest.php b/tests/Core/Base/AliasedTest.php new file mode 100644 index 0000000000..95b316b172 --- /dev/null +++ b/tests/Core/Base/AliasedTest.php @@ -0,0 +1,38 @@ +assertTrue($interface->isInterface()); + $this->assertTrue($interface->hasMethod('getAlias')); + $this->assertTrue($interface->getMethod('getAlias')->isPublic()); + } + + /** + * @throws \ReflectionException + */ + public function testClass() + { + $class = new \ReflectionClass(self::ALIASED_CLASS_NAME); + $this->assertTrue($class->implementsInterface(self::INTERFACE_NAME)); + $this->assertTrue($class->hasMethod('getAlias')); + $this->assertTrue($class->getMethod('getAlias')->isPublic()); + } +} \ No newline at end of file diff --git a/tests/Core/SingletonTest.php b/tests/Core/SingletonTest.php index 1ff0da27f1..5e5d9164bd 100644 --- a/tests/Core/SingletonTest.php +++ b/tests/Core/SingletonTest.php @@ -59,16 +59,10 @@ public function testCreationProhibition() $this->assertTrue( $child->getMethod('__sleep')->isFinal() ); - $this->assertTrue( - $child->getMethod('__sleep')->isPrivate() - ); $this->assertTrue( $child->getMethod('__clone')->isFinal() ); - $this->assertTrue( - $child->getMethod('__clone')->isPrivate() - ); } public function testMissingCleanup() diff --git a/tests/Main/ClassUtilsTest.php b/tests/Main/ClassUtilsTest.php index 0681d59bfb..8f1f426bd5 100644 --- a/tests/Main/ClassUtilsTest.php +++ b/tests/Main/ClassUtilsTest.php @@ -6,13 +6,18 @@ use OnPHP\Core\Base\Singleton; use OnPHP\Core\DB\ImaginaryDialect; use OnPHP\Core\Exception\ClassNotFoundException; +use OnPHP\Core\Exception\MissingElementException; use OnPHP\Core\Exception\WrongArgumentException; use OnPHP\Core\Form\Filters\UrlEncodeFilter; use OnPHP\Main\Util\ClassUtils; -use OnPHP\Tests\TestEnvironment\ClassUtilsTestAbstract; -use OnPHP\Tests\TestEnvironment\ClassUtilsTestClass; -use OnPHP\Tests\TestEnvironment\ClassUtilsTestClassChild; -use OnPHP\Tests\TestEnvironment\ClassUtilsTestInterface; +use OnPHP\Tests\Meta\Business\TestObject; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestAbstract; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestClass; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestClassChild; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestClassLazyLoad; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestInterface; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestTrait; +use OnPHP\Tests\TestEnvironment\ClassUtils\TestTraitChild; use OnPHP\Tests\TestEnvironment\TestCase; /** @@ -20,8 +25,12 @@ */ final class ClassUtilsTest extends TestCase { - - public function testOldStypeStaticMethodCall() + /** + * @throws ClassNotFoundException + * @throws WrongArgumentException + * @throws MissingElementException + */ + public function testOldStyleStaticMethodCall() { $this->assertEquals( ClassUtils::callStaticMethod( @@ -37,7 +46,12 @@ public function testOldStypeStaticMethodCall() ImaginaryDialect::me() ); } - + + /** + * @throws ClassNotFoundException + * @throws WrongArgumentException + * @throws MissingElementException + */ public function testStaticMethodCall() { $this->assertEquals( @@ -53,14 +67,52 @@ public function testStaticMethodCall() ClassUtils::callStaticMethod(ImaginaryDialect::class.'::me'), ImaginaryDialect::me() ); + + try { + ClassUtils::callStaticMethod([]); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::callStaticMethod(false); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::callStaticMethod(function() { return true; }); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::callStaticMethod(555); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::callStaticMethod(555.55); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::callStaticMethod(new \DateTime()); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } } - public function testInexistentStaticMethodCall() { + public function testInexistedStaticMethodCall() + { $this->expectException(ClassNotFoundException::class); ClassUtils::callStaticMethod('InexistantClass::InSaNeMeThOd'); } - public function testInexistentMultiplyStaticMethodCall() + public function testInexistedMultiplyStaticMethodCall() { $this->expectException(WrongArgumentException::class); ClassUtils::callStaticMethod(Identifier::class.'::comp::lete::non::sense'); @@ -69,11 +121,11 @@ public function testInexistentMultiplyStaticMethodCall() public function testSet() { $source = - ClassUtilsTestClass::create()-> + TestClass::create()-> setText('new Text'); $destination = - ClassUtilsTestClass::create()-> + TestClass::create()-> setText('old Text'); ClassUtils::fillNullProperties($source, $destination); @@ -85,10 +137,10 @@ public function testSet() public function testNotSet() { - $source = ClassUtilsTestClass::create(); + $source = TestClass::create(); $destination = - ClassUtilsTestClass::create()-> + TestClass::create()-> setText('old Text'); ClassUtils::fillNullProperties($source, $destination); @@ -101,15 +153,15 @@ public function testNotSet() public function testObject() { $innerObject = - ClassUtilsTestClass::create()-> + TestClass::create()-> setText('inner Object'); $source = - ClassUtilsTestClass::create()-> + TestClass::create()-> setObject($innerObject); $destination = - ClassUtilsTestClass::create()-> + TestClass::create()-> setText('old Text'); ClassUtils::fillNullProperties($source, $destination); @@ -122,97 +174,252 @@ public function testObject() $this->assertTrue($destination->getObject() === $innerObject); } + public function testCopyProperties() + { + $source = TestClass::create(); + $destination = TestClass::create()->setText('old Text'); + + ClassUtils::copyProperties($source, $destination); + $this->assertEquals($source->getText(), $destination->getText()); + $this->assertEquals($source->getObject(), $destination->getObject()); + $this->assertNull($destination->getText()); + $this->assertNull($destination->getObject()); + + $destination + ->setText('old text') + ->setObject( + TestClass::create() + ->setText('old inner object text') + ); + ClassUtils::copyProperties($source, $destination); + $this->assertEquals($source->getText(), $destination->getText()); + $this->assertEquals($source->getObject(), $destination->getObject()); + $this->assertNull($destination->getText()); + $this->assertNull($destination->getObject()); + + $source + ->setText('source text') + ->setObject( + TestClass::create() + ->setText('source inner text') + ->setObject( + TestClass::create()->setText('double inner source text') + ) + ); + ClassUtils::copyProperties($source, $destination); + $this->assertNotNull($destination->getText()); + $this->assertNotNull($destination->getObject()); + $this->assertNotNull($destination->getObject()->getObject()); + $this->assertEquals($source->getText(), $destination->getText()); + $this->assertEquals($source->getObject(), $destination->getObject()); + $this->assertEquals($source->getObject()->getText(), $destination->getObject()->getText()); + $this->assertEquals('source inner text', $destination->getObject()->getText()); + $this->assertEquals($source->getObject()->getObject(), $destination->getObject()->getObject()); + $this->assertEquals('double inner source text', $destination->getObject()->getObject()->getText()); + $this->assertEquals( + $source->getObject()->getObject()->getText(), + $destination->getObject()->getObject()->getText() + ); + + $source = TestClassLazyLoad::create(); + $source->name = 'name'; + $destination = TestClassLazyLoad::create()->setText('old Text'); + + ClassUtils::copyProperties($source, $destination); + $this->assertNotEquals($source->getText(), $destination->getText()); + $this->assertEquals('old Text', $destination->getText()); + $this->assertNotEquals($source->name, $destination->name); + $this->assertNull($destination->name); + + $source->setText('source text')->setObject(TestClass::create()); + ClassUtils::copyProperties($source, $destination); + $this->assertNotEquals($source->getText(), $destination->getText()); + $this->assertEquals('old Text', $destination->getText()); + $this->assertNull($destination->getObject()); + + $source->setTestId(1); + ClassUtils::copyProperties($source, $destination); + $this->assertEquals($source->getTestId(), $destination->getTestId()); + $this->assertNotNull($source->getTest()); + $this->assertNotNull($destination->getTest()); + $this->assertEquals($source->getTest(), $destination->getTest()); + + $source->dropTest(); + ClassUtils::copyProperties($source, $destination); + $this->assertEquals($source->getTestId(), $destination->getTestId()); + $this->assertNull($source->getTest()); + $this->assertNull($destination->getTest()); + } + + public function testClassImplements() + { + $interfaces = ClassUtils::isClassImplements(TestClassLazyLoad::class); + $interfacesParent = ClassUtils::isClassImplements(TestClass::class); + $this->assertIsArray($interfaces); + $this->assertIsArray($interfacesParent); + $this->assertEquals($interfaces, $interfacesParent); + $this->assertArrayHasKey(TestInterface::class, $interfaces); + $this->assertArrayHasKey(TestInterface::class, $interfacesParent); + $this->assertIsArray(ClassUtils::isClassImplements(TestInterface::class)); + $this->assertEmpty(ClassUtils::isClassImplements(TestInterface::class)); + $this->assertIsArray(ClassUtils::isClassImplements(TestTrait::class)); + $this->assertEmpty(ClassUtils::isClassImplements(TestTrait::class)); + $this->assertIsArray(ClassUtils::isClassImplements(function () { return true; })); + $this->assertEmpty(ClassUtils::isClassImplements(function () { return true; })); + $this->assertArrayHasKey( + \DateTimeInterface::class, + ClassUtils::isClassImplements(\DateTime::class) + ); + + try { + ClassUtils::isClassImplements('\SomeUnexistedClass'); + $this->fail('ClassNotFoundException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(ClassNotFoundException::class, $exception); + } + } + public function testInstanceOf() { + $this->assertFalse(ClassUtils::isInstanceOf('2007-07-14&genre', 'Date')); + $this->assertTrue(ClassUtils::isInstanceOf(new \DateTime(), 'DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf(new \DateTime(), '\DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf(new \DateTime(), 'DateTime')); + $this->assertTrue(ClassUtils::isInstanceOf(new \DateTime(), '\DateTime')); + $this->assertFalse(ClassUtils::isInstanceOf(TestClass::class, function() { return true; })); + $this->assertTrue(ClassUtils::isInstanceOf('\DateTime', '\DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf('\DateTime', 'DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf('DateTime', '\DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf('DateTime', 'DateTimeInterface')); + $this->assertTrue(ClassUtils::isInstanceOf(function () { return true; }, '\Closure')); + $this->assertTrue(ClassUtils::isInstanceOf(function () { return true; }, \Closure::class)); try { - $this->assertFalse(ClassUtils::isInstanceOf('2007-07-14&genre', 'Date')); - } catch (WrongArgumentException $e) { - /* pass */ + ClassUtils::isInstanceOf(TestClass::class, true); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::isInstanceOf(false, \Closure::class); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); } - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestClassChild::class, ClassUtilsTestClass::class)); - $this->assertFalse(ClassUtils::isInstanceOf(ClassUtilsTestClass::class, ClassUtilsTestClassChild::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestClassChild::class, ClassUtilsTestInterface::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestClass::class, ClassUtilsTestInterface::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestAbstract::class, ClassUtilsTestInterface::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestAbstract::class, ClassUtilsTestClass::class)); - $this->assertFalse(ClassUtils::isInstanceOf(ClassUtilsTestAbstract::class, ClassUtilsTestClassChild::class)); + try { + $this->assertFalse(ClassUtils::isInstanceOf(TestClass::class, [])); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + $this->assertFalse(ClassUtils::isInstanceOf([],TestClass::class)); + $this->fail('WrongArgumentException expected'); + } catch(\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + $this->assertTrue(ClassUtils::isInstanceOf(TestClassChild::class, TestClass::class)); + $this->assertFalse(ClassUtils::isInstanceOf(TestClass::class, TestClassChild::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestClassChild::class, TestInterface::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestClass::class, TestInterface::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestAbstract::class, TestInterface::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestAbstract::class, TestClass::class)); + $this->assertFalse(ClassUtils::isInstanceOf(TestAbstract::class, TestClassChild::class)); + + $this->assertFalse(ClassUtils::isInstanceOf(TestClass::class, TestTrait::class)); + $this->assertFalse(ClassUtils::isInstanceOf(TestClass::class, TestTraitChild::class)); + $this->assertFalse(ClassUtils::isInstanceOf(TestClassChild::class, TestTrait::class)); + $this->assertFalse(ClassUtils::isInstanceOf(TestClassChild::class, TestTraitChild::class)); - $base = new ClassUtilsTestClass; + $base = new TestClass; $this->assertTrue(ClassUtils::isInstanceOf($base, $base)); + $this->assertFalse(ClassUtils::isInstanceOf($base, TestTrait::class)); + $this->assertFalse(ClassUtils::isInstanceOf($base, TestTraitChild::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestAbstract::class, $base)); - $this->assertFalse(ClassUtils::isInstanceOf($base, ClassUtilsTestAbstract::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestAbstract::class, $base)); + $this->assertFalse(ClassUtils::isInstanceOf($base, TestAbstract::class)); - $child = new ClassUtilsTestClassChild(); + $child = new TestClassChild(); $this->assertFalse(ClassUtils::isInstanceOf($base, $child)); $this->assertTrue(ClassUtils::isInstanceOf($child, $base)); - $this->assertFalse(ClassUtils::isInstanceOf($base, ClassUtilsTestClassChild::class)); - $this->assertTrue(ClassUtils::isInstanceOf($child, ClassUtilsTestClass::class)); - - $this->assertTrue(ClassUtils::isInstanceOf('\\'.ClassUtilsTestClass::class, ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isInstanceOf(ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isInstanceOf('\\'.ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isInstanceOf('\\'.ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - - $this->assertTrue(ClassUtils::isInstanceOf('\\'.ClassUtilsTestClass::class, new ClassUtilsTestClass)); - $this->assertTrue(ClassUtils::isInstanceOf('\\'.ClassUtilsTestClassChild::class, new ClassUtilsTestClass())); - $this->assertFalse(ClassUtils::isInstanceOf(new ClassUtilsTestClass(), '\\'.ClassUtilsTestClassChild::class)); - + $this->assertFalse(ClassUtils::isInstanceOf($base, TestClassChild::class)); + $this->assertTrue(ClassUtils::isInstanceOf($child, TestClass::class)); + + $this->assertFalse(ClassUtils::isInstanceOf($child, TestTrait::class)); + $this->assertFalse(ClassUtils::isInstanceOf($child, TestTraitChild::class)); + + $this->assertTrue(ClassUtils::isInstanceOf('\\'.TestClass::class, TestClass::class)); + $this->assertTrue(ClassUtils::isInstanceOf(TestClass::class, '\\'.TestClass::class)); + $this->assertTrue(ClassUtils::isInstanceOf('\\'.TestClass::class, '\\'.TestClass::class)); + $this->assertTrue(ClassUtils::isInstanceOf('\\'.TestClass::class, '\\'.TestClass::class)); + + $this->assertTrue(ClassUtils::isInstanceOf('\\'.TestClass::class, new TestClass)); + $this->assertTrue(ClassUtils::isInstanceOf('\\'.TestClassChild::class, new TestClass())); + $this->assertFalse(ClassUtils::isInstanceOf(new TestClass(), '\\'.TestClassChild::class)); + try { - ClassUtils::isSameClassNames('ClassUtilsTestClass', ClassUtilsTestClass::class); + ClassUtils::isSameClassNames('TestClass', TestClass::class); $this->fail('WrongArgumentException expected'); - } catch (WrongArgumentException $e) { - //pass + } catch (\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); } - + try { - ClassUtils::isSameClassNames('\Some\Namespace\FakeClassName', ClassUtilsTestClass::class); + ClassUtils::isSameClassNames('\Some\Namespace\FakeClassName', TestClass::class); $this->fail('WrongArgumentException expected'); - } catch (WrongArgumentException $e) { - //pass + } catch (\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); } } - public function testSameClassNames() { - $this->assertTrue(ClassUtils::isSameClassNames('\\'.ClassUtilsTestClass::class, ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isSameClassNames(ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isSameClassNames('\\'.ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - $this->assertTrue(ClassUtils::isSameClassNames('\\'.ClassUtilsTestClass::class, '\\'.ClassUtilsTestClass::class)); - - $this->assertTrue(ClassUtils::isSameClassNames('\\'.ClassUtilsTestClass::class, new ClassUtilsTestClass)); - $this->assertFalse(ClassUtils::isSameClassNames('\\'.ClassUtilsTestClassChild::class, new ClassUtilsTestClass())); - $this->assertFalse(ClassUtils::isSameClassNames(new ClassUtilsTestClass(), '\\'.ClassUtilsTestClassChild::class)); + public function testSameClassNames() + { + $this->assertTrue(ClassUtils::isSameClassNames('\\'.TestClass::class, TestClass::class)); + $this->assertTrue(ClassUtils::isSameClassNames(TestClass::class, '\\'.TestClass::class)); + $this->assertTrue(ClassUtils::isSameClassNames('\\'.TestClass::class, '\\'.TestClass::class)); + $this->assertTrue(ClassUtils::isSameClassNames('\\'.TestClass::class, '\\'.TestClass::class)); + $this->assertTrue(ClassUtils::isSameClassNames('\\'.TestClass::class, new TestClass)); + $this->assertFalse(ClassUtils::isSameClassNames('\\'.TestClassChild::class, new TestClass())); + $this->assertFalse(ClassUtils::isSameClassNames(new TestClass(), '\\'.TestClassChild::class)); + + $this->assertTrue(ClassUtils::isSameClassNames(function() { return true; }, 'Closure')); + $this->assertTrue(ClassUtils::isSameClassNames(function() { return true; }, '\Closure')); + $this->assertTrue(ClassUtils::isSameClassNames('Closure', function() { return true; })); + $this->assertTrue(ClassUtils::isSameClassNames('\Closure', function() { return true; })); + $this->assertTrue(ClassUtils::isSameClassNames('\DateTime', 'DateTime')); + $this->assertTrue(ClassUtils::isSameClassNames('DateTime', '\DateTime')); + $this->assertTrue(ClassUtils::isSameClassNames('\DateTime', '\DateTime')); + $this->assertTrue(ClassUtils::isSameClassNames('DateTime', 'DateTime')); + try { - $this->assertFalse( - ClassUtils::isSameClassNames( - '\Some\Namespace\FakeClassName', - ClassUtilsTestClass::class - ) - ); + ClassUtils::isSameClassNames(TestTrait::class, TestTrait::class); $this->fail('WrongArgumentException expected'); - } catch (WrongArgumentException $e) { - //pass + } catch (\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); } - + try { - $this->assertFalse( - ClassUtils::isSameClassNames( - 123, - ClassUtilsTestClass::class - ) - ); + ClassUtils::isSameClassNames('\Some\Namespace\FakeClassName',TestClass::class); + $this->fail('WrongArgumentException expected'); + } catch (\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); + } + try { + ClassUtils::isSameClassNames(123,TestClass::class); $this->fail('WrongArgumentException expected'); - } catch (WrongArgumentException $e) { - //pass + } catch (\Throwable $exception) { + $this->assertInstanceOf(WrongArgumentException::class, $exception); } } public function testIsClassName() { $this->assertFalse(ClassUtils::isClassName(null)); + $this->assertFalse(ClassUtils::isClassName([])); + $this->assertFalse(ClassUtils::isClassName(false)); + $this->assertFalse(ClassUtils::isClassName(function() { return true; })); $this->assertFalse(ClassUtils::isClassName('')); $this->assertFalse(ClassUtils::isClassName(0)); $this->assertFalse(ClassUtils::isClassName('0')); @@ -221,5 +428,4 @@ public function testIsClassName() $this->assertTrue(ClassUtils::isClassName('_1')); $this->assertTrue(ClassUtils::isClassName('Correct_Class1')); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/tests/TestEnvironment/Base/AliasedTestInstance.php b/tests/TestEnvironment/Base/AliasedTestInstance.php new file mode 100644 index 0000000000..65500304ee --- /dev/null +++ b/tests/TestEnvironment/Base/AliasedTestInstance.php @@ -0,0 +1,13 @@ +object; } - public function setObject(ClassUtilsTestClass $object) + public function setObject(TestClass $object) { $this->object = $object; diff --git a/tests/TestEnvironment/ClassUtils/TestClassChild.php b/tests/TestEnvironment/ClassUtils/TestClassChild.php new file mode 100644 index 0000000000..6dd9658334 --- /dev/null +++ b/tests/TestEnvironment/ClassUtils/TestClassChild.php @@ -0,0 +1,5 @@ +testId; + } + + public function setTestId($testId) + { + $this->testId = $testId; + + return $this; + } + + public function getTest() + { + if ( + null === $this->test + && null !== $this->testId + ) { + $this->test = (new self)->setTestId($this->testId); + } + + return $this->test; + } + + public function setTest(TestClassLazyLoad $class) + { + $this->test = $class; + $this->testId = $class->getTestId(); + + return $this; + } + + public function dropTest() + { + $this->testId = null; + $this->test = null; + + return $this; + } +} diff --git a/tests/TestEnvironment/ClassUtils/TestInterface.php b/tests/TestEnvironment/ClassUtils/TestInterface.php new file mode 100644 index 0000000000..9afaf44884 --- /dev/null +++ b/tests/TestEnvironment/ClassUtils/TestInterface.php @@ -0,0 +1,5 @@ +