5
5
use MongoDB \BSON \Binary ;
6
6
use MongoDB \GridFS \CollectionWrapper ;
7
7
use MongoDB \GridFS \ReadableStream ;
8
+ use MongoDB \Tests \CommandObserver ;
9
+ use stdClass ;
8
10
9
11
/**
10
12
* Functional tests for the internal ReadableStream class.
@@ -188,6 +190,15 @@ public function testReadBytesWithNegativeLength()
188
190
$ stream ->readBytes (-1 );
189
191
}
190
192
193
+ public function testSeekBeforeReading ()
194
+ {
195
+ $ fileDocument = $ this ->collectionWrapper ->findFileById ('length-10 ' );
196
+ $ stream = new ReadableStream ($ this ->collectionWrapper , $ fileDocument );
197
+
198
+ $ stream ->seek (8 );
199
+ $ this ->assertSame ('ij ' , $ stream ->readBytes (2 ));
200
+ }
201
+
191
202
/**
192
203
* @expectedException MongoDB\Exception\InvalidArgumentException
193
204
* @expectedExceptionMessage $offset must be >= 0 and <= 10; given: 11
@@ -199,4 +210,109 @@ public function testSeekOutOfRange()
199
210
200
211
$ stream ->seek (11 );
201
212
}
213
+
214
+ /**
215
+ * @dataProvider providePreviousChunkSeekOffsetAndBytes
216
+ */
217
+ public function testSeekPreviousChunk ($ offset , $ length , $ expectedBytes )
218
+ {
219
+ $ fileDocument = $ this ->collectionWrapper ->findFileById ('length-10 ' );
220
+ $ stream = new ReadableStream ($ this ->collectionWrapper , $ fileDocument );
221
+
222
+ // Read to initialize and advance the chunk iterator to the last chunk
223
+ $ this ->assertSame ('abcdefghij ' , $ stream ->readBytes (10 ));
224
+
225
+ $ commands = [];
226
+
227
+ (new CommandObserver )->observe (
228
+ function () use ($ stream , $ offset , $ length , $ expectedBytes ) {
229
+ $ stream ->seek ($ offset );
230
+ $ this ->assertSame ($ expectedBytes , $ stream ->readBytes ($ length ));
231
+ },
232
+ function (stdClass $ command ) use (&$ commands ) {
233
+ $ commands [] = key ((array ) $ command );
234
+ }
235
+ );
236
+
237
+ $ this ->assertSame (['find ' ], $ commands );
238
+ }
239
+
240
+ public function providePreviousChunkSeekOffsetAndBytes ()
241
+ {
242
+ return [
243
+ [0 , 4 , 'abcd ' ],
244
+ [2 , 4 , 'cdef ' ],
245
+ [4 , 4 , 'efgh ' ],
246
+ [6 , 4 , 'ghij ' ],
247
+ ];
248
+ }
249
+
250
+ /**
251
+ * @dataProvider provideSameChunkSeekOffsetAndBytes
252
+ */
253
+ public function testSeekSameChunk ($ offset , $ length , $ expectedBytes )
254
+ {
255
+ $ fileDocument = $ this ->collectionWrapper ->findFileById ('length-10 ' );
256
+ $ stream = new ReadableStream ($ this ->collectionWrapper , $ fileDocument );
257
+
258
+ // Read to initialize and advance the chunk iterator to the middle chunk
259
+ $ this ->assertSame ('abcdef ' , $ stream ->readBytes (6 ));
260
+
261
+ $ commands = [];
262
+
263
+ (new CommandObserver )->observe (
264
+ function () use ($ stream , $ offset , $ length , $ expectedBytes ) {
265
+ $ stream ->seek ($ offset );
266
+ $ this ->assertSame ($ expectedBytes , $ stream ->readBytes ($ length ));
267
+ },
268
+ function (stdClass $ command ) use (&$ commands ) {
269
+ $ commands [] = key ((array ) $ command );
270
+ }
271
+ );
272
+
273
+ $ this ->assertSame ([], $ commands );
274
+ }
275
+
276
+ public function provideSameChunkSeekOffsetAndBytes ()
277
+ {
278
+ return [
279
+ [4 , 4 , 'efgh ' ],
280
+ [6 , 4 , 'ghij ' ],
281
+ ];
282
+ }
283
+
284
+ /**
285
+ * @dataProvider provideSubsequentChunkSeekOffsetAndBytes
286
+ */
287
+ public function testSeekSubsequentChunk ($ offset , $ length , $ expectedBytes )
288
+ {
289
+ $ fileDocument = $ this ->collectionWrapper ->findFileById ('length-10 ' );
290
+ $ stream = new ReadableStream ($ this ->collectionWrapper , $ fileDocument );
291
+
292
+ // Read to initialize the chunk iterator to the first chunk
293
+ $ this ->assertSame ('a ' , $ stream ->readBytes (1 ));
294
+
295
+ $ commands = [];
296
+
297
+ (new CommandObserver )->observe (
298
+ function () use ($ stream , $ offset , $ length , $ expectedBytes ) {
299
+ $ stream ->seek ($ offset );
300
+ $ this ->assertSame ($ expectedBytes , $ stream ->readBytes ($ length ));
301
+ },
302
+ function (stdClass $ command ) use (&$ commands ) {
303
+ $ commands [] = key ((array ) $ command );
304
+ }
305
+ );
306
+
307
+ $ this ->assertSame ([], $ commands );
308
+ }
309
+
310
+ public function provideSubsequentChunkSeekOffsetAndBytes ()
311
+ {
312
+ return [
313
+ [4 , 4 , 'efgh ' ],
314
+ [6 , 4 , 'ghij ' ],
315
+ [8 , 2 , 'ij ' ],
316
+ ];
317
+ }
202
318
}
0 commit comments