From 3b46e3544ab8c8a97057d1731fe916b9ee318b8f Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 27 Oct 2020 08:49:36 +0100 Subject: [PATCH 1/2] Add a way to make the CallCenter fail fast --- src/Prophecy/Call/CallCenter.php | 17 ++++++++++++++++- src/Prophecy/Prophecy/ObjectProphecy.php | 10 ++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Prophecy/Call/CallCenter.php b/src/Prophecy/Call/CallCenter.php index 00c526d7e..7b5329333 100644 --- a/src/Prophecy/Call/CallCenter.php +++ b/src/Prophecy/Call/CallCenter.php @@ -27,6 +27,11 @@ class CallCenter { private $util; + /** + * @var bool + */ + private $failFast = false; + /** * @var Call[] */ @@ -81,7 +86,12 @@ public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments // There are method prophecies, so it's a fake/stub. Searching prophecy for this call $matches = $this->findMethodProphecies($prophecy, $methodName, $arguments); - // If fake/stub doesn't have method prophecy for this call - throw exception + // If fake/stub doesn't have method prophecy for this call - throw exception to fail fast + if ($this->failFast && !count($matches)) { + $this->createUnexpectedCallException($prophecy, $methodName, $arguments); + } + + // If fake/stub doesn't have method prophecy for this call - record unexpected call and fail on checkPredictions if (!count($matches)) { $this->unexpectedCalls->attach(new Call($methodName, $arguments, null, null, $file, $line), $prophecy); $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line); @@ -145,6 +155,11 @@ public function findCalls($methodName, ArgumentsWildcard $wildcard) ); } + public function makeUnexpectedCallsFailFast(bool $failFast): void + { + $this->failFast = $failFast; + } + /** * @throws UnexpectedCallException */ diff --git a/src/Prophecy/Prophecy/ObjectProphecy.php b/src/Prophecy/Prophecy/ObjectProphecy.php index 11b87cf1b..408e53a00 100644 --- a/src/Prophecy/Prophecy/ObjectProphecy.php +++ b/src/Prophecy/Prophecy/ObjectProphecy.php @@ -126,6 +126,16 @@ public function reveal() return $double; } + /** + * Disables the possibility of using this as a spy, making unexpected calls fail immediately + * + * @param bool $enable + */ + public function enableSpyBehavior(bool $enable = true): void + { + $this->callCenter->makeUnexpectedCallsFailFast($enable); + } + /** * Adds method prophecy to object prophecy. * From 26d364404dc1117ff1fe3a4975ae39da8f1387bc Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 27 Oct 2020 10:27:14 +0100 Subject: [PATCH 2/2] Add new specs --- spec/Prophecy/Call/CallCenterSpec.php | 27 +++++++++++++++++++ spec/Prophecy/Prophecy/ObjectProphecySpec.php | 10 +++++++ src/Prophecy/Prophecy/ObjectProphecy.php | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/spec/Prophecy/Call/CallCenterSpec.php b/spec/Prophecy/Call/CallCenterSpec.php index e0cdab646..279831071 100644 --- a/spec/Prophecy/Call/CallCenterSpec.php +++ b/spec/Prophecy/Call/CallCenterSpec.php @@ -124,6 +124,33 @@ function it_executes_promise_of_method_prophecy_that_matches_with_highest_score_ ->shouldReturn('second'); } + function createWithFailFast(bool $failFast) + { + $callCenter = new self(); + $callCenter->makeUnexpectedCallsFailFast($failFast); + + return $callCenter; + } + + function it_throws_exception_if_call_does_not_match_any_of_defined_method_prophecies_and_fail_fast_is_enabled( + $objectProphecy, + MethodProphecy $method, + ArgumentsWildcard $arguments + ) { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(false); + $arguments->__toString()->willReturn('arg1, arg2'); + + $objectProphecy->getMethodProphecies()->willReturn(array('method1' => array($method))); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->makeUnexpectedCallsFailFast(true); + + $this->shouldThrow('Prophecy\Exception\Call\UnexpectedCallException') + ->duringMakeCall($objectProphecy, 'getName', array('world', 'everything')); + } + function it_returns_null_if_method_prophecy_that_matches_makeCall_arguments_has_no_promise( $objectProphecy, MethodProphecy $method, diff --git a/spec/Prophecy/Prophecy/ObjectProphecySpec.php b/spec/Prophecy/Prophecy/ObjectProphecySpec.php index 782c97b8d..63c433318 100644 --- a/spec/Prophecy/Prophecy/ObjectProphecySpec.php +++ b/spec/Prophecy/Prophecy/ObjectProphecySpec.php @@ -298,6 +298,16 @@ function it_throws_UnexpectedCallException_during_checkPredictions_if_unexpected $this->shouldThrow('Prophecy\Exception\Call\UnexpectedCallException') ->duringCheckProphecyMethodsPredictions(); } + + function it_makes_CallCenter_fail_fast_if_spy_behaviour_is_disabled($lazyDouble, CallCenter $callCenter) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->makeUnexpectedCallsFailFast(true) + ->shouldBeCalled(); + + $this->enableSpyBehavior(false); + } } class ObjectProphecySpecFixtureA diff --git a/src/Prophecy/Prophecy/ObjectProphecy.php b/src/Prophecy/Prophecy/ObjectProphecy.php index 408e53a00..dac53793e 100644 --- a/src/Prophecy/Prophecy/ObjectProphecy.php +++ b/src/Prophecy/Prophecy/ObjectProphecy.php @@ -133,7 +133,7 @@ public function reveal() */ public function enableSpyBehavior(bool $enable = true): void { - $this->callCenter->makeUnexpectedCallsFailFast($enable); + $this->callCenter->makeUnexpectedCallsFailFast(! $enable); } /**