Skip to content

Commit e382ff2

Browse files
committed
Merge remote-tracking branch 'origin' into release
2 parents 1d8ae9b + aa87d49 commit e382ff2

33 files changed

+958
-167
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {FlatListProps} from 'react-native';
2+
import {WheelPickerProps, WheelPickerItemProps, ITEM_HEIGHT} 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 itemsLength = listDriver.getProps().data?.length ?? 0;
16+
17+
const moveToItem = (index: number, itemHeight: number = ITEM_HEIGHT, numberOfRows: number = itemsLength) => {
18+
listDriver.triggerEvent('onMomentumScrollEnd', {
19+
contentOffset: {x: 0, y: itemHeight * index},
20+
contentSize: {height: numberOfRows * itemHeight, width: 400},
21+
layoutMeasurement: {height: 100, width: 400}
22+
});
23+
};
24+
25+
const getListHeight = () => {
26+
//@ts-expect-error
27+
return listDriver.getProps().height;
28+
};
29+
30+
const labelDriver = TextDriver({
31+
renderTree: props.renderTree,
32+
testID: `${props.testID}.label`
33+
});
34+
35+
const getLabel = () => {
36+
return labelDriver.getText();
37+
};
38+
39+
return {...driver, ...listDriver, getListHeight, moveToItem, getLabel};
40+
};
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: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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 with default itemHeight and numberOfRows', () => {
43+
const props = {itemHeight: undefined, numberOfVisibleRows: undefined};
44+
const renderTree = render(<TestCase {...props}/>);
45+
const driver = WheelPickerDriver({renderTree, testID});
46+
47+
driver.moveToItem(4);
48+
expect(onChange).toHaveBeenCalledWith(4, 4);
49+
50+
driver.moveToItem(7);
51+
expect(onChange).toHaveBeenCalledWith(7, 7);
52+
});
53+
54+
it('should call onChange after scrolling ends', () => {
55+
const renderTree = render(<TestCase/>);
56+
const driver = WheelPickerDriver({renderTree, testID});
57+
58+
driver.moveToItem(4, ITEM_HEIGHT);
59+
expect(onChange).toHaveBeenCalledWith(4, 4);
60+
61+
driver.moveToItem(7, ITEM_HEIGHT);
62+
expect(onChange).toHaveBeenCalledWith(7, 7);
63+
});
64+
});
65+
66+
describe('initialValue', () => {
67+
it('should not call onChange when initialValue is updated', () => {
68+
const renderTree = render(<TestCase/>);
69+
renderTree.rerender(<TestCase initialValue={2}/>);
70+
expect(onChange).not.toHaveBeenCalled();
71+
});
72+
});
73+
74+
describe('label', () => {
75+
it('should return label', () => {
76+
const label = 'Hours';
77+
const renderTree = render(<TestCase label={label}/>);
78+
const driver = WheelPickerDriver({renderTree, testID});
79+
expect(driver.getLabel()).toEqual(label);
80+
});
81+
});
82+
83+
describe('PickerItem', () => {
84+
it('should get first item\'s label', () => {
85+
const renderTree = render(<TestCase/>);
86+
const index = 0;
87+
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
88+
expect(driver.getLabel()).toEqual('item #0');
89+
});
90+
91+
it('should get first item\'s text style when no active/inactive colors', () => {
92+
const renderTree = render(<TestCase textStyle={{color: Colors.green30}}/>);
93+
const index = 0;
94+
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
95+
expect(driver.getLabelStyle()?.color).toEqual(Colors.green30);
96+
});
97+
98+
//TODO: Fix these test's using AnimatedStyle mocking
99+
// it('should call onChange after second item is pressed', async () => {
100+
// const renderTree = render(<TestCase/>);
101+
// const index = 1;
102+
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
103+
104+
// driver.press();
105+
106+
// expect(await onChange).toHaveBeenCalledTimes(1);
107+
// expect(onChange).toHaveBeenCalledWith(1);
108+
// });
109+
110+
// it('should not call onChange after first item is pressed', async () => {
111+
// const renderTree = render(<TestCase/>);
112+
// const index = 0;
113+
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
114+
115+
// driver.press();
116+
117+
// expect(onChange).not.toHaveBeenCalledTimes(1);
118+
// });
119+
});
120+
});

src/components/WheelPicker/index.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {WheelPickerAlign} from './types';
2323
export {WheelPickerAlign};
2424

2525
const AnimatedFlatList = Animated.createAnimatedComponent<FlatListProps<ItemProps>>(FlatList);
26+
export const ITEM_HEIGHT = 44;
2627

2728
export interface WheelPickerProps {
2829
/**
@@ -101,7 +102,7 @@ export interface WheelPickerProps {
101102

102103
const WheelPicker = ({
103104
items: propItems,
104-
itemHeight = 44,
105+
itemHeight = ITEM_HEIGHT,
105106
numberOfVisibleRows = 5,
106107
activeTextColor = Colors.$textPrimary,
107108
inactiveTextColor,
@@ -232,14 +233,14 @@ const WheelPicker = ({
232233
activeColor={activeTextColor}
233234
inactiveColor={inactiveTextColor}
234235
style={textStyle}
236+
testID={`${testID}.item_${index}`}
235237
{...item}
236238
disableRTL={shouldDisableRTL}
237239
fakeLabel={label}
238240
fakeLabelStyle={labelStyle}
239241
fakeLabelProps={fakeLabelProps}
240242
centerH={!label}
241243
onSelect={selectItem}
242-
testID={`${testID}.item_${index}`}
243244
/>
244245
);
245246
},
@@ -296,7 +297,14 @@ const WheelPicker = ({
296297
// @ts-expect-error
297298
<View style={labelContainerStyle} width={flatListWidth} pointerEvents="none">
298299
<View style={labelInnerContainerStyle} centerV pointerEvents="none">
299-
<Text {...labelMargins} text80M {...labelProps} color={activeTextColor} style={labelStyle}>
300+
<Text
301+
{...labelMargins}
302+
text80M
303+
{...labelProps}
304+
color={activeTextColor}
305+
style={labelStyle}
306+
testID={`${testID}.label`}
307+
>
300308
{label}
301309
</Text>
302310
</View>
@@ -310,7 +318,8 @@ const WheelPicker = ({
310318
label,
311319
labelProps,
312320
activeTextColor,
313-
labelStyle
321+
labelStyle,
322+
testID
314323
]);
315324

316325
const fader = useMemo(() => (position: FaderPosition) => {

src/components/hint/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class Hint extends Component<HintProps, HintState> {
227227

228228
if (!this.state.targetLayoutInWindow || this.props.onBackgroundPress) {
229229
setTimeout(() => {
230-
this.targetRef?.measureInWindow((x: number, y: number, width: number, height: number) => {
230+
this.targetRef?.measureInWindow?.((x: number, y: number, width: number, height: number) => {
231231
const targetLayoutInWindow = {x, y, width, height};
232232
this.setState({targetLayoutInWindow});
233233
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import {render} from '@testing-library/react-native';
3+
import MaskedInput from '../new';
4+
import Text from '../../../components/text';
5+
import {TextFieldDriver} from '../../textField/TextField.driver.new';
6+
7+
const testID = 'field';
8+
9+
const TestCase = () => {
10+
return <MaskedInput testID={testID} renderMaskedText={(text?: string) => <Text>{text}</Text>}/>;
11+
};
12+
13+
describe('MaskedInput (new)', () => {
14+
it('Sanity - it renders', () => {
15+
const renderTree = render(<TestCase/>);
16+
const mainInputDriver = TextFieldDriver({renderTree, testID});
17+
mainInputDriver.exists();
18+
});
19+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import {render} from '@testing-library/react-native';
3+
import MaskedInput from '../old';
4+
import Text from '../../../components/text';
5+
import {TextFieldDriver} from '../../textField/TextField.driver.new';
6+
7+
const testID = 'field';
8+
9+
const TestCase = () => {
10+
// @ts-expect-error - this has an error, but this is an old component and I don't want to spend time fixing it
11+
return <MaskedInput testID={testID} renderMaskedText={(text?: string) => <Text>{text}</Text>}/>;
12+
};
13+
14+
describe('MaskedInput (old)', () => {
15+
it('Sanity - it renders', () => {
16+
const renderTree = render(<TestCase/>);
17+
const mainInputDriver = TextFieldDriver({renderTree, testID});
18+
mainInputDriver.exists();
19+
});
20+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {ModalProps} from './index';
2+
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
3+
import {ButtonDriver} from '../button/Button.driver.new';
4+
5+
export const ModalDriver = (props: ComponentProps) => {
6+
const {renderTree, testID} = props;
7+
const driver = useComponentDriver<ModalProps>(props);
8+
const overlayDriver = ButtonDriver({renderTree, testID: `${testID}.TouchableOverlay`});
9+
10+
const isVisible = () => {
11+
return !!driver.getProps().visible;
12+
};
13+
14+
return {...driver, isVisible, pressOnBackground: overlayDriver.press};
15+
};

0 commit comments

Comments
 (0)