2024-01-25 10:10:55 +08:00

178 lines
6.7 KiB
TypeScript

import '../../fixtures/window';
import PropTypes from 'prop-types';
import { LowcodeTypes, parseMetadata, parseProps } from '../../../src/builtin-simulator/utils/parse-metadata';
import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret';
describe('parseMetadata', () => {
it('parseMetadata', async () => {
const md1 = parseMetadata('Div');
const md2 = parseMetadata({ componentName: 'Div' });
});
it('LowcodeTypes.shape', async () => {
const result = (window as any).PropTypes.shape()
expect(result).toBeDefined();
});
});
describe('LowcodeTypes basic type validators', () => {
it('should validate string types', () => {
const stringValidator = LowcodeTypes.string;
// 对 stringValidator 进行测试
const props = { testProp: 'This is a string' };
const propName = 'testProp';
const componentName = 'TestComponent';
const result = stringValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeNull(); // No error for valid string
});
it('should fail with a non-string type', () => {
const stringValidator = LowcodeTypes.string;
const props = { testProp: 42 };
const propName = 'testProp';
const componentName = 'TestComponent';
const result = stringValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeInstanceOf(Error); // Error for non-string type
expect(result.message).toContain('Invalid prop `testProp` of type `number` supplied to `TestComponent`, expected `string`.');
});
it('should pass with a valid number', () => {
const numberValidator = LowcodeTypes.number;
const props = { testProp: 42 };
const propName = 'testProp';
const componentName = 'TestComponent';
const result = numberValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeNull(); // No error for valid number
});
it('should fail with a non-number type', () => {
const numberValidator = LowcodeTypes.number;
const props = { testProp: 'Not a number' };
const propName = 'testProp';
const componentName = 'TestComponent';
const result = numberValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeInstanceOf(Error); // Error for non-number type
expect(result.message).toContain('Invalid prop `testProp` of type `string` supplied to `TestComponent`, expected `number`.');
});
});
describe('Custom type constructors', () => {
it('should create a custom type validator using define', () => {
const customType = LowcodeTypes.define(PropTypes.string, 'customType');
const props = { testProp: 'This is a string' };
const propName = 'testProp';
const componentName = 'TestComponent';
// 测试有效值
const validResult = customType(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(validResult).toBeNull(); // No error for valid string
// 测试无效值
const invalidProps = { testProp: 42 };
const invalidResult = customType(invalidProps, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(invalidResult).toBeInstanceOf(Error); // Error for non-string type
// 验证 lowcodeType 属性
expect(customType.lowcodeType).toEqual('customType');
// 验证 isRequired 属性
const requiredResult = customType.isRequired(invalidProps, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(requiredResult).toBeInstanceOf(Error); // Error for non-string type
});
});
describe('Advanced type constructors', () => {
describe('oneOf Type Validator', () => {
const oneOfValidator = LowcodeTypes.oneOf(['red', 'green', 'blue']);
const propName = 'color';
const componentName = 'ColorPicker';
it('should pass with a valid value', () => {
const props = { color: 'red' };
const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeNull(); // No error for valid value
});
it('should fail with an invalid value', () => {
const props = { color: 'yellow' };
const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeInstanceOf(Error); // Error for invalid value
expect(result.message).toContain(`Invalid prop \`${propName}\` of value \`yellow\` supplied to \`${componentName}\`, expected one of ["red","green","blue"].`);
});
it('should fail with a non-existing value', () => {
const props = { color: 'others' };
const result = oneOfValidator(props, propName, componentName, 'prop', null, ReactPropTypesSecret);
expect(result).toBeInstanceOf(Error); // Error for non-existing value
expect(result.message).toContain(`Invalid prop \`${propName}\` of value \`others\` supplied to \`${componentName}\`, expected one of ["red","green","blue"].`);
});
});
});
describe('parseProps function', () => {
it('should correctly parse propTypes and defaultProps', () => {
const component = {
propTypes: {
name: LowcodeTypes.string,
age: LowcodeTypes.number,
},
defaultProps: {
name: 'John Doe',
age: 30,
},
};
const parsedProps = parseProps(component);
// 测试结果长度
expect(parsedProps.length).toBe(2);
// 测试 name 属性
const nameProp: any = parsedProps.find(prop => prop.name === 'name');
expect(nameProp).toBeDefined();
expect(nameProp.propType).toEqual('string');
expect(nameProp.defaultValue).toEqual('John Doe');
// 测试 age 属性
const ageProp: any = parsedProps.find(prop => prop.name === 'age');
expect(ageProp).toBeDefined();
expect(ageProp.propType).toEqual('number');
expect(ageProp.defaultValue).toEqual(30);
});
});
describe('parseProps function', () => {
it('should correctly parse propTypes and defaultProps', () => {
const component = {
propTypes: {
name: LowcodeTypes.string,
age: LowcodeTypes.number,
},
defaultProps: {
name: 'John Doe',
age: 30,
},
};
const parsedProps = parseProps(component);
// 测试结果长度
expect(parsedProps.length).toBe(2);
// 测试 name 属性
const nameProp: any = parsedProps.find(prop => prop.name === 'name');
expect(nameProp).toBeDefined();
expect(nameProp.propType).toEqual('string');
expect(nameProp.defaultValue).toEqual('John Doe');
// 测试 age 属性
const ageProp: any = parsedProps.find(prop => prop.name === 'age');
expect(ageProp).toBeDefined();
expect(ageProp.propType).toEqual('number');
expect(ageProp.defaultValue).toEqual(30);
});
});