Skip to content

Commit 947c621

Browse files
liujupingJackLian
authored andcommitted
test(utils): add more test case for checkPropTypes
1 parent dca3448 commit 947c621

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

packages/utils/src/check-prop-types.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import { Logger } from './logger';
88
const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true);
99
const logger = new Logger({ level: 'warn', bizName: 'utils' });
1010

11-
export function transformPropTypesRuleToString(rule: IPublicTypePropType): string {
11+
export function transformPropTypesRuleToString(rule: IPublicTypePropType | string): string {
1212
if (!rule) {
1313
return 'PropTypes.any';
1414
}
1515

1616
if (typeof rule === 'string') {
17-
return `PropTypes.${rule}`;
17+
return rule.startsWith('PropTypes.') ? rule : `PropTypes.${rule}`;
1818
}
1919

2020
if (isRequiredPropType(rule)) {
@@ -34,7 +34,11 @@ export function transformPropTypesRuleToString(rule: IPublicTypePropType): strin
3434
case 'shape':
3535
case 'exact':
3636
return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`;
37+
default:
38+
logger.error(`Unknown prop type: ${type}`);
3739
}
40+
41+
return 'PropTypes.any';
3842
}
3943

4044
export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean {
@@ -45,7 +49,7 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam
4549
}
4650
if (typeof rule === 'string') {
4751
// eslint-disable-next-line no-new-func
48-
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2);
52+
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2);
4953
}
5054
if (!ruleFunction || typeof ruleFunction !== 'function') {
5155
logger.warn('checkPropTypes should have a function type rule argument');

packages/utils/test/src/check-prop-types.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@ describe('checkPropTypes', () => {
1212
expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false);
1313
});
1414

15+
it('should validate correctly with valid object prop type', () => {
16+
expect(checkPropTypes({ a: 123 }, 'age', PropTypes.object, 'TestComponent')).toBe(true);
17+
expect(checkPropTypes({ a: '123' }, 'age', PropTypes.object, 'TestComponent')).toBe(true);
18+
});
19+
20+
it('should validate correctly with valid object string prop type', () => {
21+
expect(checkPropTypes({ a: 123 }, 'age', 'object', 'TestComponent')).toBe(true);
22+
expect(checkPropTypes({ a: '123' }, 'age', 'object', 'TestComponent')).toBe(true);
23+
});
24+
25+
it('should validate correctly with valid isRequired prop type', () => {
26+
const rule = {
27+
type: 'string',
28+
isRequired: true,
29+
};
30+
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.string.isRequired');
31+
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
32+
expect(checkPropTypes(undefined, 'type', rule, 'TestComponent')).toBe(false);
33+
});
34+
1535
it('should handle custom rule functions correctly', () => {
1636
const customRule = (props, propName) => {
1737
if (props[propName] !== 123) {
@@ -28,6 +48,11 @@ describe('checkPropTypes', () => {
2848
expect(result).toBe(true);
2949
});
3050

51+
it('should interpret and validate a rule given as a string', () => {
52+
expect(checkPropTypes(123, 'age', 'number', 'TestComponent')).toBe(true);
53+
expect(checkPropTypes('123', 'age', 'string', 'TestComponent')).toBe(true);
54+
});
55+
3156
it('should log a warning for invalid rule type', () => {
3257
const result = checkPropTypes(123, 'age', 123, 'TestComponent');
3358
expect(result).toBe(true);
@@ -60,6 +85,46 @@ describe('checkPropTypes', () => {
6085
expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false);
6186
});
6287

88+
it('should validate correctly with valid oneOfType prop type', () => {
89+
const rule = {
90+
type: 'oneOfType',
91+
value: [
92+
'bool',
93+
{
94+
type: 'shape',
95+
value: [
96+
{
97+
name: 'type',
98+
propType: {
99+
type: 'oneOf',
100+
value: ['JSExpression'],
101+
}
102+
},
103+
{
104+
name: 'value',
105+
propType: 'string',
106+
},
107+
],
108+
},
109+
],
110+
};
111+
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.bool, PropTypes.shape({type: PropTypes.oneOf(["JSExpression"]),value: PropTypes.string})])');
112+
expect(checkPropTypes(true, 'type', rule, 'TestComponent')).toBe(true);
113+
expect(checkPropTypes({ type: 'JSExpression', value: '1 + 1 === 2' }, 'type', rule, 'TestComponent')).toBe(true);
114+
expect(checkPropTypes({ type: 'JSExpression' }, 'type', rule, 'TestComponent')).toBe(true);
115+
expect(checkPropTypes({ type: 'JSExpression', value: 123 }, 'type', rule, 'TestComponent')).toBe(false);
116+
});
117+
118+
it('should log a warning for invalid type', () => {
119+
const rule = {
120+
type: 'inval',
121+
value: ['News', 'Photos'],
122+
}
123+
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.any');
124+
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
125+
expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(true);
126+
});
127+
63128
// arrayOf
64129
it('should validate correctly with valid arrayOf prop type', () => {
65130
const rule = {

0 commit comments

Comments
 (0)