Commit 930fb185 authored by Jeremy Mikola's avatar Jeremy Mikola

Ignore extra fields in change stream document comparisons

MongoDB 4.0 adds a "clusterTime" field to change stream documents. Rather than add conditional logic to expect this in tests, implement a new comparison function that fields not found in our expected document.
parent c0d35516
...@@ -979,7 +979,7 @@ class DocumentationExamplesTest extends FunctionalTestCase ...@@ -979,7 +979,7 @@ class DocumentationExamplesTest extends FunctionalTestCase
'documentKey' => ['_id' => 1], 'documentKey' => ['_id' => 1],
]; ];
$this->assertSameDocument($expectedChange, $lastChange); $this->assertMatchesDocument($expectedChange, $lastChange);
// Start Changestream Example 3 // Start Changestream Example 3
$resumeToken = ($lastChange !== null) ? $lastChange->_id : null; $resumeToken = ($lastChange !== null) ? $lastChange->_id : null;
...@@ -1002,7 +1002,7 @@ class DocumentationExamplesTest extends FunctionalTestCase ...@@ -1002,7 +1002,7 @@ class DocumentationExamplesTest extends FunctionalTestCase
'documentKey' => ['_id' => 2], 'documentKey' => ['_id' => 2],
]; ];
$this->assertSameDocument($expectedChange, $nextChange); $this->assertMatchesDocument($expectedChange, $nextChange);
// Start Changestream Example 4 // Start Changestream Example 4
$pipeline = [['$match' => ['$or' => [['fullDocument.username' => 'alice'], ['operationType' => 'delete']]]]]; $pipeline = [['$match' => ['$or' => [['fullDocument.username' => 'alice'], ['operationType' => 'delete']]]]];
......
...@@ -57,7 +57,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -57,7 +57,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 2], 'documentKey' => ['_id' => 2],
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream); $this->killChangeStreamCursor($changeStream);
...@@ -74,7 +74,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -74,7 +74,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 3] 'documentKey' => ['_id' => 3]
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
} }
public function testNextResumesAfterConnectionException() public function testNextResumesAfterConnectionException()
...@@ -203,7 +203,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -203,7 +203,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 2], 'documentKey' => ['_id' => 2],
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream); $this->killChangeStreamCursor($changeStream);
...@@ -224,7 +224,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -224,7 +224,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 3], 'documentKey' => ['_id' => 3],
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
} }
public function testKey() public function testKey()
...@@ -452,7 +452,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -452,7 +452,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()], 'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 1], 'documentKey' => ['_id' => 1],
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream); $this->killChangeStreamCursor($changeStream);
...@@ -466,7 +466,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -466,7 +466,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()], 'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 2], 'documentKey' => ['_id' => 2],
]; ];
$this->assertSameDocument($expectedResult, $changeStream->current()); $this->assertMatchesDocument($expectedResult, $changeStream->current());
} }
/** /**
...@@ -484,16 +484,8 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -484,16 +484,8 @@ class WatchFunctionalTest extends FunctionalTestCase
$changeStream->next(); $changeStream->next();
$this->assertTrue($changeStream->valid()); $this->assertTrue($changeStream->valid());
$changeDocument = $changeStream->current();
// Unset the resume token and namespace, which are intentionally omitted
if (is_array($changeDocument)) {
unset($changeDocument['_id'], $changeDocument['ns']);
} else {
unset($changeDocument->_id, $changeDocument->ns);
}
$this->assertEquals($expectedChangeDocument, $changeDocument); $this->assertMatchesDocument($expectedChangeDocument, $changeStream->current());
} }
public function provideTypeMapOptionsAndExpectedChangeDocument() public function provideTypeMapOptionsAndExpectedChangeDocument()
......
...@@ -69,6 +69,49 @@ abstract class TestCase extends BaseTestCase ...@@ -69,6 +69,49 @@ abstract class TestCase extends BaseTestCase
$this->assertCount(1, $errors); $this->assertCount(1, $errors);
} }
/**
* Asserts that a document has expected values for some fields.
*
* Only fields in the expected document will be checked. The actual document
* may contain additional fields.
*
* @param array|object $expectedDocument
* @param array|object $actualDocument
*/
protected function assertMatchesDocument($expectedDocument, $actualDocument)
{
$normalizedExpectedDocument = $this->normalizeBSON($expectedDocument);
$normalizedActualDocument = $this->normalizeBSON($actualDocument);
$extraKeys = [];
/* Avoid unsetting fields while we're iterating on the ArrayObject to
* work around https://bugs.php.net/bug.php?id=70246 */
foreach ($normalizedActualDocument as $key => $value) {
if ( ! $normalizedExpectedDocument->offsetExists($key)) {
$extraKeys[] = $key;
}
}
foreach ($extraKeys as $key) {
$normalizedActualDocument->offsetUnset($key);
}
$this->assertEquals(
\MongoDB\BSON\toJSON(\MongoDB\BSON\fromPHP($normalizedExpectedDocument)),
\MongoDB\BSON\toJSON(\MongoDB\BSON\fromPHP($normalizedActualDocument))
);
}
/**
* Asserts that a document has expected values for all fields.
*
* The actual document will be compared directly with the expected document
* and may not contain extra fields.
*
* @param array|object $expectedDocument
* @param array|object $actualDocument
*/
protected function assertSameDocument($expectedDocument, $actualDocument) protected function assertSameDocument($expectedDocument, $actualDocument)
{ {
$this->assertEquals( $this->assertEquals(
......
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