Skip to content

WheelPicker - add driver #2903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/components/WheelPicker/WheelPicker.driver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {FlatListProps} from 'react-native';
import {WheelPickerProps, WheelPickerItemProps} from './index';
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
import {useScrollableDriver} from '../../testkit/new/useScrollable.driver';
import {TextDriver} from '../../components/Text/Text.driver.new';

export const WheelPickerDriver = (props: ComponentProps) => {
const driver = useComponentDriver<WheelPickerProps>(props);

const listDriver = useScrollableDriver<FlatListProps<WheelPickerItemProps>>(useComponentDriver({
renderTree: props.renderTree,
testID: `${props.testID}.list`
}));

const moveToItem = (index: number, numberOfRows: number, itemHeight: number) => {
listDriver.triggerEvent('onMomentumScrollEnd', {
contentOffset: {x: 0, y: itemHeight * index},
contentSize: {height: numberOfRows * itemHeight, width: 400},
layoutMeasurement: {height: 100, width: 400}
});
};

const getListHeight = () => {
//@ts-expect-error
return listDriver.getProps().height;
};

const labelDriver = TextDriver({
renderTree: props.renderTree,
testID: `${props.testID}.label`
});

const getLabel = () => {
return labelDriver.getText();
};

return {...driver, ...listDriver, getListHeight, moveToItem, getLabel};
};
25 changes: 25 additions & 0 deletions src/components/WheelPicker/WheelPickerItem.driver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
// import {usePressableDriver} from '../../testkit';
import {TextDriver} from '../../components/Text/Text.driver.new';
// import {WheelPickerItemProps} from './index';


export const WheelPickerItemDriver = (props: ComponentProps) => {
const driver = useComponentDriver(props);
// const driver = usePressableDriver<WheelPickerItemProps>(useComponentDriver(props));

const labelDriver = TextDriver({
renderTree: props.renderTree,
testID: `${props.testID}.text`
});

const getLabel = () => {
return labelDriver.getText();
};

const getLabelStyle = () => {
return labelDriver.getStyle(); // NOTE: when there's active/inactive colors the color will be animated sharedValue instead of string
};

return {...driver, getLabel, getLabelStyle};
};
82 changes: 0 additions & 82 deletions src/components/WheelPicker/__tests__/index.spec.js

This file was deleted.

108 changes: 108 additions & 0 deletions src/components/WheelPicker/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import _ from 'lodash';
import React from 'react';
import {render/* , act, waitFor */} from '@testing-library/react-native';
import {Colors} from '../../../style';
import WheelPicker from '../index';
import {WheelPickerDriver} from '../WheelPicker.driver';
import {WheelPickerItemDriver} from '../WheelPickerItem.driver';

const ITEM_HEIGHT = 50;
const NUM_OF_ROWS = 10;
const testID = 'wheel';
const onChange = jest.fn();

const TestCase = props => {
return (
<WheelPicker
testID={testID}
items={_.times(60, i => i).map(item => ({label: `item #${item}`, value: item, testID: `${item}`}))}
initialValue={0}
onChange={onChange}
numberOfVisibleRows={NUM_OF_ROWS}
itemHeight={ITEM_HEIGHT}
activeTextColor={Colors.red30}
inactiveTextColor={Colors.blue30}
{...props}
/>
);
};

describe('WheelPicker', () => {
beforeEach(() => {
onChange.mockClear();
});

describe('FlatList', () => {
it('should present $NUM_OF_ROWS rows', () => {
const renderTree = render(<TestCase/>);
const driver = WheelPickerDriver({renderTree, testID});
expect(driver.getListHeight()).toBe(NUM_OF_ROWS * ITEM_HEIGHT);
});

it('should call onChange after scrolling ends', () => {
const renderTree = render(<TestCase/>);
const driver = WheelPickerDriver({renderTree, testID});

driver.moveToItem(4, NUM_OF_ROWS, ITEM_HEIGHT);
expect(onChange).toHaveBeenCalledWith(4, 4);

driver.moveToItem(7, NUM_OF_ROWS, ITEM_HEIGHT);
expect(onChange).toHaveBeenCalledWith(7, 7);
});
});

describe('initialValue', () => {
it('should not call onChange when initialValue is updated', () => {
const renderTree = render(<TestCase/>);
renderTree.rerender(<TestCase initialValue={2}/>);
expect(onChange).not.toHaveBeenCalled();
});
});

describe('label', () => {
it('should return label', () => {
const label = 'Hours';
const renderTree = render(<TestCase label={label}/>);
const driver = WheelPickerDriver({renderTree, testID});
expect(driver.getLabel()).toEqual(label);
});
});

describe('PickerItem', () => {
it('should get first item\'s label', () => {
const renderTree = render(<TestCase/>);
const index = 0;
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
expect(driver.getLabel()).toEqual('item #0');
});

it('should get first item\'s text style when no active/inactive colors', () => {
const renderTree = render(<TestCase textStyle={{color: Colors.green30}}/>);
const index = 0;
const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});
expect(driver.getLabelStyle()?.color).toEqual(Colors.green30);
});

//TODO: Fix these test's using AnimatedStyle mocking
// it('should call onChange after second item is pressed', async () => {
// const renderTree = render(<TestCase/>);
// const index = 1;
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});

// driver.press();

// expect(await onChange).toHaveBeenCalledTimes(1);
// expect(onChange).toHaveBeenCalledWith(1);
// });

// it('should not call onChange after first item is pressed', async () => {
// const renderTree = render(<TestCase/>);
// const index = 0;
// const driver = WheelPickerItemDriver({renderTree, testID: `${index}`});

// driver.press();

// expect(onChange).not.toHaveBeenCalledTimes(1);
// });
});
});
14 changes: 11 additions & 3 deletions src/components/WheelPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,14 @@ const WheelPicker = ({
activeColor={activeTextColor}
inactiveColor={inactiveTextColor}
style={textStyle}
testID={`${testID}.item_${index}`}
{...item}
disableRTL={shouldDisableRTL}
fakeLabel={label}
fakeLabelStyle={labelStyle}
fakeLabelProps={fakeLabelProps}
centerH={!label}
onSelect={selectItem}
testID={`${testID}.item_${index}`}
/>
);
},
Expand Down Expand Up @@ -296,7 +296,14 @@ const WheelPicker = ({
// @ts-expect-error
<View style={labelContainerStyle} width={flatListWidth} pointerEvents="none">
<View style={labelInnerContainerStyle} centerV pointerEvents="none">
<Text {...labelMargins} text80M {...labelProps} color={activeTextColor} style={labelStyle}>
<Text
{...labelMargins}
text80M
{...labelProps}
color={activeTextColor}
style={labelStyle}
testID={`${testID}.label`}
>
{label}
</Text>
</View>
Expand All @@ -310,7 +317,8 @@ const WheelPicker = ({
label,
labelProps,
activeTextColor,
labelStyle
labelStyle,
testID
]);

const fader = useMemo(() => (position: FaderPosition) => {
Expand Down
21 changes: 21 additions & 0 deletions src/components/sectionsWheelPicker/SectionsWheelPicker.driver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import _ from 'lodash';
import {useComponentDriver, ComponentProps} from '../../testkit/new/Component.driver';
import {WheelPickerDriver} from '../WheelPicker/WheelPicker.driver';
import {SectionsWheelPickerProps} from './index';

export const SectionsWheelPickerDriver = (props: ComponentProps) => {
const driver = useComponentDriver<SectionsWheelPickerProps>(props);
const sections = driver.getProps().children as SectionsWheelPickerProps;
const sectionsDrivers = _.map(sections, (_, index) => {
const sectionTestID = `${props.testID}.${index}`;
return WheelPickerDriver({
renderTree: props.renderTree,
testID: sectionTestID
});
});




return {...driver, sections, sectionsDrivers};
};
41 changes: 41 additions & 0 deletions src/components/sectionsWheelPicker/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import _ from 'lodash';
import React from 'react';
import SectionsWheelPicker from '../index';
import {render} from '@testing-library/react-native';
import {SectionsWheelPickerDriver} from '../SectionsWheelPicker.driver';
import {sections, labels} from '../mockSections';

const testID = 'sectionsWheel';
const onChange = jest.fn();

const TestCase = props => {
return (
<SectionsWheelPicker
testID={testID}
numberOfVisibleRows={4}
sections={sections}
{...props}
/>
);
};

describe('SectionsWheelPicker', () => {
beforeEach(() => {
onChange.mockClear();
});

it('should present 3 sections', () => {
const renderTree = render(<TestCase/>);
const driver = SectionsWheelPickerDriver({renderTree, testID});
expect(driver.sectionsDrivers.length).toBe(3);
});

it('should have 3 labels', () => {
const renderTree = render(<TestCase/>);
const driver = SectionsWheelPickerDriver({renderTree, testID});
const sectionsDrivers = driver.sectionsDrivers;
_.map(sectionsDrivers, (sectionDriver, index) => {
expect(sectionDriver.getLabel()).toBe(labels[index]);
});
});
});
6 changes: 3 additions & 3 deletions src/components/sectionsWheelPicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import _ from 'lodash';
import React, {useMemo} from 'react';
import React, {PropsWithChildren, useMemo} from 'react';
import {TextStyle, StyleSheet} from 'react-native';
import {Constants, asBaseComponent} from '../../commons/new';
import View from '../view';
import WheelPicker, {WheelPickerProps} from '../WheelPicker';

export type SectionsWheelPickerProps = {
export type SectionsWheelPickerProps = PropsWithChildren<{
/**
* Array of sections.
*/
Expand Down Expand Up @@ -34,7 +34,7 @@ export type SectionsWheelPickerProps = {
textStyle?: TextStyle;
disableRTL?: boolean;
testID?: string;
};
}>;

/**
* @description: SectionsWheelPicker component for presenting set of wheelPickers
Expand Down
Loading