Skip to content

Commit ba71fbb

Browse files
Revert "Closes #6498"
This reverts commit 6b0c3a2.
1 parent bbb938f commit ba71fbb

File tree

7 files changed

+87
-160
lines changed

7 files changed

+87
-160
lines changed

src/Framework/MockObject/Runtime/AbstractInvocationImplementation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ final public function willThrowException(Throwable $exception): InvocationStubbe
218218

219219
final public function seal(): void
220220
{
221-
$this->invocationHandler->seal();
221+
$this->invocationHandler->seal($this->invocationHandler->isMockObject());
222222
}
223223

224224
/**

src/Framework/MockObject/Runtime/Api/Method.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace PHPUnit\Framework\MockObject;
1111

1212
use PHPUnit\Framework\Constraint\Constraint;
13+
use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
1314
use PHPUnit\Framework\MockObject\Runtime\PropertyHook;
1415

1516
/**
@@ -25,7 +26,7 @@ public function method(Constraint|PropertyHook|string $constraint): InvocationSt
2526
{
2627
return $this
2728
->__phpunit_getInvocationHandler()
28-
->configureStub()
29+
->expects(new AnyInvokedCount)
2930
->method($constraint);
3031
}
3132
}

src/Framework/MockObject/Runtime/Api/MockObjectApi.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010
namespace PHPUnit\Framework\MockObject;
1111

12-
use function assert;
1312
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
1413

1514
/**
@@ -43,10 +42,6 @@ abstract public function __phpunit_unsetInvocationMocker(): void;
4342

4443
public function expects(InvocationOrder $matcher): InvocationMocker
4544
{
46-
$handler = $this->__phpunit_getInvocationHandler();
47-
48-
assert($handler instanceof MockObjectInvocationHandler);
49-
50-
return $handler->expects($matcher);
45+
return $this->__phpunit_getInvocationHandler()->expects($matcher);
5146
}
5247
}

src/Framework/MockObject/Runtime/Api/TestDoubleState.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,11 @@ public function invocationHandler(): InvocationHandler
4040
return $this->invocationHandler;
4141
}
4242

43-
if ($this->isMockObject) {
44-
$this->invocationHandler = new MockObjectInvocationHandler(
45-
$this->configurableMethods,
46-
$this->generateReturnValues,
47-
);
48-
} else {
49-
$this->invocationHandler = new TestStubInvocationHandler(
50-
$this->configurableMethods,
51-
$this->generateReturnValues,
52-
);
53-
}
43+
$this->invocationHandler = new InvocationHandler(
44+
$this->configurableMethods,
45+
$this->generateReturnValues,
46+
$this->isMockObject,
47+
);
5448

5549
return $this->invocationHandler;
5650
}

src/Framework/MockObject/Runtime/InvocationHandler.php

Lines changed: 78 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@
1010
namespace PHPUnit\Framework\MockObject;
1111

1212
use function array_any;
13+
use function array_unique;
14+
use function array_values;
15+
use function in_array;
1316
use function strtolower;
1417
use Exception;
15-
use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount;
18+
use PHPUnit\Framework\MockObject\Rule\InvocationOrder;
19+
use PHPUnit\Framework\MockObject\Rule\InvokedCount;
20+
use PHPUnit\Framework\MockObject\Rule\MethodName;
1621
use Throwable;
1722

1823
/**
1924
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
2025
*
2126
* @internal This class is not covered by the backward compatibility promise for PHPUnit
2227
*/
23-
abstract class InvocationHandler
28+
final class InvocationHandler
2429
{
25-
/**
26-
* @var list<ConfigurableMethod>
27-
*/
28-
protected readonly array $configurableMethods;
29-
3030
/**
3131
* @var list<Matcher>
3232
*/
@@ -36,16 +36,28 @@ abstract class InvocationHandler
3636
* @var array<non-empty-string, Matcher>
3737
*/
3838
private array $matcherMap = [];
39+
40+
/**
41+
* @var list<ConfigurableMethod>
42+
*/
43+
private readonly array $configurableMethods;
3944
private readonly bool $returnValueGeneration;
45+
private readonly bool $isMockObject;
4046
private bool $sealed = false;
4147

4248
/**
4349
* @param list<ConfigurableMethod> $configurableMethods
4450
*/
45-
public function __construct(array $configurableMethods, bool $returnValueGeneration)
51+
public function __construct(array $configurableMethods, bool $returnValueGeneration, bool $isMockObject = false)
4652
{
4753
$this->configurableMethods = $configurableMethods;
4854
$this->returnValueGeneration = $returnValueGeneration;
55+
$this->isMockObject = $isMockObject;
56+
}
57+
58+
public function isMockObject(): bool
59+
{
60+
return $this->isMockObject;
4961
}
5062

5163
public function hasMatchers(): bool
@@ -86,16 +98,23 @@ public function registerMatcher(string $id, Matcher $matcher): void
8698
/**
8799
* @throws TestDoubleSealedException
88100
*/
89-
public function configureStub(): InvocationStubber
101+
public function expects(InvocationOrder $rule): InvocationMocker|InvocationStubber
90102
{
91-
if ($this->isSealed()) {
103+
if ($this->sealed) {
92104
throw new TestDoubleSealedException;
93105
}
94106

95-
$matcher = new Matcher(new AnyInvokedCount);
96-
107+
$matcher = new Matcher($rule);
97108
$this->addMatcher($matcher);
98109

110+
if ($this->isMockObject) {
111+
return new InvocationMockerImplementation(
112+
$this,
113+
$matcher,
114+
...$this->configurableMethods,
115+
);
116+
}
117+
99118
return new InvocationStubberImplementation(
100119
$this,
101120
$matcher,
@@ -157,28 +176,64 @@ public function verify(): void
157176
}
158177
}
159178

160-
public function isSealed(): bool
179+
public function seal(bool $isMockObject): void
161180
{
162-
return $this->sealed;
163-
}
181+
if ($this->sealed) {
182+
return;
183+
}
184+
185+
$this->sealed = true;
186+
187+
if (!$isMockObject) {
188+
return;
189+
}
190+
191+
$configuredMethods = $this->configuredMethodNames();
192+
193+
foreach ($this->configurableMethods as $method) {
194+
if (!in_array($method->name(), $configuredMethods, true)) {
195+
$matcher = new Matcher(new InvokedCount(0));
164196

165-
abstract public function seal(): void;
197+
$matcher->setMethodNameRule(new MethodName($method->name()));
166198

167-
protected function addMatcher(Matcher $matcher): void
199+
$this->addMatcher($matcher);
200+
}
201+
}
202+
}
203+
204+
public function isSealed(): bool
168205
{
169-
$this->matchers[] = $matcher;
206+
return $this->sealed;
170207
}
171208

172-
protected function markSealed(): void
209+
private function addMatcher(Matcher $matcher): void
173210
{
174-
$this->sealed = true;
211+
$this->matchers[] = $matcher;
175212
}
176213

177214
/**
178-
* @return list<Matcher>
215+
* Returns the list of method names that have been configured with expectations.
216+
* Only considers exact string matches for method names.
217+
* Methods with any() expectation are considered configured.
218+
*
219+
* @return list<non-empty-string>
179220
*/
180-
protected function matchers(): array
221+
private function configuredMethodNames(): array
181222
{
182-
return $this->matchers;
223+
$names = [];
224+
225+
foreach ($this->matchers as $matcher) {
226+
if (!$matcher->hasMethodNameRule()) {
227+
continue;
228+
}
229+
230+
foreach ($this->configurableMethods as $method) {
231+
if ($matcher->methodNameRule()->matchesName($method->name())) {
232+
$names[] = $method->name();
233+
}
234+
}
235+
}
236+
237+
return array_values(array_unique($names));
183238
}
184239
}

src/Framework/MockObject/Runtime/MockObjectInvocationHandler.php

Lines changed: 0 additions & 91 deletions
This file was deleted.

src/Framework/MockObject/Runtime/TestStubInvocationHandler.php

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)