Commit d06c288e authored by Jeremy Mikola's avatar Jeremy Mikola

PHPLIB-367: BSONArray/Document cloning should respect uncloneable objects

parent 9420a3b4
...@@ -23,6 +23,7 @@ use MongoDB\Driver\Server; ...@@ -23,6 +23,7 @@ use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Exception\InvalidArgumentException; use MongoDB\Exception\InvalidArgumentException;
use stdClass; use stdClass;
use ReflectionClass;
/** /**
* Applies a type map to a document. * Applies a type map to a document.
...@@ -216,5 +217,9 @@ function recursive_copy($element) { ...@@ -216,5 +217,9 @@ function recursive_copy($element) {
return $element; return $element;
} }
if ( ! (new ReflectionClass($element))->isCloneable()) {
return $element;
}
return clone $element; return clone $element;
} }
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
namespace MongoDB\Tests\Model; namespace MongoDB\Tests\Model;
use MongoDB\BSON\ObjectId;
use MongoDB\Model\BSONArray; use MongoDB\Model\BSONArray;
use MongoDB\Model\BSONDocument; use MongoDB\Model\BSONDocument;
use MongoDB\Tests\TestCase; use MongoDB\Tests\TestCase;
use stdClass; use stdClass;
use ReflectionClass;
class BSONArrayTest extends TestCase class BSONArrayTest extends TestCase
{ {
...@@ -43,6 +45,36 @@ class BSONArrayTest extends TestCase ...@@ -43,6 +45,36 @@ class BSONArrayTest extends TestCase
$this->assertNotSame($array[1][2][1], $arrayClone[1][2][1]); $this->assertNotSame($array[1][2][1], $arrayClone[1][2][1]);
} }
public function testCloneRespectsUncloneableObjects()
{
$this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
$array = new BSONArray([
[new UncloneableObject],
new BSONArray([new UncloneableObject]),
]);
$arrayClone = clone $array;
$this->assertNotSame($array, $arrayClone);
$this->assertSame($array[0][0], $arrayClone[0][0]);
$this->assertNotSame($array[1], $arrayClone[1]);
$this->assertSame($array[1][0], $arrayClone[1][0]);
}
public function testCloneSupportsBSONTypes()
{
/* Note: this test does not check that the BSON type itself is cloned,
* as that is not yet supported in the driver (see: PHPC-1230). */
$array = new BSONArray([
[new ObjectId],
new BSONArray([new ObjectId]),
]);
$arrayClone = clone $array;
$this->assertNotSame($array, $arrayClone);
$this->assertNotSame($array[1], $arrayClone[1]);
}
public function testJsonSerialize() public function testJsonSerialize()
{ {
$document = new BSONArray([ $document = new BSONArray([
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
namespace MongoDB\Tests\Model; namespace MongoDB\Tests\Model;
use MongoDB\BSON\ObjectId;
use MongoDB\Model\BSONArray; use MongoDB\Model\BSONArray;
use MongoDB\Model\BSONDocument; use MongoDB\Model\BSONDocument;
use MongoDB\Tests\TestCase; use MongoDB\Tests\TestCase;
use ArrayObject; use ArrayObject;
use stdClass; use stdClass;
use ReflectionClass;
class BSONDocumentTest extends TestCase class BSONDocumentTest extends TestCase
{ {
...@@ -51,6 +53,36 @@ class BSONDocumentTest extends TestCase ...@@ -51,6 +53,36 @@ class BSONDocumentTest extends TestCase
$this->assertNotSame($document['b']['c'][1], $documentClone['b']['c'][1]); $this->assertNotSame($document['b']['c'][1], $documentClone['b']['c'][1]);
} }
public function testCloneRespectsUncloneableObjects()
{
$this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
$document = new BSONDocument([
'a' => ['a' => new UncloneableObject],
'b' => new BSONDocument(['a' => new UncloneableObject]),
]);
$documentClone = clone $document;
$this->assertNotSame($document, $documentClone);
$this->assertSame($document['a']['a'], $documentClone['a']['a']);
$this->assertNotSame($document['b'], $documentClone['b']);
$this->assertSame($document['b']['a'], $documentClone['b']['a']);
}
public function testCloneSupportsBSONTypes()
{
/* Note: this test does not check that the BSON type itself is cloned,
* as that is not yet supported in the driver (see: PHPC-1230). */
$document = new BSONDocument([
'a' => ['a' => new ObjectId],
'b' => new BSONDocument(['a' => new ObjectId]),
]);
$documentClone = clone $document;
$this->assertNotSame($document, $documentClone);
$this->assertNotSame($document['b'], $documentClone['b']);
}
public function testJsonSerialize() public function testJsonSerialize()
{ {
$document = new BSONDocument([ $document = new BSONDocument([
......
<?php
namespace MongoDB\Tests\Model;
/**
* This class is used by the BSONArray and BSONDocument clone tests.
*/
class UncloneableObject
{
private function __clone()
{
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment