mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-10 18:03:01 +00:00
feat(utils): move checkPropTypes to utils module
This commit is contained in:
parent
cd67a8cea3
commit
0e65f02116
@ -4,7 +4,7 @@
|
||||
import classnames from 'classnames';
|
||||
import { create as createDataSourceEngine } from '@alilc/lowcode-datasource-engine/interpret';
|
||||
import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicTypeJSONValue, IPublicTypeCompositeValue } from '@alilc/lowcode-types';
|
||||
import { isI18nData, isJSExpression, isJSFunction } from '@alilc/lowcode-utils';
|
||||
import { checkPropTypes, isI18nData, isJSExpression, isJSFunction } from '@alilc/lowcode-utils';
|
||||
import adapter from '../adapter';
|
||||
import divFactory from '../components/Div';
|
||||
import visualDomFactory from '../components/VisualDom';
|
||||
@ -21,7 +21,6 @@ import {
|
||||
isFileSchema,
|
||||
transformArrayToMap,
|
||||
transformStringToFunction,
|
||||
checkPropTypes,
|
||||
getI18n,
|
||||
getFileCssName,
|
||||
capitalizeFirstLetter,
|
||||
|
||||
@ -6,16 +6,11 @@ import { isI18nData, isJSExpression } from '@alilc/lowcode-utils';
|
||||
import { isEmpty } from 'lodash';
|
||||
import IntlMessageFormat from 'intl-messageformat';
|
||||
import pkg from '../../package.json';
|
||||
import * as ReactIs from 'react-is';
|
||||
import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret';
|
||||
import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers';
|
||||
|
||||
(window as any).sdkVersion = pkg.version;
|
||||
|
||||
export { pick, isEqualWith as deepEqual, cloneDeep as clone, isEmpty, throttle, debounce } from 'lodash';
|
||||
|
||||
const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true);
|
||||
|
||||
const EXPRESSION_TYPE = {
|
||||
JSEXPRESSION: 'JSExpression',
|
||||
JSFUNCTION: 'JSFunction',
|
||||
@ -183,77 +178,6 @@ export function transformArrayToMap(arr: any[], key: string, overwrite = true) {
|
||||
return res;
|
||||
}
|
||||
|
||||
export function isBasicType(propType: IPublicTypePropType): propType is IPublicTypeBasicType {
|
||||
if (!propType) {
|
||||
return false;
|
||||
}
|
||||
return typeof propType === 'string';
|
||||
}
|
||||
|
||||
export function isRequiredType(propType: IPublicTypePropType): propType is IPublicTypeRequiredType {
|
||||
if (!propType) {
|
||||
return false;
|
||||
}
|
||||
return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type);
|
||||
}
|
||||
|
||||
export function transformPropTypesRuleToString(rule: IPublicTypePropType): string {
|
||||
if (!rule) {
|
||||
return 'PropTypes.any';
|
||||
}
|
||||
|
||||
if (typeof rule === 'string') {
|
||||
return `PropTypes.${rule}`;
|
||||
}
|
||||
|
||||
if (isRequiredType(rule)) {
|
||||
const { type, isRequired } = rule;
|
||||
return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`;
|
||||
}
|
||||
|
||||
const { type, value } = rule;
|
||||
switch (type) {
|
||||
case 'oneOf':
|
||||
return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`;
|
||||
case 'oneOfType':
|
||||
return `PropTypes.oneOfType([${value.map((item: any) => transformPropTypesRuleToString(item)).join(', ')}])`;
|
||||
case 'arrayOf':
|
||||
case 'objectOf':
|
||||
return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`;
|
||||
case 'shape':
|
||||
case 'exact':
|
||||
return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`;
|
||||
}
|
||||
}
|
||||
|
||||
export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean {
|
||||
let ruleFunction = rule;
|
||||
if (typeof rule === 'object') {
|
||||
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2);
|
||||
}
|
||||
if (typeof rule === 'string') {
|
||||
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2);
|
||||
}
|
||||
if (!ruleFunction || typeof ruleFunction !== 'function') {
|
||||
logger.warn('checkPropTypes should have a function type rule argument');
|
||||
return true;
|
||||
}
|
||||
const err = ruleFunction(
|
||||
{
|
||||
[name]: value,
|
||||
},
|
||||
name,
|
||||
componentName,
|
||||
'prop',
|
||||
null,
|
||||
ReactPropTypesSecret,
|
||||
);
|
||||
if (err) {
|
||||
logger.warn(err);
|
||||
}
|
||||
return !err;
|
||||
}
|
||||
|
||||
/**
|
||||
* transform string to a function
|
||||
* @param str function in string form
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import factoryWithTypeCheckers from 'prop-types/factoryWithTypeCheckers';
|
||||
import {
|
||||
isSchema,
|
||||
isFileSchema,
|
||||
@ -18,17 +17,9 @@ import {
|
||||
parseThisRequiredExpression,
|
||||
parseI18n,
|
||||
parseData,
|
||||
checkPropTypes,
|
||||
transformPropTypesRuleToString,
|
||||
isRequiredType,
|
||||
isBasicType,
|
||||
} from '../../src/utils/common';
|
||||
import logger from '../../src/utils/logger';
|
||||
|
||||
var ReactIs = require('react-is');
|
||||
|
||||
const PropTypes = factoryWithTypeCheckers(ReactIs.isElement, true);
|
||||
|
||||
describe('test isSchema', () => {
|
||||
it('should be false when empty value is passed', () => {
|
||||
expect(isSchema(null)).toBeFalsy();
|
||||
@ -470,213 +461,3 @@ describe('test parseData ', () => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('test isBasicType ', () => {
|
||||
it('should work', () => {
|
||||
expect(isBasicType(null)).toBeFalsy();
|
||||
expect(isBasicType(undefined)).toBeFalsy();
|
||||
expect(isBasicType({})).toBeFalsy();
|
||||
expect(isBasicType({ type: 'any other type' })).toBeFalsy();
|
||||
expect(isBasicType('string')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('test isRequiredType', () => {
|
||||
it('should work', () => {
|
||||
expect(isRequiredType(null)).toBeFalsy();
|
||||
expect(isRequiredType(undefined)).toBeFalsy();
|
||||
expect(isRequiredType({})).toBeFalsy();
|
||||
expect(isRequiredType({ type: 'any other type' })).toBeFalsy();
|
||||
expect(isRequiredType('string')).toBeFalsy();
|
||||
expect(isRequiredType({ type: 'string' })).toBeTruthy();
|
||||
expect(isRequiredType({ type: 'string', isRequired: true })).toBeTruthy();
|
||||
});
|
||||
})
|
||||
|
||||
describe('checkPropTypes', () => {
|
||||
it('should validate correctly with valid prop type', () => {
|
||||
expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true);
|
||||
});
|
||||
|
||||
it('should log a warning and return false with invalid prop type', () => {
|
||||
expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false);
|
||||
expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle custom rule functions correctly', () => {
|
||||
const customRule = (props, propName) => {
|
||||
if (props[propName] !== 123) {
|
||||
return new Error('Invalid value');
|
||||
}
|
||||
};
|
||||
const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should interpret and validate a rule given as a string', () => {
|
||||
const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should log a warning for invalid rule type', () => {
|
||||
const result = checkPropTypes(123, 'age', 123, 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
// oneOf
|
||||
it('should validate correctly with valid oneOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'oneOf',
|
||||
value: ['News', 'Photos'],
|
||||
}
|
||||
expect(transformPropTypesRuleToString(rule)).toBe(`PropTypes.oneOf(["News","Photos"])`);
|
||||
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// oneOfType
|
||||
it('should validate correctly with valid oneOfType prop type', () => {
|
||||
const rule = {
|
||||
type: 'oneOfType',
|
||||
value: ['string', 'number', {
|
||||
type: 'array',
|
||||
isRequired: true,
|
||||
}],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array.isRequired])');
|
||||
expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes(123, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// arrayOf
|
||||
it('should validate correctly with valid arrayOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'arrayOf',
|
||||
value: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.arrayOf(PropTypes.string.isRequired)');
|
||||
expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes(['News', 123], 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// objectOf
|
||||
it('should validate correctly with valid objectOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'objectOf',
|
||||
value: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.objectOf(PropTypes.string.isRequired)');
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// shape
|
||||
it('should validate correctly with valid shape prop type', () => {
|
||||
const rule = {
|
||||
type: 'shape',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
|
||||
// isRequired
|
||||
const rule2 = {
|
||||
type: 'shape',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// exact
|
||||
it('should validate correctly with valid exact prop type', () => {
|
||||
const rule = {
|
||||
type: 'exact',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
|
||||
// isRequired
|
||||
const rule2 = {
|
||||
type: 'exact',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false);
|
||||
});
|
||||
});
|
||||
@ -17,6 +17,7 @@
|
||||
"@alilc/lowcode-types": "1.3.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mobx": "^6.3.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^16"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
68
packages/utils/src/check-prop-types.ts
Normal file
68
packages/utils/src/check-prop-types.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import * as ReactIs from 'react-is';
|
||||
import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret';
|
||||
import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers';
|
||||
import { IPublicTypePropType } from '@alilc/lowcode-types';
|
||||
import { isRequiredPropType } from './check-types/is-required-prop-type';
|
||||
import { Logger } from './logger';
|
||||
|
||||
const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true);
|
||||
const logger = new Logger({ level: 'warn', bizName: 'utils' });
|
||||
|
||||
export function transformPropTypesRuleToString(rule: IPublicTypePropType): string {
|
||||
if (!rule) {
|
||||
return 'PropTypes.any';
|
||||
}
|
||||
|
||||
if (typeof rule === 'string') {
|
||||
return `PropTypes.${rule}`;
|
||||
}
|
||||
|
||||
if (isRequiredPropType(rule)) {
|
||||
const { type, isRequired } = rule;
|
||||
return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`;
|
||||
}
|
||||
|
||||
const { type, value } = rule;
|
||||
switch (type) {
|
||||
case 'oneOf':
|
||||
return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`;
|
||||
case 'oneOfType':
|
||||
return `PropTypes.oneOfType([${value.map((item: any) => transformPropTypesRuleToString(item)).join(', ')}])`;
|
||||
case 'arrayOf':
|
||||
case 'objectOf':
|
||||
return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`;
|
||||
case 'shape':
|
||||
case 'exact':
|
||||
return `PropTypes.${type}({${value.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`).join(',')}})`;
|
||||
}
|
||||
}
|
||||
|
||||
export function checkPropTypes(value: any, name: string, rule: any, componentName: string): boolean {
|
||||
let ruleFunction = rule;
|
||||
if (typeof rule === 'object') {
|
||||
// eslint-disable-next-line no-new-func
|
||||
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(rule)}`)(PropTypes2);
|
||||
}
|
||||
if (typeof rule === 'string') {
|
||||
// eslint-disable-next-line no-new-func
|
||||
ruleFunction = new Function(`"use strict"; const PropTypes = arguments[0]; return ${rule}`)(PropTypes2);
|
||||
}
|
||||
if (!ruleFunction || typeof ruleFunction !== 'function') {
|
||||
logger.warn('checkPropTypes should have a function type rule argument');
|
||||
return true;
|
||||
}
|
||||
const err = ruleFunction(
|
||||
{
|
||||
[name]: value,
|
||||
},
|
||||
name,
|
||||
componentName,
|
||||
'prop',
|
||||
null,
|
||||
ReactPropTypesSecret,
|
||||
);
|
||||
if (err) {
|
||||
logger.warn(err);
|
||||
}
|
||||
return !err;
|
||||
}
|
||||
@ -23,4 +23,6 @@ export * from './is-location-data';
|
||||
export * from './is-setting-field';
|
||||
export * from './is-lowcode-component-type';
|
||||
export * from './is-lowcode-project-schema';
|
||||
export * from './is-component-schema';
|
||||
export * from './is-component-schema';
|
||||
export * from './is-basic-prop-type';
|
||||
export * from './is-required-prop-type';
|
||||
8
packages/utils/src/check-types/is-basic-prop-type.ts
Normal file
8
packages/utils/src/check-types/is-basic-prop-type.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { IPublicTypeBasicType, IPublicTypePropType } from '@alilc/lowcode-types';
|
||||
|
||||
export function isBasicPropType(propType: IPublicTypePropType): propType is IPublicTypeBasicType {
|
||||
if (!propType) {
|
||||
return false;
|
||||
}
|
||||
return typeof propType === 'string';
|
||||
}
|
||||
8
packages/utils/src/check-types/is-required-prop-type.ts
Normal file
8
packages/utils/src/check-types/is-required-prop-type.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { IPublicTypePropType, IPublicTypeRequiredType } from '@alilc/lowcode-types';
|
||||
|
||||
export function isRequiredPropType(propType: IPublicTypePropType): propType is IPublicTypeRequiredType {
|
||||
if (!propType) {
|
||||
return false;
|
||||
}
|
||||
return typeof propType === 'object' && propType.type && ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'any'].includes(propType.type);
|
||||
}
|
||||
@ -5,7 +5,7 @@ import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import './context-menu.scss';
|
||||
|
||||
const logger = new Logger({ level: 'warn', bizName: 'designer' });
|
||||
const logger = new Logger({ level: 'warn', bizName: 'utils' });
|
||||
const { Item, Divider, PopupItem } = Menu;
|
||||
|
||||
const MAX_LEVEL = 2;
|
||||
|
||||
@ -32,3 +32,4 @@ export { transactionManager } from './transaction-manager';
|
||||
export * from './check-types';
|
||||
export * from './workspace';
|
||||
export * from './context-menu';
|
||||
export { checkPropTypes } from './check-prop-types';
|
||||
190
packages/utils/test/src/check-prop-types.test.ts
Normal file
190
packages/utils/test/src/check-prop-types.test.ts
Normal file
@ -0,0 +1,190 @@
|
||||
import { checkPropTypes, transformPropTypesRuleToString } from '../../src/check-prop-types';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
describe('checkPropTypes', () => {
|
||||
it('should validate correctly with valid prop type', () => {
|
||||
expect(checkPropTypes(123, 'age', PropTypes.number, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('123', 'age', PropTypes.string, 'TestComponent')).toBe(true);
|
||||
});
|
||||
|
||||
it('should log a warning and return false with invalid prop type', () => {
|
||||
expect(checkPropTypes(123, 'age', PropTypes.string, 'TestComponent')).toBe(false);
|
||||
expect(checkPropTypes('123', 'age', PropTypes.number, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle custom rule functions correctly', () => {
|
||||
const customRule = (props, propName) => {
|
||||
if (props[propName] !== 123) {
|
||||
return new Error('Invalid value');
|
||||
}
|
||||
};
|
||||
const result = checkPropTypes(123, 'customProp', customRule, 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should interpret and validate a rule given as a string', () => {
|
||||
const result = checkPropTypes(123, 'age', 'PropTypes.number', 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should log a warning for invalid rule type', () => {
|
||||
const result = checkPropTypes(123, 'age', 123, 'TestComponent');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
// oneOf
|
||||
it('should validate correctly with valid oneOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'oneOf',
|
||||
value: ['News', 'Photos'],
|
||||
}
|
||||
expect(transformPropTypesRuleToString(rule)).toBe(`PropTypes.oneOf(["News","Photos"])`);
|
||||
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('Others', 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// oneOfType
|
||||
it('should validate correctly with valid oneOfType prop type', () => {
|
||||
const rule = {
|
||||
type: 'oneOfType',
|
||||
value: ['string', 'number', {
|
||||
type: 'array',
|
||||
isRequired: true,
|
||||
}],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array.isRequired])');
|
||||
expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes('News', 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes(123, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({}, 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// arrayOf
|
||||
it('should validate correctly with valid arrayOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'arrayOf',
|
||||
value: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.arrayOf(PropTypes.string.isRequired)');
|
||||
expect(checkPropTypes(['News', 'Photos'], 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes(['News', 123], 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// objectOf
|
||||
it('should validate correctly with valid objectOf prop type', () => {
|
||||
const rule = {
|
||||
type: 'objectOf',
|
||||
value: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.objectOf(PropTypes.string.isRequired)');
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// shape
|
||||
it('should validate correctly with valid shape prop type', () => {
|
||||
const rule = {
|
||||
type: 'shape',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
|
||||
// isRequired
|
||||
const rule2 = {
|
||||
type: 'shape',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.shape({a: PropTypes.string.isRequired,b: PropTypes.number})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false);
|
||||
});
|
||||
|
||||
// exact
|
||||
it('should validate correctly with valid exact prop type', () => {
|
||||
const rule = {
|
||||
type: 'exact',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number.isRequired})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ a: 'News', b: 'Photos' }, 'type', rule, 'TestComponent')).toBe(false);
|
||||
|
||||
// isRequired
|
||||
const rule2 = {
|
||||
type: 'exact',
|
||||
value: [
|
||||
{
|
||||
name: 'a',
|
||||
propType: {
|
||||
type: 'string',
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
propType: {
|
||||
type: 'number',
|
||||
isRequired: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(transformPropTypesRuleToString(rule2)).toBe('PropTypes.exact({a: PropTypes.string.isRequired,b: PropTypes.number})');
|
||||
expect(checkPropTypes({ a: 'News', b: 123 }, 'type', rule2, 'TestComponent')).toBe(true);
|
||||
expect(checkPropTypes({ b: 123 }, 'type', rule2, 'TestComponent')).toBe(false);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,11 @@
|
||||
import { isBasicPropType } from '../../../src';
|
||||
|
||||
describe('test isBasicPropType ', () => {
|
||||
it('should work', () => {
|
||||
expect(isBasicPropType(null)).toBeFalsy();
|
||||
expect(isBasicPropType(undefined)).toBeFalsy();
|
||||
expect(isBasicPropType({})).toBeFalsy();
|
||||
expect(isBasicPropType({ type: 'any other type' })).toBeFalsy();
|
||||
expect(isBasicPropType('string')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
import { isRequiredPropType } from '../../../src';
|
||||
|
||||
describe('test isRequiredType', () => {
|
||||
it('should work', () => {
|
||||
expect(isRequiredPropType(null)).toBeFalsy();
|
||||
expect(isRequiredPropType(undefined)).toBeFalsy();
|
||||
expect(isRequiredPropType({})).toBeFalsy();
|
||||
expect(isRequiredPropType({ type: 'any other type' })).toBeFalsy();
|
||||
expect(isRequiredPropType('string')).toBeFalsy();
|
||||
expect(isRequiredPropType({ type: 'string' })).toBeTruthy();
|
||||
expect(isRequiredPropType({ type: 'string', isRequired: true })).toBeTruthy();
|
||||
});
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user