mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-02-05 20:55:37 +00:00
test(utils): add ut to package/utils
This commit is contained in:
parent
938c71fb46
commit
621245393f
@ -11,6 +11,7 @@ const jestConfig = {
|
|||||||
'!**/node_modules/**',
|
'!**/node_modules/**',
|
||||||
'!**/vendor/**',
|
'!**/vendor/**',
|
||||||
],
|
],
|
||||||
|
setupFilesAfterEnv: ['./jest.setup.js'],
|
||||||
};
|
};
|
||||||
|
|
||||||
// 只对本仓库内的 pkg 做 mapping
|
// 只对本仓库内的 pkg 做 mapping
|
||||||
|
|||||||
1
packages/utils/jest.setup.js
Normal file
1
packages/utils/jest.setup.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import '@testing-library/jest-dom';
|
||||||
@ -9,7 +9,7 @@
|
|||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"module": "es/index.js",
|
"module": "es/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "build-scripts test --config build.test.json",
|
"test": "build-scripts test --config build.test.json --jest-coverage",
|
||||||
"build": "build-scripts build"
|
"build": "build-scripts build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -21,8 +21,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.18",
|
||||||
|
"@testing-library/jest-dom": "^6.1.4",
|
||||||
|
"@testing-library/react": "^11.2.7",
|
||||||
"@types/node": "^13.7.1",
|
"@types/node": "^13.7.1",
|
||||||
"@types/react": "^16"
|
"@types/react": "^16",
|
||||||
|
"react-dom": "^16.14.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
|
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isActionContentObject(obj: any): obj is IPublicTypeActionContentObject {
|
export function isActionContentObject(obj: any): obj is IPublicTypeActionContentObject {
|
||||||
return obj && typeof obj === 'object';
|
return isObject(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,9 @@ import { isValidElement } from 'react';
|
|||||||
import { isReactComponent } from '../is-react';
|
import { isReactComponent } from '../is-react';
|
||||||
import { IPublicTypeCustomView } from '@alilc/lowcode-types';
|
import { IPublicTypeCustomView } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
|
||||||
export function isCustomView(obj: any): obj is IPublicTypeCustomView {
|
export function isCustomView(obj: any): obj is IPublicTypeCustomView {
|
||||||
return obj && (isValidElement(obj) || isReactComponent(obj));
|
if (!obj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isValidElement(obj) || isReactComponent(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicEnumDragObjectType } from '@alilc/lowcode-types';
|
import { IPublicEnumDragObjectType } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isDragAnyObject(obj: any): boolean {
|
export function isDragAnyObject(obj: any): boolean {
|
||||||
return obj && obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types';
|
import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataObject {
|
export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataObject {
|
||||||
return obj && obj.type === IPublicEnumDragObjectType.NodeData;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type === IPublicEnumDragObjectType.NodeData;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicEnumDragObjectType, IPublicModelNode, IPublicTypeDragNodeObject } from '@alilc/lowcode-types';
|
import { IPublicEnumDragObjectType, IPublicModelNode, IPublicTypeDragNodeObject } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isDragNodeObject<Node = IPublicModelNode>(obj: any): obj is IPublicTypeDragNodeObject<Node> {
|
export function isDragNodeObject<Node = IPublicModelNode>(obj: any): obj is IPublicTypeDragNodeObject<Node> {
|
||||||
return obj && obj.type === IPublicEnumDragObjectType.Node;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type === IPublicEnumDragObjectType.Node;
|
||||||
}
|
}
|
||||||
@ -1,7 +1,10 @@
|
|||||||
|
import { isFunction } from '../is-function';
|
||||||
import { isReactClass } from '../is-react';
|
import { isReactClass } from '../is-react';
|
||||||
import { IPublicTypeDynamicSetter } from '@alilc/lowcode-types';
|
import { IPublicTypeDynamicSetter } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
|
||||||
export function isDynamicSetter(obj: any): obj is IPublicTypeDynamicSetter {
|
export function isDynamicSetter(obj: any): obj is IPublicTypeDynamicSetter {
|
||||||
return obj && typeof obj === 'function' && !isReactClass(obj);
|
if (!isFunction(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !isReactClass(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
3
packages/utils/src/check-types/is-function.ts
Normal file
3
packages/utils/src/check-types/is-function.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function isFunction(obj: any): obj is Function {
|
||||||
|
return obj && typeof obj === 'function';
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
|
import { IPublicTypeI18nData } from '@alilc/lowcode-types';
|
||||||
// type checks
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
import { IPublicTypeI18nData } from "@alilc/lowcode-types";
|
|
||||||
|
|
||||||
export function isI18nData(obj: any): obj is IPublicTypeI18nData {
|
export function isI18nData(obj: any): obj is IPublicTypeI18nData {
|
||||||
return obj && obj.type === 'i18n';
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type === 'i18n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,26 @@
|
|||||||
|
import { IPublicTypeJSFunction } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
|
interface InnerJsFunction {
|
||||||
|
type: 'JSExpression';
|
||||||
|
source: string;
|
||||||
|
value: string;
|
||||||
|
extType: 'function';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部版本 的 { type: 'JSExpression', source: '', value: '', extType: 'function' } 能力上等同于 JSFunction
|
* 内部版本 的 { type: 'JSExpression', source: '', value: '', extType: 'function' } 能力上等同于 JSFunction
|
||||||
*/
|
*/
|
||||||
export function isInnerJsFunction(data: any) {
|
export function isInnerJsFunction(data: any): data is InnerJsFunction {
|
||||||
return data && data.type === 'JSExpression' && data.extType === 'function';
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.type === 'JSExpression' && data.extType === 'function';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJSFunction(data: any): boolean {
|
export function isJSFunction(data: any): data is IPublicTypeJSFunction {
|
||||||
return typeof data === 'object' && data && data.type === 'JSFunction' || isInnerJsFunction(data);
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.type === 'JSFunction' || isInnerJsFunction(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
|
import { IPublicTypeJSBlock } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isJSBlock(data: any): boolean {
|
export function isJSBlock(data: any): data is IPublicTypeJSBlock {
|
||||||
return data && data.type === 'JSBlock';
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.type === 'JSBlock';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
|
import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。
|
* 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。
|
||||||
@ -11,5 +12,8 @@ import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function isJSExpression(data: any): data is IPublicTypeJSExpression {
|
export function isJSExpression(data: any): data is IPublicTypeJSExpression {
|
||||||
return data && data.type === 'JSExpression' && data.extType !== 'function';
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.type === 'JSExpression' && data.extType !== 'function';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicTypeJSSlot } from '@alilc/lowcode-types';
|
import { IPublicTypeJSSlot } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isJSSlot(data: any): data is IPublicTypeJSSlot {
|
export function isJSSlot(data: any): data is IPublicTypeJSSlot {
|
||||||
return data && data.type === 'JSSlot';
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.type === 'JSSlot';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types';
|
import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationChildrenDetail {
|
export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationChildrenDetail {
|
||||||
return obj && obj.type === IPublicTypeLocationDetailType.Children;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type === IPublicTypeLocationDetailType.Children;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicTypeLocationData } from '@alilc/lowcode-types';
|
import { IPublicTypeLocationData } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isLocationData(obj: any): obj is IPublicTypeLocationData {
|
export function isLocationData(obj: any): obj is IPublicTypeLocationData {
|
||||||
return obj && obj.target && obj.detail;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 'target' in obj && 'detail' in obj;
|
||||||
}
|
}
|
||||||
@ -1,6 +1,15 @@
|
|||||||
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from "@alilc/lowcode-types";
|
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
|
||||||
import { isComponentSchema } from "./is-component-schema";
|
import { isComponentSchema } from './is-component-schema';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isLowcodeProjectSchema(data: any): data is IPublicTypeProjectSchema<IPublicTypeComponentSchema> {
|
export function isLowcodeProjectSchema(data: any): data is IPublicTypeProjectSchema<IPublicTypeComponentSchema> {
|
||||||
return data && data.componentsTree && data.componentsTree.length && isComponentSchema(data.componentsTree[0]);
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!('componentsTree' in data) || data.componentsTree.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isComponentSchema(data.componentsTree[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicTypeNodeSchema } from '@alilc/lowcode-types';
|
import { IPublicTypeNodeSchema } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isNodeSchema(data: any): data is IPublicTypeNodeSchema {
|
export function isNodeSchema(data: any): data is IPublicTypeNodeSchema {
|
||||||
return data && data.componentName && !data.isNode;
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 'componentName' in data && !data.isNode;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicModelNode } from '@alilc/lowcode-types';
|
import { IPublicModelNode } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isNode<Node = IPublicModelNode>(node: any): node is Node {
|
export function isNode<Node = IPublicModelNode>(node: any): node is Node {
|
||||||
return node && node.isNode;
|
if (!isObject(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return node.isNode;
|
||||||
}
|
}
|
||||||
3
packages/utils/src/check-types/is-object.ts
Normal file
3
packages/utils/src/check-types/is-object.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function isObject(obj: any): boolean {
|
||||||
|
return obj && typeof obj === 'object';
|
||||||
|
}
|
||||||
@ -1,6 +1,10 @@
|
|||||||
import { IPublicTypeComponentMap, IPublicTypeProCodeComponent } from '@alilc/lowcode-types';
|
import { IPublicTypeComponentMap, IPublicTypeProCodeComponent } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isProCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeProCodeComponent {
|
export function isProCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeProCodeComponent {
|
||||||
|
if (!isObject(desc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return 'package' in desc;
|
return 'package' in desc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { IPublicTypeProjectSchema } from "@alilc/lowcode-types";
|
import { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isProjectSchema(data: any): data is IPublicTypeProjectSchema {
|
export function isProjectSchema(data: any): data is IPublicTypeProjectSchema {
|
||||||
return data && data.componentsTree;
|
if (!isObject(data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 'componentsTree' in data;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { IPublicTypeSetterConfig } from '@alilc/lowcode-types';
|
import { IPublicTypeSetterConfig } from '@alilc/lowcode-types';
|
||||||
import { isCustomView } from './is-custom-view';
|
import { isCustomView } from './is-custom-view';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isSetterConfig(obj: any): obj is IPublicTypeSetterConfig {
|
export function isSetterConfig(obj: any): obj is IPublicTypeSetterConfig {
|
||||||
return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj);
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 'componentName' in obj && !isCustomView(obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
import { IPublicModelSettingField } from "@alilc/lowcode-types";
|
import { IPublicModelSettingField } from '@alilc/lowcode-types';
|
||||||
|
import { isObject } from '../is-object';
|
||||||
|
|
||||||
export function isSettingField(obj: any): obj is IPublicModelSettingField {
|
export function isSettingField(obj: any): obj is IPublicModelSettingField {
|
||||||
return obj && obj.isSettingField;
|
if (!isObject(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'isSettingField' in obj && obj.isSettingField;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,8 @@ const excludePropertyNames = [
|
|||||||
'arguments',
|
'arguments',
|
||||||
];
|
];
|
||||||
|
|
||||||
export function cloneEnumerableProperty(target: any, origin: any) {
|
export function cloneEnumerableProperty(target: any, origin: any, excludes = excludePropertyNames) {
|
||||||
const compExtraPropertyNames = Object.keys(origin).filter(d => !excludePropertyNames.includes(d));
|
const compExtraPropertyNames = Object.keys(origin).filter(d => !excludes.includes(d));
|
||||||
|
|
||||||
compExtraPropertyNames.forEach((d: string) => {
|
compExtraPropertyNames.forEach((d: string) => {
|
||||||
(target as any)[d] = origin[d];
|
(target as any)[d] = origin[d];
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export function isObject(value: any): value is Record<string, unknown> {
|
export function isObject(value: any): value is Record<string, any> {
|
||||||
return value !== null && typeof value === 'object';
|
return value !== null && typeof value === 'object';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,27 +2,49 @@ import { ComponentClass, Component, FunctionComponent, ComponentType, createElem
|
|||||||
import { cloneEnumerableProperty } from './clone-enumerable-property';
|
import { cloneEnumerableProperty } from './clone-enumerable-property';
|
||||||
|
|
||||||
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
||||||
const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
|
export const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
|
||||||
const REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
|
export const REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
|
||||||
|
|
||||||
export function isReactClass(obj: any): obj is ComponentClass<any> {
|
export function isReactClass(obj: any): obj is ComponentClass<any> {
|
||||||
return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component);
|
if (!obj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function acceptsRef(obj: any): boolean {
|
export function acceptsRef(obj: any): boolean {
|
||||||
return obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj);
|
if (!obj) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj?.prototype?.isReactComponent || isForwardOrMemoForward(obj)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isForwardRefType(obj: any): boolean {
|
export function isForwardRefType(obj: any): boolean {
|
||||||
return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE;
|
if (!obj || !obj?.$$typeof) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj?.$$typeof === REACT_FORWARD_REF_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMemoType(obj: any): boolean {
|
export function isMemoType(obj: any): boolean {
|
||||||
return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE;
|
if (!obj || !obj?.$$typeof) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.$$typeof === REACT_MEMO_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isForwardOrMemoForward(obj: any): boolean {
|
export function isForwardOrMemoForward(obj: any): boolean {
|
||||||
return obj?.$$typeof && (
|
if (!obj || !obj?.$$typeof) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
// React.forwardRef(..)
|
// React.forwardRef(..)
|
||||||
isForwardRefType(obj) ||
|
isForwardRefType(obj) ||
|
||||||
// React.memo(React.forwardRef(..))
|
// React.memo(React.forwardRef(..))
|
||||||
|
|||||||
@ -88,7 +88,7 @@ const shouldOutput = (
|
|||||||
|
|
||||||
const output = (logLevel: string, bizName: string) => {
|
const output = (logLevel: string, bizName: string) => {
|
||||||
return (...args: any[]) => {
|
return (...args: any[]) => {
|
||||||
return outputFunction[logLevel].apply(console, getLogArgs(args, bizName, logLevel));
|
return outputFunction[logLevel]?.apply(console, getLogArgs(args, bizName, logLevel));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +142,6 @@ const defaultOptions: Options = {
|
|||||||
bizName: '*',
|
bizName: '*',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
bizName: string;
|
bizName: string;
|
||||||
targetBizName: string;
|
targetBizName: string;
|
||||||
@ -192,7 +191,6 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export { Logger };
|
export { Logger };
|
||||||
|
|
||||||
export function getLogger(config: { level: Level; bizName: string }): Logger {
|
export function getLogger(config: { level: Level; bizName: string }): Logger {
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
import { isI18NObject } from './is-object';
|
import { isI18NObject } from './is-object';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { IPublicEnumTransformStage, IPublicModelComponentMeta } from '@alilc/lowcode-types';
|
import { IPublicEnumTransformStage, IPublicModelComponentMeta } from '@alilc/lowcode-types';
|
||||||
|
import { Logger } from './logger';
|
||||||
|
|
||||||
|
const logger = new Logger({ level: 'warn', bizName: 'utils' });
|
||||||
|
|
||||||
interface Variable {
|
interface Variable {
|
||||||
type: 'variable';
|
type: 'variable';
|
||||||
@ -10,7 +13,10 @@ interface Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isVariable(obj: any): obj is Variable {
|
export function isVariable(obj: any): obj is Variable {
|
||||||
return obj && obj.type === 'variable';
|
if (!obj || typeof obj !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return obj.type === 'variable';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isUseI18NSetter(prototype: any, propName: string) {
|
export function isUseI18NSetter(prototype: any, propName: string) {
|
||||||
@ -103,12 +109,15 @@ export function invariant(check: any, message: string, thing?: any) {
|
|||||||
|
|
||||||
export function deprecate(fail: any, message: string, alterative?: string) {
|
export function deprecate(fail: any, message: string, alterative?: string) {
|
||||||
if (fail) {
|
if (fail) {
|
||||||
console.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : ''));
|
logger.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRegExp(obj: any): obj is RegExp {
|
export function isRegExp(obj: any): obj is RegExp {
|
||||||
return obj && obj.test && obj.exec && obj.compile;
|
if (!obj || typeof obj !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 'test' in obj && 'exec' in obj && 'compile' in obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
let nativeSelectionEnabled = true;
|
export let nativeSelectionEnabled = true;
|
||||||
|
|
||||||
const preventSelection = (e: Event) => {
|
const preventSelection = (e: Event) => {
|
||||||
if (nativeSelectionEnabled) {
|
if (nativeSelectionEnabled) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import { createDefer } from './create-defer';
|
import { createDefer } from './create-defer';
|
||||||
|
import { Logger } from './logger';
|
||||||
|
|
||||||
|
const logger = new Logger({ level: 'warn', bizName: 'utils' });
|
||||||
|
|
||||||
export function evaluate(script: string, scriptType?: string) {
|
export function evaluate(script: string, scriptType?: string) {
|
||||||
const scriptEl = document.createElement('script');
|
const scriptEl = document.createElement('script');
|
||||||
@ -53,7 +56,7 @@ export function newFunction(args: string, code: string) {
|
|||||||
// eslint-disable-next-line no-new-func
|
// eslint-disable-next-line no-new-func
|
||||||
return new Function(args, code);
|
return new Function(args, code);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Caught error, Cant init func');
|
logger.warn('Caught error, Cant init func');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
|
|
||||||
const SizePresets: any = {
|
const SizePresets: any = {
|
||||||
xsmall: 8,
|
xsmall: 8,
|
||||||
|
|||||||
10
packages/utils/test/src/__snapshots__/is-react.test.tsx.snap
Normal file
10
packages/utils/test/src/__snapshots__/is-react.test.tsx.snap
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`wrapReactClass should render the FunctionComponent with props 1`] = `
|
||||||
|
<FunctionComponent
|
||||||
|
prop1="value1"
|
||||||
|
prop2="value2"
|
||||||
|
>
|
||||||
|
Child Text
|
||||||
|
</FunctionComponent>
|
||||||
|
`;
|
||||||
@ -1,342 +0,0 @@
|
|||||||
|
|
||||||
import { buildComponents } from "../../../src/build-components";
|
|
||||||
|
|
||||||
function Button() {};
|
|
||||||
|
|
||||||
function WrapButton() {};
|
|
||||||
|
|
||||||
function ButtonGroup() {};
|
|
||||||
|
|
||||||
function WrapButtonGroup() {};
|
|
||||||
|
|
||||||
ButtonGroup.Button = Button;
|
|
||||||
|
|
||||||
Button.displayName = "Button";
|
|
||||||
ButtonGroup.displayName = "ButtonGroup";
|
|
||||||
ButtonGroup.prototype.isReactComponent = true;
|
|
||||||
Button.prototype.isReactComponent = true;
|
|
||||||
|
|
||||||
jest.mock('../../../src/is-react', () => {
|
|
||||||
const original = jest.requireActual('../../../src/is-react');
|
|
||||||
return {
|
|
||||||
...original,
|
|
||||||
wrapReactClass(view) {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('build-component', () => {
|
|
||||||
it('basic button', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': {
|
|
||||||
Button,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'Button',
|
|
||||||
subName: 'Button',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('component is a __esModule', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': {
|
|
||||||
__esModule: true,
|
|
||||||
default: Button,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
it('basic warp button', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': {
|
|
||||||
WrapButton,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
WrapButton: {
|
|
||||||
componentName: 'WrapButton',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'WrapButton',
|
|
||||||
subName: 'WrapButton',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
WrapButton,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('destructuring is false button', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': Button
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Button and ButtonGroup', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': {
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'Button',
|
|
||||||
subName: 'Button',
|
|
||||||
},
|
|
||||||
ButtonGroup: {
|
|
||||||
componentName: 'ButtonGroup',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'ButtonGroup',
|
|
||||||
subName: 'ButtonGroup',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('ButtonGroup and ButtonGroup.Button', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': {
|
|
||||||
ButtonGroup,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'ButtonGroup',
|
|
||||||
subName: 'ButtonGroup.Button',
|
|
||||||
},
|
|
||||||
ButtonGroup: {
|
|
||||||
componentName: 'ButtonGroup',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'ButtonGroup',
|
|
||||||
subName: 'ButtonGroup',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('ButtonGroup.default and ButtonGroup.Button', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': ButtonGroup,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'Button',
|
|
||||||
subName: 'Button',
|
|
||||||
},
|
|
||||||
ButtonGroup: {
|
|
||||||
componentName: 'ButtonGroup',
|
|
||||||
package: '@alilc/button',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'default',
|
|
||||||
subName: 'default',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no npm component', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/button': Button,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Button: null,
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no npm component and global button', () => {
|
|
||||||
window.Button = Button;
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Button: null,
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
});
|
|
||||||
window.Button = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('componentsMap value is component funtion', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Button,
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('componentsMap value is component', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Button: WrapButton,
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button: WrapButton,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('componentsMap value is mix component', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
WrapButton,
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button: {
|
|
||||||
WrapButton,
|
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('componentsMap value is Lowcode Component', () => {
|
|
||||||
expect(
|
|
||||||
buildComponents(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
Button: {
|
|
||||||
componentName: 'Component',
|
|
||||||
schema: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
(component) => {
|
|
||||||
return component as any;
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.toEqual({
|
|
||||||
Button: {
|
|
||||||
componentsMap: [],
|
|
||||||
componentsTree: [
|
|
||||||
{
|
|
||||||
componentName: 'Component',
|
|
||||||
schema: {},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
version: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('build div component', () => {
|
|
||||||
it('build div component', () => {
|
|
||||||
const components = buildComponents(
|
|
||||||
{
|
|
||||||
'@alilc/div': 'div'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
div: {
|
|
||||||
componentName: 'div',
|
|
||||||
package: '@alilc/div'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {},
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(components['div']).not.toBeNull();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@ -0,0 +1,616 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
accessLibrary,
|
||||||
|
generateHtmlComp,
|
||||||
|
getSubComponent,
|
||||||
|
buildComponents,
|
||||||
|
getProjectUtils,
|
||||||
|
} from "../../../src/build-components";
|
||||||
|
|
||||||
|
function Button() {};
|
||||||
|
|
||||||
|
function WrapButton() {};
|
||||||
|
|
||||||
|
function ButtonGroup() {};
|
||||||
|
|
||||||
|
function WrapButtonGroup() {};
|
||||||
|
|
||||||
|
ButtonGroup.Button = Button;
|
||||||
|
|
||||||
|
Button.displayName = "Button";
|
||||||
|
ButtonGroup.displayName = "ButtonGroup";
|
||||||
|
ButtonGroup.prototype.isReactComponent = true;
|
||||||
|
Button.prototype.isReactComponent = true;
|
||||||
|
|
||||||
|
jest.mock('../../../src/is-react', () => {
|
||||||
|
const original = jest.requireActual('../../../src/is-react');
|
||||||
|
return {
|
||||||
|
...original,
|
||||||
|
wrapReactClass(view) {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('accessLibrary', () => {
|
||||||
|
it('should return a library object when given a library object', () => {
|
||||||
|
const libraryObject = { key: 'value' };
|
||||||
|
const result = accessLibrary(libraryObject);
|
||||||
|
expect(result).toEqual(libraryObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate an HTML component when given a string library name', () => {
|
||||||
|
const libraryName = 'div';
|
||||||
|
const result = accessLibrary(libraryName);
|
||||||
|
|
||||||
|
// You can write more specific assertions to validate the generated component
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases to cover other scenarios
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('generateHtmlComp', () => {
|
||||||
|
it('should generate an HTML component for valid HTML tags', () => {
|
||||||
|
const htmlTags = ['a', 'img', 'div', 'span', 'svg'];
|
||||||
|
htmlTags.forEach((tag) => {
|
||||||
|
const result = generateHtmlComp(tag);
|
||||||
|
|
||||||
|
// You can write more specific assertions to validate the generated component
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined for an invalid HTML tag', () => {
|
||||||
|
const invalidTag = 'invalidtag';
|
||||||
|
const result = generateHtmlComp(invalidTag);
|
||||||
|
expect(result).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases to cover other scenarios
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSubComponent', () => {
|
||||||
|
it('should return the root library if paths are empty', () => {
|
||||||
|
const library = { component: 'RootComponent' };
|
||||||
|
const paths = [];
|
||||||
|
const result = getSubComponent(library, paths);
|
||||||
|
expect(result).toEqual(library);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the specified sub-component', () => {
|
||||||
|
const library = {
|
||||||
|
components: {
|
||||||
|
Button: 'ButtonComponent',
|
||||||
|
Text: 'TextComponent',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const paths = ['components', 'Button'];
|
||||||
|
const result = getSubComponent(library, paths);
|
||||||
|
expect(result).toEqual('ButtonComponent');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle missing keys in the path', () => {
|
||||||
|
const library = {
|
||||||
|
components: {
|
||||||
|
Button: 'ButtonComponent',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const paths = ['components', 'Text'];
|
||||||
|
const result = getSubComponent(library, paths);
|
||||||
|
expect(result).toEqual({
|
||||||
|
Button: 'ButtonComponent',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle exceptions and return null', () => {
|
||||||
|
const library = 'ButtonComponent';
|
||||||
|
const paths = ['components', 'Button'];
|
||||||
|
// Simulate an exception by providing a non-object in place of 'ButtonComponent'
|
||||||
|
const result = getSubComponent(library, paths);
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle the "default" key as the first path element', () => {
|
||||||
|
const library = {
|
||||||
|
default: 'DefaultComponent',
|
||||||
|
};
|
||||||
|
const paths = ['default'];
|
||||||
|
const result = getSubComponent(library, paths);
|
||||||
|
expect(result).toEqual('DefaultComponent');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getProjectUtils', () => {
|
||||||
|
it('should return an empty object when given empty metadata and library map', () => {
|
||||||
|
const libraryMap = {};
|
||||||
|
const utilsMetadata = [];
|
||||||
|
const result = getProjectUtils(libraryMap, utilsMetadata);
|
||||||
|
expect(result).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return project utilities based on metadata and library map', () => {
|
||||||
|
const libraryMap = {
|
||||||
|
'package1': 'library1',
|
||||||
|
'package2': 'library2',
|
||||||
|
};
|
||||||
|
|
||||||
|
const utilsMetadata = [
|
||||||
|
{
|
||||||
|
name: 'util1',
|
||||||
|
npm: {
|
||||||
|
package: 'package1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'util2',
|
||||||
|
npm: {
|
||||||
|
package: 'package2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
global['library1'] = { name: 'library1' };
|
||||||
|
global['library2'] = { name: 'library2' };
|
||||||
|
|
||||||
|
const result = getProjectUtils(libraryMap, utilsMetadata);
|
||||||
|
|
||||||
|
// Define the expected output based on the mocked accessLibrary
|
||||||
|
const expectedOutput = {
|
||||||
|
'util1': { name: 'library1' },
|
||||||
|
'util2': { name: 'library2' },
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
|
||||||
|
global['library1'] = null;
|
||||||
|
global['library1'] = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle metadata with destructuring', () => {
|
||||||
|
const libraryMap = {
|
||||||
|
'package1': { destructuring: true, util1: 'library1', util2: 'library2' },
|
||||||
|
};
|
||||||
|
|
||||||
|
const utilsMetadata = [
|
||||||
|
{
|
||||||
|
name: 'util1',
|
||||||
|
npm: {
|
||||||
|
package: 'package1',
|
||||||
|
destructuring: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = getProjectUtils(libraryMap, utilsMetadata);
|
||||||
|
|
||||||
|
// Define the expected output based on the mocked accessLibrary
|
||||||
|
const expectedOutput = {
|
||||||
|
'util1': 'library1',
|
||||||
|
'util2': 'library2',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('buildComponents', () => {
|
||||||
|
it('should create components from component map with React components', () => {
|
||||||
|
const libraryMap = {};
|
||||||
|
const componentsMap = {
|
||||||
|
Button: () => <button>Button</button>,
|
||||||
|
Text: () => <p>Text</p>,
|
||||||
|
};
|
||||||
|
|
||||||
|
const createComponent = (schema) => {
|
||||||
|
// Mock createComponent function
|
||||||
|
return schema.componentsTree.map((component) => component.component);
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = buildComponents(libraryMap, componentsMap, createComponent);
|
||||||
|
|
||||||
|
expect(result.Button).toBeDefined();
|
||||||
|
expect(result.Text).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create components from component map with component schemas', () => {
|
||||||
|
const libraryMap = {};
|
||||||
|
const componentsMap = {
|
||||||
|
Button: {
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Component'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Component'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const createComponent = (schema) => {
|
||||||
|
// Mock createComponent function
|
||||||
|
return schema.componentsTree.map((component) => component.component);
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = buildComponents(libraryMap, componentsMap, createComponent);
|
||||||
|
|
||||||
|
expect(result.Button).toBeDefined();
|
||||||
|
expect(result.Text).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create components from component map with React components and schemas', () => {
|
||||||
|
const libraryMap = {};
|
||||||
|
const componentsMap = {
|
||||||
|
Button: () => <button>Button</button>,
|
||||||
|
Text: {
|
||||||
|
type: 'ComponentSchema',
|
||||||
|
// Add component schema properties here
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const createComponent = (schema) => {
|
||||||
|
// Mock createComponent function
|
||||||
|
return schema.componentsTree.map((component) => component.component);
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = buildComponents(libraryMap, componentsMap, createComponent);
|
||||||
|
|
||||||
|
expect(result.Button).toBeDefined();
|
||||||
|
expect(result.Text).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create components from component map with library mappings', () => {
|
||||||
|
const libraryMap = {
|
||||||
|
'libraryName1': 'library1',
|
||||||
|
'libraryName2': 'library2',
|
||||||
|
};
|
||||||
|
const componentsMap = {
|
||||||
|
Button: {
|
||||||
|
package: 'libraryName1',
|
||||||
|
version: '1.0',
|
||||||
|
exportName: 'ButtonComponent',
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
package: 'libraryName2',
|
||||||
|
version: '2.0',
|
||||||
|
exportName: 'TextComponent',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const createComponent = (schema) => {
|
||||||
|
// Mock createComponent function
|
||||||
|
return schema.componentsTree.map((component) => component.component);
|
||||||
|
};
|
||||||
|
|
||||||
|
global['library1'] = () => <button>ButtonComponent</button>;
|
||||||
|
global['library2'] = () => () => <p>TextComponent</p>;
|
||||||
|
|
||||||
|
const result = buildComponents(libraryMap, componentsMap, createComponent);
|
||||||
|
|
||||||
|
expect(result.Button).toBeDefined();
|
||||||
|
expect(result.Text).toBeDefined();
|
||||||
|
|
||||||
|
global['library1'] = null;
|
||||||
|
global['library2'] = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('build-component', () => {
|
||||||
|
it('basic button', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': {
|
||||||
|
Button,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Button',
|
||||||
|
subName: 'Button',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('component is a __esModule', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': {
|
||||||
|
__esModule: true,
|
||||||
|
default: Button,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
it('basic warp button', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': {
|
||||||
|
WrapButton,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
WrapButton: {
|
||||||
|
componentName: 'WrapButton',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'WrapButton',
|
||||||
|
subName: 'WrapButton',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
WrapButton,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('destructuring is false button', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': Button
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Button and ButtonGroup', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': {
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Button',
|
||||||
|
subName: 'Button',
|
||||||
|
},
|
||||||
|
ButtonGroup: {
|
||||||
|
componentName: 'ButtonGroup',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'ButtonGroup',
|
||||||
|
subName: 'ButtonGroup',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ButtonGroup and ButtonGroup.Button', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': {
|
||||||
|
ButtonGroup,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'ButtonGroup',
|
||||||
|
subName: 'ButtonGroup.Button',
|
||||||
|
},
|
||||||
|
ButtonGroup: {
|
||||||
|
componentName: 'ButtonGroup',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'ButtonGroup',
|
||||||
|
subName: 'ButtonGroup',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ButtonGroup.default and ButtonGroup.Button', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': ButtonGroup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Button',
|
||||||
|
subName: 'Button',
|
||||||
|
},
|
||||||
|
ButtonGroup: {
|
||||||
|
componentName: 'ButtonGroup',
|
||||||
|
package: '@alilc/button',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'default',
|
||||||
|
subName: 'default',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no npm component', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/button': Button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Button: null,
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no npm component and global button', () => {
|
||||||
|
window.Button = Button;
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
Button: null,
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
});
|
||||||
|
window.Button = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('componentsMap value is component funtion', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
Button,
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('componentsMap value is component', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
Button: WrapButton,
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button: WrapButton,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('componentsMap value is mix component', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
WrapButton,
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button: {
|
||||||
|
WrapButton,
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('componentsMap value is Lowcode Component', () => {
|
||||||
|
expect(
|
||||||
|
buildComponents(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
Button: {
|
||||||
|
componentName: 'Component',
|
||||||
|
schema: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(component) => {
|
||||||
|
return component as any;
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.toEqual({
|
||||||
|
Button: {
|
||||||
|
componentsMap: [],
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Component',
|
||||||
|
schema: {},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
version: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('build div component', () => {
|
||||||
|
it('build div component', () => {
|
||||||
|
const components = buildComponents(
|
||||||
|
{
|
||||||
|
'@alilc/div': 'div'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
div: {
|
||||||
|
componentName: 'div',
|
||||||
|
package: '@alilc/div'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(components['div']).not.toBeNull();
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import { isActionContentObject } from '../../../src/check-types/is-action-content-object';
|
||||||
|
|
||||||
|
describe('isActionContentObject', () => {
|
||||||
|
test('should return true for an object', () => {
|
||||||
|
const obj = { prop: 'value' };
|
||||||
|
expect(isActionContentObject(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for a non-object', () => {
|
||||||
|
expect(isActionContentObject('not an object')).toBe(false);
|
||||||
|
expect(isActionContentObject(123)).toBe(false);
|
||||||
|
expect(isActionContentObject(null)).toBe(false);
|
||||||
|
expect(isActionContentObject(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for an empty object', () => {
|
||||||
|
const obj = {};
|
||||||
|
expect(isActionContentObject(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
26
packages/utils/test/src/check-types/is-custom-view.test.tsx
Normal file
26
packages/utils/test/src/check-types/is-custom-view.test.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { isCustomView } from '../../../src/check-types/is-custom-view';
|
||||||
|
import { IPublicTypeCustomView } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isCustomView', () => {
|
||||||
|
test('should return true when obj is a valid React element', () => {
|
||||||
|
const obj: IPublicTypeCustomView = <div>Hello, World!</div>;
|
||||||
|
expect(isCustomView(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return true when obj is a valid React component', () => {
|
||||||
|
const MyComponent: React.FC = () => <div>Hello, World!</div>;
|
||||||
|
const obj: IPublicTypeCustomView = MyComponent;
|
||||||
|
expect(isCustomView(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false when obj is null or undefined', () => {
|
||||||
|
expect(isCustomView(null)).toBe(false);
|
||||||
|
expect(isCustomView(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false when obj is not a valid React element or component', () => {
|
||||||
|
const obj: IPublicTypeCustomView = 'not a valid object';
|
||||||
|
expect(isCustomView(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
13
packages/utils/test/src/check-types/is-dom-text.test.ts
Normal file
13
packages/utils/test/src/check-types/is-dom-text.test.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { isDOMText } from '../../../src/check-types/is-dom-text';
|
||||||
|
|
||||||
|
describe('isDOMText', () => {
|
||||||
|
it('should return true when the input is a string', () => {
|
||||||
|
const result = isDOMText('Hello World');
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when the input is not a string', () => {
|
||||||
|
const result = isDOMText(123);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import { isDragAnyObject } from '../../../src/check-types/is-drag-any-object';
|
||||||
|
import { IPublicEnumDragObjectType } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isDragAnyObject', () => {
|
||||||
|
it('should return false if obj is null', () => {
|
||||||
|
const result = isDragAnyObject(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if obj is number', () => {
|
||||||
|
const result = isDragAnyObject(2);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if obj.type is NodeData', () => {
|
||||||
|
const obj = { type: IPublicEnumDragObjectType.NodeData };
|
||||||
|
const result = isDragAnyObject(obj);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if obj.type is Node', () => {
|
||||||
|
const obj = { type: IPublicEnumDragObjectType.Node };
|
||||||
|
const result = isDragAnyObject(obj);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if obj.type is anything else', () => {
|
||||||
|
const obj = { type: 'SomeOtherType' };
|
||||||
|
const result = isDragAnyObject(obj);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types';
|
||||||
|
import { isDragNodeDataObject } from '../../../src/check-types/is-drag-node-data-object';
|
||||||
|
|
||||||
|
describe('isDragNodeDataObject', () => {
|
||||||
|
test('should return true for valid IPublicTypeDragNodeDataObject', () => {
|
||||||
|
const obj: IPublicTypeDragNodeDataObject = {
|
||||||
|
type: IPublicEnumDragObjectType.NodeData,
|
||||||
|
// 其他属性...
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDragNodeDataObject(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid IPublicTypeDragNodeDataObject', () => {
|
||||||
|
const obj: any = {
|
||||||
|
type: 'InvalidType',
|
||||||
|
// 其他属性...
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDragNodeDataObject(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for null or undefined', () => {
|
||||||
|
expect(isDragNodeDataObject(null)).toBe(false);
|
||||||
|
expect(isDragNodeDataObject(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 可以添加更多测试用例...
|
||||||
|
});
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
import { IPublicEnumDragObjectType } from '@alilc/lowcode-types';
|
||||||
|
import { isDragNodeObject } from '../../../src/check-types/is-drag-node-object';
|
||||||
|
|
||||||
|
describe('isDragNodeObject', () => {
|
||||||
|
it('should return true if the object is of IPublicTypeDragNodeObject type and has type IPublicEnumDragObjectType.Node', () => {
|
||||||
|
const obj = {
|
||||||
|
type: IPublicEnumDragObjectType.Node,
|
||||||
|
//... other properties
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDragNodeObject(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the object is not of IPublicTypeDragNodeObject type', () => {
|
||||||
|
const obj = {
|
||||||
|
type: IPublicEnumDragObjectType.OtherType,
|
||||||
|
//... other properties
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDragNodeObject(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the object is of IPublicTypeDragNodeObject type but type is not IPublicEnumDragObjectType.Node', () => {
|
||||||
|
const obj = {
|
||||||
|
type: IPublicEnumDragObjectType.OtherType,
|
||||||
|
//... other properties
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDragNodeObject(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the object is null or undefined', () => {
|
||||||
|
expect(isDragNodeObject(null)).toBe(false);
|
||||||
|
expect(isDragNodeObject(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import { isDynamicSetter } from '../../../src/check-types/is-dynamic-setter';
|
||||||
|
|
||||||
|
describe('isDynamicSetter', () => {
|
||||||
|
it('returns true if input is a dynamic setter function', () => {
|
||||||
|
const dynamicSetter = (value: any) => {
|
||||||
|
// some implementation
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isDynamicSetter(dynamicSetter)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if input is not a dynamic setter function', () => {
|
||||||
|
expect(isDynamicSetter('not a function')).toBeFalsy();
|
||||||
|
expect(isDynamicSetter(null)).toBeFalsy();
|
||||||
|
expect(isDynamicSetter(undefined)).toBeFalsy();
|
||||||
|
expect(isDynamicSetter(2)).toBeFalsy();
|
||||||
|
expect(isDynamicSetter(0)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if input is a React class', () => {
|
||||||
|
class ReactClass extends Component {
|
||||||
|
// some implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(isDynamicSetter(ReactClass)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
27
packages/utils/test/src/check-types/is-i18n-data.test.ts
Normal file
27
packages/utils/test/src/check-types/is-i18n-data.test.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { isI18nData } from '../../../src/check-types/is-i18n-data';
|
||||||
|
import { IPublicTypeI18nData } from "@alilc/lowcode-types";
|
||||||
|
|
||||||
|
describe('isI18nData', () => {
|
||||||
|
it('should return true for valid i18n data', () => {
|
||||||
|
const i18nData: IPublicTypeI18nData = {
|
||||||
|
type: 'i18n',
|
||||||
|
// add any other required properties here
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isI18nData(i18nData)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for invalid i18n data', () => {
|
||||||
|
const invalidData = {
|
||||||
|
type: 'some-other-type',
|
||||||
|
// add any other properties here
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isI18nData(invalidData)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for undefined or null', () => {
|
||||||
|
expect(isI18nData(undefined)).toBe(false);
|
||||||
|
expect(isI18nData(null)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
61
packages/utils/test/src/check-types/is-isfunction.test.ts
Normal file
61
packages/utils/test/src/check-types/is-isfunction.test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { isInnerJsFunction, isJSFunction } from '../../../src/check-types/is-isfunction';
|
||||||
|
|
||||||
|
describe('isInnerJsFunction', () => {
|
||||||
|
test('should return true for valid input', () => {
|
||||||
|
const data = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
source: '',
|
||||||
|
value: '',
|
||||||
|
extType: 'function'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isInnerJsFunction(data)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid input', () => {
|
||||||
|
const data = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
source: '',
|
||||||
|
value: '',
|
||||||
|
extType: 'object'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isInnerJsFunction(data)).toBe(false);
|
||||||
|
expect(isInnerJsFunction(null)).toBe(false);
|
||||||
|
expect(isInnerJsFunction(undefined)).toBe(false);
|
||||||
|
expect(isInnerJsFunction(1)).toBe(false);
|
||||||
|
expect(isInnerJsFunction(0)).toBe(false);
|
||||||
|
expect(isInnerJsFunction('string')).toBe(false);
|
||||||
|
expect(isInnerJsFunction('')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isJSFunction', () => {
|
||||||
|
test('should return true for valid input', () => {
|
||||||
|
const data = {
|
||||||
|
type: 'JSFunction',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isJSFunction(data)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return true for inner js function', () => {
|
||||||
|
const data = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
source: '',
|
||||||
|
value: '',
|
||||||
|
extType: 'function'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isJSFunction(data)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid input', () => {
|
||||||
|
expect(isJSFunction(null)).toBe(false);
|
||||||
|
expect(isJSFunction(undefined)).toBe(false);
|
||||||
|
expect(isJSFunction('string')).toBe(false);
|
||||||
|
expect(isJSFunction('')).toBe(false);
|
||||||
|
expect(isJSFunction(0)).toBe(false);
|
||||||
|
expect(isJSFunction(2)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
22
packages/utils/test/src/check-types/is-jsblock.test.ts
Normal file
22
packages/utils/test/src/check-types/is-jsblock.test.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { isJSBlock } from '../../../src/check-types/is-jsblock';
|
||||||
|
|
||||||
|
describe('isJSBlock', () => {
|
||||||
|
it('should return false if data is null or undefined', () => {
|
||||||
|
expect(isJSBlock(null)).toBe(false);
|
||||||
|
expect(isJSBlock(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if data is not an object', () => {
|
||||||
|
expect(isJSBlock('JSBlock')).toBe(false);
|
||||||
|
expect(isJSBlock(123)).toBe(false);
|
||||||
|
expect(isJSBlock(true)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if data.type is not "JSBlock"', () => {
|
||||||
|
expect(isJSBlock({ type: 'InvalidType' })).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if data is an object and data.type is "JSBlock"', () => {
|
||||||
|
expect(isJSBlock({ type: 'JSBlock' })).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
39
packages/utils/test/src/check-types/is-jsexpression.test.ts
Normal file
39
packages/utils/test/src/check-types/is-jsexpression.test.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { isJSExpression } from '../../../src/check-types/is-jsexpression';
|
||||||
|
|
||||||
|
describe('isJSExpression', () => {
|
||||||
|
it('should return true if the input is a valid JSExpression object', () => {
|
||||||
|
const validJSExpression = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
extType: 'variable',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isJSExpression(validJSExpression);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the input is not a valid JSExpression object', () => {
|
||||||
|
const invalidJSExpression = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
extType: 'function',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isJSExpression(invalidJSExpression);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the input is null', () => {
|
||||||
|
const result = isJSExpression(null);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the input is undefined', () => {
|
||||||
|
const result = isJSExpression(undefined);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加其他需要的测试
|
||||||
|
});
|
||||||
37
packages/utils/test/src/check-types/is-jsslot.test.ts
Normal file
37
packages/utils/test/src/check-types/is-jsslot.test.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { isJSSlot } from '../../../src/check-types/is-jsslot';
|
||||||
|
import { IPublicTypeJSSlot } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isJSSlot', () => {
|
||||||
|
it('should return true when input is of type IPublicTypeJSSlot', () => {
|
||||||
|
const input: IPublicTypeJSSlot = {
|
||||||
|
type: 'JSSlot',
|
||||||
|
// other properties of IPublicTypeJSSlot
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isJSSlot(input);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when input is not of type IPublicTypeJSSlot', () => {
|
||||||
|
const input = {
|
||||||
|
type: 'OtherType',
|
||||||
|
// other properties
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isJSSlot(input);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when input is null or undefined', () => {
|
||||||
|
const input1 = null;
|
||||||
|
const input2 = undefined;
|
||||||
|
|
||||||
|
const result1 = isJSSlot(input1);
|
||||||
|
const result2 = isJSSlot(input2);
|
||||||
|
|
||||||
|
expect(result1).toBe(false);
|
||||||
|
expect(result2).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { isLocationChildrenDetail } from '../../../src/check-types/is-location-children-detail';
|
||||||
|
import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isLocationChildrenDetail', () => {
|
||||||
|
it('should return true when obj is IPublicTypeLocationChildrenDetail', () => {
|
||||||
|
const obj: IPublicTypeLocationChildrenDetail = {
|
||||||
|
type: IPublicTypeLocationDetailType.Children,
|
||||||
|
// 添加其他必要的属性
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isLocationChildrenDetail(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when obj is not IPublicTypeLocationChildrenDetail', () => {
|
||||||
|
const obj = {
|
||||||
|
type: 'other',
|
||||||
|
// 添加其他必要的属性
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isLocationChildrenDetail(obj)).toBe(false);
|
||||||
|
expect(isLocationChildrenDetail(null)).toBe(false);
|
||||||
|
expect(isLocationChildrenDetail(undefined)).toBe(false);
|
||||||
|
expect(isLocationChildrenDetail('string')).toBe(false);
|
||||||
|
expect(isLocationChildrenDetail(0)).toBe(false);
|
||||||
|
expect(isLocationChildrenDetail(2)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
44
packages/utils/test/src/check-types/is-location-data.test.ts
Normal file
44
packages/utils/test/src/check-types/is-location-data.test.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { isLocationData } from '../../../src/check-types/is-location-data';
|
||||||
|
import { IPublicTypeLocationData } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isLocationData', () => {
|
||||||
|
it('should return true when obj is valid location data', () => {
|
||||||
|
const obj: IPublicTypeLocationData = {
|
||||||
|
target: 'some target',
|
||||||
|
detail: 'some detail',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isLocationData(obj);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when obj is missing target or detail', () => {
|
||||||
|
const obj1 = {
|
||||||
|
target: 'some target',
|
||||||
|
// missing detail
|
||||||
|
};
|
||||||
|
|
||||||
|
const obj2 = {
|
||||||
|
// missing target
|
||||||
|
detail: 'some detail',
|
||||||
|
};
|
||||||
|
|
||||||
|
const result1 = isLocationData(obj1);
|
||||||
|
const result2 = isLocationData(obj2);
|
||||||
|
|
||||||
|
expect(result1).toBe(false);
|
||||||
|
expect(result2).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when obj is null or undefined', () => {
|
||||||
|
const obj1 = null;
|
||||||
|
const obj2 = undefined;
|
||||||
|
|
||||||
|
const result1 = isLocationData(obj1);
|
||||||
|
const result2 = isLocationData(obj2);
|
||||||
|
|
||||||
|
expect(result1).toBe(false);
|
||||||
|
expect(result2).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import { isLowCodeComponentType } from '../../../src/check-types/is-lowcode-component-type';
|
||||||
|
import { IPublicTypeLowCodeComponent, IPublicTypeProCodeComponent } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isLowCodeComponentType', () => {
|
||||||
|
test('should return true for a low code component type', () => {
|
||||||
|
const desc: IPublicTypeLowCodeComponent = {
|
||||||
|
// create a valid low code component description
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isLowCodeComponentType(desc)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for a pro code component type', () => {
|
||||||
|
const desc: IPublicTypeProCodeComponent = {
|
||||||
|
// create a valid pro code component description
|
||||||
|
package: 'pro-code'
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isLowCodeComponentType(desc)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
import { isLowcodeProjectSchema } from "../../../src/check-types/is-lowcode-project-schema";
|
||||||
|
|
||||||
|
describe("isLowcodeProjectSchema", () => {
|
||||||
|
it("should return false when data is null", () => {
|
||||||
|
const result = isLowcodeProjectSchema(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when data is undefined", () => {
|
||||||
|
const result = isLowcodeProjectSchema(undefined);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when data is not an object", () => {
|
||||||
|
const result = isLowcodeProjectSchema("not an object");
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when componentsTree is missing", () => {
|
||||||
|
const data = { someKey: "someValue" };
|
||||||
|
const result = isLowcodeProjectSchema(data);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when componentsTree is an empty array", () => {
|
||||||
|
const data = { componentsTree: [] };
|
||||||
|
const result = isLowcodeProjectSchema(data);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false when the first element of componentsTree is not a component schema", () => {
|
||||||
|
const data = { componentsTree: [{}] };
|
||||||
|
const result = isLowcodeProjectSchema(data);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return true when all conditions are met", () => {
|
||||||
|
const data = { componentsTree: [{ prop: "value", componentName: 'Component' }] };
|
||||||
|
const result = isLowcodeProjectSchema(data);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
43
packages/utils/test/src/check-types/is-node-schema.test.ts
Normal file
43
packages/utils/test/src/check-types/is-node-schema.test.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { isNodeSchema } from '../../../src/check-types/is-node-schema';
|
||||||
|
|
||||||
|
describe('isNodeSchema', () => {
|
||||||
|
// 测试正常情况
|
||||||
|
it('should return true for valid IPublicTypeNodeSchema', () => {
|
||||||
|
const validData = {
|
||||||
|
componentName: 'Component',
|
||||||
|
isNode: false,
|
||||||
|
};
|
||||||
|
expect(isNodeSchema(validData)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 测试 null 或 undefined
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
expect(isNodeSchema(null)).toBe(false);
|
||||||
|
expect(isNodeSchema(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 测试没有componentName属性的情况
|
||||||
|
it('should return false if componentName is missing', () => {
|
||||||
|
const invalidData = {
|
||||||
|
isNode: false,
|
||||||
|
};
|
||||||
|
expect(isNodeSchema(invalidData)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 测试isNode为true的情况
|
||||||
|
it('should return false if isNode is true', () => {
|
||||||
|
const invalidData = {
|
||||||
|
componentName: 'Component',
|
||||||
|
isNode: true,
|
||||||
|
};
|
||||||
|
expect(isNodeSchema(invalidData)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 测试其他数据类型的情况
|
||||||
|
it('should return false for other data types', () => {
|
||||||
|
expect(isNodeSchema('string')).toBe(false);
|
||||||
|
expect(isNodeSchema(123)).toBe(false);
|
||||||
|
expect(isNodeSchema([])).toBe(false);
|
||||||
|
expect(isNodeSchema({})).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
19
packages/utils/test/src/check-types/is-node.test.ts
Normal file
19
packages/utils/test/src/check-types/is-node.test.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { isNode } from '../../../src/check-types/is-node';
|
||||||
|
|
||||||
|
describe('isNode', () => {
|
||||||
|
it('should return true for a valid node', () => {
|
||||||
|
const node = { isNode: true };
|
||||||
|
expect(isNode(node)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an invalid node', () => {
|
||||||
|
const node = { isNode: false };
|
||||||
|
expect(isNode(node)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an undefined node', () => {
|
||||||
|
expect(isNode(undefined)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases if needed
|
||||||
|
});
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { isProCodeComponentType } from '../../../src/check-types/is-procode-component-type';
|
||||||
|
|
||||||
|
describe('isProCodeComponentType', () => {
|
||||||
|
it('should return true if the given desc object contains "package" property', () => {
|
||||||
|
const desc = { package: 'packageName' };
|
||||||
|
expect(isProCodeComponentType(desc)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if the given desc object does not contain "package" property', () => {
|
||||||
|
const desc = { name: 'componentName' };
|
||||||
|
expect(isProCodeComponentType(desc)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { IPublicTypeProjectSchema } from "@alilc/lowcode-types";
|
||||||
|
import { isProjectSchema } from "../../../src/check-types/is-project-schema";
|
||||||
|
|
||||||
|
describe("isProjectSchema", () => {
|
||||||
|
it("should return true if data has componentsTree property", () => {
|
||||||
|
const data: IPublicTypeProjectSchema = {
|
||||||
|
// ...
|
||||||
|
componentsTree: {
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
};
|
||||||
|
expect(isProjectSchema(data)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false if data does not have componentsTree property", () => {
|
||||||
|
const data = {
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
expect(isProjectSchema(data)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false if data is null or undefined", () => {
|
||||||
|
expect(isProjectSchema(null)).toBe(false);
|
||||||
|
expect(isProjectSchema(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更多的测试用例...
|
||||||
|
});
|
||||||
26
packages/utils/test/src/check-types/is-setter-config.test.ts
Normal file
26
packages/utils/test/src/check-types/is-setter-config.test.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { isSetterConfig } from '../../../src/check-types/is-setter-config';
|
||||||
|
|
||||||
|
describe('isSetterConfig', () => {
|
||||||
|
test('should return true for valid setter config', () => {
|
||||||
|
const config = {
|
||||||
|
componentName: 'MyComponent',
|
||||||
|
// Add other required properties here
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isSetterConfig(config)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false for invalid setter config', () => {
|
||||||
|
const config = {
|
||||||
|
// Missing componentName property
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isSetterConfig(config)).toBe(false);
|
||||||
|
expect(isSetterConfig(null)).toBe(false);
|
||||||
|
expect(isSetterConfig(undefined)).toBe(false);
|
||||||
|
expect(isSetterConfig(0)).toBe(false);
|
||||||
|
expect(isSetterConfig(2)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases for different scenarios you want to cover
|
||||||
|
});
|
||||||
18
packages/utils/test/src/check-types/is-setting-field.test.ts
Normal file
18
packages/utils/test/src/check-types/is-setting-field.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { isSettingField } from "../../../src/check-types/is-setting-field";
|
||||||
|
|
||||||
|
describe("isSettingField", () => {
|
||||||
|
it("should return true for an object that has isSettingField property", () => {
|
||||||
|
const obj = { isSettingField: true };
|
||||||
|
expect(isSettingField(obj)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false for an object that does not have isSettingField property", () => {
|
||||||
|
const obj = { foo: "bar" };
|
||||||
|
expect(isSettingField(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return false for a falsy value", () => {
|
||||||
|
const obj = null;
|
||||||
|
expect(isSettingField(obj)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
18
packages/utils/test/src/check-types/is-title-config.test.ts
Normal file
18
packages/utils/test/src/check-types/is-title-config.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { isTitleConfig } from '../../../src/check-types/is-title-config';
|
||||||
|
|
||||||
|
describe('isTitleConfig', () => {
|
||||||
|
it('should return true for valid config object', () => {
|
||||||
|
const config = { title: 'My Title' };
|
||||||
|
expect(isTitleConfig(config)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for invalid config object', () => {
|
||||||
|
const config = { title: 'My Title', type: 'i18n' , i18nData: {} };
|
||||||
|
expect(isTitleConfig(config)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for non-object input', () => {
|
||||||
|
const config = 'invalid';
|
||||||
|
expect(isTitleConfig(config)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
30
packages/utils/test/src/clone-deep.test.ts
Normal file
30
packages/utils/test/src/clone-deep.test.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { cloneDeep } from '../../src/clone-deep';
|
||||||
|
|
||||||
|
describe('cloneDeep', () => {
|
||||||
|
it('should clone null', () => {
|
||||||
|
const src = null;
|
||||||
|
expect(cloneDeep(src)).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clone undefined', () => {
|
||||||
|
const src = undefined;
|
||||||
|
expect(cloneDeep(src)).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clone an array', () => {
|
||||||
|
const src = [1, 2, 3, 4];
|
||||||
|
expect(cloneDeep(src)).toEqual(src);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clone an object', () => {
|
||||||
|
const src = { name: 'John', age: 25 };
|
||||||
|
expect(cloneDeep(src)).toEqual(src);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should deep clone nested objects', () => {
|
||||||
|
const src = { person: { name: 'John', age: 25 } };
|
||||||
|
const cloned = cloneDeep(src);
|
||||||
|
expect(cloned).toEqual(src);
|
||||||
|
expect(cloned.person).not.toBe(src.person);
|
||||||
|
});
|
||||||
|
});
|
||||||
30
packages/utils/test/src/clone-enumerable-property.test.ts
Normal file
30
packages/utils/test/src/clone-enumerable-property.test.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { cloneEnumerableProperty } from '../../src/clone-enumerable-property';
|
||||||
|
|
||||||
|
describe('cloneEnumerableProperty', () => {
|
||||||
|
test('should clone enumerable properties from origin to target', () => {
|
||||||
|
// Arrange
|
||||||
|
const target = {};
|
||||||
|
const origin = { prop1: 1, prop2: 'hello', prop3: true };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = cloneEnumerableProperty(target, origin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBe(target);
|
||||||
|
expect(result).toEqual(origin);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should exclude properties specified in excludePropertyNames', () => {
|
||||||
|
// Arrange
|
||||||
|
const target = {};
|
||||||
|
const origin = { prop1: 1, prop2: 'hello', prop3: true };
|
||||||
|
const excludePropertyNames = ['prop2'];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = cloneEnumerableProperty(target, origin, excludePropertyNames);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toBe(target);
|
||||||
|
expect(result).toEqual({ prop1: 1, prop3: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
38
packages/utils/test/src/create-content.test.tsx
Normal file
38
packages/utils/test/src/create-content.test.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { createContent } from '../../src/create-content';
|
||||||
|
|
||||||
|
const MyComponent = () => {
|
||||||
|
return <div>MyComponent</div>
|
||||||
|
}
|
||||||
|
describe('createContent', () => {
|
||||||
|
test('should return the same content if it is a valid React element', () => {
|
||||||
|
const content = <div>Hello</div>;
|
||||||
|
const result = createContent(content);
|
||||||
|
|
||||||
|
expect(result).toEqual(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should clone the element with props if props are provided', () => {
|
||||||
|
const content = <div></div>;
|
||||||
|
const props = { className: 'my-class' };
|
||||||
|
const result = createContent(content, props);
|
||||||
|
|
||||||
|
expect(result.props).toEqual(props);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should create an element with props if the content is a React component', () => {
|
||||||
|
const content = MyComponent;
|
||||||
|
const props = { className: 'my-class' };
|
||||||
|
const result = createContent(content, props);
|
||||||
|
|
||||||
|
expect(result.type).toEqual(content);
|
||||||
|
expect(result.props).toEqual(props);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return the content if it is not a React element or a React component', () => {
|
||||||
|
const content = 'Hello';
|
||||||
|
const result = createContent(content);
|
||||||
|
|
||||||
|
expect(result).toEqual(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
16
packages/utils/test/src/create-defer.test.ts
Normal file
16
packages/utils/test/src/create-defer.test.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { createDefer } from '../../src/create-defer';
|
||||||
|
|
||||||
|
describe('createDefer', () => {
|
||||||
|
it('should resolve with given value', async () => {
|
||||||
|
const defer = createDefer<number>();
|
||||||
|
defer.resolve(42);
|
||||||
|
const result = await defer.promise();
|
||||||
|
expect(result).toBe(42);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reject with given reason', async () => {
|
||||||
|
const defer = createDefer<number>();
|
||||||
|
defer.reject('error');
|
||||||
|
await expect(defer.promise()).rejects.toEqual('error');
|
||||||
|
});
|
||||||
|
});
|
||||||
45
packages/utils/test/src/is-object.test.ts
Normal file
45
packages/utils/test/src/is-object.test.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { isObject, isI18NObject } from '../../src/is-object';
|
||||||
|
|
||||||
|
describe('isObject', () => {
|
||||||
|
it('should return true for an object', () => {
|
||||||
|
const obj = { key: 'value' };
|
||||||
|
const result = isObject(obj);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null', () => {
|
||||||
|
const result = isObject(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a non-object value', () => {
|
||||||
|
const value = 42; // Not an object
|
||||||
|
const result = isObject(value);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isI18NObject', () => {
|
||||||
|
it('should return true for an I18N object', () => {
|
||||||
|
const i18nObject = { type: 'i18n', data: 'some data' };
|
||||||
|
const result = isI18NObject(i18nObject);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a non-I18N object', () => {
|
||||||
|
const nonI18nObject = { type: 'other', data: 'some data' };
|
||||||
|
const result = isI18NObject(nonI18nObject);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null', () => {
|
||||||
|
const result = isI18NObject(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a non-object value', () => {
|
||||||
|
const value = 42; // Not an object
|
||||||
|
const result = isI18NObject(value);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,38 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { isReactComponent, wrapReactClass } from "../../src/is-react";
|
|
||||||
|
|
||||||
class reactDemo extends React.Component {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const reactMemo = React.memo(reactDemo);
|
|
||||||
|
|
||||||
const reactForwardRef = React.forwardRef((props, ref): any => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('is-react-ut', () => {
|
|
||||||
it('isReactComponent', () => {
|
|
||||||
expect(isReactComponent(null)).toBeFalsy();
|
|
||||||
expect(isReactComponent(() => {})).toBeTruthy();
|
|
||||||
expect(isReactComponent({
|
|
||||||
$$typeof: Symbol.for('react.memo')
|
|
||||||
})).toBeTruthy();
|
|
||||||
expect(isReactComponent({
|
|
||||||
$$typeof: Symbol.for('react.forward_ref')
|
|
||||||
})).toBeTruthy();
|
|
||||||
expect(isReactComponent(reactDemo)).toBeTruthy();
|
|
||||||
expect(isReactComponent(reactMemo)).toBeTruthy();
|
|
||||||
expect(isReactComponent(reactForwardRef)).toBeTruthy();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('wrapReactClass', () => {
|
|
||||||
const wrap = wrapReactClass(() => {});
|
|
||||||
expect(isReactComponent(wrap)).toBeTruthy();
|
|
||||||
|
|
||||||
const fun = () => {};
|
|
||||||
fun.displayName = 'mock';
|
|
||||||
expect(wrapReactClass(fun).displayName).toBe('mock');
|
|
||||||
})
|
|
||||||
})
|
|
||||||
316
packages/utils/test/src/is-react.test.tsx
Normal file
316
packages/utils/test/src/is-react.test.tsx
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
import React, { Component, createElement } from "react";
|
||||||
|
import {
|
||||||
|
isReactComponent,
|
||||||
|
wrapReactClass,
|
||||||
|
isForwardOrMemoForward,
|
||||||
|
isMemoType,
|
||||||
|
isForwardRefType,
|
||||||
|
acceptsRef,
|
||||||
|
isReactClass,
|
||||||
|
REACT_MEMO_TYPE,
|
||||||
|
REACT_FORWARD_REF_TYPE,
|
||||||
|
} from "../../src/is-react";
|
||||||
|
|
||||||
|
class reactDemo extends React.Component {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const reactMemo = React.memo(reactDemo);
|
||||||
|
|
||||||
|
const reactForwardRef = React.forwardRef((props, ref): any => {
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('is-react-ut', () => {
|
||||||
|
it('isReactComponent', () => {
|
||||||
|
expect(isReactComponent(null)).toBeFalsy();
|
||||||
|
expect(isReactComponent(() => {})).toBeTruthy();
|
||||||
|
expect(isReactComponent({
|
||||||
|
$$typeof: Symbol.for('react.memo')
|
||||||
|
})).toBeTruthy();
|
||||||
|
expect(isReactComponent({
|
||||||
|
$$typeof: Symbol.for('react.forward_ref')
|
||||||
|
})).toBeTruthy();
|
||||||
|
expect(isReactComponent(reactDemo)).toBeTruthy();
|
||||||
|
expect(isReactComponent(reactMemo)).toBeTruthy();
|
||||||
|
expect(isReactComponent(reactForwardRef)).toBeTruthy();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('wrapReactClass', () => {
|
||||||
|
const wrap = wrapReactClass(() => {});
|
||||||
|
expect(isReactComponent(wrap)).toBeTruthy();
|
||||||
|
|
||||||
|
const fun = () => {};
|
||||||
|
fun.displayName = 'mock';
|
||||||
|
expect(wrapReactClass(fun).displayName).toBe('mock');
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('wrapReactClass', () => {
|
||||||
|
it('should wrap a FunctionComponent', () => {
|
||||||
|
// Create a mock FunctionComponent
|
||||||
|
const MockComponent: React.FunctionComponent = (props) => {
|
||||||
|
return <div>{props.children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wrap the FunctionComponent using wrapReactClass
|
||||||
|
const WrappedComponent = wrapReactClass(MockComponent);
|
||||||
|
const instance = new WrappedComponent();
|
||||||
|
|
||||||
|
// Check if the WrappedComponent extends Component
|
||||||
|
expect(instance instanceof React.Component).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the FunctionComponent with props', () => {
|
||||||
|
// Create a mock FunctionComponent
|
||||||
|
const MockComponent: React.FunctionComponent = (props) => {
|
||||||
|
return <div>{props.children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
MockComponent.displayName = 'FunctionComponent';
|
||||||
|
|
||||||
|
// Wrap the FunctionComponent using wrapReactClass
|
||||||
|
const WrappedComponent = wrapReactClass(MockComponent);
|
||||||
|
|
||||||
|
// Create some test props
|
||||||
|
const testProps = { prop1: 'value1', prop2: 'value2' };
|
||||||
|
|
||||||
|
// Render the WrappedComponent with test props
|
||||||
|
const rendered = createElement(WrappedComponent, testProps, 'Child Text');
|
||||||
|
|
||||||
|
// Check if the WrappedComponent renders the FunctionComponent with props
|
||||||
|
expect(rendered).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isReactComponent', () => {
|
||||||
|
it('should identify a class component as a React component', () => {
|
||||||
|
class ClassComponent extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div>Class Component</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(isReactComponent(ClassComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should identify a functional component as a React component', () => {
|
||||||
|
const FunctionalComponent = () => {
|
||||||
|
return <div>Functional Component</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isReactComponent(FunctionalComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should identify a forward ref component as a React component', () => {
|
||||||
|
const ForwardRefComponent = React.forwardRef((props, ref) => {
|
||||||
|
return <div ref={ref}>Forward Ref Component</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isReactComponent(ForwardRefComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should identify a memo component as a React component', () => {
|
||||||
|
const MemoComponent = React.memo(() => {
|
||||||
|
return <div>Memo Component</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isReactComponent(MemoComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for non-React components', () => {
|
||||||
|
const plainObject = { prop: 'value' };
|
||||||
|
const notAComponent = 'Not a component';
|
||||||
|
|
||||||
|
expect(isReactComponent(plainObject)).toBe(false);
|
||||||
|
expect(isReactComponent(notAComponent)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(isReactComponent(nullValue)).toBe(false);
|
||||||
|
expect(isReactComponent(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isForwardOrMemoForward', () => {
|
||||||
|
it('should return true for a forwardRef component', () => {
|
||||||
|
const forwardRefComponent = React.forwardRef(() => {
|
||||||
|
return <div>ForwardRef Component</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isForwardOrMemoForward(forwardRefComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for a memoized forwardRef component', () => {
|
||||||
|
const forwardRefComponent = React.forwardRef(() => {
|
||||||
|
return <div>ForwardRef Component</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
const memoizedComponent = React.memo(forwardRefComponent);
|
||||||
|
|
||||||
|
expect(isForwardOrMemoForward(memoizedComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a memoized component that is not a forwardRef', () => {
|
||||||
|
const memoizedComponent = React.memo(() => {
|
||||||
|
return <div>Memoized Component</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isForwardOrMemoForward(memoizedComponent)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a plain object', () => {
|
||||||
|
const plainObject = { prop: 'value' };
|
||||||
|
|
||||||
|
expect(isForwardOrMemoForward(plainObject)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(isForwardOrMemoForward(nullValue)).toBe(false);
|
||||||
|
expect(isForwardOrMemoForward(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isMemoType', () => {
|
||||||
|
it('should return true for an object with $$typeof matching REACT_MEMO_TYPE', () => {
|
||||||
|
const memoTypeObject = { $$typeof: REACT_MEMO_TYPE };
|
||||||
|
|
||||||
|
expect(isMemoType(memoTypeObject)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object with $$typeof not matching REACT_MEMO_TYPE', () => {
|
||||||
|
const otherTypeObject = { $$typeof: Symbol.for('other.type') };
|
||||||
|
|
||||||
|
expect(isMemoType(otherTypeObject)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object with no $$typeof property', () => {
|
||||||
|
const noTypeObject = { key: 'value' };
|
||||||
|
|
||||||
|
expect(isMemoType(noTypeObject)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(isMemoType(nullValue)).toBe(false);
|
||||||
|
expect(isMemoType(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isForwardRefType', () => {
|
||||||
|
it('should return true for an object with $$typeof matching REACT_FORWARD_REF_TYPE', () => {
|
||||||
|
const forwardRefTypeObject = { $$typeof: REACT_FORWARD_REF_TYPE };
|
||||||
|
|
||||||
|
expect(isForwardRefType(forwardRefTypeObject)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object with $$typeof not matching REACT_FORWARD_REF_TYPE', () => {
|
||||||
|
const otherTypeObject = { $$typeof: Symbol.for('other.type') };
|
||||||
|
|
||||||
|
expect(isForwardRefType(otherTypeObject)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object with no $$typeof property', () => {
|
||||||
|
const noTypeObject = { key: 'value' };
|
||||||
|
|
||||||
|
expect(isForwardRefType(noTypeObject)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(isForwardRefType(nullValue)).toBe(false);
|
||||||
|
expect(isForwardRefType(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('acceptsRef', () => {
|
||||||
|
it('should return true for an object with isReactComponent in its prototype', () => {
|
||||||
|
const objWithIsReactComponent = {
|
||||||
|
prototype: {
|
||||||
|
isReactComponent: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(acceptsRef(objWithIsReactComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for an object that is forwardRef or memoized forwardRef', () => {
|
||||||
|
const forwardRefObject = React.forwardRef(() => {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const memoizedForwardRefObject = React.memo(forwardRefObject);
|
||||||
|
|
||||||
|
expect(acceptsRef(forwardRefObject)).toBe(true);
|
||||||
|
expect(acceptsRef(memoizedForwardRefObject)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object without isReactComponent in its prototype', () => {
|
||||||
|
const objWithoutIsReactComponent = {
|
||||||
|
prototype: {
|
||||||
|
someOtherProperty: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(acceptsRef(objWithoutIsReactComponent)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(acceptsRef(nullValue)).toBe(false);
|
||||||
|
expect(acceptsRef(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isReactClass', () => {
|
||||||
|
it('should return true for an object with isReactComponent in its prototype', () => {
|
||||||
|
class ReactClassComponent extends Component {
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(isReactClass(ReactClassComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for an object with Component in its prototype chain', () => {
|
||||||
|
class CustomComponent extends Component {
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(isReactClass(CustomComponent)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object without isReactComponent in its prototype', () => {
|
||||||
|
class NonReactComponent {
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(isReactClass(NonReactComponent)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null or undefined', () => {
|
||||||
|
const nullValue = null;
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
|
||||||
|
expect(isReactClass(nullValue)).toBe(false);
|
||||||
|
expect(isReactClass(undefinedValue)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
45
packages/utils/test/src/is-shaken.test.ts
Normal file
45
packages/utils/test/src/is-shaken.test.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { isShaken } from '../../src/is-shaken';
|
||||||
|
|
||||||
|
describe('isShaken', () => {
|
||||||
|
it('should return true if e1 has shaken property', () => {
|
||||||
|
const e1: any = { shaken: true };
|
||||||
|
const e2: MouseEvent | DragEvent = { target: null } as MouseEvent | DragEvent;
|
||||||
|
|
||||||
|
expect(isShaken(e1, e2)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if e1.target and e2.target are different', () => {
|
||||||
|
const e1: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent;
|
||||||
|
const e2: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent;
|
||||||
|
|
||||||
|
expect(isShaken(e1, e2)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if e1 and e2 targets are the same and distance is less than SHAKE_DISTANCE', () => {
|
||||||
|
const target = {};
|
||||||
|
const e1: MouseEvent | DragEvent = { target: target } as MouseEvent | DragEvent;
|
||||||
|
const e2: MouseEvent | DragEvent = { target: target } as MouseEvent | DragEvent;
|
||||||
|
|
||||||
|
// Assuming SHAKE_DISTANCE is 100
|
||||||
|
e1.clientY = 50;
|
||||||
|
e2.clientY = 50;
|
||||||
|
|
||||||
|
e1.clientX = 60;
|
||||||
|
e2.clientX = 60;
|
||||||
|
|
||||||
|
expect(isShaken(e1, e2)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if e1 and e2 targets are the same and distance is greater than SHAKE_DISTANCE', () => {
|
||||||
|
const e1: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent;
|
||||||
|
const e2: MouseEvent | DragEvent = { target: {} } as MouseEvent | DragEvent;
|
||||||
|
|
||||||
|
// Assuming SHAKE_DISTANCE is 100
|
||||||
|
e1.clientY = 50;
|
||||||
|
e1.clientX = 50;
|
||||||
|
e2.clientY = 200;
|
||||||
|
e2.clientX = 200;
|
||||||
|
|
||||||
|
expect(isShaken(e1, e2)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,4 +1,321 @@
|
|||||||
import { shouldUseVariableSetter } from '../../src/misc';
|
import {
|
||||||
|
isVariable,
|
||||||
|
isUseI18NSetter,
|
||||||
|
convertToI18NObject,
|
||||||
|
isString,
|
||||||
|
waitForThing,
|
||||||
|
arrShallowEquals,
|
||||||
|
isFromVC,
|
||||||
|
executePendingFn,
|
||||||
|
compatStage,
|
||||||
|
invariant,
|
||||||
|
isRegExp,
|
||||||
|
shouldUseVariableSetter,
|
||||||
|
} from '../../src/misc';
|
||||||
|
import { IPublicModelComponentMeta } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('isVariable', () => {
|
||||||
|
it('should return true for a variable object', () => {
|
||||||
|
const variable = { type: 'variable', variable: 'foo', value: 'bar' };
|
||||||
|
const result = isVariable(variable);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for non-variable objects', () => {
|
||||||
|
const obj = { type: 'object' };
|
||||||
|
const result = isVariable(obj);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isUseI18NSetter', () => {
|
||||||
|
it('should return true for a property with I18nSetter', () => {
|
||||||
|
const prototype = { options: { configure: [{ name: 'propName', setter: { type: { displayName: 'I18nSetter' } } }] } };
|
||||||
|
const propName = 'propName';
|
||||||
|
const result = isUseI18NSetter(prototype, propName);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a property without I18nSetter', () => {
|
||||||
|
const prototype = { options: { configure: [{ name: 'propName', setter: { type: { displayName: 'OtherSetter' } } }] } };
|
||||||
|
const propName = 'propName';
|
||||||
|
const result = isUseI18NSetter(prototype, propName);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('convertToI18NObject', () => {
|
||||||
|
it('should return the input if it is already an I18N object', () => {
|
||||||
|
const i18nObject = { type: 'i18n', use: 'en', en: 'Hello' };
|
||||||
|
const result = convertToI18NObject(i18nObject);
|
||||||
|
expect(result).toEqual(i18nObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert a string to an I18N object', () => {
|
||||||
|
const inputString = 'Hello';
|
||||||
|
const result = convertToI18NObject(inputString);
|
||||||
|
const expectedOutput = { type: 'i18n', use: 'zh-CN', 'zh-CN': inputString };
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isString', () => {
|
||||||
|
it('should return true for a string', () => {
|
||||||
|
const stringValue = 'Hello, world!';
|
||||||
|
const result = isString(stringValue);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for an empty string', () => {
|
||||||
|
const emptyString = '';
|
||||||
|
const result = isString(emptyString);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a number', () => {
|
||||||
|
const numberValue = 42; // Not a string
|
||||||
|
const result = isString(numberValue);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for an object', () => {
|
||||||
|
const objectValue = { key: 'value' }; // Not a string
|
||||||
|
const result = isString(objectValue);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null', () => {
|
||||||
|
const result = isString(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for undefined', () => {
|
||||||
|
const undefinedValue = undefined;
|
||||||
|
const result = isString(undefinedValue);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a boolean', () => {
|
||||||
|
const booleanValue = true; // Not a string
|
||||||
|
const result = isString(booleanValue);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('waitForThing', () => {
|
||||||
|
it('should resolve immediately if the thing is available', async () => {
|
||||||
|
const obj = { prop: 'value' };
|
||||||
|
const path = 'prop';
|
||||||
|
const result = await waitForThing(obj, path);
|
||||||
|
expect(result).toBe('value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve after a delay if the thing becomes available', async () => {
|
||||||
|
const obj = { prop: undefined };
|
||||||
|
const path = 'prop';
|
||||||
|
const delay = 100; // Adjust the delay as needed
|
||||||
|
setTimeout(() => {
|
||||||
|
obj.prop = 'value';
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
const result = await waitForThing(obj, path);
|
||||||
|
expect(result).toBe('value');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('arrShallowEquals', () => {
|
||||||
|
it('should return true for two empty arrays', () => {
|
||||||
|
const arr1 = [];
|
||||||
|
const arr2 = [];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for two arrays with the same elements in the same order', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [1, 2, 3];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for two arrays with the same elements in a different order', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [3, 2, 1];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for two arrays with different lengths', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [1, 2];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for one array and a non-array', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const nonArray = 'not an array';
|
||||||
|
const result = arrShallowEquals(arr1, nonArray);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for two arrays with different elements', () => {
|
||||||
|
const arr1 = [1, 2, 3];
|
||||||
|
const arr2 = [3, 4, 5];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true for arrays with duplicate elements', () => {
|
||||||
|
const arr1 = [1, 2, 2, 3];
|
||||||
|
const arr2 = [2, 3, 3, 1];
|
||||||
|
const result = arrShallowEquals(arr1, arr2);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isFromVC', () => {
|
||||||
|
it('should return true when advanced configuration is present', () => {
|
||||||
|
// Create a mock meta object with advanced configuration
|
||||||
|
const meta: IPublicModelComponentMeta = {
|
||||||
|
getMetadata: () => ({ configure: { advanced: true } }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isFromVC(meta);
|
||||||
|
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when advanced configuration is not present', () => {
|
||||||
|
// Create a mock meta object without advanced configuration
|
||||||
|
const meta: IPublicModelComponentMeta = {
|
||||||
|
getMetadata: () => ({ configure: { advanced: false } }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isFromVC(meta);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when meta is undefined', () => {
|
||||||
|
const meta: IPublicModelComponentMeta | undefined = undefined;
|
||||||
|
|
||||||
|
const result = isFromVC(meta);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when meta does not have configure information', () => {
|
||||||
|
// Create a mock meta object without configure information
|
||||||
|
const meta: IPublicModelComponentMeta = {
|
||||||
|
getMetadata: () => ({}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isFromVC(meta);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when configure.advanced is not present', () => {
|
||||||
|
// Create a mock meta object with incomplete configure information
|
||||||
|
const meta: IPublicModelComponentMeta = {
|
||||||
|
getMetadata: () => ({ configure: {} }),
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = isFromVC(meta);
|
||||||
|
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('executePendingFn', () => {
|
||||||
|
it('should execute the provided function after the specified timeout', async () => {
|
||||||
|
// Mock the function to execute
|
||||||
|
const fn = jest.fn();
|
||||||
|
|
||||||
|
// Call executePendingFn with the mocked function and a short timeout
|
||||||
|
executePendingFn(fn, 100);
|
||||||
|
|
||||||
|
// Ensure the function has not been called immediately
|
||||||
|
expect(fn).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
// Wait for the specified timeout
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
|
// Ensure the function has been called after the timeout
|
||||||
|
expect(fn).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute the provided function with a default timeout if not specified', async () => {
|
||||||
|
// Mock the function to execute
|
||||||
|
const fn = jest.fn();
|
||||||
|
|
||||||
|
// Call executePendingFn with the mocked function without specifying a timeout
|
||||||
|
executePendingFn(fn);
|
||||||
|
|
||||||
|
// Ensure the function has not been called immediately
|
||||||
|
expect(fn).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
// Wait for the default timeout (2000 milliseconds)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
|
// Ensure the function has been called after the default timeout
|
||||||
|
expect(fn).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('compatStage', () => {
|
||||||
|
it('should convert a number to an enum stage', () => {
|
||||||
|
const result = compatStage(3);
|
||||||
|
expect(result).toBe('save');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should warn about the deprecated usage', () => {
|
||||||
|
const warnSpy = jest.spyOn(console, 'warn');
|
||||||
|
const result = compatStage(2);
|
||||||
|
expect(result).toBe('serilize');
|
||||||
|
expect(warnSpy).toHaveBeenCalledWith(
|
||||||
|
'stage 直接指定为数字的使用方式已经过时,将在下一版本移除,请直接使用 IPublicEnumTransformStage.Render|Serilize|Save|Clone|Init|Upgrade'
|
||||||
|
);
|
||||||
|
warnSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the enum stage if it is already an enum', () => {
|
||||||
|
const result = compatStage('render');
|
||||||
|
expect(result).toBe('render');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('invariant', () => {
|
||||||
|
it('should not throw an error if the check is true', () => {
|
||||||
|
expect(() => invariant(true, 'Test invariant', 'thing')).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the check is false', () => {
|
||||||
|
expect(() => invariant(false, 'Test invariant', 'thing')).toThrowError(
|
||||||
|
"Invariant failed: Test invariant in 'thing'"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isRegExp', () => {
|
||||||
|
it('should return true for a valid RegExp', () => {
|
||||||
|
const regex = /test/;
|
||||||
|
const result = isRegExp(regex);
|
||||||
|
expect(result).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for a non-RegExp object', () => {
|
||||||
|
const nonRegExp = { test: /test/ };
|
||||||
|
const result = isRegExp(nonRegExp);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for null', () => {
|
||||||
|
const result = isRegExp(null);
|
||||||
|
expect(result).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('shouldUseVariableSetter', () => {
|
it('shouldUseVariableSetter', () => {
|
||||||
expect(shouldUseVariableSetter(false, true)).toBeFalsy();
|
expect(shouldUseVariableSetter(false, true)).toBeFalsy();
|
||||||
|
|||||||
18
packages/utils/test/src/navtive-selection.test.ts
Normal file
18
packages/utils/test/src/navtive-selection.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { setNativeSelection, nativeSelectionEnabled } from '../../src/navtive-selection';
|
||||||
|
|
||||||
|
describe('setNativeSelection', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// 在每个测试运行之前重置nativeSelectionEnabled的值
|
||||||
|
setNativeSelection(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should enable native selection', () => {
|
||||||
|
setNativeSelection(true);
|
||||||
|
expect(nativeSelectionEnabled).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should disable native selection', () => {
|
||||||
|
setNativeSelection(false);
|
||||||
|
expect(nativeSelectionEnabled).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,4 +1,132 @@
|
|||||||
import { compatibleLegaoSchema } from '../../src/schema';
|
import {
|
||||||
|
compatibleLegaoSchema,
|
||||||
|
getNodeSchemaById,
|
||||||
|
applyActivities,
|
||||||
|
} from '../../src/schema';
|
||||||
|
import { ActivityType } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
describe('compatibleLegaoSchema', () => {
|
||||||
|
it('should handle null input', () => {
|
||||||
|
const result = compatibleLegaoSchema(null);
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert Legao schema to JSExpression', () => {
|
||||||
|
// Create your test input
|
||||||
|
const legaoSchema = {
|
||||||
|
type: 'LegaoType',
|
||||||
|
source: 'LegaoSource',
|
||||||
|
compiled: 'LegaoCompiled',
|
||||||
|
};
|
||||||
|
const result = compatibleLegaoSchema(legaoSchema);
|
||||||
|
|
||||||
|
// Define the expected output
|
||||||
|
const expectedOutput = {
|
||||||
|
type: 'JSExpression',
|
||||||
|
value: 'LegaoCompiled',
|
||||||
|
extType: 'function',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assert that the result matches the expected output
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases for other scenarios
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getNodeSchemaById', () => {
|
||||||
|
it('should find a node in the schema', () => {
|
||||||
|
// Create your test schema and node ID
|
||||||
|
const testSchema = {
|
||||||
|
id: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'child1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'child1.1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const nodeId = 'child1.1';
|
||||||
|
|
||||||
|
const result = getNodeSchemaById(testSchema, nodeId);
|
||||||
|
|
||||||
|
// Define the expected output
|
||||||
|
const expectedOutput = {
|
||||||
|
id: 'child1.1',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assert that the result matches the expected output
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases for other scenarios
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('applyActivities', () => {
|
||||||
|
it('should apply ADD activity', () => {
|
||||||
|
// Create your test schema and activities
|
||||||
|
const testSchema = {
|
||||||
|
id: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'child1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'child1.1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const activities = [
|
||||||
|
{
|
||||||
|
type: ActivityType.ADDED,
|
||||||
|
payload: {
|
||||||
|
location: {
|
||||||
|
parent: {
|
||||||
|
nodeId: 'child1',
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
id: 'newChild',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = applyActivities(testSchema, activities);
|
||||||
|
|
||||||
|
// Define the expected output
|
||||||
|
const expectedOutput = {
|
||||||
|
id: 'root',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'child1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'newChild',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'child1.1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Assert that the result matches the expected output
|
||||||
|
expect(result).toEqual(expectedOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more test cases for other activity types and scenarios
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Schema Ut', () => {
|
describe('Schema Ut', () => {
|
||||||
it('props', () => {
|
it('props', () => {
|
||||||
const schema = {
|
const schema = {
|
||||||
|
|||||||
47
packages/utils/test/src/script.test.ts
Normal file
47
packages/utils/test/src/script.test.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import {
|
||||||
|
evaluate,
|
||||||
|
evaluateExpression,
|
||||||
|
newFunction,
|
||||||
|
} from '../../src/script';
|
||||||
|
|
||||||
|
describe('evaluate', () => {
|
||||||
|
test('should evaluate the given script', () => {
|
||||||
|
const script = 'console.log("Hello, world!");';
|
||||||
|
global.console = { log: jest.fn() };
|
||||||
|
|
||||||
|
evaluate(script);
|
||||||
|
|
||||||
|
expect(global.console.log).toHaveBeenCalledWith('Hello, world!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('evaluateExpression', () => {
|
||||||
|
test('should evaluate the given expression', () => {
|
||||||
|
const expr = 'return 1 + 2';
|
||||||
|
|
||||||
|
const result = evaluateExpression(expr);
|
||||||
|
|
||||||
|
expect(result).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('newFunction', () => {
|
||||||
|
test('should create a new function with the given arguments and code', () => {
|
||||||
|
const args = 'a, b';
|
||||||
|
const code = 'return a + b';
|
||||||
|
|
||||||
|
const result = newFunction(args, code);
|
||||||
|
|
||||||
|
expect(result).toBeInstanceOf(Function);
|
||||||
|
expect(result(1, 2)).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return null if an error occurs', () => {
|
||||||
|
const args = 'a, b';
|
||||||
|
const code = 'return a +;'; // Invalid code
|
||||||
|
|
||||||
|
const result = newFunction(args, code);
|
||||||
|
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
35
packages/utils/test/src/svg-icon.test.tsx
Normal file
35
packages/utils/test/src/svg-icon.test.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import { SVGIcon, IconProps } from '../../src/svg-icon';
|
||||||
|
|
||||||
|
describe('SVGIcon', () => {
|
||||||
|
it('should render SVG element with correct size', () => {
|
||||||
|
const iconProps: IconProps = {
|
||||||
|
size: 'small',
|
||||||
|
viewBox: '0 0 24 24',
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = render(<SVGIcon {...iconProps} />);
|
||||||
|
|
||||||
|
const svgElement = container.querySelector('svg');
|
||||||
|
|
||||||
|
expect(svgElement).toHaveAttribute('width', '12');
|
||||||
|
expect(svgElement).toHaveAttribute('height', '12');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render SVG element with custom size', () => {
|
||||||
|
const iconProps: IconProps = {
|
||||||
|
size: 24,
|
||||||
|
viewBox: '0 0 24 24',
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = render(<SVGIcon {...iconProps} />);
|
||||||
|
|
||||||
|
const svgElement = container.querySelector('svg');
|
||||||
|
|
||||||
|
expect(svgElement).toHaveAttribute('width', '24');
|
||||||
|
expect(svgElement).toHaveAttribute('height', '24');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add more tests for other scenarios if needed
|
||||||
|
});
|
||||||
58
packages/utils/test/src/transaction-manager.test.ts
Normal file
58
packages/utils/test/src/transaction-manager.test.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { transactionManager } from '../../src/transaction-manager';
|
||||||
|
import { IPublicEnumTransitionType } from '@alilc/lowcode-types';
|
||||||
|
|
||||||
|
const type = IPublicEnumTransitionType.REPAINT;
|
||||||
|
|
||||||
|
describe('TransactionManager', () => {
|
||||||
|
let fn1: jest.Mock;
|
||||||
|
let fn2: jest.Mock;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fn1 = jest.fn();
|
||||||
|
fn2 = jest.fn();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('executeTransaction should emit startTransaction and endTransaction events', () => {
|
||||||
|
const startTransactionSpy = jest.spyOn(transactionManager.emitter, 'emit');
|
||||||
|
const endTransactionSpy = jest.spyOn(transactionManager.emitter, 'emit');
|
||||||
|
|
||||||
|
transactionManager.executeTransaction(() => {
|
||||||
|
// Perform some action within the transaction
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(startTransactionSpy).toHaveBeenCalledWith(`[${type}]startTransaction`);
|
||||||
|
expect(endTransactionSpy).toHaveBeenCalledWith(`[${type}]endTransaction`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onStartTransaction should register the provided function for startTransaction event', () => {
|
||||||
|
const offSpy = jest.spyOn(transactionManager.emitter, 'off');
|
||||||
|
|
||||||
|
const offFunction = transactionManager.onStartTransaction(fn1);
|
||||||
|
|
||||||
|
expect(transactionManager.emitter.listenerCount(`[${type}]startTransaction`)).toBe(1);
|
||||||
|
expect(offSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
offFunction();
|
||||||
|
|
||||||
|
expect(transactionManager.emitter.listenerCount(`[${type}]startTransaction`)).toBe(0);
|
||||||
|
expect(offSpy).toHaveBeenCalledWith(`[${type}]startTransaction`, fn1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onEndTransaction should register the provided function for endTransaction event', () => {
|
||||||
|
const offSpy = jest.spyOn(transactionManager.emitter, 'off');
|
||||||
|
|
||||||
|
const offFunction = transactionManager.onEndTransaction(fn2);
|
||||||
|
|
||||||
|
expect(transactionManager.emitter.listenerCount(`[${type}]endTransaction`)).toBe(1);
|
||||||
|
expect(offSpy).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
offFunction();
|
||||||
|
|
||||||
|
expect(transactionManager.emitter.listenerCount(`[${type}]endTransaction`)).toBe(0);
|
||||||
|
expect(offSpy).toHaveBeenCalledWith(`[${type}]endTransaction`, fn2);
|
||||||
|
});
|
||||||
|
});
|
||||||
11
packages/utils/test/src/unique-id.test.ts
Normal file
11
packages/utils/test/src/unique-id.test.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { uniqueId } from '../../src/unique-id';
|
||||||
|
|
||||||
|
test('uniqueId should return a unique id with prefix', () => {
|
||||||
|
const id = uniqueId('test');
|
||||||
|
expect(id.startsWith('test')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('uniqueId should return a unique id without prefix', () => {
|
||||||
|
const id = uniqueId();
|
||||||
|
expect(id).not.toBeFalsy();
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user