Skip to content

Commit

Permalink
Cloning readonly properties does not work in PHP 8.2
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Apr 9, 2024
1 parent 20c1475 commit 5af0410
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@
*/
namespace PHPUnit\Framework\MockObject;

use function version_compare;
use PHPUnit\Event\Code\TestMethodBuilder;
use PHPUnit\Event\Facade as EventFacade;

/**
* @internal This trait is not covered by the backward compatibility promise for PHPUnit
*/
trait DoubledCloneMethod
{
public function __clone(): void
{
if (version_compare('8.3.0', PHP_VERSION, '>')) {
EventFacade::emitter()->testTriggeredPhpunitError(
TestMethodBuilder::fromCallStack(),
'Cloning test double objects requires PHP 8.3',

Check warning on line 26 in src/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php

View check run for this annotation

Codecov / codecov/patch

src/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php#L24-L26

Added lines #L24 - L26 were not covered by tests
);

return;

Check warning on line 29 in src/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php

View check run for this annotation

Codecov / codecov/patch

src/Framework/MockObject/Runtime/Api/DoubledCloneMethod.php#L29

Added line #L29 was not covered by tests
}

$this->__phpunit_state = clone $this->__phpunit_state;

$this->__phpunit_state()->cloneInvocationHandler();
Expand Down
13 changes: 13 additions & 0 deletions src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@
*/
namespace PHPUnit\Framework\MockObject;

use function version_compare;
use PHPUnit\Event\Code\TestMethodBuilder;
use PHPUnit\Event\Facade as EventFacade;

/**
* @internal This trait is not covered by the backward compatibility promise for PHPUnit
*/
trait ProxiedCloneMethod
{
public function __clone(): void
{
if (version_compare('8.3.0', PHP_VERSION, '>')) {
EventFacade::emitter()->testTriggeredPhpunitError(
TestMethodBuilder::fromCallStack(),
'Cloning test double objects requires PHP 8.3',

Check warning on line 26 in src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php

View check run for this annotation

Codecov / codecov/patch

src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php#L24-L26

Added lines #L24 - L26 were not covered by tests
);

return;

Check warning on line 29 in src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php

View check run for this annotation

Codecov / codecov/patch

src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php#L29

Added line #L29 was not covered by tests
}

$this->__phpunit_state = clone $this->__phpunit_state;

Check warning on line 32 in src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php

View workflow job for this annotation

GitHub Actions / Mutation Testing

Escaped Mutant for Mutator "CloneRemoval": --- Original +++ New @@ @@ EventFacade::emitter()->testTriggeredPhpunitError(TestMethodBuilder::fromCallStack(), 'Cloning test double objects requires PHP 8.3'); return; } - $this->__phpunit_state = clone $this->__phpunit_state; + $this->__phpunit_state = $this->__phpunit_state; $this->__phpunit_state()->cloneInvocationHandler(); parent::__clone(); } abstract public function __phpunit_state(): TestDoubleState; }

$this->__phpunit_state()->cloneInvocationHandler();

Check warning on line 34 in src/Framework/MockObject/Runtime/Api/ProxiedCloneMethod.php

View workflow job for this annotation

GitHub Actions / Mutation Testing

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ return; } $this->__phpunit_state = clone $this->__phpunit_state; - $this->__phpunit_state()->cloneInvocationHandler(); + parent::__clone(); } abstract public function __phpunit_state(): TestDoubleState; }
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/Framework/MockObject/MockObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnorePhpunitDeprecations;
use PHPUnit\Framework\Attributes\Medium;
use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -443,6 +444,7 @@ public function testWillReturnCallbackWithVariadicVariables(): void
$this->assertSame($testData, $actual);
}

#[RequiresPhp('8.3')]
public function testExpectationsAreClonedWhenTestDoubleIsCloned(): void
{
$double = $this->createMock(InterfaceWithReturnTypeDeclaration::class);
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/Framework/MockObject/TestDoubleTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Exception;
use PHPUnit\Framework\Attributes\IgnorePhpunitDeprecations;
use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
use PHPUnit\TestFixture\MockObject\ExtendableClassWithCloneMethod;
Expand Down Expand Up @@ -240,6 +241,7 @@ final public function testMethodWithNeverReturnTypeDeclarationThrowsException():
}

#[TestDox('Original __clone() method is not called by default when test double object is cloned')]
#[RequiresPhp('8.3')]
final public function testOriginalCloneMethodIsNotCalledByDefaultWhenTestDoubleObjectIsCloned(): void
{
$double = clone $this->createTestDouble(ExtendableClassWithCloneMethod::class);
Expand All @@ -248,6 +250,7 @@ final public function testOriginalCloneMethodIsNotCalledByDefaultWhenTestDoubleO
}

#[TestDox('Original __clone() method can optionally be called when test double object is cloned')]
#[RequiresPhp('8.3')]
final public function testOriginalCloneMethodCanOptionallyBeCalledWhenTestDoubleObjectIsCloned(): void
{
$double = $this->getMockBuilder(ExtendableClassWithCloneMethod::class)->enableOriginalClone()->getMock();
Expand Down

0 comments on commit 5af0410

Please sign in to comment.