mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-14 04:43:14 +00:00
326 lines
9.8 KiB
TypeScript
326 lines
9.8 KiB
TypeScript
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', () => {
|
|
expect(shouldUseVariableSetter(false, true)).toBeFalsy();
|
|
expect(shouldUseVariableSetter(true, true)).toBeTruthy();
|
|
expect(shouldUseVariableSetter(true, false)).toBeTruthy();
|
|
expect(shouldUseVariableSetter(undefined, false)).toBeFalsy();
|
|
expect(shouldUseVariableSetter(undefined, true)).toBeTruthy();
|
|
}); |