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
'documentKey' => ['_id' => 1],
];
$this->assertSameDocument($expectedChange, $lastChange);
$this->assertMatchesDocument($expectedChange, $lastChange);
// Start Changestream Example 3
$resumeToken = ($lastChange !== null) ? $lastChange->_id : null;
......@@ -1002,7 +1002,7 @@ class DocumentationExamplesTest extends FunctionalTestCase
'documentKey' => ['_id' => 2],
];
$this->assertSameDocument($expectedChange, $nextChange);
$this->assertMatchesDocument($expectedChange, $nextChange);
// Start Changestream Example 4
$pipeline = [['$match' => ['$or' => [['fullDocument.username' => 'alice'], ['operationType' => 'delete']]]]];
......
......@@ -57,7 +57,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 2],
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream);
......@@ -74,7 +74,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 3]
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
}
public function testNextResumesAfterConnectionException()
......@@ -203,7 +203,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 2],
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream);
......@@ -224,7 +224,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'documentKey' => ['_id' => 3],
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
}
public function testKey()
......@@ -452,7 +452,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 1],
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
$this->killChangeStreamCursor($changeStream);
......@@ -466,7 +466,7 @@ class WatchFunctionalTest extends FunctionalTestCase
'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
'documentKey' => ['_id' => 2],
];
$this->assertSameDocument($expectedResult, $changeStream->current());
$this->assertMatchesDocument($expectedResult, $changeStream->current());
}
/**
......@@ -484,16 +484,8 @@ class WatchFunctionalTest extends FunctionalTestCase
$changeStream->next();
$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()
......
......@@ -69,6 +69,49 @@ abstract class TestCase extends BaseTestCase
$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)
{
$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