@@ -171,6 +171,37 @@ public function testOperatorSessionLsid(): void
171171 $ this ->assertResult (false , $ c , ['x ' => 1 ], 'session LSID does not match (embedded) ' );
172172 }
173173
174+ public function testOperatorMatchAsDocument (): void
175+ {
176+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => 1 ]]]);
177+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches ' );
178+ $ this ->assertResult (false , $ c , ['json ' => '{"x": 2} ' ], 'JSON document does not match ' );
179+ $ this ->assertResult (false , $ c , ['json ' => '{"x": 1, "y": 2} ' ], 'JSON document cannot contain extra fields ' );
180+
181+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => 1.0 ]]]);
182+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches (flexible numeric comparison) ' );
183+
184+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => ['$$exists ' => true ]]]]);
185+ $ this ->assertResult (true , $ c , ['json ' => '{"x": 1} ' ], 'JSON document matches (special operators) ' );
186+ $ this ->assertResult (false , $ c , ['json ' => '{"y": 1} ' ], 'JSON document does not match (special operators) ' );
187+
188+ $ c = new Matches (['json ' => ['$$matchAsDocument ' => ['x ' => ['$$type ' => 'objectId ' ]]]]);
189+ $ this ->assertResult (true , $ c , ['json ' => '{"x": {"$oid": "57e193d7a9cc81b4027498b5"}} ' ], 'JSON document matches (extended JSON) ' );
190+ $ this ->assertResult (false , $ c , ['json ' => '{"x": {"$numberDecimal": "1234.5"}} ' ], 'JSON document does not match (extended JSON) ' );
191+ }
192+
193+ public function testOperatorMatchAsRoot (): void
194+ {
195+ $ c = new Matches (['x ' => ['$$matchAsRoot ' => ['y ' => 2 ]]]);
196+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2 , 'z ' => 3 ]], 'Nested document matches (allow extra fields) ' );
197+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2.0 , 'z ' => 3.0 ]], 'Nested document matches (flexible numeric comparison) ' );
198+ $ this ->assertResult (false , $ c , ['x ' => ['y ' => 3 , 'z ' => 3 ]], 'Nested document does not match ' );
199+
200+ $ c = new Matches (['x ' => ['$$matchAsRoot ' => ['y ' => ['$$exists ' => true ]]]]);
201+ $ this ->assertResult (true , $ c , ['x ' => ['y ' => 2 , 'z ' => 3 ]], 'Nested document matches (special operators) ' );
202+ $ this ->assertResult (false , $ c , ['x ' => ['z ' => 3 ]], 'Nested document matches (special operators) ' );
203+ }
204+
174205 #[DataProvider('errorMessageProvider ' )]
175206 public function testErrorMessages ($ expectedMessageRegex , Matches $ constraint , $ actualValue ): void
176207 {
@@ -302,6 +333,10 @@ public static function operatorErrorMessageProvider()
302333 '$$sessionLsid requires string ' ,
303334 new Matches (['x ' => ['$$sessionLsid ' => 1 ]], new EntityMap ()),
304335 ],
336+ '$$matchAsDocument type ' => [
337+ '$$matchAsDocument requires a BSON document ' ,
338+ new Matches (['x ' => ['$$matchAsDocument ' => 'foo ' ]]),
339+ ],
305340 ];
306341 }
307342
0 commit comments