Skip to content

Commit

Permalink
test(utils): add ut to package/utils
Browse files Browse the repository at this point in the history
  • Loading branch information
liujuping committed Nov 13, 2023
1 parent 6320867 commit 92c107a
Show file tree
Hide file tree
Showing 74 changed files with 2,620 additions and 439 deletions.
1 change: 1 addition & 0 deletions packages/utils/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const jestConfig = {
'!**/node_modules/**',
'!**/vendor/**',
],
setupFilesAfterEnv: ['./jest.setup.js'],
};

// 只对本仓库内的 pkg 做 mapping
Expand Down
1 change: 1 addition & 0 deletions packages/utils/jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom';
7 changes: 5 additions & 2 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"main": "lib/index.js",
"module": "es/index.js",
"scripts": {
"test": "build-scripts test --config build.test.json",
"test": "build-scripts test --config build.test.json --jest-coverage",
"build": "build-scripts build"
},
"dependencies": {
Expand All @@ -21,8 +21,11 @@
},
"devDependencies": {
"@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/react": "^16"
"@types/react": "^16",
"react-dom": "^16.14.0"
},
"publishConfig": {
"access": "public",
Expand Down
3 changes: 2 additions & 1 deletion packages/utils/src/check-types/is-action-content-object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IPublicTypeActionContentObject } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isActionContentObject(obj: any): obj is IPublicTypeActionContentObject {
return obj && typeof obj === 'object';
return isObject(obj);
}
6 changes: 4 additions & 2 deletions packages/utils/src/check-types/is-custom-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { isValidElement } from 'react';
import { isReactComponent } from '../is-react';
import { IPublicTypeCustomView } from '@alilc/lowcode-types';


export function isCustomView(obj: any): obj is IPublicTypeCustomView {
return obj && (isValidElement(obj) || isReactComponent(obj));
if (!obj) {
return false;
}
return isValidElement(obj) || isReactComponent(obj);
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-drag-any-object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicEnumDragObjectType } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

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;
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-drag-node-data-object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicEnumDragObjectType, IPublicTypeDragNodeDataObject } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataObject {
return obj && obj.type === IPublicEnumDragObjectType.NodeData;
if (!isObject(obj)) {
return false;
}
return obj.type === IPublicEnumDragObjectType.NodeData;
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-drag-node-object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicEnumDragObjectType, IPublicModelNode, IPublicTypeDragNodeObject } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

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;
}
7 changes: 5 additions & 2 deletions packages/utils/src/check-types/is-dynamic-setter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { isFunction } from '../is-function';
import { isReactClass } from '../is-react';
import { IPublicTypeDynamicSetter } from '@alilc/lowcode-types';


export function isDynamicSetter(obj: any): obj is IPublicTypeDynamicSetter {
return obj && typeof obj === 'function' && !isReactClass(obj);
if (!isFunction(obj)) {
return false;
}
return !isReactClass(obj);
}
3 changes: 3 additions & 0 deletions packages/utils/src/check-types/is-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isFunction(obj: any): obj is Function {
return obj && typeof obj === 'function';
}
11 changes: 6 additions & 5 deletions packages/utils/src/check-types/is-i18n-data.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

// type checks

import { IPublicTypeI18nData } from "@alilc/lowcode-types";
import { IPublicTypeI18nData } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isI18nData(obj: any): obj is IPublicTypeI18nData {
return obj && obj.type === 'i18n';
if (!isObject(obj)) {
return false;
}
return obj.type === 'i18n';
}
24 changes: 20 additions & 4 deletions packages/utils/src/check-types/is-isfunction.ts
Original file line number Diff line number Diff line change
@@ -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
*/
export function isInnerJsFunction(data: any) {
return data && data.type === 'JSExpression' && data.extType === 'function';
export function isInnerJsFunction(data: any): data is InnerJsFunction {
if (!isObject(data)) {
return false;
}
return data.type === 'JSExpression' && data.extType === 'function';
}

export function isJSFunction(data: any): boolean {
return typeof data === 'object' && data && data.type === 'JSFunction' || isInnerJsFunction(data);
export function isJSFunction(data: any): data is IPublicTypeJSFunction {
if (!isObject(data)) {
return false;
}
return data.type === 'JSFunction' || isInnerJsFunction(data);
}
9 changes: 7 additions & 2 deletions packages/utils/src/check-types/is-jsblock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { IPublicTypeJSBlock } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isJSBlock(data: any): boolean {
return data && data.type === 'JSBlock';
export function isJSBlock(data: any): data is IPublicTypeJSBlock {
if (!isObject(data)) {
return false;
}
return data.type === 'JSBlock';
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-jsexpression.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

/**
* 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。
Expand All @@ -11,5 +12,8 @@ import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
* @returns
*/
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';
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-jsslot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicTypeJSSlot } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isJSSlot(data: any): data is IPublicTypeJSSlot {
return data && data.type === 'JSSlot';
if (!isObject(data)) {
return false;
}
return data.type === 'JSSlot';
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicTypeLocationChildrenDetail, IPublicTypeLocationDetailType } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isLocationChildrenDetail(obj: any): obj is IPublicTypeLocationChildrenDetail {
return obj && obj.type === IPublicTypeLocationDetailType.Children;
if (!isObject(obj)) {
return false;
}
return obj.type === IPublicTypeLocationDetailType.Children;
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-location-data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicTypeLocationData } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

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;
}
15 changes: 12 additions & 3 deletions packages/utils/src/check-types/is-lowcode-project-schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from "@alilc/lowcode-types";
import { isComponentSchema } from "./is-component-schema";
import { IPublicTypeComponentSchema, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import { isComponentSchema } from './is-component-schema';
import { isObject } from '../is-object';

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]);
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-node-schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicTypeNodeSchema } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

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;
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-node.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { IPublicModelNode } from '@alilc/lowcode-types';
import { isObject } from '../is-object';

export function isNode<Node = IPublicModelNode>(node: any): node is Node {
return node && node.isNode;
if (!isObject(node)) {
return false;
}
return node.isNode;
}
3 changes: 3 additions & 0 deletions packages/utils/src/check-types/is-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isObject(obj: any): boolean {
return obj && typeof obj === 'object';
}
6 changes: 5 additions & 1 deletion packages/utils/src/check-types/is-procode-component-type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { IPublicTypeComponentMap, IPublicTypeProCodeComponent } from '@alilc/lowcode-types';

import { isObject } from '../is-object';

export function isProCodeComponentType(desc: IPublicTypeComponentMap): desc is IPublicTypeProCodeComponent {
if (!isObject(desc)) {
return false;
}

return 'package' in desc;
}
8 changes: 6 additions & 2 deletions packages/utils/src/check-types/is-project-schema.ts
Original file line number Diff line number Diff line change
@@ -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 {
return data && data.componentsTree;
if (!isObject(data)) {
return false;
}
return 'componentsTree' in data;
}
7 changes: 5 additions & 2 deletions packages/utils/src/check-types/is-setter-config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { IPublicTypeSetterConfig } from '@alilc/lowcode-types';
import { isCustomView } from './is-custom-view';

import { isObject } from '../is-object';

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);
}
9 changes: 7 additions & 2 deletions packages/utils/src/check-types/is-setting-field.ts
Original file line number Diff line number Diff line change
@@ -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 {
return obj && obj.isSettingField;
if (!isObject(obj)) {
return false;
}

return 'isSettingField' in obj && obj.isSettingField;
}
4 changes: 2 additions & 2 deletions packages/utils/src/clone-enumerable-property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const excludePropertyNames = [
'arguments',
];

export function cloneEnumerableProperty(target: any, origin: any) {
const compExtraPropertyNames = Object.keys(origin).filter(d => !excludePropertyNames.includes(d));
export function cloneEnumerableProperty(target: any, origin: any, excludes = excludePropertyNames) {
const compExtraPropertyNames = Object.keys(origin).filter(d => !excludes.includes(d));

compExtraPropertyNames.forEach((d: string) => {
(target as any)[d] = origin[d];
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/is-object.ts
Original file line number Diff line number Diff line change
@@ -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';
}

Expand Down
38 changes: 30 additions & 8 deletions packages/utils/src/is-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,49 @@ import { ComponentClass, Component, FunctionComponent, ComponentType, createElem
import { cloneEnumerableProperty } from './clone-enumerable-property';

const hasSymbol = typeof Symbol === 'function' && Symbol.for;
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_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
export const REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;

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 {
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 {
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 {
return obj?.$$typeof && obj.$$typeof === REACT_MEMO_TYPE;
export function isMemoType(obj: any): boolean {
if (!obj || !obj?.$$typeof) {
return false;
}
return obj.$$typeof === REACT_MEMO_TYPE;
}

export function isForwardOrMemoForward(obj: any): boolean {
return obj?.$$typeof && (
if (!obj || !obj?.$$typeof) {
return false;
}
return (
// React.forwardRef(..)
isForwardRefType(obj) ||
// React.memo(React.forwardRef(..))
Expand Down
Loading

0 comments on commit 92c107a

Please sign in to comment.