From 12c5d771833312544dfc687f4d48d77a4a6e8b0f Mon Sep 17 00:00:00 2001 From: Robert Basic Date: Thu, 26 Dec 2019 10:27:17 +0100 Subject: [PATCH 1/2] Revert "Improve exception debugging" This reverts commit 8b3789415c1a86f5623af5a48615592246163589. --- composer.json | 3 +- .../NoMatchingExpectationException.php | 169 ++---------------- library/Mockery/Expectation.php | 8 - library/Mockery/ExpectationDirector.php | 17 +- tests/Mockery/ContainerTest.php | 4 +- tests/Mockery/ExpectationTest.php | 2 +- 6 files changed, 29 insertions(+), 174 deletions(-) diff --git a/composer.json b/composer.json index bc846435f..bf0bd0e1a 100644 --- a/composer.json +++ b/composer.json @@ -33,8 +33,7 @@ "require": { "php": ">=5.6.0", "lib-pcre": ">=7.0", - "hamcrest/hamcrest-php": "~2.0", - "sebastian/comparator": "^1.2.4|^3.0" + "hamcrest/hamcrest-php": "~2.0" }, "require-dev": { "phpunit/phpunit": "~5.7.10|~6.5|~7.0|~8.0" diff --git a/library/Mockery/Exception/NoMatchingExpectationException.php b/library/Mockery/Exception/NoMatchingExpectationException.php index c320653e9..fe5f3515a 100644 --- a/library/Mockery/Exception/NoMatchingExpectationException.php +++ b/library/Mockery/Exception/NoMatchingExpectationException.php @@ -20,194 +20,51 @@ namespace Mockery\Exception; -use Hamcrest\Util; use Mockery; -use SebastianBergmann\Comparator\ComparisonFailure; -use SebastianBergmann\Comparator\Factory; class NoMatchingExpectationException extends Mockery\Exception { - /** - * @var string - */ - protected $method; + protected $method = null; - /** - * @var array - */ - protected $actual; + protected $actual = array(); - /** - * @var Mockery\MockInterface - */ - protected $mockObject; + protected $mockObject = null; - /** - * @param string $methodName - * @param array $actualArguments - * @param array $expectations - */ - public function __construct( - Mockery\MockInterface $mock, - $methodName, - $actualArguments, - $expectations - ) { - $this->setMock($mock); - $this->setMethodName($methodName); - $this->setActualArguments($actualArguments); - - $diffs = []; - foreach ($expectations as $expectation) { - $expectedArguments = $expectation->getExpectedArgs(); - - $diff = $this->diff( - $this->normalizeForDiff($expectedArguments), - $this->normalizeForDiff($actualArguments) - ); - if (null === $diff) { - // If we reach this, it means that the exception has not been - // raised by a non-strict equality. So the diff is null. - // We do the comparison again but this time comparing references - // of objects. - $diff = $this->diff( - $this->normalizeForStrictDiff($expectedArguments), - $this->normalizeForStrictDiff($actualArguments) - ); - } - - $diffs[] = sprintf( - "\n%s::%s with arguments%s", - $expectation->getMock()->mockery_getName(), - $expectation->getName(), - null !== $diff ? $diff : "\n### No diff ###" - ); - } - - $message = 'No matching expectation found for ' - . $this->getMockName() . '::' - . \Mockery::formatArgs($methodName, $actualArguments) - . '. Either the method was unexpected or its arguments matched' - . ' no expected argument list for this method.' - . PHP_EOL . PHP_EOL - . 'Here is the list of available expectations and their diff with actual input:' - . PHP_EOL - . implode('', $diffs); - - parent::__construct($message, 0, null); - } - - /** - * @return $this - */ - private function setMock(Mockery\MockInterface $mock) + public function setMock(Mockery\LegacyMockInterface $mock) { $this->mockObject = $mock; return $this; } - /** - * @param string $name - * - * @return $this - */ - private function setMethodName($name) + public function setMethodName($name) { $this->method = $name; return $this; } - /** - * @param array $count - * - * @return $this - */ - private function setActualArguments($count) + public function setActualArguments($count) { $this->actual = $count; return $this; } - /** - * @return array - */ - public function getActualArguments() - { - return $this->actual; - } - - /** - * @return Mockery\MockInterface - */ - private function getMock() + public function getMock() { return $this->mockObject; } - /** - * @return string - */ - private function getMockName() + public function getMethodName() { - return $this->getMock()->mockery_getName(); - } - - /** - * @param array $expectedArguments - * @param array $actualArguments - * - * @return string|null - */ - private function diff($expectedArguments, $actualArguments) - { - $comparatorFactory = new Factory(); - $comparator = $comparatorFactory->getComparatorFor( - $expectedArguments, - $actualArguments - ); - try { - $comparator->assertEquals($expectedArguments, $actualArguments); - } catch (ComparisonFailure $e) { - return $e->getDiff(); - } - - return null; + return $this->method; } - /** - * @param array $args - * - * @return array - */ - private function normalizeForDiff($args) + public function getActualArguments() { - // Wraps items with an IsEqual matcher if it isn't a matcher already - // in order to be sure to compare same nature objects. - return Util::createMatcherArray($args); + return $this->actual; } - /** - * @param array $args - * - * @return array - */ - private function normalizeForStrictDiff($args) + public function getMockName() { - $normalized = []; - foreach ($args as $arg) { - if (!is_object($arg)) { - $normalizedArg = Util::createMatcherArray([$arg]); - $normalized[] = reset($normalizedArg); - continue; - } - - $objectRef = function_exists('spl_object_id') - ? spl_object_id($arg) - : spl_object_hash($arg); - - $normalized[] = get_class($arg).'#ref_'.$objectRef; - } - - return $normalized; + return $this->getMock()->mockery_getName(); } } diff --git a/library/Mockery/Expectation.php b/library/Mockery/Expectation.php index 613082003..4a12fc855 100644 --- a/library/Mockery/Expectation.php +++ b/library/Mockery/Expectation.php @@ -911,12 +911,4 @@ public function getExceptionMessage() { return $this->_because; } - - /** - * @return array - */ - public function getExpectedArgs() - { - return $this->_expectedArgs; - } } diff --git a/library/Mockery/ExpectationDirector.php b/library/Mockery/ExpectationDirector.php index 84ba5e0af..1310c1b38 100644 --- a/library/Mockery/ExpectationDirector.php +++ b/library/Mockery/ExpectationDirector.php @@ -89,12 +89,19 @@ public function call(array $args) { $expectation = $this->findExpectation($args); if (is_null($expectation)) { - throw new \Mockery\Exception\NoMatchingExpectationException( - $this->_mock, - $this->_name, - $args, - $this->getExpectations() + $exception = new \Mockery\Exception\NoMatchingExpectationException( + 'No matching handler found for ' + . $this->_mock->mockery_getName() . '::' + . \Mockery::formatArgs($this->_name, $args) + . '. Either the method was unexpected or its arguments matched' + . ' no expected argument list for this method' + . PHP_EOL . PHP_EOL + . \Mockery::formatObjects($args) ); + $exception->setMock($this->_mock) + ->setMethodName($this->_name) + ->setActualArguments($args); + throw $exception; } return $expectation->verifyCall($args); } diff --git a/tests/Mockery/ContainerTest.php b/tests/Mockery/ContainerTest.php index 9cdde4be7..ea35dad48 100644 --- a/tests/Mockery/ContainerTest.php +++ b/tests/Mockery/ContainerTest.php @@ -1239,7 +1239,7 @@ public function testHandlesMethodWithArgumentExpectationWhenCalledWithResource() $mock->shouldReceive('foo')->with(array('yourself' => 21)); $this->expectException(\Mockery\Exception\NoMatchingExpectationException::class); - $this->expectExceptionMessage("0 => Hamcrest\Core\IsEqual Object (...)"); + $this->expectExceptionMessage('MyTestClass::foo(resource(...))'); $mock->foo(fopen('php://memory', 'r')); } @@ -1252,7 +1252,7 @@ public function testHandlesMethodWithArgumentExpectationWhenCalledWithCircularAr $mock->shouldReceive('foo')->with(array('yourself' => 21)); $this->expectException(\Mockery\Exception\NoMatchingExpectationException::class); - $this->expectExceptionMessage("'myself' => Hamcrest\Core\IsEqual Object (...)"); + $this->expectExceptionMessage("MyTestClass::foo(['myself' => [...]])"); $mock->foo($testArray); } diff --git a/tests/Mockery/ExpectationTest.php b/tests/Mockery/ExpectationTest.php index 245072852..c2db568f9 100644 --- a/tests/Mockery/ExpectationTest.php +++ b/tests/Mockery/ExpectationTest.php @@ -1436,7 +1436,7 @@ public function testClassConstraintThrowsExceptionWhenConstraintUnmatched() { $this->mock->shouldReceive('foo')->with(Mockery::type('stdClass')); $this->expectException(\Mockery\Exception::class); - $this->mock->foo(new \DateTime()); + $this->mock->foo(new Exception); Mockery::close(); } From 580b98c96219ce598a7f3610ed1352f1ecf6de27 Mon Sep 17 00:00:00 2001 From: Robert Basic Date: Thu, 26 Dec 2019 10:30:21 +0100 Subject: [PATCH 2/2] Add changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 774c27e7c..3a7438793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 1.3.1 (2019-12-26) +* Revert improved exception debugging due to BC breaks (#1032) + ## 1.3.0 (2019-11-24) * Added capture `Mockery::capture` convenience matcher (#1020)