Skip to content

Commit ae22e93

Browse files
committed
Add more tests
1 parent 8132f7a commit ae22e93

File tree

5 files changed

+163
-16
lines changed

5 files changed

+163
-16
lines changed

lib/components/grid/Grid.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import type { Align } from "../../types";
1313
import { arePropsEqual } from "../../utils/arePropsEqual";
1414
import type { GridProps } from "./types";
1515

16-
// TODO Handle scrollbar sizes (add width/height if necessary)
17-
1816
export function Grid<CellProps extends object>({
1917
cellComponent: CellComponentProp,
2018
cellProps: cellPropsUnstable,

lib/components/list/List.test.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,12 @@ describe("List", () => {
361361
expect(HTMLElement.prototype.scrollTo).not.toHaveBeenCalled();
362362

363363
listRef.current?.scrollToRow({ index: 8 });
364+
364365
expect(HTMLElement.prototype.scrollTo).toHaveBeenCalledTimes(1);
365-
expect(HTMLElement.prototype.scrollTo).not.toHaveBeenLastCalledWith(
366-
8,
367-
"auto"
368-
);
366+
expect(HTMLElement.prototype.scrollTo).toHaveBeenLastCalledWith({
367+
behavior: "auto",
368+
top: 125
369+
});
369370
});
370371
});
371372

lib/core/createCachedBounds.test.ts

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,69 @@
1-
import { describe, test } from "vitest";
1+
import { describe, expect, test, vi } from "vitest";
2+
import { createCachedBounds } from "./createCachedBounds";
23

34
describe("createCachedBounds", () => {
4-
test("have tests", () => {
5-
// TODO Write tests
5+
test("should lazily measure items before the requested index", () => {
6+
const itemSize = vi.fn((index: number) => 10 + index);
7+
const cachedBounds = createCachedBounds({
8+
itemCount: 10,
9+
itemProps: {},
10+
itemSize
11+
});
12+
13+
expect(itemSize).not.toHaveBeenCalled();
14+
expect(cachedBounds.size).toBe(0);
15+
16+
expect(cachedBounds.get(2)).toEqual({
17+
scrollOffset: 21,
18+
size: 12
19+
});
20+
expect(itemSize).toHaveBeenCalledTimes(3);
21+
expect(cachedBounds.size).toBe(3);
22+
23+
expect(cachedBounds.get(3)).toEqual({
24+
scrollOffset: 33,
25+
size: 13
26+
});
27+
expect(itemSize).toHaveBeenCalledTimes(4);
28+
expect(cachedBounds.size).toBe(4);
29+
});
30+
31+
test("should cached measured sizes", () => {
32+
const itemSize = vi.fn(() => 10);
33+
34+
const cachedBounds = createCachedBounds({
35+
itemCount: 10,
36+
itemProps: {},
37+
itemSize
38+
});
39+
40+
expect(itemSize).not.toHaveBeenCalled();
41+
expect(cachedBounds.size).toBe(0);
42+
43+
cachedBounds.get(9);
44+
45+
expect(itemSize).toHaveBeenCalledTimes(10);
46+
expect(cachedBounds.size).toBe(10);
47+
48+
for (let index = 0; index < 10; index++) {
49+
cachedBounds.get(index);
50+
}
51+
52+
expect(itemSize).toHaveBeenCalledTimes(10);
53+
expect(cachedBounds.size).toBe(10);
54+
});
55+
56+
test("should gracefully handle an empty cache", () => {
57+
const cachedBounds = createCachedBounds({
58+
itemCount: 0,
59+
itemProps: {},
60+
itemSize: 10
61+
});
62+
63+
expect(cachedBounds.size).toBe(0);
64+
65+
expect(() => {
66+
cachedBounds.get(1);
67+
}).toThrow("Invalid index 1");
668
});
769
});

lib/core/getStartStopIndices.test.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ describe("getStartStopIndices", () => {
77
containerScrollOffset,
88
containerSize,
99
itemCount,
10-
itemSize
10+
itemSize,
11+
overscanCount = 0
1112
}: {
1213
containerScrollOffset: number;
1314
containerSize: number;
1415
itemCount: number;
1516
itemSize: number;
17+
overscanCount?: number;
1618
}) {
1719
const cachedBounds = createCachedBounds({
1820
itemCount: itemCount,
@@ -25,7 +27,7 @@ describe("getStartStopIndices", () => {
2527
containerScrollOffset,
2628
containerSize,
2729
itemCount,
28-
overscanCount: 0
30+
overscanCount
2931
});
3032
}
3133

@@ -40,7 +42,7 @@ describe("getStartStopIndices", () => {
4042
).toEqual([0, -1]);
4143
});
4244

43-
test("not enough rows to fill available height", () => {
45+
test("edge case: not enough rows to fill available height", () => {
4446
expect(
4547
getIndices({
4648
containerScrollOffset: 0,
@@ -106,5 +108,53 @@ describe("getStartStopIndices", () => {
106108
).toEqual([8, 9]);
107109
});
108110

109-
// TODO Test overscanCount
111+
describe("with overscan", () => {
112+
test("edge case: not enough rows to fill available height", () => {
113+
expect(
114+
getIndices({
115+
containerScrollOffset: 0,
116+
containerSize: 100,
117+
itemCount: 2,
118+
itemSize: 25,
119+
overscanCount: 2
120+
})
121+
).toEqual([0, 1]);
122+
});
123+
124+
test("edge case: no rows before", () => {
125+
expect(
126+
getIndices({
127+
containerScrollOffset: 0,
128+
containerSize: 100,
129+
itemCount: 100,
130+
itemSize: 25,
131+
overscanCount: 2
132+
})
133+
).toEqual([0, 5]);
134+
});
135+
136+
test("edge case: no rows after", () => {
137+
expect(
138+
getIndices({
139+
containerScrollOffset: 2400,
140+
containerSize: 100,
141+
itemCount: 100,
142+
itemSize: 25,
143+
overscanCount: 2
144+
})
145+
).toEqual([94, 99]);
146+
});
147+
148+
test("rows before and after", () => {
149+
expect(
150+
getIndices({
151+
containerScrollOffset: 100,
152+
containerSize: 100,
153+
itemCount: 100,
154+
itemSize: 25,
155+
overscanCount: 2
156+
})
157+
).toEqual([2, 9]);
158+
});
159+
});
110160
});

lib/core/useCachedBounds.test.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,43 @@
1-
import { describe, test } from "vitest";
1+
import { renderHook } from "@testing-library/react";
2+
import { describe, expect, test } from "vitest";
3+
import { EMPTY_OBJECT } from "../../src/constants";
4+
import { useCachedBounds } from "./useCachedBounds";
25

36
describe("useCachedBounds", () => {
4-
test("have tests", () => {
5-
// TODO Write tests
7+
test("should cache the CachedBounds unless props change", () => {
8+
const { result, rerender } = renderHook(
9+
(props?: Partial<Parameters<typeof useCachedBounds>>[0]) =>
10+
useCachedBounds({
11+
itemCount: 1,
12+
itemProps: EMPTY_OBJECT,
13+
itemSize: 10,
14+
...props
15+
})
16+
);
17+
18+
const cachedBoundsA = result.current;
19+
20+
rerender({
21+
itemCount: 1,
22+
itemProps: EMPTY_OBJECT,
23+
itemSize: 10
24+
});
25+
expect(result.current).toBe(cachedBoundsA);
26+
27+
rerender({
28+
itemCount: 1,
29+
itemProps: EMPTY_OBJECT,
30+
itemSize: 5
31+
});
32+
expect(result.current).not.toBe(cachedBoundsA);
33+
34+
const cachedBoundsB = result.current;
35+
36+
rerender({
37+
itemCount: 1,
38+
itemProps: EMPTY_OBJECT,
39+
itemSize: 5
40+
});
41+
expect(result.current).toBe(cachedBoundsB);
642
});
743
});

0 commit comments

Comments
 (0)