From f8c11d4168a479eabb7a3578c69610a8c60c25a8 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Mon, 26 Feb 2024 19:13:17 -0600 Subject: [PATCH 1/3] Refactor Container.php Signed-off-by: Nathanael Esayeas --- library/Mockery/Container.php | 585 ++++++++++++++++++++-------------- 1 file changed, 348 insertions(+), 237 deletions(-) diff --git a/library/Mockery/Container.php b/library/Mockery/Container.php index ea5b89e88..f6efd4ee0 100644 --- a/library/Mockery/Container.php +++ b/library/Mockery/Container.php @@ -10,20 +10,19 @@ namespace Mockery; +use Mockery; +use Mockery\Exception\InvalidOrderException; +use Mockery\Exception\RuntimeException; use Mockery\Generator\Generator; use Mockery\Generator\MockConfigurationBuilder; use Mockery\Loader\Loader as LoaderInterface; +use ReflectionClass; +use ReflectionException; +use Throwable; class Container { - const BLOCKS = \Mockery::BLOCKS; - - /** - * Store of mock objects - * - * @var array - */ - protected $_mocks = array(); + public const BLOCKS = Mockery::BLOCKS; /** * Order number of allocation @@ -40,16 +39,16 @@ class Container protected $_currentOrder = 0; /** - * Ordered groups - * - * @var array + * @var Generator */ - protected $_groups = array(); + protected $_generator; /** - * @var Generator + * Ordered groups + * + * @var array */ - protected $_generator; + protected $_groups = []; /** * @var LoaderInterface @@ -57,14 +56,107 @@ class Container protected $_loader; /** - * @var array + * Store of mock objects + * + * @var array|int,LegacyMockInterface|MockInterface> + */ + protected $_mocks = []; + + /** + * @var array + */ + protected $_namedMocks = []; + + /** + * @var Instantiator + */ + protected $instantiator; + + public function __construct(Generator $generator = null, LoaderInterface $loader = null, Instantiator $instantiator = null) + { + $this->_generator = $generator ?: Mockery::getDefaultGenerator(); + $this->_loader = $loader ?: Mockery::getDefaultLoader(); + $this->instantiator = $instantiator ?: new Instantiator(); + } + + /** + * Return a specific remembered mock according to the array index it + * was stored to in this container instance + * + * @return null|LegacyMockInterface|MockInterface + */ + public function fetchMock($reference) + { + return $this->_mocks[$reference] ?? null; + } + + /** + * @return Generator */ - protected $_namedMocks = array(); + public function getGenerator() + { + return $this->_generator; + } + + /** + * @param string $method + * @param string $parent + * @return string|null + */ + public function getKeyOfDemeterMockFor($method, $parent) + { + $keys = array_keys($this->_mocks); + + $match = preg_grep('/__demeter_' . md5($parent) . "_{$method}$/", $keys); + + if (count($match) === 1) { + $res = array_values($match); + + if (count($res) > 0) { + return $res[0]; + } + } - public function __construct(Generator $generator = null, LoaderInterface $loader = null) + return null; + } + + /** + * @return LoaderInterface + */ + public function getLoader() { - $this->_generator = $generator ?: \Mockery::getDefaultGenerator(); - $this->_loader = $loader ?: \Mockery::getDefaultLoader(); + return $this->_loader; + } + + /** + * @return array|int,LegacyMockInterface|MockInterface> + */ + public function getMocks() + { + return $this->_mocks; + } + + public function instanceMock() + { + } + + /** + * see http://php.net/manual/en/language.oop5.basic.php + * @param string $className + * @return bool + */ + public function isValidClassName($className) + { + if ($className[0] === '\\') { + $className = substr($className, 1); // remove the first backslash + } + // all the namespaces and class name should match the regex + return array_filter( + explode('\\', $className), + static function ($name): bool { + return ! preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $name); + } + ) === []; } /** @@ -75,119 +167,197 @@ public function __construct(Generator $generator = null, LoaderInterface $loader * names or partials - just so long as it's something that can be mocked. * I'll refactor it one day so it's easier to follow. * - * @param array ...$args + * @template TMock of LegacyMockInterface&MockInterface&object + * + * @param array|string ...$args * - * @return Mock - * @throws Exception\RuntimeException + * @return TMock + * @throws RuntimeException|ReflectionException */ public function mock(...$args) { + /** @var null|MockConfigurationBuilder $builder */ + $builder = null; + /** @var null|callable $expectationClosure */ $expectationClosure = null; - $quickdefs = array(); + $partialMethods = null; + $quickDefinitions = []; $constructorArgs = null; - $blocks = array(); - $class = null; + $blocks = []; if (count($args) > 1) { - $finalArg = end($args); - reset($args); + $finalArg = array_pop($args); + if (is_callable($finalArg) && is_object($finalArg)) { - $expectationClosure = array_pop($args); + $expectationClosure = $finalArg; + } else { + $args[] = $finalArg; } } - $builder = new MockConfigurationBuilder(); - foreach ($args as $k => $arg) { if ($arg instanceof MockConfigurationBuilder) { $builder = $arg; + unset($args[$k]); } } + reset($args); - $builder->setParameterOverrides(\Mockery::getConfiguration()->getInternalClassMethodParamMaps()); - $builder->setConstantsMap(\Mockery::getConfiguration()->getConstantsMap()); + $builder = $builder ?? new MockConfigurationBuilder(); + $mockeryConfiguration = Mockery::getConfiguration(); + $builder->setParameterOverrides($mockeryConfiguration->getInternalClassMethodParamMaps()); + $builder->setConstantsMap($mockeryConfiguration->getConstantsMap()); while (count($args) > 0) { $arg = array_shift($args); + // check for multiple interfaces if (is_string($arg)) { foreach (explode('|', $arg) as $type) { if ($arg === 'null') { // skip PHP 8 'null's - } elseif (strpos($type, ',') && !strpos($type, ']')) { + continue; + } + + if (strpos($type, ',') && ! strpos($type, ']')) { $interfaces = explode(',', str_replace(' ', '', $type)); + $builder->addTargets($interfaces); - } elseif (substr($type, 0, 6) == 'alias:') { + + continue; + } + + if (strpos($type, 'alias:') === 0) { $type = str_replace('alias:', '', $type); + $builder->addTarget('stdClass'); $builder->setName($type); - } elseif (substr($type, 0, 9) == 'overload:') { + + continue; + } + + if (strpos($type, 'overload:') === 0) { $type = str_replace('overload:', '', $type); + $builder->setInstanceMock(true); $builder->addTarget('stdClass'); $builder->setName($type); - } elseif (substr($type, strlen($type)-1, 1) == ']') { + + continue; + } + + if ($type[strlen($type) - 1] === ']') { $parts = explode('[', $type); - if (!class_exists($parts[0], true) && !interface_exists($parts[0], true)) { - throw new \Mockery\Exception('Can only create a partial mock from' + + $class = $parts[0]; + + if ( + ! class_exists($class, true) + && ! interface_exists($class, true) + ) { + throw new Exception('Can only create a partial mock from' . ' an existing class or interface'); } - $class = $parts[0]; - $parts[1] = str_replace(' ', '', $parts[1]); - $partialMethods = array_filter(explode(',', strtolower(rtrim($parts[1], ']')))); + $builder->addTarget($class); + + $partialMethods = array_filter( + explode( + ',', + strtolower( + rtrim( + str_replace( + ' ', + '', + $parts[1] + ), + ']' + ) + ) + ) + ); + foreach ($partialMethods as $partialMethod) { if ($partialMethod[0] === '!') { $builder->addBlackListedMethod(substr($partialMethod, 1)); + continue; } + $builder->addWhiteListedMethod($partialMethod); } - } elseif (class_exists($type, true) || interface_exists($type, true) || trait_exists($type, true)) { - $builder->addTarget($type); - } elseif (!\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed() && (!class_exists($type, true) && !interface_exists($type, true))) { - throw new \Mockery\Exception("Mockery can't find '$type' so can't mock it"); - } else { - if (!$this->isValidClassName($type)) { - throw new \Mockery\Exception('Class name contains invalid characters'); - } + + continue; + } + + if (! $this->isValidClassName($type)) { + throw new Exception('Class name contains invalid characters'); + } + + if ( + class_exists($type, true) + || interface_exists($type, true) + || trait_exists($type, true) + ) { $builder->addTarget($type); + + continue; + } + + if (! $mockeryConfiguration->mockingNonExistentMethodsAllowed()) { + throw new Exception("Mockery can't find '{$type}' so can't mock it"); } - break; // unions are "sum" types and not "intersections", and so we must only process the first part + + $builder->addTarget($type); + + // unions are "sum" types and not "intersections", and so we must only process the first part + break; } - } elseif (is_object($arg)) { + + continue; + } + + if (is_object($arg)) { $builder->addTarget($arg); - } elseif (is_array($arg)) { - if (!empty($arg) && array_keys($arg) !== range(0, count($arg) - 1)) { + + continue; + } + + if (is_array($arg)) { + if ($arg !== [] && array_keys($arg) !== range(0, count($arg) - 1)) { // if associative array if (array_key_exists(self::BLOCKS, $arg)) { $blocks = $arg[self::BLOCKS]; } + unset($arg[self::BLOCKS]); - $quickdefs = $arg; + + $quickDefinitions = $arg; } else { $constructorArgs = $arg; } - } else { - throw new \Mockery\Exception( - 'Unable to parse arguments sent to ' - . get_class($this) . '::mock()' - ); + + continue; } + + throw new Exception(sprintf( + 'Unable to parse arguments sent to %s::mock()', + static::class + )); } $builder->addBlackListedMethods($blocks); - if (!is_null($constructorArgs)) { - $builder->addBlackListedMethod("__construct"); // we need to pass through + if ($constructorArgs !== null) { + $builder->addBlackListedMethod('__construct'); // we need to pass through } else { $builder->setMockOriginalDestructor(true); } - if (!empty($partialMethods) && $constructorArgs === null) { - $constructorArgs = array(); + if ($partialMethods !== null && $constructorArgs === null) { + $constructorArgs = []; } $config = $builder->getMockConfiguration(); @@ -196,145 +366,105 @@ public function mock(...$args) $def = $this->getGenerator()->generate($config); - if (class_exists($def->getClassName(), $attemptAutoload = false)) { - $rfc = new \ReflectionClass($def->getClassName()); - if (!$rfc->implementsInterface("Mockery\LegacyMockInterface")) { - throw new \Mockery\Exception\RuntimeException("Could not load mock {$def->getClassName()}, class already exists"); + $className = $def->getClassName(); + if (class_exists($className, $attemptAutoload = false)) { + $rfc = new ReflectionClass($className); + if (! $rfc->implementsInterface(LegacyMockInterface::class)) { + throw new RuntimeException("Could not load mock {$className}, class already exists"); } } $this->getLoader()->load($def); - $mock = $this->_getInstance($def->getClassName(), $constructorArgs); + $mock = $this->_getInstance($className, $constructorArgs); $mock->mockery_init($this, $config->getTargetObject(), $config->isInstanceMock()); - if (!empty($quickdefs)) { - if (\Mockery::getConfiguration()->getQuickDefinitions()->shouldBeCalledAtLeastOnce()) { - $mock->shouldReceive($quickdefs)->atLeast()->once(); + if ($quickDefinitions !== []) { + if ($mockeryConfiguration->getQuickDefinitions()->shouldBeCalledAtLeastOnce()) { + $mock->shouldReceive($quickDefinitions)->atLeast()->once(); } else { - $mock->shouldReceive($quickdefs)->byDefault(); + $mock->shouldReceive($quickDefinitions)->byDefault(); } } - if (!empty($expectationClosure)) { + + if ($expectationClosure !== null) { $expectationClosure($mock); } - $this->rememberMock($mock); - return $mock; - } - - public function instanceMock() - { - } - - public function getLoader() - { - return $this->_loader; - } - - public function getGenerator() - { - return $this->_generator; - } - /** - * @param string $method - * @param string $parent - * @return string|null - */ - public function getKeyOfDemeterMockFor($method, $parent) - { - $keys = array_keys($this->_mocks); - $match = preg_grep("/__demeter_" . md5($parent) . "_{$method}$/", $keys); - if (count($match) == 1) { - $res = array_values($match); - if (count($res) > 0) { - return $res[0]; - } - } - return null; + return $this->rememberMock($mock); } /** - * @return array + * Fetch the next available allocation order number + * + * @return int */ - public function getMocks() + public function mockery_allocateOrder() { - return $this->_mocks; + return ++$this->_allocatedOrder; } /** - * Tear down tasks for this container - * - * @throws \Exception - * @return void + * Reset the container to its original state */ - public function mockery_teardown() + public function mockery_close() { - try { - $this->mockery_verify(); - } catch (\Exception $e) { - $this->mockery_close(); - throw $e; + foreach ($this->_mocks as $mock) { + $mock->mockery_teardown(); } + $this->_mocks = []; } /** - * Verify the container mocks + * Get current ordered number * - * @return void + * @return int */ - public function mockery_verify() + public function mockery_getCurrentOrder() { - foreach ($this->_mocks as $mock) { - $mock->mockery_verify(); - } + return $this->_currentOrder; } /** - * Retrieves all exceptions thrown by mocks + * Gets the count of expectations on the mocks * - * @return array + * @return int */ - public function mockery_thrownExceptions() + public function mockery_getExpectationCount() { - $e = []; - + $count = 0; foreach ($this->_mocks as $mock) { - $e = array_merge($e, $mock->mockery_thrownExceptions()); + $count += $mock->mockery_getExpectationCount(); } - - return $e; + return $count; } /** - * Reset the container to its original state + * Fetch array of ordered groups * - * @return void + * @return array */ - public function mockery_close() + public function mockery_getGroups() { - foreach ($this->_mocks as $mock) { - $mock->mockery_teardown(); - } - $this->_mocks = array(); + return $this->_groups; } /** - * Fetch the next available allocation order number + * Set current ordered number * - * @return int + * @param int $order + * @return int The current order number that was set */ - public function mockery_allocateOrder() + public function mockery_setCurrentOrder($order) { - $this->_allocatedOrder += 1; - return $this->_allocatedOrder; + return $this->_currentOrder = $order; } /** * Set ordering for a group * - * @param mixed $group - * @param int $order + * @param string $group + * @param int $order */ public function mockery_setGroup($group, $order) { @@ -342,93 +472,97 @@ public function mockery_setGroup($group, $order) } /** - * Fetch array of ordered groups + * Tear down tasks for this container * - * @return array + * @throws \Exception */ - public function mockery_getGroups() + public function mockery_teardown() { - return $this->_groups; + try { + $this->mockery_verify(); + } catch (\Exception $e) { + $this->mockery_close(); + throw $e; + } } /** - * Set current ordered number + * Retrieves all exceptions thrown by mocks * - * @param int $order - * @return int The current order number that was set + * @return array */ - public function mockery_setCurrentOrder($order) + public function mockery_thrownExceptions() { - $this->_currentOrder = $order; - return $this->_currentOrder; - } + /** @var array $exceptions */ + $exceptions = []; - /** - * Get current ordered number - * - * @return int - */ - public function mockery_getCurrentOrder() - { - return $this->_currentOrder; + foreach ($this->_mocks as $mock) { + foreach ($mock->mockery_thrownExceptions() as $exception) { + $exceptions[] = $exception; + } + } + + return $exceptions; } /** * Validate the current mock's ordering * - * @param string $method - * @param int $order - * @throws \Mockery\Exception - * @return void + * @param string $method + * @param int $order + * @throws Exception */ - public function mockery_validateOrder($method, $order, \Mockery\LegacyMockInterface $mock) + public function mockery_validateOrder($method, $order, LegacyMockInterface $mock) { if ($order < $this->_currentOrder) { - $exception = new \Mockery\Exception\InvalidOrderException( - 'Method ' . $method . ' called out of order: expected order ' - . $order . ', was ' . $this->_currentOrder + $exception = new InvalidOrderException( + sprintf( + 'Method %s called out of order: expected order %d, was %d', + $method, + $order, + $this->_currentOrder + ) ); + $exception->setMock($mock) ->setMethodName($method) ->setExpectedOrder($order) ->setActualOrder($this->_currentOrder); + throw $exception; } $this->mockery_setCurrentOrder($order); } /** - * Gets the count of expectations on the mocks - * - * @return int + * Verify the container mocks */ - public function mockery_getExpectationCount() + public function mockery_verify() { - $count = 0; foreach ($this->_mocks as $mock) { - $count += $mock->mockery_getExpectationCount(); + $mock->mockery_verify(); } - return $count; } /** * Store a mock and set its container reference * - * @param \Mockery\Mock $mock - * @return \Mockery\LegacyMockInterface|\Mockery\MockInterface + * @param LegacyMockInterface|MockInterface $mock + * @return LegacyMockInterface|MockInterface */ - public function rememberMock(\Mockery\LegacyMockInterface $mock) + public function rememberMock(LegacyMockInterface $mock) { - if (!isset($this->_mocks[get_class($mock)])) { - $this->_mocks[get_class($mock)] = $mock; - } else { - /** - * This condition triggers for an instance mock where origin mock - * is already remembered - */ - $this->_mocks[] = $mock; + $class = get_class($mock); + + if (! array_key_exists($class, $this->_mocks)) { + return $this->_mocks[$class] = $mock; } - return $mock; + + /** + * This condition triggers for an instance mock where origin mock + * is already remembered + */ + return $this->_mocks[] = $mock; } /** @@ -437,7 +571,7 @@ public function rememberMock(\Mockery\LegacyMockInterface $mock) * mock() to change it - thus why the method name is "self" since it will be * be used during the programming of the same mock. * - * @return \Mockery\Mock + * @return LegacyMockInterface|MockInterface */ public function self() { @@ -447,35 +581,32 @@ public function self() } /** - * Return a specific remembered mock according to the array index it - * was stored to in this container instance + * @template TMock of LegacyMockInterface&MockInterface&object * - * @return \Mockery\Mock + * @param class-string $mockName + * @param array|null $constructorArgs + * + * @return TMock */ - public function fetchMock($reference) - { - if (isset($this->_mocks[$reference])) { - return $this->_mocks[$reference]; - } - } - protected function _getInstance($mockName, $constructorArgs = null) { if ($constructorArgs !== null) { - $r = new \ReflectionClass($mockName); - return $r->newInstanceArgs($constructorArgs); + return (new ReflectionClass($mockName))->newInstanceArgs($constructorArgs); } try { - $instantiator = new Instantiator(); - $instance = $instantiator->instantiate($mockName); + /** @var TMock $instance */ + $instance = $this->instantiator->instantiate($mockName); } catch (\Exception $ex) { + /** @var class-string $internalMockName */ $internalMockName = $mockName . '_Internal'; - if (!class_exists($internalMockName)) { - eval("class $internalMockName extends $mockName {" . - 'public function __construct() {}' . - '}'); + if (! class_exists($internalMockName)) { + eval(sprintf( + 'class %s extends %s { public function __construct() {} }', + $internalMockName, + $mockName + )); } $instance = new $internalMockName(); @@ -488,38 +619,18 @@ protected function checkForNamedMockClashes($config) { $name = $config->getName(); - if (!$name) { + if ($name === null) { return; } $hash = $config->getHash(); - if (isset($this->_namedMocks[$name])) { - if ($hash !== $this->_namedMocks[$name]) { - throw new \Mockery\Exception( - "The mock named '$name' has been already defined with a different mock configuration" - ); - } + if (array_key_exists($name, $this->_namedMocks) && $hash !== $this->_namedMocks[$name]) { + throw new Exception( + "The mock named '{$name}' has been already defined with a different mock configuration" + ); } $this->_namedMocks[$name] = $hash; } - - /** - * see http://php.net/manual/en/language.oop5.basic.php - * @param string $className - * @return bool - */ - public function isValidClassName($className) - { - $pos = strpos($className, '\\'); - if ($pos === 0) { - $className = substr($className, 1); // remove the first backslash - } - // all the namespaces and class name should match the regex - $invalidNames = array_filter(explode('\\', $className), function ($name) { - return !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $name); - }); - return empty($invalidNames); - } } From 8cc2eb622078a5018a4a9d66b7a68cc865d3c07c Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 27 Feb 2024 13:47:13 -0600 Subject: [PATCH 2/3] Update psalm-baseline.xml Signed-off-by: Nathanael Esayeas --- psalm-baseline.xml | 159 ++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 87 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 24304e59c..6f13c0af2 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -17,11 +17,9 @@ is_null(self::$_generator) is_null(self::$_loader) - - $newMockName - $mock + fetchMock($name)]]> $argument @@ -54,6 +52,7 @@ getMethod mock + mock mockery_teardown @@ -80,7 +79,6 @@ $formattedArguments[] $formatter $mock - $mock $name $reference $shortName @@ -94,6 +92,7 @@ \Mockery\ExpectationInterface + \Mockery\Mock \Mockery\MockInterface|\Mockery\LegacyMockInterface \Mockery\MockInterface|\Mockery\LegacyMockInterface \Mockery\MockInterface|\Mockery\LegacyMockInterface @@ -118,6 +117,15 @@ \Mockery\Mock + + $mock + + + fetchMock($name)]]> + + + $mocks[$demeterMockKey] + null @@ -159,6 +167,10 @@ $parentMock !== null + + andReturn($mock);]]> + return $mock; + Mockery\Container @@ -166,6 +178,7 @@ require $tmpfname + $mock $parRefMethod $parRefMethodRetType @@ -185,16 +198,13 @@ purgeMockeryContainer startMockery - - $e - - - dismissed - purgeMockeryContainer startMockery + + dismissed + @@ -403,119 +413,95 @@ - + $constructorArgs $arg instanceof MockConfigurationBuilder is_object($arg) - is_string($arg) + + $keys + $mocks[$index] - - new $internalMockName() - - - $mock - + + rememberMock($mock)]]> + + + TMock + $config - $constructorArgs - $mockName $reference - _getInstance checkForNamedMockClashes - getGenerator - getLoader instanceMock + mockery_close mockery_setGroup + mockery_teardown + mockery_validateOrder + mockery_verify - + $blocks - $constructorArgs - getClassName()]]> - getClassName()]]> - $mock - mockery_thrownExceptions()]]> - $mockName - getConstantsMap()]]> - getInternalClassMethodParamMaps()]]> + $className + $className + $config + getTargetObject()]]> + getTargetObject()]]> + $def + getConstantsMap()]]> + getInternalClassMethodParamMaps()]]> + $name - $keys + $constructorArgs - _groups[$group]]]> _mocks[$reference]]]> _namedMocks[$name]]]> - _namedMocks[$name]]]> $blocks + $className $config - $count $def + $exception + $exceptions[] $hash - $instance - $mock - $mock - $mock - $mock - $mock $name - \Mockery\Mock - \Mockery\Mock - int + LegacyMockInterface|MockInterface - atLeast - byDefault - generate - getClassName - getClassName - getClassName getClassName getHash getName - getTargetObject - isInstanceMock - load - mockery_getExpectationCount - mockery_init - mockery_teardown - mockery_thrownExceptions - mockery_verify once setActualOrder setExpectedOrder setMethodName - shouldReceive - shouldReceive - - mockery_getExpectationCount()]]> - $mockName - + + _namedMocks]]> + - $count $mocks[$index] - _mocks[$reference]]]> - - Mock - + + $exceptions + ]]> + - $arg + $expectationClosure $parts[1] @@ -528,24 +514,30 @@ mockery_setGroup - \Mockery\LegacyMockInterface|\Mockery\MockInterface int - - mockingNonExistentMethodsAllowed() && (!class_exists($type, true) && !interface_exists($type, true))]]> - mockingNonExistentMethodsAllowed() && (!class_exists($type, true) && !interface_exists($type, true))]]> - 0]]> is_array($arg) + + mockery_init + - is_object($finalArg) + + atLeast + byDefault + mockery_thrownExceptions + + + atLeast + byDefault + - $class + $expectationClosure @@ -2012,15 +2004,11 @@ mockery_allocateOrder mockery_findExpectation mockery_getCurrentOrder - mockery_getExpectationCount mockery_getGroups mockery_getMockableProperties - mockery_init mockery_setCurrentOrder mockery_setExpectationsFor mockery_setGroup - mockery_teardown - mockery_verify shouldAllowMockingMethod shouldAllowMockingProtectedMethods shouldDeferMissing @@ -2051,9 +2039,6 @@ load - - load - From 7b131df7518e508fa30856f5819f97549fdc7035 Mon Sep 17 00:00:00 2001 From: Nathanael Esayeas Date: Tue, 27 Feb 2024 14:11:34 -0600 Subject: [PATCH 3/3] Refactor function call Signed-off-by: Nathanael Esayeas --- library/Mockery/Container.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Mockery/Container.php b/library/Mockery/Container.php index f6efd4ee0..0b42af05b 100644 --- a/library/Mockery/Container.php +++ b/library/Mockery/Container.php @@ -112,7 +112,7 @@ public function getKeyOfDemeterMockFor($method, $parent) if (count($match) === 1) { $res = array_values($match); - if (count($res) > 0) { + if ([] !== $res) { return $res[0]; } }