@@ -30,6 +30,12 @@ public function testFlexibleNumericComparison(): void
30
30
$ this ->assertResult (true , $ c , ['x ' => 1.0 , 'y ' => 1.0 ], 'Float instead of expected int matches ' );
31
31
$ this ->assertResult (true , $ c , ['x ' => 1 , 'y ' => 1 ], 'Int instead of expected float matches ' );
32
32
$ this ->assertResult (false , $ c , ['x ' => 'foo ' , 'y ' => 1.0 ], 'Different type does not match ' );
33
+
34
+ /* Matches uses PHPUnit's comparators, which follow PHP behavior. This
35
+ * is more liberal than the comparison logic called for by the unified
36
+ * test format. This test can be removed when PHPLIB-1577 is addressed.
37
+ */
38
+ $ this ->assertResult (true , $ c , ['x ' => '1.0 ' , 'y ' => '1 ' ], 'Numeric strings may match ints and floats ' );
33
39
}
34
40
35
41
public function testDoNotAllowExtraRootKeys (): void
@@ -171,6 +177,37 @@ public function testOperatorSessionLsid(): void
171
177
$ this ->assertResult (false , $ c , ['x ' => 1 ], 'session LSID does not match (embedded) ' );
172
178
}
173
179
180
+ public function testOperatorMatchAsDocument (): void
181
+ {
182
+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => 1 ]]]);
183
+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches ' );
184
+ $ this ->assertResult (false , $ c , ['json ' => '{"x": 2} ' ], 'JSON document does not match ' );
185
+ $ this ->assertResult (false , $ c , ['json ' => '{"x": 1, "y": 2} ' ], 'JSON document cannot contain extra fields ' );
186
+
187
+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => 1.0 ]]]);
188
+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches (flexible numeric comparison) ' );
189
+
190
+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => ['$$exists ' => true ]]]]);
191
+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches (special operators) ' );
192
+ $ this ->assertResult (false , $ c , ['json ' => '{"y": 1} ' ], 'JSON document does not match (special operators) ' );
193
+
194
+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => ['$$type ' => 'objectId ' ]]]]);
195
+ $ this ->assertResult (true , $ c , ['json ' => '{"x": {"$oid": "57e193d7a9cc81b4027498b5"}} ' ], 'JSON document matches (extended JSON) ' );
196
+ $ this ->assertResult (false , $ c , ['json ' => '{"x": {"$numberDecimal": "1234.5"}} ' ], 'JSON document does not match (extended JSON) ' );
197
+ }
198
+
199
+ public function testOperatorMatchAsRoot (): void
200
+ {
201
+ $ c = new Matches (['x ' => ['$$matchAsRoot ' => ['y ' => 2 ]]]);
202
+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2 , 'z ' => 3 ]], 'Nested document matches (allow extra fields) ' );
203
+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2.0 , 'z ' => 3.0 ]], 'Nested document matches (flexible numeric comparison) ' );
204
+ $ this ->assertResult (false , $ c , ['x ' => ['y ' => 3 , 'z ' => 3 ]], 'Nested document does not match ' );
205
+
206
+ $ c = new Matches (['x ' => ['$$matchAsRoot ' => ['y ' => ['$$exists ' => true ]]]]);
207
+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2 , 'z ' => 3 ]], 'Nested document matches (special operators) ' );
208
+ $ this ->assertResult (false , $ c , ['x ' => ['z ' => 3 ]], 'Nested document matches (special operators) ' );
209
+ }
210
+
174
211
#[DataProvider('errorMessageProvider ' )]
175
212
public function testErrorMessages ($ expectedMessageRegex , Matches $ constraint , $ actualValue ): void
176
213
{
@@ -302,6 +339,10 @@ public static function operatorErrorMessageProvider()
302
339
'$$sessionLsid requires string ' ,
303
340
new Matches (['x ' => ['$$sessionLsid ' => 1 ]], new EntityMap ()),
304
341
],
342
+ '$$matchAsDocument type ' => [
343
+ '$$matchAsDocument requires a BSON document ' ,
344
+ new Matches (['x ' => ['$$matchAsDocument ' => 'foo ' ]]),
345
+ ],
305
346
];
306
347
}
307
348
0 commit comments