@@ -292,6 +292,90 @@ function ($result) use (&$count) {
292292 $ this ->assertSame (5 , $ count );
293293 }
294294
295+ public function testChunksProcessLastPartialChunk (): void
296+ {
297+ $ table = $ this ->database ->table ('sample_table ' );
298+ $ this ->fillData ();
299+
300+ $ select = $ table ->select ()->orderBy ('id ' );
301+
302+ // 10 rows split by chunks of 3: the last chunk holds the single remaining row (10 % 3 == 1)
303+ $ visited = [];
304+ $ select ->runChunks (
305+ 3 ,
306+ function (StatementInterface $ result ) use (&$ visited ): void {
307+ foreach ($ result as $ row ) {
308+ $ visited [] = $ row ['id ' ];
309+ }
310+ },
311+ );
312+
313+ $ this ->assertEquals (\range (1 , 10 ), $ visited );
314+ }
315+
316+ public function testChunksWithLimitGreaterThanCount (): void
317+ {
318+ $ table = $ this ->database ->table ('sample_table ' );
319+ $ this ->fillData ();
320+
321+ $ select = $ table ->select ()->orderBy ('id ' );
322+
323+ // chunk size larger than the total row count must still yield every row in a single chunk
324+ $ visited = [];
325+ $ chunks = 0 ;
326+ $ select ->runChunks (
327+ 100 ,
328+ function (StatementInterface $ result ) use (&$ visited , &$ chunks ): void {
329+ $ chunks ++;
330+ foreach ($ result as $ row ) {
331+ $ visited [] = $ row ['id ' ];
332+ }
333+ },
334+ );
335+
336+ $ this ->assertSame (1 , $ chunks );
337+ $ this ->assertEquals (\range (1 , 10 ), $ visited );
338+ }
339+
340+ public function testChunksOnEmptyResultNeverInvokesCallback (): void
341+ {
342+ $ table = $ this ->database ->table ('sample_table ' );
343+ // no data inserted
344+
345+ $ select = $ table ->select ();
346+
347+ $ invoked = false ;
348+ $ select ->runChunks (
349+ 5 ,
350+ function () use (&$ invoked ): void {
351+ $ invoked = true ;
352+ },
353+ );
354+
355+ $ this ->assertFalse ($ invoked );
356+ }
357+
358+ public function testChunksPassOffsetAndCountToCallback (): void
359+ {
360+ $ table = $ this ->database ->table ('sample_table ' );
361+ $ this ->fillData ();
362+
363+ $ select = $ table ->select ();
364+
365+ $ offsets = [];
366+ $ counts = [];
367+ $ select ->runChunks (
368+ 3 ,
369+ function (StatementInterface $ result , int $ offset , int $ count ) use (&$ offsets , &$ counts ): void {
370+ $ offsets [] = $ offset ;
371+ $ counts [] = $ count ;
372+ },
373+ );
374+
375+ $ this ->assertSame ([0 , 3 , 6 , 9 ], $ offsets );
376+ $ this ->assertSame ([10 , 10 , 10 , 10 ], $ counts );
377+ }
378+
295379 public function testNativeParameters (): void
296380 {
297381 $ this ->fillData ();
0 commit comments