SPB Git forge

spb/cancerindex

Public
37commits 1branches 0releases
2.9 MBsize
maindefault branch
10 days agolast push
TypeScript 97.2% SQL 1.5% CSS 0.6% JavaScript 0.5%
3.1 KB · 88 lines typescript
Raw Blame History
1import { describe, it, expect } from 'vitest';2import { pageCount, clampPage, offsetFor, pageInfo, pageWindow } from '@/lib/pagination';34describe('pageCount', () => {5  it('is at least 1', () => {6    expect(pageCount(0, 50)).toBe(1);7    expect(pageCount(-5, 50)).toBe(1);8    expect(pageCount(Number.NaN, 50)).toBe(1);9  });10  it('rounds up', () => {11    expect(pageCount(50, 50)).toBe(1);12    expect(pageCount(51, 50)).toBe(2);13    expect(pageCount(405, 50)).toBe(9);14    expect(pageCount(3000, 50)).toBe(60);15  });16  it('guards against a zero page size', () => {17    expect(pageCount(10, 0)).toBe(10);18  });19});2021describe('clampPage', () => {22  it('clamps into [1, pageCount]', () => {23    expect(clampPage(0, 405, 50)).toBe(1);24    expect(clampPage(-3, 405, 50)).toBe(1);25    expect(clampPage(9, 405, 50)).toBe(9);26    expect(clampPage(10, 405, 50)).toBe(9);27    expect(clampPage(99999, 405, 50)).toBe(9);28    expect(clampPage(Number.NaN, 405, 50)).toBe(1);29    expect(clampPage(2.7, 405, 50)).toBe(2);30  });31  it('is 1 when there are no rows', () => {32    expect(clampPage(7, 0, 50)).toBe(1);33  });34});3536describe('offsetFor', () => {37  it('computes SQL offsets', () => {38    expect(offsetFor(1, 50)).toBe(0);39    expect(offsetFor(2, 50)).toBe(50);40    expect(offsetFor(9, 25)).toBe(200);41    expect(offsetFor(0, 50)).toBe(0);42  });43});4445describe('pageInfo', () => {46  it('describes a middle page', () => {47    const p = pageInfo(3, 50, 405);48    expect(p).toMatchObject({ page: 3, pageSize: 50, total: 405, pageCount: 9, offset: 100, from: 101, to: 150, hasPrev: true, hasNext: true });49  });50  it('describes the last, partial page', () => {51    const p = pageInfo(9, 50, 405);52    expect(p).toMatchObject({ page: 9, offset: 400, from: 401, to: 405, hasPrev: true, hasNext: false });53  });54  it('clamps an out-of-range request to the last page (never an empty page)', () => {55    const p = pageInfo(50, 50, 405);56    expect(p.page).toBe(9);57    expect(p.offset).toBe(400);58  });59  it('handles an empty result', () => {60    const p = pageInfo(1, 50, 0);61    expect(p).toMatchObject({ page: 1, pageCount: 1, offset: 0, from: 0, to: 0, hasPrev: false, hasNext: false });62  });63  it('handles a single page', () => {64    const p = pageInfo(1, 25, 12);65    expect(p).toMatchObject({ page: 1, pageCount: 1, from: 1, to: 12, hasPrev: false, hasNext: false });66  });67});6869describe('pageWindow', () => {70  it('collapses to [1] for one page', () => {71    expect(pageWindow(1, 1)).toEqual([1]);72  });73  it('shows first, last and neighbours with gaps', () => {74    expect(pageWindow(7, 20)).toEqual([1, null, 6, 7, 8, null, 20]);75  });76  it('fills a gap of exactly one page instead of an ellipsis', () => {77    expect(pageWindow(3, 20)).toEqual([1, 2, 3, 4, null, 20]);78    expect(pageWindow(18, 20)).toEqual([1, null, 17, 18, 19, 20]);79  });80  it('lists every page when there are few', () => {81    expect(pageWindow(2, 4)).toEqual([1, 2, 3, 4]);82    expect(pageWindow(1, 2)).toEqual([1, 2]);83  });84  it('honours a wider radius', () => {85    expect(pageWindow(10, 30, 2)).toEqual([1, null, 8, 9, 10, 11, 12, null, 30]);86  });87});88