Skip to content

Commit 05f2687

Browse files
committed
[workflow/test] Working on test cases
1 parent 025c253 commit 05f2687

14 files changed

Lines changed: 530 additions & 170 deletions

package.json

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,11 @@
1010
"test": "jest --coverage"
1111
},
1212
"dependencies": {
13-
"@hookform/resolvers": "^5.1.1",
14-
"@testing-library/react-native": "^12.9.0",
1513
"lodash": "^4.17.21",
1614
"react": "18.3.1",
17-
"react-hook-form": "^7.58.0",
1815
"react-native": "0.76.3",
19-
"react-native-phone-number-input": "^2.1.0",
2016
"react-native-vector-icons": "^10.2.0",
21-
"use-context-selector": "^2.0.0",
22-
"yup": "^1.6.1"
17+
"use-context-selector": "^2.0.0"
2318
},
2419
"devDependencies": {
2520
"@babel/core": "^7.25.2",
@@ -43,7 +38,8 @@
4338
"jest": "^29.6.3",
4439
"prettier": "2.8.8",
4540
"react-test-renderer": "18.2.0",
46-
"typescript": "5.0.4"
41+
"typescript": "5.0.4",
42+
"@testing-library/react-native": "^12.9.0"
4743
},
4844
"engines": {
4945
"node": ">=18"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import { Animated } from 'react-native';
3+
import { gray, InputLabel } from '../src';
4+
import { fireEvent, render } from './test-utils';
5+
6+
describe('InputLabel', () => {
7+
it('updates textLayoutRect state when onLayout is called', () => {
8+
const { getByText } = render(<InputLabel placeholder="Test Label" labelAnimatedValue={new Animated.Value(0)} />);
9+
10+
const textElement = getByText('Test Label');
11+
12+
fireEvent(textElement, 'layout', {
13+
nativeEvent: {
14+
layout: {
15+
x: 0,
16+
y: 0,
17+
width: 100,
18+
height: 20,
19+
},
20+
},
21+
});
22+
23+
expect(textElement.props.style).toEqual({ color: gray[800], fontSize: 14 });
24+
});
25+
});

src/packages/react-native-material-elements/__test__/OtpInput.test.tsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { fireEvent, render } from './test-utils';
55
describe('OTP Component', () => {
66
const mockOtpInputTestId = 'mock-otp-input-test-id';
77

8+
const mockOnChange = jest.fn();
9+
810
beforeEach(() => {
911
jest.clearAllMocks();
1012
});
@@ -25,7 +27,6 @@ describe('OTP Component', () => {
2527
});
2628

2729
it('calls onChange with the correct OTP value', () => {
28-
const mockOnChange = jest.fn();
2930
const { getByTestId } = render(<OTPInput length={3} onChange={mockOnChange} />);
3031

3132
const firstInput = getByTestId('otp-input-0');
@@ -111,4 +112,49 @@ describe('OTP Component', () => {
111112
expect(thirdInput).toBeDefined();
112113
expect(thirdInput.props.value).toEqual('3');
113114
});
115+
116+
it('ignores text input when length > 1', () => {
117+
const { getByTestId } = render(<OTPInput length={4} onChange={mockOnChange} />);
118+
const firstInput = getByTestId('otp-input-0');
119+
120+
fireEvent.changeText(firstInput, '12');
121+
122+
expect(mockOnChange).not.toHaveBeenCalled();
123+
expect(firstInput.props.value).toBe('');
124+
});
125+
126+
it('calls onChange when a single character is entered', () => {
127+
const { getByTestId } = render(<OTPInput length={4} onChange={mockOnChange} />);
128+
const firstInput = getByTestId('otp-input-0');
129+
130+
fireEvent.changeText(firstInput, '1');
131+
132+
expect(mockOnChange).toHaveBeenCalledWith('1');
133+
expect(firstInput.props.value).toBe('1');
134+
});
135+
136+
it('throws error when defaultValue length > OTP length', () => {
137+
const spy = jest.spyOn(console, 'error').mockImplementation();
138+
expect(() => render(<OTPInput length={3} defaultValue="12345" />)).toThrow(
139+
'Default value must be equal or less then otp length',
140+
);
141+
spy.mockRestore();
142+
});
143+
144+
it('applies defaultValue when valid', () => {
145+
const { getByTestId } = render(<OTPInput length={4} defaultValue="12" />);
146+
expect(getByTestId('otp-input-0').props.value).toBe('1');
147+
expect(getByTestId('otp-input-1').props.value).toBe('2');
148+
expect(getByTestId('otp-input-2').props.value).toBe('');
149+
expect(getByTestId('otp-input-3').props.value).toBe('');
150+
});
151+
152+
it('focus handler is called on focus event', () => {
153+
const { getByTestId } = render(<OTPInput length={4} />);
154+
const secondInput = getByTestId('otp-input-1');
155+
156+
fireEvent(secondInput, 'focus');
157+
158+
expect(secondInput.props.selectTextOnFocus).toBe(true);
159+
});
114160
});
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { SegmentedControl } from '../src';
2+
import { SegmentedControlContainer } from '../src/components/SegmentedControl/SegmentedControlContainer';
3+
import { SegmentedControlItem } from '../src/components/SegmentedControl/SegmentedControlItem';
4+
import { fireEvent, render } from './test-utils';
5+
6+
describe('SegmentedControl component', () => {
7+
beforeEach(() => {
8+
jest.clearAllMocks();
9+
});
10+
11+
it('should render correctly with default props', () => {
12+
const { toJSON } = render(<SegmentedControl data={['']} selectedIndex={0} />);
13+
expect(toJSON()).toMatchSnapshot();
14+
});
15+
});
16+
17+
describe('SegmentedControlContainer component', () => {
18+
beforeEach(() => {
19+
jest.clearAllMocks();
20+
});
21+
22+
it('should render correctly with default props', () => {
23+
const { toJSON } = render(<SegmentedControlContainer />);
24+
expect(toJSON()).toMatchSnapshot();
25+
});
26+
});
27+
28+
describe('SegmentedControlItem component', () => {
29+
const mockTestId = 'segmented-item-test-id';
30+
31+
const mockOnPress = jest.fn();
32+
33+
beforeEach(() => {
34+
jest.clearAllMocks();
35+
});
36+
37+
it('should render correctly with default props', () => {
38+
const { toJSON } = render(<SegmentedControlItem data={''} index={0} />);
39+
expect(toJSON()).toMatchSnapshot();
40+
});
41+
42+
it('should render the data when data passed as string', () => {
43+
const { getByText } = render(<SegmentedControlItem data={'First'} index={0} />);
44+
45+
const text = getByText('First');
46+
expect(text).toBeDefined();
47+
});
48+
49+
it('should render the data when data passed as number', () => {
50+
const { getByText } = render(<SegmentedControlItem data={1000} index={0} />);
51+
52+
const text = getByText('1000');
53+
expect(text).toBeDefined();
54+
});
55+
56+
it('should called the onPress function when click on the SegmentedControlItem', () => {
57+
const { getByTestId } = render(<SegmentedControlItem data={''} testID={mockTestId} index={0} onPress={mockOnPress} />);
58+
59+
const item = getByTestId(mockTestId);
60+
61+
fireEvent(item, 'press', { nativeEvent: {} });
62+
63+
expect(mockOnPress).toHaveBeenCalledTimes(1);
64+
});
65+
66+
it('should called the onPress function with string data when click on the SegmentedControlItem', () => {
67+
const { getByTestId } = render(<SegmentedControlItem data={'data'} testID={mockTestId} index={0} onPress={mockOnPress} />);
68+
69+
const item = getByTestId(mockTestId);
70+
71+
fireEvent(item, 'press', { nativeEvent: {} });
72+
73+
expect(mockOnPress).toHaveBeenCalledTimes(1);
74+
expect(mockOnPress).toHaveBeenCalledWith('data', 0);
75+
});
76+
77+
it('should called the onPress function with object data when click on the SegmentedControlItem', () => {
78+
const { getByTestId } = render(
79+
<SegmentedControlItem data={{ title: 'label' }} testID={mockTestId} index={0} onPress={mockOnPress} />,
80+
);
81+
82+
const item = getByTestId(mockTestId);
83+
84+
fireEvent(item, 'press', { nativeEvent: {} });
85+
86+
expect(mockOnPress).toHaveBeenCalledTimes(1);
87+
expect(mockOnPress).toHaveBeenCalledWith({ title: 'label' }, 0);
88+
});
89+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import { Animated } from 'react-native';
3+
import { gray, Skeleton } from '../src';
4+
import { render } from './test-utils';
5+
6+
describe('Skeleton component', () => {
7+
let colorSchemeSpy: jest.SpyInstance;
8+
9+
beforeEach(() => {
10+
jest.clearAllMocks();
11+
colorSchemeSpy = jest.spyOn(require('react-native'), 'useColorScheme');
12+
});
13+
14+
afterEach(() => {
15+
colorSchemeSpy.mockRestore();
16+
});
17+
18+
it('renders with default background in light mode', () => {
19+
colorSchemeSpy.mockReturnValue('light');
20+
const { getByTestId } = render(<Skeleton testID="skeleton" />);
21+
const skeleton = getByTestId('skeleton');
22+
expect(skeleton.props.style.backgroundColor).toBe(gray[400]);
23+
});
24+
25+
it('renders with default background in dark mode', () => {
26+
colorSchemeSpy.mockReturnValue('dark');
27+
const { getByTestId } = render(<Skeleton testID="skeleton" />);
28+
const skeleton = getByTestId('skeleton');
29+
expect(skeleton.props.style.backgroundColor).toBe(gray[800]);
30+
});
31+
32+
it('uses the custom backgroundColor when provided', () => {
33+
colorSchemeSpy.mockReturnValue('light');
34+
const { getByTestId } = render(<Skeleton testID="skeleton" backgroundColor="red" />);
35+
const skeleton = getByTestId('skeleton');
36+
expect(skeleton.props.style.backgroundColor).toBe('red');
37+
});
38+
39+
it('starts shimmer animation on mount', () => {
40+
const loopSpy = jest.spyOn(Animated, 'loop');
41+
render(<Skeleton testID="skeleton" />);
42+
expect(loopSpy).toHaveBeenCalled();
43+
});
44+
});

src/packages/react-native-material-elements/__test__/Snackbar.test.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import { DeviceEventEmitter } from 'react-native';
2-
import { HIDE_SNACK_BAR_MESSAGE, SHOW_SNACK_BAR_MESSAGE, snackbar, SnackbarProperties } from '../src';
2+
import { HIDE_SNACK_BAR_MESSAGE, SHOW_SNACK_BAR_MESSAGE, Snackbar, snackbar, SnackbarProperties } from '../src';
3+
import { render } from './test-utils';
34

45
describe('snackbar utils', () => {
56
beforeEach(() => {
67
jest.clearAllMocks();
78
});
89

10+
it('should render with default props', () => {
11+
const { toJSON } = render(<Snackbar />);
12+
expect(toJSON()).toMatchSnapshot();
13+
});
14+
915
it('should called the snack bar show method with config', () => {
1016
snackbar.show({} as any);
1117
expect(DeviceEventEmitter.emit).toHaveBeenCalled();

src/packages/react-native-material-elements/__test__/Switch.test.tsx

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
import React from 'react';
2+
import { View } from 'react-native';
23
import {
4+
getSwitchSizes,
35
Switch,
6+
SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_LARGE,
7+
SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_MEDIUM,
8+
SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_SMALL,
9+
SWITCH_CONTAINER_ANDROID_MODE_WIDTH_LARGE,
10+
SWITCH_CONTAINER_ANDROID_MODE_WIDTH_MEDIUM,
11+
SWITCH_CONTAINER_ANDROID_MODE_WIDTH_SMALL,
412
SWITCH_CONTAINER_HEIGHT_LARGE,
513
SWITCH_CONTAINER_HEIGHT_MEDIUM,
614
SWITCH_CONTAINER_HEIGHT_SMALL,
715
SWITCH_CONTAINER_WIDTH_LARGE,
816
SWITCH_CONTAINER_WIDTH_MEDIUM,
917
SWITCH_CONTAINER_WIDTH_SMALL,
18+
SWITCH_THUMB_HEIGHT_LARGE,
19+
SWITCH_THUMB_HEIGHT_MEDIUM,
20+
SWITCH_THUMB_HEIGHT_SMALL,
21+
SWITCH_THUMB_WIDTH_LARGE,
22+
SWITCH_THUMB_WIDTH_MEDIUM,
23+
SWITCH_THUMB_WIDTH_SMALL,
1024
} from '../src';
1125
import { fireEvent, render, waitFor } from './test-utils';
12-
import { View } from 'react-native';
1326

1427
describe('Switch Component', () => {
1528
const switchMockTestId = 'switch-test-id';
@@ -73,3 +86,56 @@ describe('Switch Component', () => {
7386
expect(switchComponent.props.style.height).toBe(SWITCH_CONTAINER_HEIGHT_SMALL);
7487
});
7588
});
89+
90+
describe('getSwitchSizes', () => {
91+
const sizes = ['small', 'medium', 'large'] as const;
92+
const types = ['ios', 'android'] as const;
93+
94+
sizes.forEach(size => {
95+
types.forEach(type => {
96+
it(`returns correct styles for size=${size} and type=${type}`, () => {
97+
const { thumbStyles, thumbContainerStyles } = getSwitchSizes({ size, type });
98+
99+
// check thumb styles
100+
if (size === 'small') {
101+
expect(thumbStyles.width).toBe(SWITCH_THUMB_WIDTH_SMALL);
102+
expect(thumbStyles.height).toBe(SWITCH_THUMB_HEIGHT_SMALL);
103+
}
104+
if (size === 'medium') {
105+
expect(thumbStyles.width).toBe(SWITCH_THUMB_WIDTH_MEDIUM);
106+
expect(thumbStyles.height).toBe(SWITCH_THUMB_HEIGHT_MEDIUM);
107+
}
108+
if (size === 'large') {
109+
expect(thumbStyles.width).toBe(SWITCH_THUMB_WIDTH_LARGE);
110+
expect(thumbStyles.height).toBe(SWITCH_THUMB_HEIGHT_LARGE);
111+
}
112+
113+
// check container styles
114+
if (size === 'small') {
115+
expect(thumbContainerStyles.width).toBe(
116+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_WIDTH_SMALL : SWITCH_CONTAINER_WIDTH_SMALL,
117+
);
118+
expect(thumbContainerStyles.height).toBe(
119+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_SMALL : SWITCH_CONTAINER_HEIGHT_SMALL,
120+
);
121+
}
122+
if (size === 'medium') {
123+
expect(thumbContainerStyles.width).toBe(
124+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_WIDTH_MEDIUM : SWITCH_CONTAINER_WIDTH_MEDIUM,
125+
);
126+
expect(thumbContainerStyles.height).toBe(
127+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_MEDIUM : SWITCH_CONTAINER_HEIGHT_MEDIUM,
128+
);
129+
}
130+
if (size === 'large') {
131+
expect(thumbContainerStyles.width).toBe(
132+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_WIDTH_LARGE : SWITCH_CONTAINER_WIDTH_LARGE,
133+
);
134+
expect(thumbContainerStyles.height).toBe(
135+
type === 'android' ? SWITCH_CONTAINER_ANDROID_MODE_HEIGHT_LARGE : SWITCH_CONTAINER_HEIGHT_LARGE,
136+
);
137+
}
138+
});
139+
});
140+
});
141+
});

0 commit comments

Comments
 (0)