Skip to content

Commit aafe5bb

Browse files
committedOct 10, 2022
test: increase coverage
1 parent 36a574c commit aafe5bb

File tree

6 files changed

+69
-52
lines changed

6 files changed

+69
-52
lines changed
 

‎src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { NestedListView } from './nested-list-view';
22
import { NestedRow } from './nested-row';
3-
import { INode } from './node-view';
3+
import { Node } from './node-view';
44

55
export { NestedRow };
66

7-
export { INode };
7+
export { Node as INode };
88

99
export default NestedListView;

‎src/nested-list-view/nested-list-view.test.tsx

+33-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/* eslint-disable react/jsx-no-bind */
22
import React from 'react';
33
import { Text, View } from 'react-native';
4-
import { INode } from '../node-view';
4+
import { Node } from '../node-view';
55
import { render, waitFor, fireEvent } from '@testing-library/react-native';
66
import { NestedListView } from './nested-list-view';
77
import { NestedRow } from '../nested-row';
88

9-
const renderNode = (node: INode) => (
9+
const renderNode = (node: Node) => (
1010
<View>
1111
<Text>{node.title}</Text>
1212
</View>
@@ -39,6 +39,28 @@ describe('NestedListView', () => {
3939
});
4040
});
4141

42+
test('renders with an empty array', async () => {
43+
const data = [] as any;
44+
const { queryByText } = render(
45+
<NestedListView
46+
getChildrenName={() => 'items'}
47+
renderNode={(node: any) => (
48+
<View>
49+
<Text>{node.title}</Text>
50+
</View>
51+
)}
52+
data={data}
53+
/>,
54+
);
55+
56+
await waitFor(() => {
57+
[1, 2, 3].forEach((item: number) => {
58+
const component = queryByText(`child${item}`);
59+
expect(component).toBeDefined();
60+
});
61+
});
62+
});
63+
4264
test('renders with nested arrays', async () => {
4365
const data = [
4466
{
@@ -123,13 +145,13 @@ describe('NestedListView', () => {
123145

124146
const { queryByText } = render(
125147
<NestedListView
126-
getChildrenName={(node: INode) => {
148+
getChildrenName={(node: Node) => {
127149
if (node.title === 'child2') {
128150
return 'descendants';
129151
}
130152
return 'items';
131153
}}
132-
renderNode={(node: INode) => (
154+
renderNode={(node: Node) => (
133155
<View>
134156
<Text>{node.title}</Text>
135157
</View>
@@ -165,13 +187,13 @@ describe('NestedListView', () => {
165187

166188
const { queryByText } = render(
167189
<NestedListView
168-
getChildrenName={(node: INode) => {
190+
getChildrenName={(node: Node) => {
169191
if (node.title === 'child2') {
170192
return 'children';
171193
}
172194
return 'items';
173195
}}
174-
renderNode={(node: INode) => (
196+
renderNode={(node: Node) => (
175197
<View>
176198
<Text>{node.title}</Text>
177199
</View>
@@ -234,7 +256,7 @@ describe('NestedListView', () => {
234256
const { queryByText } = render(
235257
<NestedListView
236258
getChildrenName={() => 'children'}
237-
renderNode={(node: INode) => (
259+
renderNode={(node: Node) => (
238260
<View>
239261
<Text>{node.name}</Text>
240262
</View>
@@ -274,7 +296,7 @@ describe('NestedListView', () => {
274296
const { queryByText } = render(
275297
<NestedListView
276298
onNodePressed={mockOnNodePressed}
277-
renderNode={(node: INode) => (
299+
renderNode={(node: Node) => (
278300
<View>
279301
<Text>{node.title}</Text>
280302
</View>
@@ -306,7 +328,7 @@ describe('NestedListView', () => {
306328
<NestedListView
307329
keepOpenedState
308330
onNodePressed={mockOnNodePressed}
309-
renderNode={(node: INode) => (
331+
renderNode={(node: Node) => (
310332
<View>
311333
<Text>{node.title}</Text>
312334
</View>
@@ -337,7 +359,7 @@ describe('NestedListView', () => {
337359
const { queryByText } = render(
338360
<NestedListView
339361
onNodePressed={mockOnNodePressed}
340-
renderNode={(node: INode, level?: number) => (
362+
renderNode={(node: Node, level?: number) => (
341363
<NestedRow level={level}>
342364
<Text>{node.title}</Text>
343365
</NestedRow>
@@ -395,7 +417,7 @@ describe('NestedListView', () => {
395417

396418
const { getByText } = render(
397419
<NestedListView
398-
renderNode={(item: INode, level: number, isLastItem: boolean) => {
420+
renderNode={(item: Node, level: number, isLastItem: boolean) => {
399421
mockIsTheLast(isLastItem);
400422

401423
return (

‎src/nested-list-view/nested-list-view.tsx

+10-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import hashObjectGenerator from 'object-hash';
22
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
33
import { StyleSheet, Text, View } from 'react-native';
4-
import { INode, NodeView } from '../node-view';
4+
import { Node, NodeView } from '../node-view';
55
import { NodeProvider } from '../nodes-context-provider';
66

77
const styles = StyleSheet.create({
@@ -23,13 +23,9 @@ const styles = StyleSheet.create({
2323
export interface IProps {
2424
data: any;
2525
extraData?: any;
26-
renderNode: (
27-
item: INode,
28-
level: number,
29-
isLastLevel: boolean,
30-
) => ReactElement;
31-
onNodePressed?: (item: INode) => void;
32-
getChildrenName?: (item: INode) => string;
26+
renderNode: (item: Node, level: number, isLastLevel: boolean) => ReactElement;
27+
onNodePressed?: (item: Node) => void;
28+
getChildrenName?: (item: Node) => string;
3329
style?: StyleSheet;
3430
keepOpenedState?: boolean;
3531
initialNumToRender?: number;
@@ -43,7 +39,7 @@ const defaultRootNode = {
4339
name: 'root',
4440
opened: true,
4541
hidden: true,
46-
} as INode;
42+
} as Node;
4743

4844
const NestedListView: React.FC<IProps> = React.memo(
4945
({
@@ -56,7 +52,7 @@ const NestedListView: React.FC<IProps> = React.memo(
5652
initialNumToRender,
5753
}: IProps) => {
5854
const generateIds = useCallback(
59-
(node?: INode) => {
55+
(node?: Node) => {
6056
if (!node) {
6157
return {
6258
_internalId: '',
@@ -76,7 +72,7 @@ const NestedListView: React.FC<IProps> = React.memo(
7672
(key: string) => children[key],
7773
);
7874
}
79-
copyNode[childrenName] = children.map((_: INode, index: number) =>
75+
copyNode[childrenName] = children.map((_: Node, index: number) =>
8076
generateIds(children[index]),
8177
);
8278
}
@@ -98,7 +94,7 @@ const NestedListView: React.FC<IProps> = React.memo(
9894
);
9995

10096
const generateRootNode = useCallback(
101-
(props: IProps): INode => {
97+
(props: IProps): Node => {
10298
return {
10399
_internalId: 'root',
104100
items: props.data
@@ -112,7 +108,7 @@ const NestedListView: React.FC<IProps> = React.memo(
112108
[generateIds],
113109
);
114110

115-
const [_root, setRoot]: [INode, (_rootNode: INode) => void] =
111+
const [_root, setRoot]: [Node, (_rootNode: Node) => void] =
116112
useState(defaultRootNode);
117113

118114
useEffect(() => {
@@ -135,7 +131,7 @@ const NestedListView: React.FC<IProps> = React.memo(
135131
]);
136132

137133
const _getChildrenName = useCallback(
138-
(node: INode) => {
134+
(node: Node) => {
139135
if (node.name === 'root') {
140136
return 'items';
141137
}

‎src/node-view/node-view.tsx

+16-19
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
22
import { Pressable, VirtualizedList } from 'react-native';
33
import { useNodesContext } from '../nodes-context-provider';
4-
import { INode } from './types';
4+
import { Node } from './types';
55

66
export interface IProps {
7-
getChildrenName: (item: INode) => string;
8-
node: INode;
7+
getChildrenName: (item: Node) => string;
8+
node: Node;
99
level: number;
10-
onNodePressed?: (item: INode) => void;
11-
renderNode: (
12-
item: INode,
13-
level: number,
14-
isLastLevel: boolean,
15-
) => ReactElement;
16-
renderChildrenNode?: (item: INode) => ReactElement;
10+
onNodePressed?: (item: Node) => void;
11+
renderNode: (item: Node, level: number, isLastLevel: boolean) => ReactElement;
12+
renderChildrenNode?: (item: Node) => ReactElement;
1713
extraData?: any;
1814
keepOpenedState?: boolean;
1915
initialNumToRender?: number;
@@ -31,7 +27,7 @@ const NodeView: React.FC<IProps> = React.memo(
3127
initialNumToRender,
3228
}) => {
3329
const { openedNodes, setOpenNode } = useNodesContext();
34-
const [_node, setNode]: [INode, any] = useState({
30+
const [_node, setNode]: [Node, any] = useState({
3531
...node,
3632
opened:
3733
keepOpenedState && openedNodes[node._internalId]
@@ -48,10 +44,11 @@ const NodeView: React.FC<IProps> = React.memo(
4844

4945
const _onNodePressed = useCallback(() => {
5046
if (keepOpenedState) {
51-
setOpenNode({
52-
internalId: _node._internalId,
53-
opened: !_node.opened,
54-
});
47+
setOpenNode &&
48+
setOpenNode({
49+
internalId: _node._internalId,
50+
opened: !_node.opened,
51+
});
5552
}
5653

5754
setNode({
@@ -65,7 +62,7 @@ const NodeView: React.FC<IProps> = React.memo(
6562
}, [_node, keepOpenedState, onNodePressed, setOpenNode]);
6663

6764
const renderChildren = useCallback(
68-
(item: INode, _level: number): ReactElement => (
65+
(item: Node, _level: number): ReactElement => (
6966
<NodeView
7067
getChildrenName={getChildrenName}
7168
node={item}
@@ -80,15 +77,15 @@ const NodeView: React.FC<IProps> = React.memo(
8077
);
8178

8279
const renderItem = useCallback(
83-
({ item }: { item: INode }) => renderChildren(item, level),
80+
({ item }: { item: Node }) => renderChildren(item, level),
8481
[renderChildren, level],
8582
);
8683

8784
const getItem = useCallback((data, index) => data && data[index], []);
8885

89-
const getItemCount = useCallback((data) => data?.length ?? 0, []);
86+
const getItemCount = useCallback((data) => data?.length, []);
9087

91-
const keyExtractor = useCallback((item: INode) => item._internalId, []);
88+
const keyExtractor = useCallback((item: Node) => item._internalId, []);
9289

9390
const nodeChildrenName = getChildrenName(_node);
9491
const nodeChildren: [] = _node[nodeChildrenName];

‎src/node-view/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export interface INode {
1+
export interface Node {
22
_internalId: string;
33
hidden: boolean;
44
opened: boolean;

‎src/nodes-context-provider/nodes-context-provider.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ type SetOpenedNodesParams = {
55
opened: boolean;
66
};
77

8-
type INodexContext = {
8+
type NodeContext = {
99
openedNodes: { [name: string]: boolean };
10-
setOpenNode: ({ internalId, opened }: SetOpenedNodesParams) => void;
10+
setOpenNode?: ({ internalId, opened }: SetOpenedNodesParams) => void;
1111
};
1212

13-
const NodesContext = React.createContext<INodexContext>({
13+
const defaultContextValue = {
1414
openedNodes: {},
15-
setOpenNode: (_: SetOpenedNodesParams) => {},
16-
});
15+
setOpenNode: undefined,
16+
};
17+
18+
const NodesContext = React.createContext<NodeContext>(defaultContextValue);
1719

1820
export const useNodesContext = () => useContext(NodesContext);
1921

0 commit comments

Comments
 (0)