2
2
3
3
namespace MongoDB \Tests \UnifiedSpecTests ;
4
4
5
+ use MongoDB \Driver \Exception \BulkWriteCommandException ;
5
6
use MongoDB \Driver \Exception \BulkWriteException ;
6
7
use MongoDB \Driver \Exception \CommandException ;
7
8
use MongoDB \Driver \Exception \ExecutionTimeoutException ;
12
13
use stdClass ;
13
14
use Throwable ;
14
15
16
+ use function count ;
15
17
use function PHPUnit \Framework \assertArrayHasKey ;
16
18
use function PHPUnit \Framework \assertContainsOnly ;
17
19
use function PHPUnit \Framework \assertCount ;
@@ -56,14 +58,18 @@ final class ExpectedError
56
58
57
59
private ?string $ codeName = null ;
58
60
59
- private ?Matches $ matchesResultDocument = null ;
61
+ private ?Matches $ matchesErrorResponse = null ;
60
62
61
63
private array $ includedLabels = [];
62
64
63
65
private array $ excludedLabels = [];
64
66
65
67
private ?ExpectedResult $ expectedResult = null ;
66
68
69
+ private ?array $ writeErrors = null ;
70
+
71
+ private ?array $ writeConcernErrors = null ;
72
+
67
73
public function __construct (?stdClass $ o , EntityMap $ entityMap )
68
74
{
69
75
if ($ o === null ) {
@@ -102,7 +108,7 @@ public function __construct(?stdClass $o, EntityMap $entityMap)
102
108
103
109
if (isset ($ o ->errorResponse )) {
104
110
assertIsObject ($ o ->errorResponse );
105
- $ this ->matchesResultDocument = new Matches ($ o ->errorResponse , $ entityMap );
111
+ $ this ->matchesErrorResponse = new Matches ($ o ->errorResponse , $ entityMap );
106
112
}
107
113
108
114
if (isset ($ o ->errorLabelsContain )) {
@@ -120,6 +126,24 @@ public function __construct(?stdClass $o, EntityMap $entityMap)
120
126
if (property_exists ($ o , 'expectResult ' )) {
121
127
$ this ->expectedResult = new ExpectedResult ($ o , $ entityMap );
122
128
}
129
+
130
+ if (isset ($ o ->writeErrors )) {
131
+ assertIsObject ($ o ->writeErrors );
132
+ assertContainsOnly ('object ' , (array ) $ o ->writeErrors );
133
+
134
+ foreach ($ o ->writeErrors as $ i => $ writeError ) {
135
+ $ this ->writeErrors [$ i ] = new Matches ($ writeError , $ entityMap );
136
+ }
137
+ }
138
+
139
+ if (isset ($ o ->writeConcernErrors )) {
140
+ assertIsArray ($ o ->writeConcernErrors );
141
+ assertContainsOnly ('object ' , $ o ->writeConcernErrors );
142
+
143
+ foreach ($ o ->writeConcernErrors as $ i => $ writeConcernError ) {
144
+ $ this ->writeConcernErrors [$ i ] = new Matches ($ writeConcernError , $ entityMap );
145
+ }
146
+ }
123
147
}
124
148
125
149
/**
@@ -159,15 +183,21 @@ public function assert(?Throwable $e = null): void
159
183
$ this ->assertCodeName ($ e );
160
184
}
161
185
162
- if (isset ($ this ->matchesResultDocument )) {
163
- assertThat ($ e , logicalOr (isInstanceOf (CommandException::class), isInstanceOf (BulkWriteException::class)));
186
+ if (isset ($ this ->matchesErrorResponse )) {
187
+ assertThat ($ e , logicalOr (
188
+ isInstanceOf (CommandException::class),
189
+ isInstanceOf (BulkWriteException::class),
190
+ isInstanceOf (BulkWriteCommandException::class),
191
+ ));
164
192
165
193
if ($ e instanceof CommandException) {
166
- assertThat ($ e ->getResultDocument (), $ this ->matchesResultDocument , 'CommandException result document matches ' );
194
+ assertThat ($ e ->getResultDocument (), $ this ->matchesErrorResponse , 'CommandException result document matches expected errorResponse ' );
195
+ } elseif ($ e instanceof BulkWriteCommandException) {
196
+ assertThat ($ e ->getErrorReply (), $ this ->matchesErrorResponse , 'BulkWriteCommandException error reply matches expected errorResponse ' );
167
197
} elseif ($ e instanceof BulkWriteException) {
168
198
$ writeErrors = $ e ->getWriteResult ()->getErrorReplies ();
169
199
assertCount (1 , $ writeErrors );
170
- assertThat ($ writeErrors [0 ], $ this ->matchesResultDocument , 'BulkWriteException result document matches ' );
200
+ assertThat ($ writeErrors [0 ], $ this ->matchesErrorResponse , 'BulkWriteException first error reply matches expected errorResponse ' );
171
201
}
172
202
}
173
203
@@ -184,16 +214,34 @@ public function assert(?Throwable $e = null): void
184
214
}
185
215
186
216
if (isset ($ this ->expectedResult )) {
187
- assertInstanceOf (BulkWriteException::class, $ e );
188
- $ this ->expectedResult ->assert ($ e ->getWriteResult ());
217
+ assertThat ($ e , logicalOr (
218
+ isInstanceOf (BulkWriteException::class),
219
+ isInstanceOf (BulkWriteCommandException::class),
220
+ ));
221
+
222
+ if ($ e instanceof BulkWriteCommandException) {
223
+ $ this ->expectedResult ->assert ($ e ->getPartialResult ());
224
+ } elseif ($ e instanceof BulkWriteException) {
225
+ $ this ->expectedResult ->assert ($ e ->getWriteResult ());
226
+ }
227
+ }
228
+
229
+ if (isset ($ this ->writeErrors )) {
230
+ assertInstanceOf (BulkWriteCommandException::class, $ e );
231
+ $ this ->assertWriteErrors ($ e ->getWriteErrors ());
232
+ }
233
+
234
+ if (isset ($ this ->writeConcernErrors )) {
235
+ assertInstanceOf (BulkWriteCommandException::class, $ e );
236
+ $ this ->assertWriteConcernErrors ($ e ->getWriteConcernErrors ());
189
237
}
190
238
}
191
239
192
240
private function assertIsClientError (Throwable $ e ): void
193
241
{
194
- /* Note: BulkWriteException may proxy a previous exception. Unwrap it
195
- * to check the original error. */
196
- if ($ e instanceof BulkWriteException && $ e ->getPrevious () !== null ) {
242
+ /* Note: BulkWriteException and BulkWriteCommandException may proxy a
243
+ * previous exception. Unwrap it to check the original error. */
244
+ if (( $ e instanceof BulkWriteException || $ e instanceof BulkWriteCommandException) && $ e ->getPrevious () !== null ) {
197
245
$ e = $ e ->getPrevious ();
198
246
}
199
247
@@ -230,4 +278,47 @@ private function assertCodeName(ServerException $e): void
230
278
assertObjectHasProperty ('codeName ' , $ result );
231
279
assertSame ($ this ->codeName , $ result ->codeName );
232
280
}
281
+
282
+ private function assertWriteErrors (array $ writeErrors ): void
283
+ {
284
+ assertCount (count ($ this ->writeErrors ), $ writeErrors );
285
+
286
+ foreach ($ this ->writeErrors as $ i => $ matchesWriteError ) {
287
+ assertArrayHasKey ($ i , $ writeErrors );
288
+ $ writeError = $ writeErrors [$ i ];
289
+
290
+ // Not required by the spec test, but asserts PHPC correctness
291
+ assertSame ((int ) $ i , $ writeError ->getIndex ());
292
+
293
+ /* Convert the WriteError into a document for matching. These
294
+ * field names are derived from the CRUD spec. */
295
+ $ writeErrorDocument = [
296
+ 'code ' => $ writeError ->getCode (),
297
+ 'message ' => $ writeError ->getMessage (),
298
+ 'details ' => $ writeError ->getInfo (),
299
+ ];
300
+
301
+ assertThat ($ writeErrorDocument , $ matchesWriteError );
302
+ }
303
+ }
304
+
305
+ private function assertWriteConcernErrors (array $ writeConcernErrors ): void
306
+ {
307
+ assertCount (count ($ this ->writeConcernErrors ), $ writeConcernErrors );
308
+
309
+ foreach ($ this ->writeConcernErrors as $ i => $ matchesWriteConcernError ) {
310
+ assertArrayHasKey ($ i , $ writeConcernErrors );
311
+ $ writeConcernError = $ writeConcernErrors [$ i ];
312
+
313
+ /* Convert the WriteConcernError into a document for matching.
314
+ * These field names are derived from the CRUD spec. */
315
+ $ writeConcernErrorDocument = [
316
+ 'code ' => $ writeConcernError ->getCode (),
317
+ 'message ' => $ writeConcernError ->getMessage (),
318
+ 'details ' => $ writeConcernError ->getInfo (),
319
+ ];
320
+
321
+ assertThat ($ writeConcernErrorDocument , $ matchesWriteConcernError );
322
+ }
323
+ }
233
324
}
0 commit comments