Skip to content

Commit

Permalink
test(utils): add more test case for checkPropTypes
Browse files Browse the repository at this point in the history
  • Loading branch information
liujuping committed Jan 25, 2024
1 parent 0e65f02 commit 726978a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
10 changes: 7 additions & 3 deletions packages/utils/src/check-prop-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import { Logger } from './logger';
const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true);
const logger = new Logger({ level: 'warn', bizName: 'utils' });

export function transformPropTypesRuleToString(rule: IPublicTypePropType): string {
export function transformPropTypesRuleToString(rule: IPublicTypePropType | string): string {
if (!rule) {
return 'PropTypes.any';
}

if (typeof rule === 'string') {
return `PropTypes.${rule}`;
return rule.startsWith('PropTypes.') ? rule : `PropTypes.${rule}`;
}

if (isRequiredPropType(rule)) {
Expand All @@ -34,7 +34,11 @@ export function transformPropTypesRuleToString(rule: IPublicTypePropType): strin
case 'shape':
case 'exact':
return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`;
default:
logger.error(`Unknown prop type: ${type}`);
}

return 'PropTypes.any';
}

export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean {
Expand All @@ -45,7 +49,7 @@ export function checkPropTypes(value: any, name: string, rule: any, componentNam
}
if (typeof rule === 'string') {
// eslint-disable-next-line no-new-func
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2);
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2);
}
if (!ruleFunction || typeof ruleFunction !== 'function') {
logger.warn('checkPropTypes should have a function type rule argument');
Expand Down
65 changes: 65 additions & 0 deletions packages/utils/test/src/check-prop-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ describe('checkPropTypes', () => {
expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false);
});

it('should validate correctly with valid object prop type', () => {
expect(checkPropTypes({ a: 123 }, 'age', PropTypes.object, 'TestComponent')).toBe(true);
expect(checkPropTypes({ a: '123' }, 'age', PropTypes.object, 'TestComponent')).toBe(true);
});

it('should validate correctly with valid object string prop type', () => {
expect(checkPropTypes({ a: 123 }, 'age', 'object', 'TestComponent')).toBe(true);
expect(checkPropTypes({ a: '123' }, 'age', 'object', 'TestComponent')).toBe(true);
});

it('should validate correctly with valid isRequired prop type', () => {
const rule = {
type: 'string',
isRequired: true,
};
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.string.isRequired');
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
expect(checkPropTypes(undefined, 'type', rule, 'TestComponent')).toBe(false);
});

it('should handle custom rule functions correctly', () => {
const customRule = (props, propName) => {
if (props[propName] !== 123) {
Expand All @@ -28,6 +48,11 @@ describe('checkPropTypes', () => {
expect(result).toBe(true);
});

it('should interpret and validate a rule given as a string', () => {
expect(checkPropTypes(123, 'age', 'number', 'TestComponent')).toBe(true);
expect(checkPropTypes('123', 'age', 'string', 'TestComponent')).toBe(true);
});

it('should log a warning for invalid rule type', () => {
const result = checkPropTypes(123, 'age', 123, 'TestComponent');
expect(result).toBe(true);
Expand Down Expand Up @@ -60,6 +85,46 @@ describe('checkPropTypes', () => {
expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false);
});

it('should validate correctly with valid oneOfType prop type', () => {
const rule = {
type: 'oneOfType',
value: [
'bool',
{
type: 'shape',
value: [
{
name: 'type',
propType: {
type: 'oneOf',
value: ['JSExpression'],
}
},
{
name: 'value',
propType: 'string',
},
],
},
],
};
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.bool, PropTypes.shape({type: PropTypes.oneOf(["JSExpression"]),value: PropTypes.string})])');
expect(checkPropTypes(true, 'type', rule, 'TestComponent')).toBe(true);
expect(checkPropTypes({ type: 'JSExpression', value: '1 + 1 === 2' }, 'type', rule, 'TestComponent')).toBe(true);
expect(checkPropTypes({ type: 'JSExpression' }, 'type', rule, 'TestComponent')).toBe(true);
expect(checkPropTypes({ type: 'JSExpression', value: 123 }, 'type', rule, 'TestComponent')).toBe(false);
});

it('should log a warning for invalid type', () => {
const rule = {
type: 'inval',
value: ['News', 'Photos'],
}
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.any');
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(true);
});

// arrayOf
it('should validate correctly with valid arrayOf prop type', () => {
const rule = {
Expand Down

0 comments on commit 726978a

Please sign in to comment.