Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor!: change Pagination from default to named export
feat: expose paginationStateReducer test: add 100% coverage refactor!: when page size or total items is changed and a target page is not specified, the current page is left as is instead of changing to 0 BREAKING CHANGE: flowtypes are no exported
- Loading branch information
Showing
10 changed files
with
377 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { getPaginationMeta, PaginationState } from "../getPaginationMeta"; | ||
|
||
const MULTI_PAGE_FIRST_PAGE: PaginationState = { | ||
totalItems: 100, | ||
pageSize: 10, | ||
currentPage: 0, | ||
}; | ||
|
||
describe("getPaginationMeta", () => { | ||
it("correctly calculates startIndex and lastIndex on the first page", () => { | ||
const meta = getPaginationMeta(MULTI_PAGE_FIRST_PAGE); | ||
expect(meta.startIndex).toBe(0); | ||
expect(meta.endIndex).toBe(9); | ||
}); | ||
|
||
it("correctly calculates startIndex and endIndex on the second page", () => { | ||
const meta = getPaginationMeta({ ...MULTI_PAGE_FIRST_PAGE, currentPage: 1 }); | ||
expect(meta.startIndex).toBe(10); | ||
expect(meta.endIndex).toBe(19); | ||
}); | ||
|
||
it("correctly calculates startIndex and endIndex on the last page", () => { | ||
const meta = getPaginationMeta({ ...MULTI_PAGE_FIRST_PAGE, currentPage: 9 }); | ||
expect(meta.startIndex).toBe(90); | ||
expect(meta.endIndex).toBe(99); | ||
}); | ||
|
||
it("correctly calculates endIndex on a half-full last page", () => { | ||
const meta = getPaginationMeta({ totalItems: 92, pageSize: 10, currentPage: 9 }); | ||
expect(meta.endIndex).toBe(91); | ||
}); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import { paginationStateReducer } from "../paginationStateReducer"; | ||
import { PaginationState } from "../getPaginationMeta"; | ||
|
||
const MULTI_PAGE_FIRST_PAGE: PaginationState = { | ||
totalItems: 100, | ||
pageSize: 10, | ||
currentPage: 0, | ||
}; | ||
|
||
describe("paginationStateReducer", () => { | ||
it("sets the next page when not on the last page", () => { | ||
const nextState = paginationStateReducer(MULTI_PAGE_FIRST_PAGE, { type: "NEXT_PAGE" }); | ||
expect(nextState.currentPage).toBe(1); | ||
}); | ||
|
||
it("does not set the next page when on the last page", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 1, pageSize: 1, currentPage: 0 }, | ||
{ type: "NEXT_PAGE" } | ||
); | ||
expect(nextState.currentPage).toBe(0); | ||
}); | ||
|
||
it("sets the previous page when not on the first page", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 2, pageSize: 1, currentPage: 1 }, | ||
{ type: "PREVIOUS_PAGE" } | ||
); | ||
expect(nextState.currentPage).toBe(0); | ||
}); | ||
|
||
it("does not set the previous page when on the first page", () => { | ||
const nextState = paginationStateReducer(MULTI_PAGE_FIRST_PAGE, { type: "PREVIOUS_PAGE" }); | ||
expect(nextState.currentPage).toBe(0); | ||
}); | ||
|
||
it("allows totalPages to be set", () => { | ||
const nextTotalItems = 12; | ||
const nextState = paginationStateReducer(MULTI_PAGE_FIRST_PAGE, { | ||
type: "SET_TOTALITEMS", | ||
totalItems: nextTotalItems, | ||
}); | ||
|
||
expect(nextState.totalItems).toBe(nextTotalItems); | ||
}); | ||
|
||
it("allows pageSize to be set", () => { | ||
const nextPageSize = 12; | ||
const nextState = paginationStateReducer(MULTI_PAGE_FIRST_PAGE, { | ||
type: "SET_PAGESIZE", | ||
pageSize: nextPageSize, | ||
}); | ||
|
||
expect(nextState.pageSize).toBe(nextPageSize); | ||
}); | ||
|
||
it("allows currentPage to be set", () => { | ||
const nextCurrentPage = 12; | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 100, pageSize: 1, currentPage: 0 }, | ||
{ | ||
type: "SET_PAGE", | ||
page: nextCurrentPage, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(nextCurrentPage); | ||
}); | ||
|
||
it("disallows currentPage from being set below 0", () => { | ||
const nextCurrentPage = -1; | ||
const nextState = paginationStateReducer(MULTI_PAGE_FIRST_PAGE, { | ||
type: "SET_PAGE", | ||
page: nextCurrentPage, | ||
}); | ||
|
||
expect(nextState.currentPage).toBe(0); | ||
}); | ||
|
||
it("disallows currentPage from being set above totalPages", () => { | ||
const nextCurrentPage = 1; | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 1, pageSize: 1, currentPage: 0 }, | ||
{ | ||
type: "SET_PAGE", | ||
page: nextCurrentPage, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(0); | ||
}); | ||
|
||
it("limits currentPage within totalPages when pageSize is increased", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 100, pageSize: 10, currentPage: 9 }, | ||
{ | ||
type: "SET_PAGESIZE", | ||
pageSize: 50, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(1); | ||
}); | ||
|
||
it("doesn't change currentPage if it wouldn't be out of bounds when pageSize is increased", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 100, pageSize: 10, currentPage: 2 }, | ||
{ | ||
type: "SET_PAGESIZE", | ||
pageSize: 25, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(2); | ||
}); | ||
|
||
it("limits currentPage within totalPages when totalItems is decreased", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 100, pageSize: 10, currentPage: 9 }, | ||
{ | ||
type: "SET_TOTALITEMS", | ||
totalItems: 20, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(1); | ||
}); | ||
|
||
it("doesn't change currentPage if it wouldn't be out of bounds when totalItems is decreased", () => { | ||
const nextState = paginationStateReducer( | ||
{ totalItems: 100, pageSize: 10, currentPage: 9 }, | ||
{ | ||
type: "SET_TOTALITEMS", | ||
totalItems: 95, | ||
} | ||
); | ||
|
||
expect(nextState.currentPage).toBe(9); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { renderHook, act } from "@testing-library/react-hooks"; | ||
import { usePagination } from "../usePagination"; | ||
|
||
const DEFAULT_STATE = { totalItems: 100, initialPageSize: 10, initialPage: 1 }; | ||
|
||
describe("usePagination", () => { | ||
it("correctly initializes the page state and contains the expected metadata", () => { | ||
const { result } = renderHook(() => usePagination(DEFAULT_STATE)); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage); | ||
expect(result.current.totalItems).toBe(DEFAULT_STATE.totalItems); | ||
expect(result.current.pageSize).toBe(DEFAULT_STATE.initialPageSize); | ||
expect(result.current.startIndex).toBe( | ||
DEFAULT_STATE.initialPage * DEFAULT_STATE.initialPageSize | ||
); | ||
expect(result.current.endIndex).toBe( | ||
(DEFAULT_STATE.initialPage + 1) * DEFAULT_STATE.initialPageSize - 1 | ||
); | ||
expect(result.current.nextEnabled).toBe(true); | ||
expect(result.current.previousEnabled).toBe(true); | ||
}); | ||
|
||
it("sets the next page when setNextPage is called", () => { | ||
const { result } = renderHook(() => usePagination(DEFAULT_STATE)); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage); | ||
|
||
act(() => { | ||
result.current.setNextPage(); | ||
}); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage + 1); | ||
}); | ||
|
||
it("sets the previous page when setPreviousPage is called", () => { | ||
const { result } = renderHook(() => usePagination(DEFAULT_STATE)); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage); | ||
|
||
act(() => { | ||
result.current.setPreviousPage(); | ||
}); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage - 1); | ||
}); | ||
|
||
it("sets the page when setPage is called", () => { | ||
const { result } = renderHook(() => usePagination(DEFAULT_STATE)); | ||
|
||
expect(result.current.currentPage).toBe(DEFAULT_STATE.initialPage); | ||
|
||
act(() => { | ||
result.current.setPage(0); | ||
}); | ||
|
||
expect(result.current.currentPage).toBe(0); | ||
}); | ||
|
||
it("sets the pageSize when setPageSize is called", () => { | ||
const { result } = renderHook(() => usePagination(DEFAULT_STATE)); | ||
|
||
expect(result.current.pageSize).toBe(DEFAULT_STATE.initialPageSize); | ||
|
||
act(() => { | ||
result.current.setPageSize(5); | ||
}); | ||
|
||
expect(result.current.pageSize).toBe(5); | ||
}); | ||
|
||
// This is required so that the hook can be rendered before server-provided data is available | ||
it("initializes configurations to 0 when not provided", () => { | ||
const { result } = renderHook(() => usePagination()); | ||
|
||
expect(result.current.totalItems).toBe(0); | ||
expect(result.current.pageSize).toBe(0); | ||
expect(result.current.currentPage).toBe(0); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
export * from "./getPaginationState"; | ||
export * from "./getPaginationMeta"; | ||
export * from "./Pagination"; | ||
export * from "./usePagination"; |
Oops, something went wrong.