Skip to content

Commit d3347ff

Browse files
WheelPicker - add driver (#2903)
* WheelPicker - add driver * rename function * Adding SectionsWheelPicker driver * remove extra const * move listdriver to top * Update src/components/WheelPicker/__tests__/index.spec.tsx add todo Co-authored-by: Adi Mordo <[email protected]> * Update src/components/WheelPicker/__tests__/index.spec.tsx foramt * Update src/components/WheelPicker/__tests__/index.spec.tsx format remove spaces * Update src/components/sectionsWheelPicker/mockSections.ts remove commented line * Update src/components/sectionsWheelPicker/mockSections.ts remove commented line * Update src/components/sectionsWheelPicker/mockSections.ts remove commented line --------- Co-authored-by: Adi Mordo <[email protected]>
1 parent 9e0c032 commit d3347ff

File tree

11 files changed

+302
-98
lines changed

11 files changed

+302
-98
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {FlatListProps} from 'react-native';
2+
import {WheelPickerProps, WheelPickerItemProps} from './index';
3+
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
4+
import {useScrollableDriver} from '../../testkit/new/useScrollable.driver';
5+
import {TextDriver} from '../../components/Text/Text.driver.new';
6+
7+
export const WheelPickerDriver = (props: ComponentProps) => {
8+
const driver = useComponentDriver<WheelPickerProps>(props);
9+
10+
const listDriver = useScrollableDriver<FlatListProps<WheelPickerItemProps>>(useComponentDriver({
11+
renderTree: props.renderTree,
12+
testID: `${props.testID}.list`
13+
}));
14+
15+
const moveToItem = (index: number, numberOfRows: number, itemHeight: number) => {
16+
listDriver.triggerEvent('onMomentumScrollEnd', {
17+
contentOffset: {x: 0, y: itemHeight * index},
18+
contentSize: {height: numberOfRows * itemHeight, width: 400},
19+
layoutMeasurement: {height: 100, width: 400}
20+
});
21+
};
22+
23+
const getListHeight = () => {
24+
//@ts-expect-error
25+
return listDriver.getProps().height;
26+
};
27+
28+
const labelDriver = TextDriver({
29+
renderTree: props.renderTree,
30+
testID: `${props.testID}.label`
31+
});
32+
33+
const getLabel = () => {
34+
return labelDriver.getText();
35+
};
36+
37+
return {...driver, ...listDriver, getListHeight, moveToItem, getLabel};
38+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
2+
// import {usePressableDriver} from '../../testkit';
3+
import {TextDriver} from '../../components/Text/Text.driver.new';
4+
// import {WheelPickerItemProps} from './index';
5+
6+
7+
export const WheelPickerItemDriver = (props: ComponentProps) => {
8+
const driver = useComponentDriver(props);
9+
// const driver = usePressableDriver<WheelPickerItemProps>(useComponentDriver(props));
10+
11+
const labelDriver = TextDriver({
12+
renderTree: props.renderTree,
13+
testID: `${props.testID}.text`
14+
});
15+
16+
const getLabel = () => {
17+
return labelDriver.getText();
18+
};
19+
20+
const getLabelStyle = () => {
21+
return labelDriver.getStyle(); // NOTE: when there's active/inactive colors the color will be animated sharedValue instead of string
22+
};
23+
24+
return {...driver, getLabel, getLabelStyle};
25+
};

src/components/WheelPicker/__tests__/index.spec.js

Lines changed: 0 additions & 82 deletions
This file was deleted.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import _ from 'lodash';
2+
import React from 'react';
3+
import {render/* , act, waitFor */} from '@testing-library/react-native';
4+
import {Colors} from '../../../style';
5+
import WheelPicker from '../index';
6+
import {WheelPickerDriver} from '../WheelPicker.driver';
7+
import {WheelPickerItemDriver} from '../WheelPickerItem.driver';
8+
9+
const ITEM_HEIGHT = 50;
10+
const NUM_OF_ROWS = 10;
11+
const testID = 'wheel';
12+
const onChange = jest.fn();
13+
14+
const TestCase = props => {
15+
return (
16+
<WheelPicker
17+
testID={testID}
18+
items={_.times(60, i => i).map(item => ({label: `item #${item}`, value: item, testID: `${item}`}))}
19+
initialValue={0}
20+
onChange={onChange}
21+
numberOfVisibleRows={NUM_OF_ROWS}
22+
itemHeight={ITEM_HEIGHT}
23+
activeTextColor={Colors.red30}
24+
inactiveTextColor={Colors.blue30}
25+
{...props}
26+
/>
27+
);
28+
};
29+
30+
describe('WheelPicker', () => {
31+
beforeEach(() => {
32+
onChange.mockClear();
33+
});
34+
35+
describe('FlatList', () => {
36+
it('should present $NUM_OF_ROWS rows', () => {
37+
const renderTree = render(<TestCase/>);
38+
const driver = WheelPickerDriver({renderTree, testID});
39+
expect(driver.getListHeight()).toBe(NUM_OF_ROWS * ITEM_HEIGHT);
40+
});
41+
42+
it('should call onChange after scrolling ends', () => {
43+
const renderTree = render(<TestCase/>);
44+
const driver = WheelPickerDriver({renderTree, testID});
45+
46+
driver.moveToItem(4, NUM_OF_ROWS, ITEM_HEIGHT);
47+
expect(onChange).toHaveBeenCalledWith(4, 4);
48+
49+
driver.moveToItem(7, NUM_OF_ROWS, ITEM_HEIGHT);
50+
expect(onChange).toHaveBeenCalledWith(7, 7);
51+
});
52+
});
53+
54+
describe('initialValue', () => {
55+
it('should not call onChange when initialValue is updated', () => {
56+
const renderTree = render(<TestCase/>);
57+
renderTree.rerender(<TestCase initialValue={2}/>);
58+
expect(onChange).not.toHaveBeenCalled();
59+
});
60+
});
61+
62+
describe('label', () => {
63+
it('should return label', () => {
64+
const label = 'Hours';
65+
const renderTree = render(<TestCase label={label}/>);
66+
const driver = WheelPickerDriver({renderTree, testID});
67+
expect(driver.getLabel()).toEqual(label);
68+
});
69+
});
70+
71+
describe('PickerItem', () => {
72+
it('should get first item\'s label', () => {
73+
const renderTree = render(<TestCase/>);
74+
const index = 0;
75+
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
76+
expect(driver.getLabel()).toEqual('item #0');
77+
});
78+
79+
it('should get first item\'s text style when no active/inactive colors', () => {
80+
const renderTree = render(<TestCase textStyle={{color: Colors.green30}}/>);
81+
const index = 0;
82+
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
83+
expect(driver.getLabelStyle()?.color).toEqual(Colors.green30);
84+
});
85+
86+
//TODO: Fix these test's using AnimatedStyle mocking
87+
// it('should call onChange after second item is pressed', async () => {
88+
// const renderTree = render(<TestCase/>);
89+
// const index = 1;
90+
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
91+
92+
// driver.press();
93+
94+
// expect(await onChange).toHaveBeenCalledTimes(1);
95+
// expect(onChange).toHaveBeenCalledWith(1);
96+
// });
97+
98+
// it('should not call onChange after first item is pressed', async () => {
99+
// const renderTree = render(<TestCase/>);
100+
// const index = 0;
101+
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
102+
103+
// driver.press();
104+
105+
// expect(onChange).not.toHaveBeenCalledTimes(1);
106+
// });
107+
});
108+
});

src/components/WheelPicker/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,14 @@ const WheelPicker = ({
232232
activeColor={activeTextColor}
233233
inactiveColor={inactiveTextColor}
234234
style={textStyle}
235+
testID={`${testID}.item_${index}`}
235236
{...item}
236237
disableRTL={shouldDisableRTL}
237238
fakeLabel={label}
238239
fakeLabelStyle={labelStyle}
239240
fakeLabelProps={fakeLabelProps}
240241
centerH={!label}
241242
onSelect={selectItem}
242-
testID={`${testID}.item_${index}`}
243243
/>
244244
);
245245
},
@@ -296,7 +296,14 @@ const WheelPicker = ({
296296
// @ts-expect-error
297297
<View style={labelContainerStyle} width={flatListWidth} pointerEvents="none">
298298
<View style={labelInnerContainerStyle} centerV pointerEvents="none">
299-
<Text {...labelMargins} text80M {...labelProps} color={activeTextColor} style={labelStyle}>
299+
<Text
300+
{...labelMargins}
301+
text80M
302+
{...labelProps}
303+
color={activeTextColor}
304+
style={labelStyle}
305+
testID={`${testID}.label`}
306+
>
300307
{label}
301308
</Text>
302309
</View>
@@ -310,7 +317,8 @@ const WheelPicker = ({
310317
label,
311318
labelProps,
312319
activeTextColor,
313-
labelStyle
320+
labelStyle,
321+
testID
314322
]);
315323

316324
const fader = useMemo(() => (position: FaderPosition) => {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import _ from 'lodash';
2+
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
3+
import {WheelPickerDriver} from '../WheelPicker/WheelPicker.driver';
4+
import {SectionsWheelPickerProps} from './index';
5+
6+
export const SectionsWheelPickerDriver = (props: ComponentProps) => {
7+
const driver = useComponentDriver<SectionsWheelPickerProps>(props);
8+
const sections = driver.getProps().children as SectionsWheelPickerProps;
9+
const sectionsDrivers = _.map(sections, (_, index) => {
10+
const sectionTestID = `${props.testID}.${index}`;
11+
return WheelPickerDriver({
12+
renderTree: props.renderTree,
13+
testID: sectionTestID
14+
});
15+
});
16+
17+
18+
19+
20+
return {...driver, sections, sectionsDrivers};
21+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import _ from 'lodash';
2+
import React from 'react';
3+
import SectionsWheelPicker from '../index';
4+
import {render} from '@testing-library/react-native';
5+
import {SectionsWheelPickerDriver} from '../SectionsWheelPicker.driver';
6+
import {sections, labels} from '../mockSections';
7+
8+
const testID = 'sectionsWheel';
9+
const onChange = jest.fn();
10+
11+
const TestCase = props => {
12+
return (
13+
<SectionsWheelPicker
14+
testID={testID}
15+
numberOfVisibleRows={4}
16+
sections={sections}
17+
{...props}
18+
/>
19+
);
20+
};
21+
22+
describe('SectionsWheelPicker', () => {
23+
beforeEach(() => {
24+
onChange.mockClear();
25+
});
26+
27+
it('should present 3 sections', () => {
28+
const renderTree = render(<TestCase/>);
29+
const driver = SectionsWheelPickerDriver({renderTree, testID});
30+
expect(driver.sectionsDrivers.length).toBe(3);
31+
});
32+
33+
it('should have 3 labels', () => {
34+
const renderTree = render(<TestCase/>);
35+
const driver = SectionsWheelPickerDriver({renderTree, testID});
36+
const sectionsDrivers = driver.sectionsDrivers;
37+
_.map(sectionsDrivers, (sectionDriver, index) => {
38+
expect(sectionDriver.getLabel()).toBe(labels[index]);
39+
});
40+
});
41+
});

src/components/sectionsWheelPicker/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import _ from 'lodash';
2-
import React, {useMemo} from 'react';
2+
import React, {PropsWithChildren, useMemo} from 'react';
33
import {TextStyle, StyleSheet} from 'react-native';
44
import {Constants, asBaseComponent} from '../../commons/new';
55
import View from '../view';
66
import WheelPicker, {WheelPickerProps} from '../WheelPicker';
77

8-
export type SectionsWheelPickerProps = {
8+
export type SectionsWheelPickerProps = PropsWithChildren<{
99
/**
1010
* Array of sections.
1111
*/
@@ -34,7 +34,7 @@ export type SectionsWheelPickerProps = {
3434
textStyle?: TextStyle;
3535
disableRTL?: boolean;
3636
testID?: string;
37-
};
37+
}>;
3838

3939
/**
4040
* @description: SectionsWheelPicker component for presenting set of wheelPickers

0 commit comments

Comments
 (0)