Skip to content

Commit c2377a5

Browse files
committed
Added tests for sectionlist
1 parent 9012320 commit c2377a5

File tree

5 files changed

+193
-2
lines changed

5 files changed

+193
-2
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export type Food = {
2+
id: number;
3+
name: string;
4+
category: string;
5+
priceRange: string;
6+
};
7+
export const mockFoodData: Food[] = [
8+
{
9+
id: 554,
10+
name: "Onion Rings",
11+
category: "Side",
12+
priceRange: "low",
13+
},
14+
{
15+
id: 145,
16+
name: "Pizza",
17+
category: "Main Dish",
18+
priceRange: "high",
19+
},
20+
{
21+
id: 423,
22+
name: "Risotto",
23+
category: "Main Dish",
24+
priceRange: "high",
25+
},
26+
{
27+
id: 642,
28+
name: "Ice Cream",
29+
category: "Dessert",
30+
priceRange: "medium",
31+
},
32+
{
33+
id: 463,
34+
name: "Fries",
35+
category: "Side",
36+
priceRange: "low",
37+
},
38+
{
39+
id: 724,
40+
name: "Churros",
41+
category: "Dessert",
42+
priceRange: "medium",
43+
},
44+
];
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import * as React from "react";
2+
import { Text } from "react-native";
3+
import { render, screen } from "@testing-library/react-native";
4+
import { SectionHeader, SectionList } from "../../components/SectionList";
5+
import { Food, mockFoodData } from "../__mocks__/mock_food_data";
6+
import { uniq } from "lodash";
7+
import { DEFAULT_SECTION } from "../../components/SectionList/SectionList";
8+
9+
describe("SectionList tests", () => {
10+
test.each(["FlatList", "FlashList"])(
11+
"should render all data items in %p",
12+
(listComponent: string) => {
13+
render(
14+
<SectionList
15+
data={mockFoodData}
16+
renderItem={({ item }) => (
17+
<Text testID="data-item">{item?.name}</Text>
18+
)}
19+
sectionKey="category"
20+
listComponent={listComponent as "FlashList" | "FlatList"}
21+
/>
22+
);
23+
24+
const dataItems = screen.queryAllByTestId("data-item");
25+
expect(dataItems.length).toEqual(mockFoodData.length);
26+
}
27+
);
28+
29+
test.each(["category", "priceRange"])(
30+
"should put data into sections based on key: %p",
31+
(argument: string) => {
32+
const sectionKey = argument as keyof Food;
33+
const sections = getSections(mockFoodData, sectionKey);
34+
const sectionFoodItems = generateEmptySectionSplitArrays<Food>(sections);
35+
36+
render(
37+
<SectionList
38+
data={mockFoodData}
39+
renderItem={({ item, section }) => {
40+
if (item) {
41+
sectionFoodItems[section].push(item);
42+
}
43+
return <Text>{item?.name}</Text>;
44+
}}
45+
sectionKey={sectionKey}
46+
/>
47+
);
48+
49+
for (const section of sections) {
50+
expect(sectionFoodItems[section]).toEqual(
51+
mockFoodData.filter((item) => item[sectionKey] === section)
52+
);
53+
}
54+
}
55+
);
56+
57+
test("should render default section header when none provided", () => {
58+
const sectionKey = "category";
59+
const sectionsCount = getSectionCount(mockFoodData, sectionKey);
60+
61+
render(
62+
<SectionList
63+
data={mockFoodData}
64+
renderItem={({ item }) => <Text>{item?.name}</Text>}
65+
sectionKey={sectionKey}
66+
/>
67+
);
68+
69+
const headers = screen.queryAllByTestId("default-section-header");
70+
expect(headers).toHaveLength(sectionsCount);
71+
});
72+
73+
test("should render custom section header when provided", () => {
74+
const sectionKey = "category";
75+
const sectionsCount = getSectionCount(mockFoodData, sectionKey);
76+
77+
render(
78+
<SectionList
79+
data={mockFoodData}
80+
renderItem={({ item, section }) => (
81+
<>
82+
<SectionHeader>
83+
<Text testID="custom-header">{section}</Text>
84+
</SectionHeader>
85+
<Text>{item?.name}</Text>
86+
</>
87+
)}
88+
sectionKey={sectionKey}
89+
/>
90+
);
91+
92+
const headers = screen.queryAllByTestId("custom-header");
93+
expect(headers).toHaveLength(sectionsCount);
94+
});
95+
96+
test("should data be put under default section when section key is not in object", () => {
97+
const foodWithoutCategory: Omit<Food, "category"> = {
98+
id: 149,
99+
name: "Hot Dog",
100+
priceRange: "low",
101+
};
102+
const data = [foodWithoutCategory, ...mockFoodData];
103+
104+
render(
105+
<SectionList
106+
style={{ height: 1000 }}
107+
data={data}
108+
renderItem={({ item, section }) => {
109+
if (item === foodWithoutCategory) {
110+
return <Text testID="food-no-category">{section}</Text>;
111+
}
112+
return <Text>{item?.name}</Text>;
113+
}}
114+
sectionKey="category"
115+
/>
116+
);
117+
118+
const foodWithoutCategoryText = screen.getByTestId("food-no-category");
119+
expect(foodWithoutCategoryText.props.children[0]).toEqual(DEFAULT_SECTION);
120+
});
121+
});
122+
123+
function getSectionCount(
124+
data: { [key: string]: any }[],
125+
sectionKey: string
126+
): number {
127+
return getSections(data, sectionKey).length;
128+
}
129+
130+
function getSections(
131+
data: { [key: string]: any }[],
132+
sectionKey: string
133+
): string[] {
134+
return uniq(data.map((item) => item[sectionKey]));
135+
}
136+
137+
function generateEmptySectionSplitArrays<T>(sections: string[]): {
138+
[key: string]: T[];
139+
} {
140+
let sectionSplitArrays: { [key: string]: T[] } = {};
141+
142+
for (const section of sections) {
143+
sectionSplitArrays[section] = [];
144+
}
145+
146+
return sectionSplitArrays;
147+
}

packages/core/src/__tests__/stub.test.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/core/src/components/SectionList/SectionHeader.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const DefaultSectionHeader = withTheme(
2020
({ title, theme }: DefaultSectionHeaderProps) => {
2121
return (
2222
<Text
23+
testID="default-section-header"
2324
style={{
2425
color: theme.colors.background,
2526
backgroundColor: theme.colors.primary,

packages/core/src/components/SectionList/SectionList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ interface SectionListSectionItem {
3333

3434
type SectionListItem<T> = SectionListDataItem<T> | SectionListSectionItem;
3535

36-
const DEFAULT_SECTION = "Uncategorized";
36+
export const DEFAULT_SECTION = "Uncategorized";
3737

3838
const SectionList = <T extends { [key: string]: any }>({
3939
sectionKey,

0 commit comments

Comments
 (0)