ChannelBookChapterSliceTest.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <?php
  2. use App\Http\Controllers\TipitakaReadChapterController;
  3. /**
  4. * slice() 是纯函数,不碰数据库。段落数上限要造上千段才看得出来,走 HTTP 会真的
  5. * 去渲染每一段,所以这里直接对着方法本身测。
  6. *
  7. * @param array<int, int> $paragraphs
  8. * @param array<int, int> $lengths
  9. * @return array<int, int>
  10. */
  11. function sliceParagraphs(array $paragraphs, array $lengths, int $limit, string $unit, int $offset): array
  12. {
  13. $controller = new class extends TipitakaReadChapterController
  14. {
  15. /**
  16. * @param array<int, int> $paragraphs
  17. * @param array<int, int> $lengths
  18. * @return array<int, int>
  19. */
  20. public function sliceForTest(array $paragraphs, array $lengths, int $limit, string $unit, int $offset): array
  21. {
  22. return $this->slice($paragraphs, $lengths, $limit, $unit, $offset);
  23. }
  24. };
  25. return $controller->sliceForTest($paragraphs, $lengths, $limit, $unit, $offset);
  26. }
  27. it('caps a byte-mode block at 200 paragraphs however short the paragraphs are', function () {
  28. // 1000 段,每段 1 字节;不设段落上限的话 5000b 会把整章切成一块
  29. $paragraphs = range(1, 1000);
  30. $lengths = array_fill_keys($paragraphs, 1);
  31. expect(sliceParagraphs($paragraphs, $lengths, 5000, 'byte', 0))->toBe(range(1, 200))
  32. ->and(sliceParagraphs($paragraphs, $lengths, 5000, 'byte', 200))->toBe(range(201, 400))
  33. ->and(sliceParagraphs($paragraphs, $lengths, 5000, 'byte', 900))->toBe(range(901, 1000));
  34. });
  35. it('caps a paragraph-mode block at 200 paragraphs', function () {
  36. $paragraphs = range(1, 1000);
  37. expect(sliceParagraphs($paragraphs, [], 1000, 'para', 0))->toBe(range(1, 200))
  38. ->and(sliceParagraphs($paragraphs, [], 1000, 'para', 950))->toBe(range(951, 1000));
  39. });
  40. it('still breaks on the byte limit when paragraphs are long enough', function () {
  41. $paragraphs = range(1, 10);
  42. $lengths = array_fill_keys($paragraphs, 100);
  43. expect(sliceParagraphs($paragraphs, $lengths, 250, 'byte', 0))->toBe([1, 2, 3])
  44. ->and(sliceParagraphs($paragraphs, $lengths, 250, 'byte', 3))->toBe([4, 5, 6]);
  45. });
  46. it('never returns an empty byte-mode block when lengths are missing', function () {
  47. // pali_texts 里查不到长度时按 0 算,靠段落数上限收口,不会死循环也不会空块
  48. $paragraphs = range(1, 1000);
  49. expect(sliceParagraphs($paragraphs, [], 5000, 'byte', 0))->toBe(range(1, 200))
  50. ->and(sliceParagraphs($paragraphs, [], 5000, 'byte', 800))->toBe(range(801, 1000));
  51. });