Skip to content

Commit b8509b5

Browse files
M-i-k-e-llidord-wix
authored andcommitted
SortableList - add driver and test (#2568)
* SortableList - add driver and test * Review fixes
1 parent 513671f commit b8509b5

File tree

10 files changed

+182
-42
lines changed

10 files changed

+182
-42
lines changed

GestureDetectorMock.tsx

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,27 @@ type Props = {
66
children: any;
77
};
88

9+
const DEFAULT_DATA = {
10+
absoluteX: 0,
11+
absoluteY: 0,
12+
translationX: 0,
13+
translationY: 0,
14+
velocityX: 0,
15+
velocityY: 0,
16+
x: 0,
17+
y: 0
18+
};
19+
920
export class GestureDetectorMock extends React.Component<Props> {
1021
render() {
1122
switch (this.props.gesture.type) {
1223
case 'tap':
1324
return (
1425
<TouchableOpacity
1526
onPress={() => {
16-
this.props.gesture._handlers.onTouchesDown();
17-
this.props.gesture._handlers.onEnd();
18-
this.props.gesture._handlers.onFinalize();
27+
this.props.gesture._handlers.onTouchesDown?.();
28+
this.props.gesture._handlers.onEnd?.();
29+
this.props.gesture._handlers.onFinalize?.();
1930
}}
2031
>
2132
{this.props.children}
@@ -24,37 +35,17 @@ export class GestureDetectorMock extends React.Component<Props> {
2435
case 'pan':
2536
return (
2637
<TouchableOpacity
27-
onPress={() => {
28-
this.props.gesture._handlers.onStart({
29-
absoluteX: 0,
30-
absoluteY: 0,
31-
translationX: 0,
32-
translationY: 0,
33-
velocityX: 0,
34-
velocityY: 0,
35-
x: 0,
36-
y: 0
37-
});
38-
this.props.gesture._handlers.onUpdate({
39-
absoluteX: 0,
40-
absoluteY: 0,
41-
translationX: 0,
42-
translationY: 0,
43-
velocityX: 0,
44-
velocityY: 0,
45-
x: 0,
46-
y: 0
47-
});
48-
this.props.gesture._handlers.onEnd({
49-
absoluteX: 0,
50-
absoluteY: 0,
51-
translationX: 0,
52-
translationY: 0,
53-
velocityX: 0,
54-
velocityY: 0,
55-
x: 0,
56-
y: 0
57-
});
38+
onPress={(data) => {
39+
this.props.gesture._handlers.onStart?.(DEFAULT_DATA);
40+
if (Array.isArray(data)) {
41+
data.forEach(info => {
42+
this.props.gesture._handlers.onUpdate?.({...DEFAULT_DATA, ...info});
43+
});
44+
} else {
45+
this.props.gesture._handlers.onUpdate?.({...DEFAULT_DATA, ...data});
46+
}
47+
this.props.gesture._handlers.onEnd?.(DEFAULT_DATA);
48+
this.props.gesture._handlers.onFinalize?.(DEFAULT_DATA);
5849
}}
5950
>
6051
{this.props.children}

jest-setup.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ jest.mock('react-native-gesture-handler',
7474
PanMock.onStart = getDefaultMockedHandler('onStart');
7575
PanMock.onUpdate = getDefaultMockedHandler('onUpdate');
7676
PanMock.onEnd = getDefaultMockedHandler('onEnd');
77+
PanMock.onFinalize = getDefaultMockedHandler('onFinalize');
78+
PanMock.activateAfterLongPress = getDefaultMockedHandler('activateAfterLongPress');
79+
PanMock.enabled = getDefaultMockedHandler('enabled');
80+
PanMock.onTouchesMove = getDefaultMockedHandler('onTouchesMove');
81+
PanMock.prepare = jest.fn();
7782
PanMock.initialize = jest.fn();
7883
PanMock.toGestureArray = jest.fn(() => {
7984
return [PanMock];

src/components/button/Button.driver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {TextDriver} from '../text/Text.driver';
44

55
/**
66
* Please run clear after each test
7-
* */
7+
*/
88
export class ButtonDriver extends ComponentDriver {
99
private readonly labelDriver: TextDriver;
1010
private readonly iconDriver: ImageDriver;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import _ from 'lodash';
2+
import {ComponentDriver} from '../../testkit/Component.driver';
3+
4+
/**
5+
* Please run clear after each test
6+
*/
7+
export class SortableListItemDriver extends ComponentDriver {
8+
dragUp = async (indices: number) => {
9+
this.validateIndices(indices);
10+
const data = _.times(indices, index => {
11+
return {
12+
translationY: -52 * (index + 1)
13+
};
14+
});
15+
16+
await this.uniDriver.selectorByTestId(this.testID).then(driver => driver.drag(data));
17+
};
18+
19+
dragDown = async (indices: number) => {
20+
this.validateIndices(indices);
21+
const data = _.times(indices, index => {
22+
return {
23+
translationY: 52 * (index + 1)
24+
};
25+
});
26+
27+
await this.uniDriver.selectorByTestId(this.testID).then(driver => driver.drag(data));
28+
};
29+
30+
private validateIndices = (indices: number) => {
31+
if (indices <= 0 || !Number.isInteger(indices)) {
32+
throw Error('indices must be a positive integer');
33+
}
34+
};
35+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import _ from 'lodash';
2+
import React, {useCallback} from 'react';
3+
import Text from '../../text';
4+
import View from '../../view';
5+
import SortableList from '../index';
6+
import {ComponentDriver, SortableListItemDriver} from '../../../testkit';
7+
8+
const defaultProps = {
9+
testID: 'sortableList'
10+
};
11+
12+
const ITEMS = _.times(5, index => {
13+
return {
14+
text: `${index}`,
15+
id: `${index}`
16+
};
17+
});
18+
19+
const TestCase = props => {
20+
const renderItem = useCallback(({item}) => {
21+
return (
22+
<Text center testID={`item${item.id}`}>
23+
{item.text}
24+
</Text>
25+
);
26+
}, []);
27+
28+
return (
29+
<View flex>
30+
<View flex useSafeArea>
31+
<SortableList data={ITEMS} renderItem={renderItem} {...defaultProps} {...props}/>
32+
</View>
33+
</View>
34+
);
35+
};
36+
37+
describe('SortableList', () => {
38+
beforeEach(() => {
39+
jest.clearAllMocks();
40+
});
41+
afterEach(() => {
42+
ComponentDriver.clear();
43+
SortableListItemDriver.clear();
44+
});
45+
46+
it('SortableList onOrderChange is called - down', async () => {
47+
const onOrderChange = jest.fn();
48+
const component = <TestCase onOrderChange={onOrderChange}/>;
49+
const sortableListDriver = new ComponentDriver({component, testID: 'sortableList'});
50+
expect(await sortableListDriver.exists()).toBeTruthy();
51+
expect(onOrderChange).toHaveBeenCalledTimes(0);
52+
const item1Driver = new SortableListItemDriver({component, testID: 'item1'});
53+
expect(await item1Driver.exists()).toBeTruthy();
54+
await item1Driver.dragDown(1);
55+
expect(onOrderChange).toHaveBeenCalledTimes(1);
56+
expect(onOrderChange).toHaveBeenCalledWith([
57+
{id: '0', text: '0'},
58+
{id: '2', text: '2'},
59+
{id: '1', text: '1'},
60+
{id: '3', text: '3'},
61+
{id: '4', text: '4'}
62+
]);
63+
});
64+
65+
it('SortableList onOrderChange is called - up', async () => {
66+
const onOrderChange = jest.fn();
67+
const component = <TestCase onOrderChange={onOrderChange}/>;
68+
const sortableListDriver = new ComponentDriver({component, testID: 'sortableList'});
69+
expect(await sortableListDriver.exists()).toBeTruthy();
70+
expect(onOrderChange).toHaveBeenCalledTimes(0);
71+
const item4Driver = new SortableListItemDriver({component, testID: 'item4'});
72+
expect(await item4Driver.exists()).toBeTruthy();
73+
await item4Driver.dragUp(3);
74+
expect(onOrderChange).toHaveBeenCalledTimes(1);
75+
expect(onOrderChange).toHaveBeenCalledWith([
76+
{id: '0', text: '0'},
77+
{id: '4', text: '4'},
78+
{id: '1', text: '1'},
79+
{id: '2', text: '2'},
80+
{id: '3', text: '3'}
81+
]);
82+
});
83+
});

src/incubator/Dialog/__tests__/index.spec.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@ const TestCase = props => {
4141
);
4242
};
4343

44-
const _TestCase = props => <TestCase {...props}/>;
45-
4644
describe('Incubator.Dialog', () => {
4745
it('Incubator.Dialog should exist only if visible', async () => {
4846
const onDismiss = jest.fn();
49-
const component = _TestCase({onDismiss});
47+
const component = <TestCase onDismiss={onDismiss}/>;
5048
const dialogDriver = new ComponentDriver({component, testID: 'dialog'});
5149
expect(await dialogDriver.exists()).toBeFalsy();
5250
const openButtonDriver = new ButtonDriver({component, testID: 'openButton'});

src/testkit/Component.driver.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {UniDriver, UniDriverClass} from './UniDriver';
1+
import {DragData, UniDriver, UniDriverClass} from './UniDriver';
22
import {TestingLibraryDriver} from './drivers/TestingLibraryDriver';
33

44
export type ComponentDriverArgs = {
@@ -9,7 +9,7 @@ export type ComponentDriverArgs = {
99

1010
/**
1111
* Please run clear after each test
12-
* */
12+
*/
1313
export class ComponentDriver {
1414
protected readonly testID: string;
1515
protected readonly uniDriver: UniDriver;
@@ -45,6 +45,12 @@ export class ComponentDriver {
4545
.then((driver) => driver.press());
4646
};
4747

48+
drag = async (data: DragData | DragData[]) => {
49+
return this.uniDriver
50+
.selectorByTestId(this.testID)
51+
.then((driver) => driver.drag(data));
52+
};
53+
4854
focus = async () => {
4955
return this.uniDriver
5056
.selectorByTestId(this.testID)

src/testkit/UniDriver.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
export type DragData = {
2+
absoluteX?: number;
3+
absoluteY?: number;
4+
translationX?: number;
5+
translationY?: number;
6+
velocityX?: number;
7+
velocityY?: number;
8+
x?: number;
9+
y?: number;
10+
};
11+
112
export interface UniDriver {
213
selectorByTestId(testId: string): Promise<UniDriver>;
314
selectorByText(text: string): Promise<UniDriver>;
@@ -7,6 +18,7 @@ export interface UniDriver {
718
instance(): Promise<any>;
819
getInstanceProps(): Promise<any>;
920
press(): void;
21+
drag(data: DragData | DragData[]): void;
1022
focus(): void;
1123
blur(): void;
1224
typeText(text: string): Promise<void>;

src/testkit/drivers/TestingLibraryDriver.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {UniDriver} from '../UniDriver';
1+
import {DragData, UniDriver} from '../UniDriver';
22
import {fireEvent, render, RenderAPI} from '@testing-library/react-native';
33
import {ReactTestInstance} from 'react-test-renderer';
44
import {act} from '@testing-library/react-hooks';
@@ -85,6 +85,15 @@ export class TestingLibraryDriver implements UniDriver {
8585
fireEvent.press(this.reactTestInstances[0]);
8686
};
8787

88+
drag = (data: DragData | DragData[]): void => {
89+
if (!this.reactTestInstances) {
90+
throw new NoSelectorException();
91+
}
92+
this.validateExplicitInstance();
93+
this.validateSingleInstance();
94+
fireEvent.press(this.reactTestInstances[0], data);
95+
};
96+
8897
focus = (): void => {
8998
if (!this.reactTestInstances) {
9099
throw new NoSelectorException();

src/testkit/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export {ComponentDriver} from './Component.driver';
22
export {ImageDriver} from '../components/image/Image.driver';
3-
export {TextDriver} from '../components/Text/Text.driver';
3+
export {TextDriver} from '../components/text/Text.driver';
44
export {SwitchDriver} from '../components/switch/switch.driver';
55
export {ButtonDriver} from '../components/button/Button.driver';
66
export {TextFieldDriver} from '../incubator/TextField/TextField.driver';
@@ -10,3 +10,4 @@ export {CheckboxDriver} from '../components/checkbox/Checkbox.driver';
1010
export {HintDriver} from '../components/hint/Hint.driver';
1111
export {RadioButtonDriver} from '../components/radioButton/RadioButton.driver';
1212
export {RadioGroupDriver} from '../components/radioGroup/RadioGroup.driver';
13+
export {SortableListItemDriver} from '../components/sortableList/SortableListItem.driver';

0 commit comments

Comments
 (0)