Skip to content

Commit dfa308d

Browse files
Merge pull request #383 from marcocesarato/copilot/improve-test-coverage
[WIP] Improve test coverage to 80 percent
2 parents fa488b5 + 93bb167 commit dfa308d

11 files changed

+4116
-1459
lines changed

__tests__/BigList.additional-props.test.js

Lines changed: 445 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
import React from 'react';
2+
import { render, screen, fireEvent } from '@testing-library/react-native';
3+
import { Text, View } from 'react-native';
4+
import BigList from '../lib/BigList';
5+
6+
describe('BigList - Complete Coverage Tests', () => {
7+
test('renders with zero height sections', () => {
8+
const sections = [
9+
[],
10+
[],
11+
[{ id: '1', name: 'Item 1' }],
12+
];
13+
14+
render(
15+
<BigList
16+
sections={sections}
17+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
18+
itemHeight={50}
19+
renderEmptySections={false}
20+
/>
21+
);
22+
23+
expect(screen.getByTestId('item-1')).toBeTruthy();
24+
});
25+
26+
test('handles mixed empty and non-empty sections with headers', () => {
27+
const sections = [
28+
[],
29+
[{ id: '1', name: 'Item 1' }],
30+
[],
31+
[{ id: '2', name: 'Item 2' }],
32+
[],
33+
];
34+
35+
const renderSectionHeader = (sectionIndex) => (
36+
<View testID={`section-${sectionIndex}`}>
37+
<Text>Section {sectionIndex}</Text>
38+
</View>
39+
);
40+
41+
render(
42+
<BigList
43+
sections={sections}
44+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
45+
itemHeight={50}
46+
renderSectionHeader={renderSectionHeader}
47+
sectionHeaderHeight={40}
48+
renderEmptySections={false}
49+
/>
50+
);
51+
52+
expect(screen.getByTestId('item-1')).toBeTruthy();
53+
expect(screen.getByTestId('item-2')).toBeTruthy();
54+
});
55+
56+
test('handles very large dataset with sections', () => {
57+
const sections = Array.from({ length: 10 }, (_, sectionIdx) =>
58+
Array.from({ length: 20 }, (_, itemIdx) => ({
59+
id: `${sectionIdx}-${itemIdx}`,
60+
name: `Item ${sectionIdx}-${itemIdx}`,
61+
}))
62+
);
63+
64+
render(
65+
<BigList
66+
sections={sections}
67+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
68+
itemHeight={50}
69+
/>
70+
);
71+
72+
expect(screen.getByTestId('item-0-0')).toBeTruthy();
73+
});
74+
75+
test('handles sections with varying row counts and numColumns', () => {
76+
const sections = [
77+
Array.from({ length: 7 }, (_, i) => ({ id: `1-${i}`, name: `Item ${i}` })),
78+
Array.from({ length: 5 }, (_, i) => ({ id: `2-${i}`, name: `Item ${i}` })),
79+
Array.from({ length: 11 }, (_, i) => ({ id: `3-${i}`, name: `Item ${i}` })),
80+
];
81+
82+
render(
83+
<BigList
84+
sections={sections}
85+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
86+
itemHeight={50}
87+
numColumns={3}
88+
/>
89+
);
90+
91+
expect(screen.getByTestId('item-1-0')).toBeTruthy();
92+
expect(screen.getByTestId('item-2-0')).toBeTruthy();
93+
expect(screen.getByTestId('item-3-0')).toBeTruthy();
94+
});
95+
96+
test('renders with custom onLayout callback', () => {
97+
const onLayout = jest.fn();
98+
const data = [{ id: '1', name: 'Item 1' }];
99+
100+
render(
101+
<BigList
102+
data={data}
103+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
104+
itemHeight={50}
105+
onLayout={onLayout}
106+
/>
107+
);
108+
109+
expect(screen.getByTestId('item-1')).toBeTruthy();
110+
});
111+
112+
test('handles initialScrollIndex with sections', () => {
113+
const sections = [
114+
Array.from({ length: 10 }, (_, i) => ({ id: `1-${i}`, name: `Item ${i}` })),
115+
Array.from({ length: 10 }, (_, i) => ({ id: `2-${i}`, name: `Item ${i}` })),
116+
];
117+
118+
render(
119+
<BigList
120+
sections={sections}
121+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
122+
itemHeight={50}
123+
initialScrollIndex={5}
124+
/>
125+
);
126+
127+
expect(screen.getByTestId('item-1-0')).toBeTruthy();
128+
});
129+
130+
test('scrollToLocation returns boolean for sections', () => {
131+
const listRef = React.createRef();
132+
const sections = [
133+
Array.from({ length: 5 }, (_, i) => ({ id: `1-${i}`, name: `Item ${i}` })),
134+
Array.from({ length: 5 }, (_, i) => ({ id: `2-${i}`, name: `Item ${i}` })),
135+
];
136+
137+
render(
138+
<BigList
139+
ref={listRef}
140+
sections={sections}
141+
renderItem={({ item }) => <Text>{item.name}</Text>}
142+
itemHeight={50}
143+
/>
144+
);
145+
146+
if (listRef.current) {
147+
const result = listRef.current.scrollToLocation({
148+
sectionIndex: 1,
149+
itemIndex: 2,
150+
animated: false,
151+
});
152+
expect(typeof result).toBe('boolean');
153+
}
154+
});
155+
156+
test('handles column wrapper with different styles', () => {
157+
const data = Array.from({ length: 10 }, (_, i) => ({
158+
id: `${i}`,
159+
name: `Item ${i}`,
160+
}));
161+
162+
render(
163+
<BigList
164+
data={data}
165+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
166+
itemHeight={50}
167+
numColumns={2}
168+
columnWrapperStyle={[{ gap: 10 }, { padding: 5 }]}
169+
/>
170+
);
171+
172+
expect(screen.getByTestId('item-0')).toBeTruthy();
173+
});
174+
175+
test('renders with ListEmptyComponent as function', () => {
176+
const EmptyComponent = () => (
177+
<View testID="empty-func">
178+
<Text>Empty List</Text>
179+
</View>
180+
);
181+
182+
render(
183+
<BigList
184+
data={[]}
185+
renderItem={({ item }) => <Text>{item.name}</Text>}
186+
itemHeight={50}
187+
ListEmptyComponent={EmptyComponent}
188+
/>
189+
);
190+
191+
expect(screen.getByTestId('empty-func')).toBeTruthy();
192+
});
193+
194+
test('renders with ListHeaderComponent as function', () => {
195+
const data = [{ id: '1', name: 'Item 1' }];
196+
const HeaderComponent = () => (
197+
<View testID="header-func">
198+
<Text>Header</Text>
199+
</View>
200+
);
201+
202+
render(
203+
<BigList
204+
data={data}
205+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
206+
itemHeight={50}
207+
ListHeaderComponent={HeaderComponent}
208+
/>
209+
);
210+
211+
expect(screen.getByTestId('item-1')).toBeTruthy();
212+
});
213+
214+
test('renders with ListFooterComponent as function', () => {
215+
const data = [{ id: '1', name: 'Item 1' }];
216+
const FooterComponent = () => (
217+
<View testID="footer-func">
218+
<Text>Footer</Text>
219+
</View>
220+
);
221+
222+
render(
223+
<BigList
224+
data={data}
225+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
226+
itemHeight={50}
227+
ListFooterComponent={FooterComponent}
228+
/>
229+
);
230+
231+
expect(screen.getByTestId('item-1')).toBeTruthy();
232+
});
233+
234+
test('getSectionLengths with data array', () => {
235+
const listRef = React.createRef();
236+
const data = [
237+
{ id: '1', name: 'Item 1' },
238+
{ id: '2', name: 'Item 2' },
239+
];
240+
241+
render(
242+
<BigList
243+
ref={listRef}
244+
data={data}
245+
renderItem={({ item }) => <Text>{item.name}</Text>}
246+
itemHeight={50}
247+
/>
248+
);
249+
250+
const lengths = listRef.current.getSectionLengths();
251+
expect(Array.isArray(lengths)).toBe(true);
252+
expect(lengths[0]).toBe(2);
253+
});
254+
255+
test('hasSections returns correct value', () => {
256+
const listRef = React.createRef();
257+
const data = [{ id: '1', name: 'Item 1' }];
258+
259+
render(
260+
<BigList
261+
ref={listRef}
262+
data={data}
263+
renderItem={({ item }) => <Text>{item.name}</Text>}
264+
itemHeight={50}
265+
/>
266+
);
267+
268+
const hasSections = listRef.current.hasSections();
269+
expect(typeof hasSections).toBe('boolean');
270+
});
271+
272+
test('handles very small batchSizeThreshold', () => {
273+
const data = Array.from({ length: 50 }, (_, i) => ({
274+
id: `${i}`,
275+
name: `Item ${i}`,
276+
}));
277+
278+
render(
279+
<BigList
280+
data={data}
281+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
282+
itemHeight={50}
283+
batchSizeThreshold={0.1}
284+
/>
285+
);
286+
287+
expect(screen.getByTestId('item-0')).toBeTruthy();
288+
});
289+
290+
test('handles sections with all different lengths', () => {
291+
const sections = [
292+
[{ id: '1', name: 'Item 1' }],
293+
[{ id: '2', name: 'Item 2' }, { id: '3', name: 'Item 3' }],
294+
[
295+
{ id: '4', name: 'Item 4' },
296+
{ id: '5', name: 'Item 5' },
297+
{ id: '6', name: 'Item 6' },
298+
],
299+
];
300+
301+
render(
302+
<BigList
303+
sections={sections}
304+
renderItem={({ item }) => <Text testID={`item-${item.id}`}>{item.name}</Text>}
305+
itemHeight={50}
306+
/>
307+
);
308+
309+
expect(screen.getByTestId('item-1')).toBeTruthy();
310+
expect(screen.getByTestId('item-2')).toBeTruthy();
311+
expect(screen.getByTestId('item-4')).toBeTruthy();
312+
});
313+
});

0 commit comments

Comments
 (0)