Upstream myclabs/DeepCopy state of the touched files before 14923870ae

This commit is contained in:
upstream committed 2026-09-04 07:47:46 +02:00
1 parent 380b19a6d3
commit 3814b3f178
3 files changed
+15 -76

No files matched your search

@@ -1,7 +1,6 @@
<?php <?php
namespace DeepCopy\TypeFilter\Spl; namespace DeepCopy\TypeFilter\Spl;
use Closure;
use DeepCopy\DeepCopy; use DeepCopy\DeepCopy;
use DeepCopy\TypeFilter\TypeFilter; use DeepCopy\TypeFilter\TypeFilter;
@@ -24,30 +23,11 @@ final class ArrayObjectFilter implements TypeFilter
public function apply(mixed $arrayObject) public function apply(mixed $arrayObject)
{ {
$clone = clone $arrayObject; $clone = clone $arrayObject;
$copy = $this->createCopyClosure();
foreach ($arrayObject->getArrayCopy() as $k => $v) { foreach ($arrayObject->getArrayCopy() as $k => $v) {
$clone->offsetSet($k, $copy($v)); $clone->offsetSet($k, $this->copier->copy($v));
} }
return $clone; return $clone;
} }
/**
* Copies through the recursive entry point rather than {@see DeepCopy::copy()},
* which would reset the map of already copied objects: shared objects would
* be duplicated and a cycle running through the ArrayObject would not
* terminate. Same approach as {@see SplDoublyLinkedListFilter}.
*/
private function createCopyClosure(): Closure
{
$copier = $this->copier;
$copy = function (mixed $value) use ($copier): mixed {
return $copier->recursiveCopy($value);
};
return Closure::bind($copy, null, DeepCopy::class);
}
} }
-29
View File
@@ -247,35 +247,6 @@ class DeepCopyTest extends TestCase
$this->assertSame($copy->getProp1()->c, $copy->getProp2()); $this->assertSame($copy->getProp1()->c, $copy->getProp2());
} }
public function test_it_keeps_reference_of_objects_shared_through_an_array_object()
{
$shared = new stdClass();
$object = new stdClass();
$object->collection = new ArrayObject(['a' => $shared, 'b' => $shared]);
$object->direct = $shared;
$copy = deep_copy($object);
$this->assertEqualButNotSame($shared, $copy->collection['a']);
$this->assertSame($copy->collection['a'], $copy->collection['b']);
$this->assertSame($copy->collection['a'], $copy->direct);
}
public function test_it_can_copy_graphs_whose_circular_reference_runs_through_an_array_object()
{
$parent = new stdClass();
$child = new stdClass();
$child->parent = $parent;
$parent->children = new ArrayObject([$child]);
$copy = deep_copy($parent);
$this->assertEqualButNotSame($child, $copy->children[0]);
$this->assertSame($copy, $copy->children[0]->parent);
}
public function test_it_can_copy_graphs_with_circular_references() public function test_it_can_copy_graphs_with_circular_references()
{ {
$a = new stdClass(); $a = new stdClass();
@@ -6,8 +6,8 @@ use ArrayObject;
use DeepCopy\DeepCopy; use DeepCopy\DeepCopy;
use DeepCopy\TypeFilter\Spl\ArrayObjectFilter; use DeepCopy\TypeFilter\Spl\ArrayObjectFilter;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy;
use RecursiveArrayIterator; use RecursiveArrayIterator;
use stdClass;
/** /**
* @author Dominic Tubach <dominic.tubach@to.com> * @author Dominic Tubach <dominic.tubach@to.com>
@@ -21,40 +21,28 @@ final class ArrayObjectFilterTest extends TestCase
*/ */
private $arrayObjectFilter; private $arrayObjectFilter;
/**
* @var DeepCopy|ObjectProphecy
*/
private $copierProphecy;
protected function setUp(): void protected function setUp(): void
{ {
$this->arrayObjectFilter = new ArrayObjectFilter(new DeepCopy()); $this->copierProphecy = $this->prophesize(DeepCopy::class);
$this->arrayObjectFilter = new ArrayObjectFilter(
$this->copierProphecy->reveal()
);
} }
public function test_it_deep_copies_an_array_object(): void public function test_it_deep_copies_an_array_object(): void
{ {
$foo = new stdClass(); $arrayObject = new ArrayObject(['foo' => 'bar'], ArrayObject::ARRAY_AS_PROPS, RecursiveArrayIterator::class);
$foo->bar = 'baz'; $this->copierProphecy->copy('bar')->willReturn('baz');
$arrayObject = new ArrayObject( /** @var \ArrayObject $newArrayObject */
['foo' => $foo],
ArrayObject::ARRAY_AS_PROPS,
RecursiveArrayIterator::class
);
/** @var ArrayObject $newArrayObject */
$newArrayObject = $this->arrayObjectFilter->apply($arrayObject); $newArrayObject = $this->arrayObjectFilter->apply($arrayObject);
$this->assertSame(['foo' => 'baz'], $newArrayObject->getArrayCopy());
$this->assertNotSame($foo, $newArrayObject['foo']);
$this->assertEquals($foo, $newArrayObject['foo']);
$this->assertSame(ArrayObject::ARRAY_AS_PROPS, $newArrayObject->getFlags()); $this->assertSame(ArrayObject::ARRAY_AS_PROPS, $newArrayObject->getFlags());
$this->assertSame(RecursiveArrayIterator::class, $newArrayObject->getIteratorClass()); $this->assertSame(RecursiveArrayIterator::class, $newArrayObject->getIteratorClass());
} }
public function test_it_keeps_objects_shared_inside_the_array_object_shared(): void
{
$shared = new stdClass();
$arrayObject = new ArrayObject(['a' => $shared, 'b' => $shared]);
/** @var ArrayObject $newArrayObject */
$newArrayObject = $this->arrayObjectFilter->apply($arrayObject);
$this->assertNotSame($shared, $newArrayObject['a']);
$this->assertSame($newArrayObject['a'], $newArrayObject['b']);
}
} }