> = {};
+ const handler = ({
$subscribe,
$unsubscribe,
- $actions:$actions as StoreActions,
- $state:proxyObj,
- $computed: $computed as ComputedValues,
- $config:config,
- $queue: $queue as QueuedStoreActions,
- } as StoreHandler;
+ $a: $a as StoreActions,
+ $s: proxyObj,
+ $c: $c as ComputedValues,
+ $config: config,
+ $queue: $queue as QueuedStoreActions,
+ } as unknown) as StoreHandler;
function tryNextAction() {
if (!plannedActions.length) {
@@ -67,7 +120,9 @@ export function createStore,C extends
}
const nextAction = plannedActions.shift()!;
- const result = config.actions ? config.actions[nextAction.action].bind(self, proxyObj)(...nextAction.payload) : undefined;
+ const result = config.actions
+ ? config.actions[nextAction.action].bind(handler, proxyObj)(...nextAction.payload)
+ : undefined;
if (isPromise(result)) {
result.then(value => {
@@ -81,16 +136,16 @@ export function createStore,C extends
}
// 包装actions
- if(config.actions){
+ if (config.actions) {
Object.keys(config.actions).forEach(action => {
($queue as any)[action] = (...payload) => {
- return new Promise((resolve) => {
+ return new Promise(resolve => {
if (!proxyObj.$pending) {
proxyObj.$pending = true;
- const result = config.actions![action].bind(self, proxyObj)(...payload);
-
+ const result = config.actions![action].bind(handler, proxyObj)(...payload);
+
if (isPromise(result)) {
- result.then((value) => {
+ result.then(value => {
resolve(value);
tryNextAction();
});
@@ -102,40 +157,42 @@ export function createStore,C extends
plannedActions.push({
action,
payload,
- resolve
+ resolve,
});
}
});
};
-
- ($actions as any)[action] = function Wrapped(...payload) {
- return config.actions![action].bind(self, proxyObj)(...payload);
+
+ ($a as any)[action] = function Wrapped(...payload) {
+ return config.actions![action].bind(handler, proxyObj)(...payload);
};
- // direct store access
+ // direct store access
Object.defineProperty(handler, action, {
writable: false,
- value: $actions[action]
+ value: (...payload) => {
+ return config.actions![action].bind(handler, proxyObj)(...payload);
+ },
});
});
}
- if (config.computed) {
- Object.keys(config.computed).forEach((key) => {
- ($computed as any)[key] = config.computed![key].bind(handler, readonlyProxy(proxyObj));
+ if (config.computed) {
+ Object.keys(config.computed).forEach(key => {
+ ($c as any)[key] = config.computed![key].bind(handler, readonlyProxy(proxyObj));
- // direct store access
+ // direct store access
Object.defineProperty(handler, key, {
- get: $computed[key] as ()=>any
+ get: $c[key] as () => any,
});
});
}
// direct state access
- if(config.state){
+ if (config.state) {
Object.keys(config.state).forEach(key => {
Object.defineProperty(handler, key, {
- get: () => proxyObj[key]
+ get: () => proxyObj[key],
});
});
}
@@ -172,7 +229,7 @@ function hookStore() {
if (processingVNode.tag === FunctionComponent) {
// from FunctionComponent
- const vNodeRef = useRef(null);
+ const vNodeRef = (useRef(null) as unknown) as { current: VNode };
vNodeRef.current = processingVNode;
useEffect(() => {
@@ -195,13 +252,15 @@ function hookStore() {
function createStoreHook, C extends UserComputedValues>(
storeHandler: StoreHandler
): () => StoreHandler {
- return () => {
+ const storeHook = () => {
if (!storeHandler.$config.options?.suppressHooks) {
hookStore();
}
return storeHandler;
};
+
+ return storeHook;
}
export function useStore, C extends UserComputedValues>(
@@ -211,9 +270,9 @@ export function useStore, C extends U
if (storeObj && !storeObj.$config.options?.suppressHooks) hookStore();
- return storeObj as StoreHandler;
+ return storeObj as StoreHandler;
}
-export function clearStore(id:string):void {
+export function clearStore(id: string): void {
storeMap.delete(id);
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index ed675dbd..fe9836de 100644
--- a/package.json
+++ b/package.json
@@ -5,11 +5,12 @@
],
"scripts": {
"lint": "eslint . --ext .ts",
- "build": " rollup --config ./scripts/rollup/rollup.config.js",
- "build:watch": " rollup --watch --config ./scripts/rollup/rollup.config.js",
+ "build": "rollup --config ./scripts/rollup/rollup.config.js",
+ "build:watch": "rollup --watch --config ./scripts/rollup/rollup.config.js",
"build-3rdLib": "node ./scripts/gen3rdLib.js",
"build-3rdLib-dev": "npm run build & node ./scripts/gen3rdLib.js --dev",
"build-horizon3rdLib-dev": "npm run build & node ./scripts/gen3rdLib.js --dev --type horizon",
+ "build-types": "tsc -p ./libs/horizon/index.ts --emitDeclarationOnly --declaration --declarationDir ./build/horizon/@types --skipLibCheck",
"debug-test": "yarn test --debug",
"test": "jest --config=jest.config.js",
"watch-test": "yarn test --watch --dev"
@@ -29,6 +30,7 @@
"@babel/plugin-transform-destructuring": "7.16.7",
"@babel/plugin-transform-for-of": "7.16.7",
"@babel/plugin-transform-literals": "7.16.7",
+ "@babel/plugin-transform-object-assign": "7.16.7",
"@babel/plugin-transform-object-super": "7.16.7",
"@babel/plugin-transform-parameters": "7.16.7",
"@babel/plugin-transform-runtime": "7.16.7",
@@ -56,6 +58,7 @@
"jest-environment-jsdom-sixteen": "^1.0.3",
"prettier": "2.6.2",
"rollup": "^2.75.5",
+ "rollup-plugin-execute": "^1.1.1",
"rollup-plugin-terser": "^7.0.2",
"typescript": "4.2.3"
},
diff --git a/scripts/__tests__/DomTest/__snapshots__/DomTextarea.test.js.snap b/scripts/__tests__/DomTest/__snapshots__/DomTextarea.test.js.snap
deleted file mode 100644
index c2975807..00000000
--- a/scripts/__tests__/DomTest/__snapshots__/DomTextarea.test.js.snap
+++ /dev/null
@@ -1,5 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Dom Textarea should not incur unnecessary DOM mutations 1`] = ``;
-
-exports[`Dom Textarea should not incur unnecessary DOM mutations 2`] = ``;
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateArray.test.js b/scripts/__tests__/HorizonXText/StateManager/StateArray.test.js
deleted file mode 100644
index 826d6dda..00000000
--- a/scripts/__tests__/HorizonXText/StateManager/StateArray.test.js
+++ /dev/null
@@ -1,201 +0,0 @@
-import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
-
-describe('测试store中的Array', () => {
- const { unmountComponentAtNode } = Horizon;
- let container = null;
- beforeEach(() => {
- // 创建一个 DOM 元素作为渲染目标
- container = document.createElement('div');
- document.body.appendChild(container);
-
- const persons = [
- { name: 'p1', age: 1 },
- { name: 'p2', age: 2 },
- ];
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.push(person);
- },
- delOnePerson: state => {
- state.persons.pop();
- },
- clearPersons: state => {
- state.persons = null;
- },
- },
- });
- });
-
- afterEach(() => {
- // 退出时进行清理
- unmountComponentAtNode(container);
- container.remove();
- container = null;
-
- clearStore('user');
- });
-
- const newPerson = { name: 'p3', age: 3 };
-
- function Parent(props) {
- const userStore = useStore('user');
- const addOnePerson = function() {
- userStore.addOnePerson(newPerson);
- };
- const delOnePerson = function() {
- userStore.delOnePerson();
- };
- return (
-
-
-
-
{props.children}
-
- );
- }
-
- it('测试Array方法: push()、pop()', () => {
- function Child(props) {
- const userStore = useStore('user');
-
- return (
-
-
-
- );
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 2');
- // 在Array中增加一个对象
- Horizon.act(() => {
- triggerClickEvent(container, 'addBtn');
- });
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 3');
-
- // 在Array中删除一个对象
- Horizon.act(() => {
- triggerClickEvent(container, 'delBtn');
- });
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 2');
- });
-
- it('测试Array方法: entries()、push()、shift()、unshift、直接赋值', () => {
- let globalStore = null;
-
- function Child(props) {
- const userStore = useStore('user');
- globalStore = userStore;
-
- const nameList = [];
- const entries = userStore.$state.persons?.entries();
- if (entries) {
- for (const entry of entries) {
- nameList.push(entry[1].name);
- }
- }
-
- return (
-
-
-
- );
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
- // push
- globalStore.$state.persons.push(newPerson);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
-
- // shift
- globalStore.$state.persons.shift({ name: 'p0', age: 0 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3');
-
- // 赋值[2]
- globalStore.$state.persons[2] = { name: 'p4', age: 4 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p4');
-
- // 重新赋值[2]
- globalStore.$state.persons[2] = { name: 'p5', age: 5 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p5');
-
- // unshift
- globalStore.$state.persons.unshift({ name: 'p1', age: 1 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3 p5');
-
- // 重新赋值 null
- globalStore.$state.persons = null;
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
-
- // 重新赋值 [{ name: 'p1', age: 1 }]
- globalStore.$state.persons = [{ name: 'p1', age: 1 }];
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1');
- });
-
- it('测试Array方法: forEach()', () => {
- let globalStore = null;
-
- function Child(props) {
- const userStore = useStore('user');
- globalStore = userStore;
-
- const nameList = [];
- userStore.$state.persons?.forEach(per => {
- nameList.push(per.name);
- });
-
- return (
-
-
-
- );
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
- // push
- globalStore.$state.persons.push(newPerson);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
-
- // shift
- globalStore.$state.persons.shift({ name: 'p0', age: 0 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3');
-
- // 赋值[2]
- globalStore.$state.persons[2] = { name: 'p4', age: 4 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p4');
-
- // 重新赋值[2]
- globalStore.$state.persons[2] = { name: 'p5', age: 5 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p5');
-
- // unshift
- globalStore.$state.persons.unshift({ name: 'p1', age: 1 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3 p5');
-
- // 重新赋值 null
- globalStore.$state.persons = null;
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
-
- // 重新赋值 [{ name: 'p1', age: 1 }]
- globalStore.$state.persons = [{ name: 'p1', age: 1 }];
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1');
- });
-});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateArray.test.tsx b/scripts/__tests__/HorizonXText/StateManager/StateArray.test.tsx
new file mode 100644
index 00000000..fbe1de0b
--- /dev/null
+++ b/scripts/__tests__/HorizonXText/StateManager/StateArray.test.tsx
@@ -0,0 +1,208 @@
+//@ts-ignore
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
+import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: [
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ],
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.push(person);
+ },
+ delOnePerson: state => {
+ state.persons.pop();
+ },
+ clearPersons: state => {
+ state.persons = [];
+ },
+ reset: state => {
+ state.persons = [
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ];
+ },
+ },
+});
+
+describe('测试store中的Array', () => {
+ const { unmountComponentAtNode } = Horizon;
+ let container: HTMLElement | null = null;
+ beforeEach(() => {
+ // 创建一个 DOM 元素作为渲染目标
+ container = document.createElement('div');
+ document.body.appendChild(container);
+
+ useUserStore().reset();
+ });
+
+ afterEach(() => {
+ // 退出时进行清理
+ unmountComponentAtNode(container);
+ container?.remove();
+ container = null;
+ LogUtils.clear();
+
+ clearStore('user');
+ });
+
+ const newPerson = { name: 'p3', age: 3 };
+ function Parent(props) {
+ const userStore = useUserStore();
+ const addOnePerson = function() {
+ userStore.addOnePerson(newPerson);
+ };
+ const delOnePerson = function() {
+ userStore.delOnePerson();
+ };
+ return (
+
+
+
+
{props.children}
+
+ );
+ }
+
+ it('测试Array方法: push()、pop()', () => {
+ function Child(props) {
+ const userStore = useUserStore();
+
+ return (
+
+
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 2');
+ // 在Array中增加一个对象
+ Horizon.act(() => {
+ triggerClickEvent(container, 'addBtn');
+ });
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 3');
+
+ // 在Array中删除一个对象
+ Horizon.act(() => {
+ triggerClickEvent(container, 'delBtn');
+ });
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 2');
+ });
+
+ it('测试Array方法: entries()、push()、shift()、unshift、直接赋值', () => {
+ let globalStore = useUserStore();
+ function Child(props) {
+ const userStore = useUserStore();
+
+ const nameList: string[] = [];
+ const entries = userStore.$s.persons?.entries();
+ if (entries) {
+ for (const entry of entries) {
+ nameList.push(entry[1].name);
+ }
+ }
+
+ return (
+
+
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
+ // push
+ globalStore.$s.persons.push(newPerson);
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
+
+ // shift
+ //@ts-ignore TODO:why is this argument here?
+ globalStore.$s.persons.shift({ name: 'p0', age: 0 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3');
+
+ // 赋值[2]
+ globalStore.$s.persons[2] = { name: 'p4', age: 4 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p4');
+
+ // 重新赋值[2]
+ globalStore.$s.persons[2] = { name: 'p5', age: 5 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p5');
+
+ // unshift
+ globalStore.$s.persons.unshift({ name: 'p1', age: 1 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3 p5');
+
+ // 重新赋值 []
+ globalStore.$s.persons = [];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
+
+ // 重新赋值 [{ name: 'p1', age: 1 }]
+ globalStore.$s.persons = [{ name: 'p1', age: 1 }];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1');
+ });
+
+ it('测试Array方法: forEach()', () => {
+ let globalStore = useUserStore();
+ function Child(props) {
+ const userStore = useUserStore();
+
+ const nameList: string[] = [];
+ userStore.$s.persons?.forEach(per => {
+ nameList.push(per.name);
+ });
+
+ return (
+
+
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
+ // push
+ globalStore.$s.persons.push(newPerson);
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
+
+ // shift
+ //@ts-ignore TODO: why is this argument here?
+ globalStore.$s.persons.shift({ name: 'p0', age: 0 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3');
+
+ // 赋值[2]
+ globalStore.$s.persons[2] = { name: 'p4', age: 4 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p4');
+
+ // 重新赋值[2]
+ globalStore.$s.persons[2] = { name: 'p5', age: 5 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p5');
+
+ // unshift
+ globalStore.$s.persons.unshift({ name: 'p1', age: 1 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3 p5');
+
+ // 重新赋值 []
+ globalStore.$s.persons = [];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
+
+ // 重新赋值 [{ name: 'p1', age: 1 }]
+ globalStore.$s.persons = [{ name: 'p1', age: 1 }];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1');
+ });
+});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateMap.test.js b/scripts/__tests__/HorizonXText/StateManager/StateMap.test.tsx
similarity index 60%
rename from scripts/__tests__/HorizonXText/StateManager/StateMap.test.js
rename to scripts/__tests__/HorizonXText/StateManager/StateMap.test.tsx
index f7eaed9f..e5d1b141 100644
--- a/scripts/__tests__/HorizonXText/StateManager/StateMap.test.js
+++ b/scripts/__tests__/HorizonXText/StateManager/StateMap.test.tsx
@@ -1,45 +1,55 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: new Map([
+ ['p1', 1],
+ ['p2', 2],
+ ]),
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.set(person.name, person.age);
+ },
+ delOnePerson: (state, person) => {
+ state.persons.delete(person.name);
+ },
+ clearPersons: state => {
+ state.persons.clear();
+ },
+ reset: state => {
+ state.persons = new Map([
+ ['p1', 1],
+ ['p2', 2],
+ ]);
+ },
+ },
+});
describe('测试store中的Map', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container: HTMLElement | null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
document.body.appendChild(container);
- const persons = new Map([
- ['p1', 1],
- ['p2', 2],
- ]);
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.set(person.name, person.age);
- },
- delOnePerson: (state, person) => {
- state.persons.delete(person.name);
- },
- clearPersons: state => {
- state.persons.clear();
- },
- },
- });
+ useUserStore().reset();
});
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -47,7 +57,7 @@ describe('测试store中的Map', () => {
const newPerson = { name: 'p3', age: 3 };
function Parent(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
const addOnePerson = function() {
userStore.addOnePerson(newPerson);
};
@@ -76,43 +86,43 @@ describe('测试store中的Map', () => {
it('测试Map方法: set()、delete()、clear()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 3');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 0');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 0');
});
it('测试Map方法: keys()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- const keys = userStore.$state.persons.keys();
+ const nameList: string[] = [];
+ const keys = userStore.$s.persons.keys();
for (const key of keys) {
nameList.push(key);
}
@@ -126,32 +136,32 @@ describe('测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: values()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const ageList = [];
- const values = userStore.$state.persons.values();
+ const ageList: number[] = [];
+ const values = userStore.$s.persons.values();
for (const val of values) {
ageList.push(val);
}
@@ -165,32 +175,32 @@ describe('测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2 3');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2 3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: ');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: ');
});
it('测试Map方法: entries()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- const entries = userStore.$state.persons.entries();
+ const nameList: string[] = [];
+ const entries = userStore.$s.persons.entries();
for (const entry of entries) {
nameList.push(entry[0]);
}
@@ -204,32 +214,32 @@ describe('测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: forEach()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- userStore.$state.persons.forEach((val, key) => {
+ const nameList: string[] = [];
+ userStore.$s.persons.forEach((val, key) => {
nameList.push(key);
});
@@ -242,53 +252,53 @@ describe('测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: has()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: true');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: true');
});
it('测试Map方法: for of()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- for (const per of userStore.$state.persons) {
+ const nameList: string[] = [];
+ for (const per of userStore.$s.persons) {
nameList.push(per[0]);
}
@@ -301,23 +311,23 @@ describe('测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateMixType.test.js b/scripts/__tests__/HorizonXText/StateManager/StateMixType.test.tsx
similarity index 77%
rename from scripts/__tests__/HorizonXText/StateManager/StateMixType.test.js
rename to scripts/__tests__/HorizonXText/StateManager/StateMixType.test.tsx
index 870d7d26..bb38773d 100644
--- a/scripts/__tests__/HorizonXText/StateManager/StateMixType.test.js
+++ b/scripts/__tests__/HorizonXText/StateManager/StateMixType.test.tsx
@@ -1,10 +1,12 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
describe('测试store中的混合类型变化', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container: HTMLElement | null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
@@ -42,8 +44,9 @@ describe('测试store中的混合类型变化', () => {
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ (container as HTMLElement).remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -68,7 +71,7 @@ describe('测试store中的混合类型变化', () => {
function Child(props) {
const userStore = useStore('user');
- const days = userStore.$state.persons
+ const days = userStore.persons
.values()
.next()
.value.love.get('lanqiu').days;
@@ -82,11 +85,11 @@ describe('测试store中的混合类型变化', () => {
Horizon.render(, container);
- expect(container.querySelector('#dayList').innerHTML).toBe('love: 1 3 5');
+ expect(container?.querySelector('#dayList')?.innerHTML).toBe('love: 1 3 5');
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#dayList').innerHTML).toBe('love: 1 3 5 7');
+ expect(container?.querySelector('#dayList')?.innerHTML).toBe('love: 1 3 5 7');
});
it('属性是个class实例', () => {
@@ -103,7 +106,6 @@ describe('测试store中的混合类型变化', () => {
setName(name) {
this.name = name;
}
-
getName() {
return this.name;
}
@@ -111,7 +113,6 @@ describe('测试store中的混合类型变化', () => {
setAge(age) {
this.age = age;
}
-
getAge() {
return this.age;
}
@@ -119,7 +120,6 @@ describe('测试store中的混合类型变化', () => {
addLove(lv) {
this.loves.add(lv);
}
-
getLoves() {
return this.loves;
}
@@ -127,14 +127,19 @@ describe('测试store中的混合类型变化', () => {
let globalPerson;
let globalStore;
-
function Child(props) {
const userStore = useStore('user');
globalStore = userStore;
- const nameList = [];
- const valIterator = userStore.$state.persons.values();
- let per = valIterator.next();
+ const nameList: string[] = [];
+ const valIterator = userStore.persons.values();
+ let per = valIterator.next() as {
+ value: {
+ name: string;
+ getName: () => string;
+ };
+ done: boolean;
+ };
while (!per.done) {
nameList.push(per.value.name ?? per.value.getName());
globalPerson = per.value;
@@ -150,15 +155,15 @@ describe('测试store中的混合类型变化', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('p1 p2');
// 动态增加一个Person实例
- globalStore.$state.persons.add(new Person('ClassPerson', 5));
+ globalStore.$s.persons.add(new Person('ClassPerson', 5));
- expect(container.querySelector('#nameList').innerHTML).toBe('p1 p2 ClassPerson');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('p1 p2 ClassPerson');
globalPerson.setName('ClassPerson1');
- expect(container.querySelector('#nameList').innerHTML).toBe('p1 p2 ClassPerson1');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('p1 p2 ClassPerson1');
});
});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateSet.test.js b/scripts/__tests__/HorizonXText/StateManager/StateSet.test.tsx
similarity index 58%
rename from scripts/__tests__/HorizonXText/StateManager/StateSet.test.js
rename to scripts/__tests__/HorizonXText/StateManager/StateSet.test.tsx
index 4b6bdc7b..a1a245f0 100644
--- a/scripts/__tests__/HorizonXText/StateManager/StateSet.test.js
+++ b/scripts/__tests__/HorizonXText/StateManager/StateSet.test.tsx
@@ -1,53 +1,62 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: new Set([
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ]),
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.add(person);
+ },
+ delOnePerson: (state, person) => {
+ state.persons.delete(person);
+ },
+ clearPersons: state => {
+ state.persons.clear();
+ },
+ reset: state => {
+ state.persons = new Set([
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ]);
+ },
+ },
+});
describe('测试store中的Set', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container: HTMLElement | null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
document.body.appendChild(container);
- const persons = new Set([
- { name: 'p1', age: 1 },
- { name: 'p2', age: 2 },
- ]);
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.add(person);
- },
- delOnePerson: (state, person) => {
- state.persons.delete(person);
- },
- clearPersons: state => {
- state.persons.clear();
- },
- },
- });
+ useUserStore().reset();
});
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
const newPerson = { name: 'p3', age: 3 };
-
function Parent(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
const addOnePerson = function() {
userStore.addOnePerson(newPerson);
};
@@ -76,17 +85,17 @@ describe('测试store中的Set', () => {
it('测试Set方法: add()、delete()、clear()', () => {
function Child(props) {
- const userStore = useStore('user');
- const personArr = Array.from(userStore.$state.persons);
- const nameList = [];
- const keys = userStore.$state.persons.keys();
+ const userStore = useUserStore();
+ const personArr = Array.from(userStore.$s.persons);
+ const nameList: string[] = [];
+ const keys = userStore.$s.persons.keys();
for (const key of keys) {
nameList.push(key.name);
}
return (
-
+
);
@@ -94,35 +103,35 @@ describe('测试store中的Set', () => {
Horizon.render(, container);
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
- expect(container.querySelector('#lastAge').innerHTML).toBe('last person age: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#lastAge')?.innerHTML).toBe('last person age: 2');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 3');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 3');
// 在set中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
// clear set
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 0');
- expect(container.querySelector('#lastAge').innerHTML).toBe('last person age: 0');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 0');
+ expect(container?.querySelector('#lastAge')?.innerHTML).toBe('last person age: 0');
});
it('测试Set方法: keys()、values()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- const keys = userStore.$state.persons.keys();
- // const keys = userStore.$state.persons.values();
+ const nameList: string[] = [];
+ const keys = userStore.$s.persons.keys();
+ // const keys = userStore.$s.persons.values();
for (const key of keys) {
nameList.push(key.name);
}
@@ -136,32 +145,32 @@ describe('测试store中的Set', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在set中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear set
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Set方法: entries()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- const entries = userStore.$state.persons.entries();
+ const nameList: string[] = [];
+ const entries = userStore.$s.persons.entries();
for (const entry of entries) {
nameList.push(entry[0].name);
}
@@ -175,32 +184,32 @@ describe('测试store中的Set', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在set中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear set
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Set方法: forEach()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- userStore.$state.persons.forEach(per => {
+ const nameList: string[] = [];
+ userStore.$s.persons.forEach(per => {
nameList.push(per.name);
});
@@ -213,53 +222,53 @@ describe('测试store中的Set', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在set中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear set
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Set方法: has()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: true');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: true');
});
it('测试Set方法: for of()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
- const nameList = [];
- for (const per of userStore.$state.persons) {
+ const nameList: string[] = [];
+ for (const per of userStore.$s.persons) {
nameList.push(per.name);
}
@@ -272,23 +281,23 @@ describe('测试store中的Set', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在set中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在set中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear set
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.js b/scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.tsx
similarity index 61%
rename from scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.js
rename to scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.tsx
index 28d4ff98..2d5a441f 100644
--- a/scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.js
+++ b/scripts/__tests__/HorizonXText/StateManager/StateWeakMap.test.tsx
@@ -1,45 +1,55 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: new WeakMap([
+ [{ name: 'p1' }, 1],
+ [{ name: 'p2' }, 2],
+ ]),
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.set(person, 3);
+ },
+ delOnePerson: (state, person) => {
+ state.persons.delete(person);
+ },
+ clearPersons: state => {
+ state.persons = new WeakMap([]);
+ },
+ reset: state => {
+ state.persons = new WeakMap([
+ [{ name: 'p1' }, 1],
+ [{ name: 'p2' }, 2],
+ ]);
+ },
+ },
+});
describe('测试store中的WeakMap', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container: HTMLElement | null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
document.body.appendChild(container);
- const persons = new WeakMap([
- [{ name: 'p1' }, 1],
- [{ name: 'p2' }, 2],
- ]);
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.set(person, 3);
- },
- delOnePerson: (state, person) => {
- state.persons.delete(person);
- },
- clearPersons: state => {
- state.persons.clear();
- },
- },
- });
+ useUserStore().reset();
});
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -47,7 +57,7 @@ describe('测试store中的WeakMap', () => {
const newPerson = { name: 'p3' };
function Parent(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
const addOnePerson = function() {
userStore.addOnePerson(newPerson);
};
@@ -76,49 +86,49 @@ describe('测试store中的WeakMap', () => {
it('测试WeakMap方法: set()、delete()、has()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
// 在WeakMap中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: true');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: true');
// 在WeakMap中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
});
it('测试WeakMap方法: get()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: undefined');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: undefined');
// 在WeakMap中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 3');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 3');
});
});
diff --git a/scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.js b/scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.tsx
similarity index 59%
rename from scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.js
rename to scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.tsx
index 4c6a8fca..ecbc632d 100644
--- a/scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.js
+++ b/scripts/__tests__/HorizonXText/StateManager/StateWeakSet.test.tsx
@@ -1,53 +1,62 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: new WeakSet([
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ]),
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.add(person);
+ },
+ delOnePerson: (state, person) => {
+ state.persons.delete(person);
+ },
+ clearPersons: state => {
+ state.persons = new WeakSet([]);
+ },
+ reset: state => {
+ state.persons = new WeakSet([
+ { name: 'p1', age: 1 },
+ { name: 'p2', age: 2 },
+ ]);
+ },
+ },
+});
describe('测试store中的WeakSet', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container: HTMLElement | null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
document.body.appendChild(container);
- const persons = new WeakSet([
- { name: 'p1', age: 1 },
- { name: 'p2', age: 2 },
- ]);
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.add(person);
- },
- delOnePerson: (state, person) => {
- state.persons.delete(person);
- },
- clearPersons: state => {
- state.persons.clear();
- },
- },
- });
+ useUserStore().reset();
});
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
const newPerson = { name: 'p3', age: 3 };
-
function Parent(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
const addOnePerson = function() {
userStore.addOnePerson(newPerson);
};
@@ -69,28 +78,28 @@ describe('测试store中的WeakSet', () => {
it('测试WeakSet方法: add()、delete()、has()', () => {
function Child(props) {
- const userStore = useStore('user');
+ const userStore = useUserStore();
return (
-
+
);
}
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
// 在WeakSet中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: true');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: true');
// 在WeakSet中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
});
});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/async.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/async.test.tsx
similarity index 80%
rename from scripts/__tests__/HorizonXText/StoreFunctionality/async.test.js
rename to scripts/__tests__/HorizonXText/StoreFunctionality/async.test.tsx
index f45599d2..66c287e9 100644
--- a/scripts/__tests__/HorizonXText/StoreFunctionality/async.test.js
+++ b/scripts/__tests__/HorizonXText/StoreFunctionality/async.test.tsx
@@ -1,6 +1,8 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
import { createStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
const { unmountComponentAtNode } = Horizon;
@@ -13,7 +15,7 @@ function postpone(timer, func) {
}
describe('Asynchronous functions', () => {
- let container = null;
+ let container: HTMLElement | null = null;
const COUNTER_ID = 'counter';
const TOGGLE_ID = 'toggle';
@@ -33,7 +35,7 @@ describe('Asynchronous functions', () => {
return new Promise(resolve => {
setTimeout(() => {
state.counter++;
- resolve();
+ resolve(true);
}, 100);
});
},
@@ -53,11 +55,12 @@ describe('Asynchronous functions', () => {
afterEach(() => {
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
});
it('Should wait for async actions', async () => {
+ // @ts-ignore
jest.useRealTimers();
let globalStore;
@@ -84,14 +87,14 @@ describe('Asynchronous functions', () => {
Horizon.render(, container);
// initial state
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('false0');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('false0');
// slow toggle has nothing to wait for, it is resolved immediately
Horizon.act(() => {
triggerClickEvent(container, TOGGLE_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('true0');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('true0');
// counter increment is slow. slow toggle waits for result
Horizon.act(() => {
@@ -101,18 +104,18 @@ describe('Asynchronous functions', () => {
triggerClickEvent(container, TOGGLE_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('true0');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('true0');
// fast toggle does not wait for counter and it is resolved immediately
Horizon.act(() => {
triggerClickEvent(container, TOGGLE_FAST_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('false0');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('false0');
// at 150ms counter increment will be resolved and slow toggle immediately after
const t150 = postpone(150, () => {
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('true1');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('true1');
});
// before that, two more actions are added to queue - another counter and slow toggle
@@ -125,13 +128,14 @@ describe('Asynchronous functions', () => {
// at 250ms they should be already resolved
const t250 = postpone(250, () => {
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('false2');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('false2');
});
await Promise.all([t150, t250]);
});
it('call async action by then', async () => {
+ // @ts-ignore
jest.useFakeTimers();
let globalStore;
@@ -150,12 +154,13 @@ describe('Asynchronous functions', () => {
// call async action by then
globalStore.$queue.increment().then(() => {
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('false1');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('false1');
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('false0');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('false0');
// past 150 ms
+ // @ts-ignore
jest.advanceTimersByTime(150);
});
});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.js
deleted file mode 100644
index e42feeda..00000000
--- a/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as Horizon from '@cloudsop/horizon/index.ts';
-import { triggerClickEvent } from '../../jest/commonComponents';
-import { useLogStore } from './store';
-
-const { unmountComponentAtNode } = Horizon;
-
-describe('Basic store manipulation', () => {
- let container = null;
-
- const BUTTON_ID = 'btn';
- const RESULT_ID = 'result';
-
- beforeEach(() => {
- container = document.createElement('div');
- document.body.appendChild(container);
- });
-
- afterEach(() => {
- unmountComponentAtNode(container);
- container.remove();
- container = null;
- });
-
- it('Should use getters', () => {
- function App() {
- const logStore = useLogStore();
-
- return {logStore.length}
;
- }
-
- Horizon.render(, container);
-
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('1');
- });
-
- it('Should use actions and update components', () => {
- function App() {
- const logStore = useLogStore();
-
- return (
-
-
-
{logStore.length}
-
- );
- }
-
- Horizon.render(, container);
-
- Horizon.act(() => {
- triggerClickEvent(container, BUTTON_ID);
- });
-
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('2');
- });
-});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.tsx b/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.tsx
new file mode 100644
index 00000000..9d95c95f
--- /dev/null
+++ b/scripts/__tests__/HorizonXText/StoreFunctionality/basicAccess.test.tsx
@@ -0,0 +1,155 @@
+//@ts-ignore
+import Horizon from '@cloudsop/horizon/index.ts';
+import { triggerClickEvent } from '../../jest/commonComponents';
+import { useLogStore } from './store';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
+import { createStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+
+const { unmountComponentAtNode } = Horizon;
+
+describe('Basic store manipulation', () => {
+ let container: HTMLElement | null = null;
+
+ const BUTTON_ID = 'btn';
+ const RESULT_ID = 'result';
+
+ beforeEach(() => {
+ container = document.createElement('div');
+ document.body.appendChild(container);
+ });
+
+ afterEach(() => {
+ unmountComponentAtNode(container);
+ container?.remove();
+ container = null;
+ });
+
+ it('Should use getters', () => {
+ function App() {
+ const logStore = useLogStore();
+
+ return {logStore.length}
;
+ }
+
+ Horizon.render(, container);
+
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1');
+ });
+
+ it('Should use actions and update components', () => {
+ function App() {
+ const logStore = useLogStore();
+
+ return (
+
+
+
{logStore.length}
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ Horizon.act(() => {
+ triggerClickEvent(container, BUTTON_ID);
+ });
+
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2');
+ });
+
+ it('should call actions from own actions', () => {
+ const useIncrementStore = createStore({
+ id: 'incrementStore',
+ state: {
+ count: 2,
+ },
+ actions: {
+ increment: state => {
+ state.count++;
+ },
+ doublePlusOne: function(state) {
+ state.count = state.count * 2;
+ this.increment();
+ },
+ },
+ });
+
+ function App() {
+ const incrementStore = useIncrementStore();
+
+ return (
+
+
+
{incrementStore.count}
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ Horizon.act(() => {
+ triggerClickEvent(container, BUTTON_ID);
+ });
+
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('5');
+ });
+
+ it('should call computed from own actions', () => {
+ const useIncrementStore = createStore({
+ id: 'incrementStore',
+ state: {
+ count: 2,
+ },
+ actions: {
+ doublePlusOne: function(state) {
+ state.count = this.double + 1;
+ },
+ },
+ computed:{
+ double: (state) => {
+ return state.count*2
+ }
+ }
+ });
+
+ function App() {
+ const incrementStore = useIncrementStore();
+
+ return (
+
+
+
{incrementStore.count}
+
+ );
+ }
+
+ Horizon.render(, container);
+
+ Horizon.act(() => {
+ triggerClickEvent(container, BUTTON_ID);
+ });
+
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('5');
+ })
+});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.tsx
similarity index 64%
rename from scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.js
rename to scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.tsx
index 032234d0..94d149f0 100644
--- a/scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.js
+++ b/scripts/__tests__/HorizonXText/StoreFunctionality/dollarAccess.test.tsx
@@ -1,11 +1,13 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
import { triggerClickEvent } from '../../jest/commonComponents';
import { useLogStore } from './store';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
const { unmountComponentAtNode } = Horizon;
describe('Dollar store access', () => {
- let container = null;
+ let container: HTMLElement | null = null;
const BUTTON_ID = 'btn';
const RESULT_ID = 'result';
@@ -17,23 +19,23 @@ describe('Dollar store access', () => {
afterEach(() => {
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
});
- it('Should use $state and $computed', () => {
+ it('Should use $s and $c', () => {
function App() {
const logStore = useLogStore();
- return {logStore.$computed.length()}
;
+ return {logStore.$c.length()}
;
}
Horizon.render(, container);
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('1');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('1');
});
- it('Should use $actions and update components', () => {
+ it('Should use $a and update components', () => {
function App() {
const logStore = useLogStore();
@@ -42,12 +44,12 @@ describe('Dollar store access', () => {
- {logStore.$computed.length()}
+ {logStore.$c.length()}
);
}
@@ -58,6 +60,6 @@ describe('Dollar store access', () => {
triggerClickEvent(container, BUTTON_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('2');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('2');
});
});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.tsx
similarity index 71%
rename from scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.js
rename to scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.tsx
index 115164c0..ad6a4028 100644
--- a/scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.js
+++ b/scripts/__tests__/HorizonXText/StoreFunctionality/otherCases.test.tsx
@@ -1,11 +1,13 @@
+//@ts-ignore
import * as Horizon from '@cloudsop/horizon/index.ts';
import { createStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
import { triggerClickEvent } from '../../jest/commonComponents';
+import { describe, beforeEach, afterEach, it, expect } from '@jest/globals';
const { unmountComponentAtNode } = Horizon;
describe('Self referencing', () => {
- let container = null;
+ let container: HTMLElement | null = null;
const BUTTON_ID = 'btn';
const RESULT_ID = 'result';
@@ -15,7 +17,7 @@ describe('Self referencing', () => {
val: 2,
},
actions: {
- magic: function(state) {
+ increaseVal: function(state) {
state.val = state.val * 2 - 1;
},
},
@@ -34,7 +36,7 @@ describe('Self referencing', () => {
afterEach(() => {
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
});
@@ -45,8 +47,8 @@ describe('Self referencing', () => {
return (
{store.double}
-
);
@@ -54,29 +56,29 @@ describe('Self referencing', () => {
Horizon.render(, container);
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('4');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('4');
Horizon.act(() => {
triggerClickEvent(container, BUTTON_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('6');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('6');
Horizon.act(() => {
triggerClickEvent(container, BUTTON_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('10');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('10');
});
it('should access other stores', () => {
const useOtherStore = createStore({
state: {},
actions: {
- doMagic: () => useSelfRefStore().magic(),
+ doIncreaseVal: () => useSelfRefStore().increaseVal(),
},
computed: {
- magicConstant: () => useSelfRefStore().value,
+ selfRefStoreValue: () => useSelfRefStore().value,
},
});
@@ -85,9 +87,9 @@ describe('Self referencing', () => {
return (
-
{store.magicConstant}
-
- do magic
+ {store.selfRefStoreValue}
+
+ increase value in other store
);
@@ -95,13 +97,13 @@ describe('Self referencing', () => {
Horizon.render(, container);
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('5');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('5');
Horizon.act(() => {
triggerClickEvent(container, BUTTON_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('9');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('9');
});
it('should use parametric getters', () => {
@@ -138,11 +140,11 @@ describe('Self referencing', () => {
}
Horizon.render(, container);
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('abc');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('abc');
Horizon.act(() => {
triggerClickEvent(container, BUTTON_ID);
});
- expect(document.getElementById(RESULT_ID).innerHTML).toBe('def');
+ expect(document.getElementById(RESULT_ID)?.innerHTML).toBe('def');
});
});
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/reset.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/reset.js
similarity index 65%
rename from scripts/__tests__/HorizonXText/StoreFunctionality/reset.test.js
rename to scripts/__tests__/HorizonXText/StoreFunctionality/reset.js
index f0b349da..0cc4a4d3 100644
--- a/scripts/__tests__/HorizonXText/StoreFunctionality/reset.test.js
+++ b/scripts/__tests__/HorizonXText/StoreFunctionality/reset.js
@@ -1,14 +1,14 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
-import { createStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { triggerClickEvent } from '../../jest/commonComponents';
+import {createStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {triggerClickEvent} from '../../jest/commonComponents';
-const { unmountComponentAtNode } = Horizon;
+const {unmountComponentAtNode} = Horizon;
describe('Reset', () => {
it('RESET NOT IMPLEMENTED', async () => {
// console.log('reset functionality is not yet implemented')
expect(true).toBe(true);
- });
+ })
return;
let container = null;
@@ -19,14 +19,14 @@ describe('Reset', () => {
const useCounter = createStore({
state: {
- counter: 0,
+ counter: 0
},
actions: {
- increment: function(state) {
+ increment: function (state) {
state.counter++;
- },
+ }
},
- computed: {},
+ computed: {}
});
beforeEach(() => {
@@ -44,25 +44,17 @@ describe('Reset', () => {
function App() {
const store = useCounter();
- return (
-
-
{store.$state.counter}
-
- add
-
-
{
- store.$reset();
- }}
- id={RESET_ID}
- >
- reset
-
-
- );
+ return
+
{store.$s.counter}
+
add
+
{
+ store.$reset();
+ }} id={RESET_ID}>reset
+
+
}
- Horizon.render(, container);
+ Horizon.render(, container);
Horizon.act(() => {
triggerClickEvent(container, BUTTON_ID);
diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/store.js b/scripts/__tests__/HorizonXText/StoreFunctionality/store.ts
similarity index 100%
rename from scripts/__tests__/HorizonXText/StoreFunctionality/store.js
rename to scripts/__tests__/HorizonXText/StoreFunctionality/store.ts
diff --git a/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js b/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.tsx
similarity index 96%
rename from scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js
rename to scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.tsx
index 3683a596..e14c5d9e 100644
--- a/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js
+++ b/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.tsx
@@ -1,9 +1,12 @@
+//@ts-ignore
+import * as Horizon from '@cloudsop/horizon/index.ts';
import {
createStore,
applyMiddleware,
combineReducers,
bindActionCreators,
} from '../../../../libs/horizon/src/horizonx/adapters/redux';
+import { describe, it, expect } from '@jest/globals';
describe('Redux adapter', () => {
it('should use getState()', async () => {
@@ -142,7 +145,7 @@ describe('Redux adapter', () => {
it('Should apply enhancers', async () => {
let counter = 0;
- let middlewareCallList = [];
+ let middlewareCallList: string[] = [];
const callCounter = store => next => action => {
middlewareCallList.push('callCounter');
@@ -175,7 +178,7 @@ describe('Redux adapter', () => {
it('Should apply multiple enhancers', async () => {
let counter = 0;
let lastAction = '';
- let middlewareCallList = [];
+ let middlewareCallList: string[] = [];
const callCounter = store => next => action => {
middlewareCallList.push('callCounter');
diff --git a/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.js b/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.js
deleted file mode 100644
index 3785b92c..00000000
--- a/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { createStore, applyMiddleware, thunk } from '../../../../libs/horizon/src/horizonx/adapters/redux';
-
-describe('Redux thunk', () => {
- it('should use apply thunk middleware', async () => {
- const MAX_TODOS = 5;
-
- function addTodosIfAllowed(todoText) {
- return (dispatch, getState) => {
- const state = getState();
-
- if (state.todos.length < MAX_TODOS) {
- dispatch({ type: 'ADD_TODO', text: todoText });
- }
- };
- }
-
- const todoStore = createStore(
- (state = { todos: [] }, action) => {
- if (action.type === 'ADD_TODO') {
- return { todos: state.todos?.concat(action.text) };
- }
- return state;
- },
- null,
- applyMiddleware(thunk)
- );
-
- for (let i = 0; i < 10; i++) {
- todoStore.dispatch(addTodosIfAllowed('todo no.' + i));
- }
-
- expect(todoStore.getState().todos.length).toBe(5);
- });
-});
diff --git a/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.tsx b/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.tsx
new file mode 100644
index 00000000..39e4fc83
--- /dev/null
+++ b/scripts/__tests__/HorizonXText/adapters/ReduxAdapterThunk.test.tsx
@@ -0,0 +1,33 @@
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import { createStore, applyMiddleware, thunk } from '../../../../libs/horizon/src/horizonx/adapters/redux';
+import {describe, it, expect} from '@jest/globals';
+
+describe('Redux thunk', () => {
+ it('should use apply thunk middleware', async () => {
+ const MAX_TODOS = 5;
+
+ function addTodosIfAllowed(todoText) {
+ return (dispatch, getState) => {
+ const state = getState();
+
+ if (state.todos.length < MAX_TODOS) {
+ dispatch({type: 'ADD_TODO', text: todoText});
+ }
+ }
+ }
+
+ const todoStore = createStore((state = {todos: []}, action) => {
+ if (action.type === 'ADD_TODO') {
+ return {todos: state.todos?.concat(action.text)};
+ }
+ return state;
+ }, null, applyMiddleware(thunk));
+
+ for (let i = 0; i < 10; i++) {
+ //TODO: resolve thunk problems
+ (todoStore.dispatch as unknown as (delayedAction:(dispatch,getState)=>void)=>void)(addTodosIfAllowed('todo no.' + i));
+ }
+
+ expect(todoStore.getState().todos.length).toBe(5);
+ });
+});
diff --git a/scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.js b/scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.tsx
similarity index 50%
rename from scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.js
rename to scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.tsx
index 5977671a..4f6feec6 100644
--- a/scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.js
+++ b/scripts/__tests__/HorizonXText/adapters/ReduxReactAdapter.test.tsx
@@ -1,3 +1,4 @@
+//@ts-ignore
import horizon, * as Horizon from '@cloudsop/horizon/index.ts';
import {
batch,
@@ -8,17 +9,19 @@ import {
useSelector,
useStore,
createSelectorHook,
- createDispatchHook,
+ createDispatchHook
} from '../../../../libs/horizon/src/horizonx/adapters/redux';
-import { triggerClickEvent } from '../../jest/commonComponents';
+import {triggerClickEvent} from '../../jest/commonComponents';
+import {describe, it, beforeEach, afterEach, expect} from '@jest/globals';
+import { ReduxStoreHandler } from '@cloudsop/horizon/src/horizonx/types';
const BUTTON = 'button';
const BUTTON2 = 'button2';
const RESULT = 'result';
-const CONTAINER = 'container';
+const CONTAINER = 'container'
-function getE(id) {
- return document.getElementById(id);
+function getE(id):HTMLElement {
+ return document.getElementById(id)||document.body;
}
describe('Redux/React binding adapter', () => {
@@ -36,19 +39,17 @@ describe('Redux/React binding adapter', () => {
const reduxStore = createStore((state = 'state', action) => state);
const Child = () => {
- const store = useStore();
+ const store = useStore() as unknown as ReduxStoreHandler;
return {store.getState()}
;
};
const Wrapper = () => {
- return (
-
-
-
- );
+ return
+
+ ;
};
- Horizon.render(, getE(CONTAINER));
+ Horizon.render(, getE(CONTAINER));
expect(getE(RESULT).innerHTML).toBe('state');
});
@@ -60,30 +61,23 @@ describe('Redux/React binding adapter', () => {
});
const Child = () => {
- const store = useStore();
+ const store = useStore() as unknown as ReduxStoreHandler;
const dispatch = useDispatch();
- return (
-
-
{store.getState()}
-
{
- dispatch({ type: 'ADD' });
- }}
- >
-
- );
+ return
+
{store.getState()}
+
{
+ dispatch({type: 'ADD'});
+ }}>
+
;
};
const Wrapper = () => {
- return (
-
-
-
- );
+ return
+
+ ;
};
- Horizon.render(, getE(CONTAINER));
+ Horizon.render(, getE(CONTAINER));
expect(reduxStore.getState()).toBe(0);
@@ -101,32 +95,24 @@ describe('Redux/React binding adapter', () => {
});
const Child = () => {
- const count = useSelector(state => state);
+ const count = useSelector((state) => state);
const dispatch = useDispatch();
- return (
-
-
{count}
-
{
- dispatch({ type: 'ADD' });
- }}
- >
- click
-
-
- );
+ return
+
{count}
+
{
+ dispatch({type: 'ADD'});
+ }}>click
+
+
;
};
const Wrapper = () => {
- return (
-
-
-
- );
+ return
+
+ ;
};
- Horizon.render(, getE(CONTAINER));
+ Horizon.render(, getE(CONTAINER));
expect(getE(RESULT).innerHTML).toBe('0');
@@ -139,80 +125,58 @@ describe('Redux/React binding adapter', () => {
});
it('Should use connect', async () => {
- const reduxStore = createStore(
- (state, action) => {
- switch (action.type) {
- case 'INCREMENT':
- return {
- ...state,
- value: state.negative ? state.value - action.amount : state.value + action.amount,
- };
- case 'TOGGLE':
- return {
- ...state,
- negative: !state.negative,
- };
- default:
- return state;
- }
- },
- { negative: false, value: 0 }
- );
+ const reduxStore = createStore((state, action) => {
+ switch (action.type) {
+ case('INCREMENT'):
+ return {
+ ...state,
+ value: state.negative ? state.value - action.amount : state.value + action.amount
+ };
+ case('TOGGLE'):
+ return {
+ ...state,
+ negative: !state.negative
+ };
+ default:
+ return state;
+ }
+ }, {negative: false, value: 0});
- const Child = connect(
- (state, ownProps) => {
- // map state to props
- return { ...state, ...ownProps };
- },
- (dispatch, ownProps) => {
- // map dispatch to props
- return {
- increment: () => dispatch({ type: 'INCREMENT', amount: ownProps.amount }),
- };
- },
- (stateProps, dispatchProps, ownProps) => {
- //merge props
- return { stateProps, dispatchProps, ownProps };
- },
- {}
- )(props => {
+ const Child = connect((state, ownProps) => {
+ // map state to props
+ return {...state, ...ownProps};
+ }, (dispatch, ownProps) => {
+ // map dispatch to props
+ return {
+ // @ts-ignore
+ increment: () => dispatch({type: 'INCREMENT', amount: ownProps?.amount})
+ };
+ }, (stateProps, dispatchProps, ownProps) => {
+ //merge props
+ return {stateProps, dispatchProps, ownProps};
+ }, {})((props) => {
const n = props.stateProps.negative;
- return (
-
-
- {n ? '-' : '+'}
- {props.stateProps.value}
-
-
{
- props.dispatchProps.increment();
- }}
- >
- add {props.ownProps.amount}
-
-
- );
+ return
+
{n ? '-' : '+'}{props.stateProps.value}
+
{
+ props.dispatchProps.increment();
+ }}>add {props.ownProps.amount}
+
;
});
const Wrapper = () => {
+ //@ts-ignore
const [amount, setAmount] = Horizon.useState(5);
- return (
-
-
- {
- setAmount(3);
- }}
- >
- change amount
-
-
- );
+ return
+
+ {
+ setAmount(3);
+ }}>change amount
+
+ ;
};
- Horizon.render(, getE(CONTAINER));
+ Horizon.render(, getE(CONTAINER));
expect(getE(RESULT).innerHTML).toBe('+0');
@@ -231,7 +195,7 @@ describe('Redux/React binding adapter', () => {
});
expect(getE(RESULT).innerHTML).toBe('+8');
- });
+ })
it('Should batch dispatches', async () => {
const reduxStore = createStore((state = 0, action) => {
@@ -244,32 +208,22 @@ describe('Redux/React binding adapter', () => {
function Counter() {
renderCounter++;
- const value = useSelector(state => state);
+ const value = useSelector((state) => state);
const dispatch = useDispatch();
- return (
-
-
{value}
-
{
- batch(() => {
- for (let i = 0; i < 10; i++) {
- dispatch({ type: 'ADD' });
- }
- });
- }}
- >
-
- );
+ return
+
{value}
+
{
+ batch(() => {
+ for (let i = 0; i < 10; i++) {
+ dispatch({type: 'ADD'});
+ }
+ });
+ }}>
+
;
}
- Horizon.render(
-
-
- ,
- getE(CONTAINER)
- );
+ Horizon.render(, getE(CONTAINER));
expect(getE(RESULT).innerHTML).toBe('0');
expect(renderCounter).toBe(1);
@@ -300,49 +254,33 @@ describe('Redux/React binding adapter', () => {
const count = createSelectorHook(counterContext)();
const dispatch = createDispatchHook(counterContext)();
- return (
- {
- dispatch({ type: 'ADD' });
- }}
- >
- {count}
-
- );
+ return {
+ dispatch({type: 'ADD'});
+ }}>{count};
}
function Toggle() {
const check = createSelectorHook(toggleContext)();
const dispatch = createDispatchHook(toggleContext)();
- return (
- {
- dispatch({ type: 'TOGGLE' });
- }}
- >
- {check ? 'true' : 'false'}
-
- );
+ return {
+ dispatch({type: 'TOGGLE'});
+ }}>{check ? 'true' : 'false'};
}
function Wrapper() {
- return (
-
-
-
-
+ return
- );
+
+
+
+
;
}
- Horizon.render(, getE(CONTAINER));
+ Horizon.render(, getE(CONTAINER));
expect(getE(BUTTON).innerHTML).toBe('0');
expect(getE(BUTTON2).innerHTML).toBe('false');
diff --git a/scripts/__tests__/HorizonXText/class/ClassException.test.js b/scripts/__tests__/HorizonXText/class/ClassException.test.tsx
similarity index 54%
rename from scripts/__tests__/HorizonXText/class/ClassException.test.js
rename to scripts/__tests__/HorizonXText/class/ClassException.test.tsx
index 64cea5aa..7933d376 100644
--- a/scripts/__tests__/HorizonXText/class/ClassException.test.js
+++ b/scripts/__tests__/HorizonXText/class/ClassException.test.tsx
@@ -1,14 +1,17 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { Text } from '../../jest/commonComponents';
+import * as LogUtils from '../../jest/logUtils';
+import {clearStore, createStore, useStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {Text, triggerClickEvent} from '../../jest/commonComponents';
+import {getObserver} from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import {describe, beforeEach, afterEach, it, expect} from '@jest/globals';
describe('测试 Class VNode 清除时,对引用清除', () => {
- const { unmountComponentAtNode } = Horizon;
- let container = null;
+ const {unmountComponentAtNode} = Horizon;
+ let container:HTMLElement|null = null;
let globalState = {
name: 'bing dun dun',
isWin: true,
- isShow: true,
+ isShow: true
};
beforeEach(() => {
@@ -23,7 +26,7 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
setWin: (state, val) => {
state.isWin = val;
},
- hide: state => {
+ hide: (state) => {
state.isShow = false;
},
updateName: (state, val) => {
@@ -36,8 +39,9 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -47,23 +51,21 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
userStore = useStore('user');
render() {
+ if(!this.userStore) return ;
// Do not modify the store data in the render method. Otherwise, an infinite loop may occur.
this.userStore.updateName(this.userStore.name === 'bing dun dun' ? 'huo dun dun' : 'bing dun dun');
- return (
-
-
-
-
- );
+ return
+
+
+
;
}
}
expect(() => {
- Horizon.render(, container);
- }).toThrow(
- 'The number of updates exceeds the upper limit 50.\n' +
- ' A component maybe repeatedly invokes setState on componentWillUpdate or componentDidUpdate.'
- );
+ Horizon.render(, container);
+ }).toThrow('The number of updates exceeds the upper limit 50.\n' +
+ ' A component maybe repeatedly invokes setState on componentWillUpdate or componentDidUpdate.');
+
});
});
diff --git a/scripts/__tests__/HorizonXText/class/ClassStateArray.test.js b/scripts/__tests__/HorizonXText/class/ClassStateArray.test.js
deleted file mode 100644
index c61aed9c..00000000
--- a/scripts/__tests__/HorizonXText/class/ClassStateArray.test.js
+++ /dev/null
@@ -1,220 +0,0 @@
-import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
-
-describe('在Class组件中,测试store中的Array', () => {
- const { unmountComponentAtNode } = Horizon;
- let container = null;
- beforeEach(() => {
- // 创建一个 DOM 元素作为渲染目标
- container = document.createElement('div');
- document.body.appendChild(container);
-
- const persons = [
- { name: 'p1', age: 1 },
- { name: 'p2', age: 2 },
- ];
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.push(person);
- },
- delOnePerson: state => {
- state.persons.pop();
- },
- clearPersons: state => {
- state.persons = null;
- },
- },
- });
- });
-
- afterEach(() => {
- // 退出时进行清理
- unmountComponentAtNode(container);
- container.remove();
- container = null;
-
- clearStore('user');
- });
-
- const newPerson = { name: 'p3', age: 3 };
-
- class Parent extends Horizon.Component {
- userStore = useStore('user');
-
- addOnePerson = () => {
- this.userStore.addOnePerson(newPerson);
- };
-
- delOnePerson = () => {
- this.userStore.delOnePerson();
- };
-
- render() {
- return (
-
-
- add person
-
-
- delete person
-
-
{this.props.children}
-
- );
- }
- }
-
- it('测试Array方法: push()、pop()', () => {
- class Child extends Horizon.Component {
- userStore = useStore('user');
-
- render() {
- return (
-
-
-
- );
- }
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 2');
- // 在Array中增加一个对象
- Horizon.act(() => {
- triggerClickEvent(container, 'addBtn');
- });
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 3');
-
- // 在Array中删除一个对象
- Horizon.act(() => {
- triggerClickEvent(container, 'delBtn');
- });
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: 2');
- });
-
- it('测试Array方法: entries()、push()、shift()、unshift、直接赋值', () => {
- let globalStore = null;
-
- class Child extends Horizon.Component {
- userStore = useStore('user');
-
- constructor(props) {
- super(props);
- globalStore = this.userStore;
- }
-
- render() {
- const nameList = [];
- const entries = this.userStore.$state.persons?.entries();
- if (entries) {
- for (const entry of entries) {
- nameList.push(entry[1].name);
- }
- }
-
- return (
-
-
-
- );
- }
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
- // push
- globalStore.$state.persons.push(newPerson);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
-
- // shift
- globalStore.$state.persons.shift({ name: 'p0', age: 0 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3');
-
- // 赋值[2]
- globalStore.$state.persons[2] = { name: 'p4', age: 4 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p4');
-
- // 重新赋值[2]
- globalStore.$state.persons[2] = { name: 'p5', age: 5 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p5');
-
- // unshift
- globalStore.$state.persons.unshift({ name: 'p1', age: 1 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3 p5');
-
- // 重新赋值 null
- globalStore.$state.persons = null;
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
-
- // 重新赋值 [{ name: 'p1', age: 1 }]
- globalStore.$state.persons = [{ name: 'p1', age: 1 }];
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1');
- });
-
- it('测试Array方法: forEach()', () => {
- let globalStore = null;
-
- class Child extends Horizon.Component {
- userStore = useStore('user');
-
- constructor(props) {
- super(props);
- globalStore = this.userStore;
- }
-
- render() {
- const nameList = [];
- this.userStore.$state.persons?.forEach(per => {
- nameList.push(per.name);
- });
-
- return (
-
-
-
- );
- }
- }
-
- Horizon.render(, container);
-
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
- // push
- globalStore.$state.persons.push(newPerson);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
-
- // shift
- globalStore.$state.persons.shift({ name: 'p0', age: 0 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3');
-
- // 赋值[2]
- globalStore.$state.persons[2] = { name: 'p4', age: 4 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p4');
-
- // 重新赋值[2]
- globalStore.$state.persons[2] = { name: 'p5', age: 5 };
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p2 p3 p5');
-
- // unshift
- globalStore.$state.persons.unshift({ name: 'p1', age: 1 });
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3 p5');
-
- // 重新赋值 null
- globalStore.$state.persons = null;
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
-
- // 重新赋值 [{ name: 'p1', age: 1 }]
- globalStore.$state.persons = [{ name: 'p1', age: 1 }];
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1');
- });
-});
diff --git a/scripts/__tests__/HorizonXText/class/ClassStateArray.test.tsx b/scripts/__tests__/HorizonXText/class/ClassStateArray.test.tsx
new file mode 100644
index 00000000..2ca08ef5
--- /dev/null
+++ b/scripts/__tests__/HorizonXText/class/ClassStateArray.test.tsx
@@ -0,0 +1,231 @@
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import * as LogUtils from '../../jest/logUtils';
+import {clearStore, createStore, useStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {App, Text, triggerClickEvent} from '../../jest/commonComponents';
+import {describe, beforeEach, afterEach, it, expect} from '@jest/globals';
+
+type Person = {name:string,age:number};
+
+const persons:Person[] = [{ name: 'p1', age: 1 }, { name: 'p2', age: 2 }];
+let useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: persons,
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.push(person);
+ },
+ delOnePerson: (state) => {
+ state.persons.pop();
+ },
+ clearPersons: (state) => {
+ state.persons = [];
+ },
+ },
+});
+
+describe('在Class组件中,测试store中的Array', () => {
+ const { unmountComponentAtNode } = Horizon;
+ let container:HTMLElement|null = null;
+ beforeEach(() => {
+ // 创建一个 DOM 元素作为渲染目标
+ container = document.createElement('div');
+ document.body.appendChild(container);
+ });
+
+ afterEach(() => {
+ // 退出时进行清理
+ unmountComponentAtNode(container);
+ container?.remove();
+ container = null;
+ LogUtils.clear();
+
+ clearStore('user');
+ });
+
+ const newPerson = { name: 'p3', age: 3 };
+ class Parent extends Horizon.Component {
+ userStore = useUserStore();
+ props:{
+ children:any[]
+ };
+
+ constructor(props){
+ super(props);
+ this.props = props;
+ }
+
+ addOnePerson = () => {
+ this.userStore.addOnePerson(newPerson);
+ }
+
+ delOnePerson = () => {
+ this.userStore.delOnePerson();
+ }
+
+ render() {
+ return
+
+ add person
+
+
+ delete person
+
+
+ {this.props.children}
+
+
+ }
+ }
+
+ it('测试Array方法: push()、pop()', () => {
+ class Child extends Horizon.Component {
+ userStore = useUserStore();
+
+ render() {
+ return (
+
+
+
+ );
+ }
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 2');
+ // 在Array中增加一个对象
+ Horizon.act(() => {
+ triggerClickEvent(container, 'addBtn');
+ });
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 3');
+
+ // 在Array中删除一个对象
+ Horizon.act(() => {
+ triggerClickEvent(container, 'delBtn');
+ });
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: 2');
+ });
+
+ it('测试Array方法: entries()、push()、shift()、unshift、直接赋值', () => {
+ let globalStore = useUserStore();
+
+ class Child extends Horizon.Component {
+ userStore = useUserStore();
+
+ constructor(props) {
+ super(props);
+ globalStore = this.userStore;
+ }
+
+ render() {
+ const nameList:string[] = [];
+ const entries = this.userStore.$s.persons?.entries();
+ if (entries) {
+ for (const entry of entries) {
+ nameList.push(entry[1].name);
+ }
+ }
+
+ return (
+
+
+
+ );
+ }
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
+ // push
+ globalStore?.$s.persons.push(newPerson);
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
+
+ // shift
+ // @ts-ignore TODO:why has this function argument?
+ globalStore.$s.persons.shift({ name: 'p0', age: 0 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3');
+
+ // 赋值[2]
+ globalStore.$s.persons[2] = { name: 'p4', age: 4 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p4');
+
+ // 重新赋值[2]
+ globalStore.$s.persons[2] = { name: 'p5', age: 5 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p5');
+
+ // unshift
+ globalStore.$s.persons.unshift({ name: 'p1', age: 1 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3 p5');
+
+ // 重新赋值 []
+ globalStore.$s.persons = [];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
+
+ // 重新赋值 [{ name: 'p1', age: 1 }]
+ globalStore.$s.persons = [{ name: 'p1', age: 1 }];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1');
+ });
+
+ it('测试Array方法: forEach()', () => {
+ let globalStore = useUserStore();
+ globalStore.$s.persons.push({ name: 'p2', age: 2 });
+ class Child extends Horizon.Component {
+ userStore = useUserStore();
+
+ constructor(props) {
+ super(props);
+ globalStore = this.userStore;
+ }
+
+ render() {
+ const nameList:string[] = [];
+ this.userStore.$s.persons.forEach((per:Person) => {
+ nameList.push(per.name);
+ });
+
+ return (
+
+
+
+ );
+ }
+ }
+
+ Horizon.render(, container);
+
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
+ // push
+ globalStore.$s.persons.push(newPerson);
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
+
+ // shift
+ // @ts-ignore TODO:why has this function argument?
+ globalStore.$s.persons.shift({ name: 'p0', age: 0 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3');
+
+ // 赋值[2]
+ globalStore.$s.persons[2] = { name: 'p4', age: 4 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p4');
+
+ // 重新赋值[2]
+ globalStore.$s.persons[2] = { name: 'p5', age: 5 };
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p2 p3 p5');
+
+ // unshift
+ globalStore.$s.persons.unshift({ name: 'p1', age: 1 });
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3 p5');
+
+ // 重新赋值 []
+ globalStore.$s.persons = [];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
+
+ // 重新赋值 [{ name: 'p1', age: 1 }]
+ globalStore.$s.persons = [{ name: 'p1', age: 1 }];
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1');
+ });
+
+});
diff --git a/scripts/__tests__/HorizonXText/class/ClassStateMap.test.js b/scripts/__tests__/HorizonXText/class/ClassStateMap.test.tsx
similarity index 58%
rename from scripts/__tests__/HorizonXText/class/ClassStateMap.test.js
rename to scripts/__tests__/HorizonXText/class/ClassStateMap.test.tsx
index 071ad650..bb790d8a 100644
--- a/scripts/__tests__/HorizonXText/class/ClassStateMap.test.js
+++ b/scripts/__tests__/HorizonXText/class/ClassStateMap.test.tsx
@@ -1,45 +1,48 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { App, Text, triggerClickEvent } from '../../jest/commonComponents';
+import * as LogUtils from '../../jest/logUtils';
+import {clearStore, createStore, useStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {App, Text, triggerClickEvent} from '../../jest/commonComponents';
+import {describe, beforeEach, afterEach, it, expect} from '@jest/globals';
+
+const useUserStore = createStore({
+ id: 'user',
+ state: {
+ type: 'bing dun dun',
+ persons: new Map([['p1', 1], ['p2', 2]]),
+ },
+ actions: {
+ addOnePerson: (state, person) => {
+ state.persons.set(person.name, person.age);
+ },
+ delOnePerson: (state, person) => {
+ state.persons.delete(person.name);
+ },
+ clearPersons: (state) => {
+ state.persons.clear();
+ },
+ reset: (state)=>{
+ state.persons=new Map([['p1', 1], ['p2', 2]]);
+ }
+ },
+});
describe('在Class组件中,测试store中的Map', () => {
const { unmountComponentAtNode } = Horizon;
- let container = null;
+ let container:HTMLElement|null = null;
beforeEach(() => {
// 创建一个 DOM 元素作为渲染目标
container = document.createElement('div');
document.body.appendChild(container);
- const persons = new Map([
- ['p1', 1],
- ['p2', 2],
- ]);
-
- createStore({
- id: 'user',
- state: {
- type: 'bing dun dun',
- persons: persons,
- },
- actions: {
- addOnePerson: (state, person) => {
- state.persons.set(person.name, person.age);
- },
- delOnePerson: (state, person) => {
- state.persons.delete(person.name);
- },
- clearPersons: state => {
- state.persons.clear();
- },
- },
- });
+ useUserStore().reset();
});
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -47,17 +50,23 @@ describe('在Class组件中,测试store中的Map', () => {
const newPerson = { name: 'p3', age: 3 };
class Parent extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
+ props = {children:[]}
+
+ constructor(props){
+ super(props);
+ this.props = props;
+ }
addOnePerson = () => {
this.userStore.addOnePerson(newPerson);
- };
+ }
delOnePerson = () => {
this.userStore.delOnePerson(newPerson);
- };
+ }
clearPersons = () => {
this.userStore.clearPersons();
- };
+ }
render() {
return (
@@ -71,7 +80,9 @@ describe('在Class组件中,测试store中的Map', () => {
clear persons
- {this.props.children}
+
+ {this.props.children}
+
);
}
@@ -79,12 +90,12 @@ describe('在Class组件中,测试store中的Map', () => {
it('测试Map方法: set()、delete()、clear()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
return (
-
+
);
}
@@ -92,33 +103,33 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 3');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 2');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#size').innerHTML).toBe('persons number: 0');
+ expect(container?.querySelector('#size')?.innerHTML).toBe('persons number: 0');
});
it('测试Map方法: keys()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
- const nameList = [];
- const keys = this.userStore.$state.persons.keys();
+ const nameList:string[] = [];
+ const keys = this.userStore.$s.persons.keys();
for (const key of keys) {
nameList.push(key);
}
@@ -133,33 +144,33 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: values()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
- const ageList = [];
- const values = this.userStore.$state.persons.values();
+ const ageList:number[] = [];
+ const values = this.userStore.$s.persons.values();
for (const val of values) {
ageList.push(val);
}
@@ -174,33 +185,33 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2 3');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2 3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: 1 2');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: 1 2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#ageList').innerHTML).toBe('age list: ');
+ expect(container?.querySelector('#ageList')?.innerHTML).toBe('age list: ');
});
it('测试Map方法: entries()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
- const nameList = [];
- const entries = this.userStore.$state.persons.entries();
+ const nameList:string[] = [];
+ const entries = this.userStore.$s.persons.entries();
for (const entry of entries) {
nameList.push(entry[0]);
}
@@ -215,33 +226,33 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: forEach()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
- const nameList = [];
- this.userStore.$state.persons.forEach((val, key) => {
+ const nameList:string[] = [];
+ this.userStore.$s.persons.forEach((val, key) => {
nameList.push(key);
});
@@ -255,34 +266,34 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
it('测试Map方法: has()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
return (
-
+
);
}
@@ -290,21 +301,21 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: false');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: false');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#hasPerson').innerHTML).toBe('has new person: true');
+ expect(container?.querySelector('#hasPerson')?.innerHTML).toBe('has new person: true');
});
it('测试Map方法: for of()', () => {
class Child extends Horizon.Component {
- userStore = useStore('user');
+ userStore = useUserStore();
render() {
- const nameList = [];
- for (const per of this.userStore.$state.persons) {
+ const nameList:string[] = [];
+ for (const per of this.userStore.$s.persons) {
nameList.push(per[0]);
}
@@ -318,23 +329,23 @@ describe('在Class组件中,测试store中的Map', () => {
Horizon.render(, container);
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// 在Map中增加一个对象
Horizon.act(() => {
triggerClickEvent(container, 'addBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2 p3');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2 p3');
// 在Map中删除一个对象
Horizon.act(() => {
triggerClickEvent(container, 'delBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: p1 p2');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: p1 p2');
// clear Map
Horizon.act(() => {
triggerClickEvent(container, 'clearBtn');
});
- expect(container.querySelector('#nameList').innerHTML).toBe('name list: ');
+ expect(container?.querySelector('#nameList')?.innerHTML).toBe('name list: ');
});
});
diff --git a/scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.js b/scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.tsx
similarity index 62%
rename from scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.js
rename to scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.tsx
index a2226b1c..4fe4e719 100644
--- a/scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.js
+++ b/scripts/__tests__/HorizonXText/clear/ClassVNodeClear.test.tsx
@@ -1,15 +1,17 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { Text, triggerClickEvent } from '../../jest/commonComponents';
-import { getObserver } from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import * as LogUtils from '../../jest/logUtils';
+import {clearStore, createStore, useStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {Text, triggerClickEvent} from '../../jest/commonComponents';
+import {getObserver} from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import {describe, it, beforeEach, afterEach, expect} from '@jest/globals';
describe('测试 Class VNode 清除时,对引用清除', () => {
- const { unmountComponentAtNode } = Horizon;
- let container = null;
+ const {unmountComponentAtNode} = Horizon;
+ let container:HTMLElement|null = null;
let globalState = {
name: 'bing dun dun',
isWin: true,
- isShow: true,
+ isShow: true
};
beforeEach(() => {
@@ -24,7 +26,7 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
setWin: (state, val) => {
state.isWin = val;
},
- hide: state => {
+ hide: (state) => {
state.isShow = false;
},
updateName: (state, val) => {
@@ -37,8 +39,9 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -48,14 +51,12 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
userStore = useStore('user');
render() {
- return (
-
-
- toggle
-
- {this.userStore.isShow &&
}
-
- );
+ return
+
+ toggle
+
+ {this.userStore?.isShow &&
}
+
;
}
}
@@ -63,18 +64,16 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
userStore = useStore('user');
setWin = () => {
- this.userStore.setWin(!this.userStore.isWin);
- };
+ this.userStore?.setWin(!this.userStore?.isWin);
+ }
render() {
- return (
-
-
- toggle
-
- {this.userStore.isWin && }
-
- );
+ return
+
+ toggle
+
+ {this.userStore?.isWin && }
+
;
}
}
@@ -84,16 +83,14 @@ describe('测试 Class VNode 清除时,对引用清除', () => {
render() {
// this.userStore.updateName(this.userStore.name === 'bing dun dun' ? 'huo dun dun' : 'bing dun dun');
- return (
-
-
-
-
- );
+ return
+
+
+
;
}
}
- Horizon.render(, container);
+ Horizon.render(, container);
// Parent and Child hold the isWin key
expect(getObserver(globalState).keyVNodes.get('isWin').size).toBe(2);
diff --git a/scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.js b/scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.tsx
similarity index 59%
rename from scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.js
rename to scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.tsx
index ead0453a..76633b76 100644
--- a/scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.js
+++ b/scripts/__tests__/HorizonXText/clear/FunctionVNodeClear.test.tsx
@@ -1,15 +1,17 @@
import * as Horizon from '@cloudsop/horizon/index.ts';
-import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
-import { Text, triggerClickEvent } from '../../jest/commonComponents';
-import { getObserver } from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import * as LogUtils from '../../jest/logUtils';
+import {clearStore, createStore, useStore} from '../../../../libs/horizon/src/horizonx/store/StoreHandler';
+import {Text, triggerClickEvent} from '../../jest/commonComponents';
+import {getObserver} from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import {describe, it, beforeEach, afterEach, expect} from '@jest/globals';
describe('测试VNode清除时,对引用清除', () => {
- const { unmountComponentAtNode } = Horizon;
- let container = null;
+ const {unmountComponentAtNode} = Horizon;
+ let container:HTMLElement|null = null;
let globalState = {
name: 'bing dun dun',
isWin: true,
- isShow: true,
+ isShow: true
};
beforeEach(() => {
@@ -24,9 +26,9 @@ describe('测试VNode清除时,对引用清除', () => {
setWin: (state, val) => {
state.isWin = val;
},
- hide: state => {
+ hide: (state) => {
state.isShow = false;
- },
+ }
},
});
});
@@ -34,8 +36,9 @@ describe('测试VNode清除时,对引用清除', () => {
afterEach(() => {
// 退出时进行清理
unmountComponentAtNode(container);
- container.remove();
+ container?.remove();
container = null;
+ LogUtils.clear();
clearStore('user');
});
@@ -45,14 +48,12 @@ describe('测试VNode清除时,对引用清除', () => {
userStore = useStore('user');
render() {
- return (
-
-
- toggle
-
- {this.userStore.isShow &&
}
-
- );
+ return
+
+ toggle
+
+ {this.userStore?.isShow &&
}
+
;
}
}
@@ -60,18 +61,16 @@ describe('测试VNode清除时,对引用清除', () => {
userStore = useStore('user');
setWin = () => {
- this.userStore.setWin(!this.userStore.isWin);
- };
+ this.userStore?.setWin(!this.userStore.isWin);
+ }
render() {
- return (
-
-
- toggle
-
- {this.userStore.isWin && }
-
- );
+ return
+
+ toggle
+
+ {this.userStore?.isWin && }
+
;
}
}
@@ -79,16 +78,14 @@ describe('测试VNode清除时,对引用清除', () => {
userStore = useStore('user');
render() {
- return (
-
-
-
-
- );
+ return
+
+
+
;
}
}
- Horizon.render(, container);
+ Horizon.render(, container);
// Parent and Child hold the isWin key
expect(getObserver(globalState).keyVNodes.get('isWin').size).toBe(2);
diff --git a/scripts/__tests__/HorizonXText/edgeCases/proxy.test.js b/scripts/__tests__/HorizonXText/edgeCases/proxy.test.js
deleted file mode 100644
index a643f311..00000000
--- a/scripts/__tests__/HorizonXText/edgeCases/proxy.test.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createProxy } from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
-
-describe('Proxy', () => {
- const arr = [];
-
- it('Should not double wrap proxies', async () => {
- const proxy1 = createProxy(arr);
-
- const proxy2 = createProxy(proxy1);
-
- expect(proxy1 === proxy2).toBe(true);
- });
-
- it('Should re-use existing proxy of same object', async () => {
- const proxy1 = createProxy(arr);
-
- const proxy2 = createProxy(arr);
-
- expect(proxy1 === proxy2).toBe(true);
- });
-});
diff --git a/scripts/__tests__/HorizonXText/edgeCases/proxy.test.tsx b/scripts/__tests__/HorizonXText/edgeCases/proxy.test.tsx
new file mode 100644
index 00000000..d402e35c
--- /dev/null
+++ b/scripts/__tests__/HorizonXText/edgeCases/proxy.test.tsx
@@ -0,0 +1,48 @@
+import {createProxy} from '../../../../libs/horizon/src/horizonx/proxy/ProxyHandler';
+import {readonlyProxy} from '../../../../libs/horizon/src/horizonx/proxy/readonlyProxy';
+import {describe, beforeEach, afterEach, it, expect} from '@jest/globals';
+
+describe('Proxy', () => {
+ const arr = [];
+
+ it('Should not double wrap proxies', async () => {
+ const proxy1 = createProxy(arr);
+
+ const proxy2 = createProxy(proxy1);
+
+ expect(proxy1 === proxy2).toBe(true);
+ });
+
+ it('Should re-use existing proxy of same object', async () => {
+ const proxy1 = createProxy(arr);
+
+ const proxy2 = createProxy(arr);
+
+ expect(proxy1 === proxy2).toBe(true);
+ });
+
+ it('Readonly proxy should prevent changes', async () => {
+ const proxy1 = readonlyProxy([1]);
+
+ try{
+ proxy1.push('a');
+ expect(true).toBe(false);//we expect exception above
+ }catch(e){
+ //expected
+ }
+
+ try{
+ proxy1[0]=null;
+ expect(true).toBe(false);//we expect exception above
+ }catch(e){
+ //expected
+ }
+
+ try{
+ delete proxy1[0];
+ expect(true).toBe(false);//we expect exception above
+ }catch(e){
+ //expected
+ }
+ });
+});
diff --git a/scripts/__tests__/jest/logUtils.js b/scripts/__tests__/jest/logUtils.js
new file mode 100644
index 00000000..ecb32c98
--- /dev/null
+++ b/scripts/__tests__/jest/logUtils.js
@@ -0,0 +1,26 @@
+let dataArray = null;
+
+const log = value => {
+ if (dataArray === null) {
+ dataArray = [value];
+ } else {
+ dataArray.push(value);
+ }
+};
+
+const getAndClear = () => {
+ if (dataArray === null) {
+ return [];
+ }
+ const values = dataArray;
+ dataArray = null;
+ return values;
+};
+
+const clear = () => {
+ dataArray = dataArray ? null : dataArray;
+};
+
+exports.clear = clear;
+exports.log = log;
+exports.getAndClear = getAndClear;
diff --git a/scripts/rollup/rollup.config.js b/scripts/rollup/rollup.config.js
index 290490e5..05c7bf81 100644
--- a/scripts/rollup/rollup.config.js
+++ b/scripts/rollup/rollup.config.js
@@ -4,6 +4,7 @@ import path from 'path';
import fs from 'fs';
import replace from '@rollup/plugin-replace';
import copy from './copy-plugin';
+import execute from 'rollup-plugin-execute';
import { terser } from 'rollup-plugin-terser';
import { version as horizonVersion } from '@cloudsop/horizon/package.json';
@@ -60,6 +61,7 @@ function genConfig(mode) {
},
preventAssignment: true,
}),
+ execute('npm run build-types'),
mode === 'production' && terser(),
copy([
{