,
+
,
container
);
diff --git a/scripts/__tests__/jest/jestSetting.js b/scripts/__tests__/jest/jestSetting.js
index 35a36c4c..2111a635 100644
--- a/scripts/__tests__/jest/jestSetting.js
+++ b/scripts/__tests__/jest/jestSetting.js
@@ -3,7 +3,7 @@ import { getLogUtils } from './testUtils';
//import failOnConsole from 'jest-fail-on-console';
//failOnConsole();
-const LogUtils =getLogUtils();
+const LogUtils = getLogUtils();
global.isDev = process.env.NODE_ENV === 'development';
global.container = null;
global.beforeEach(() => {
From a037cffdee472f2504ecf5f07434f80488b08016 Mon Sep 17 00:00:00 2001
From: * <8>
Date: Sat, 7 May 2022 15:58:50 +0800
Subject: [PATCH 3/3] Match-id-e30e763e7e3b191150a54092c38ae0a52b10a195
---
.../ComponentTest/ComponentError.test.js | 43 ++
.../ComponentTest/FragmentComponent.test.js | 474 ++++++++++++++++++
.../ComponentTest/LazyComponent.test.js | 187 +++++++
.../ComponentTest/PortalComponent.test.js | 205 ++++++++
.../ComponentTest/SuspenseComponent.test.js | 59 +++
scripts/__tests__/jest/testUtils.js | 72 ++-
6 files changed, 1023 insertions(+), 17 deletions(-)
create mode 100755 scripts/__tests__/ComponentTest/ComponentError.test.js
create mode 100755 scripts/__tests__/ComponentTest/FragmentComponent.test.js
create mode 100755 scripts/__tests__/ComponentTest/LazyComponent.test.js
create mode 100755 scripts/__tests__/ComponentTest/PortalComponent.test.js
create mode 100755 scripts/__tests__/ComponentTest/SuspenseComponent.test.js
mode change 100644 => 100755 scripts/__tests__/jest/testUtils.js
diff --git a/scripts/__tests__/ComponentTest/ComponentError.test.js b/scripts/__tests__/ComponentTest/ComponentError.test.js
new file mode 100755
index 00000000..7a833d04
--- /dev/null
+++ b/scripts/__tests__/ComponentTest/ComponentError.test.js
@@ -0,0 +1,43 @@
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import { getLogUtils } from '../jest/testUtils';
+
+describe('Component Error Test', () => {
+ const LogUtils = getLogUtils();
+ it('createElement不能为null或undefined', () => {
+ const NullElement = null;
+ const UndefinedElement = undefined;
+
+ jest.spyOn(console, 'error').mockImplementation();
+ expect(() => {
+ Horizon.render(
, document.createElement('div'));
+ }).toThrow('Component type is invalid, got: null');
+
+ expect(() => {
+ Horizon.render(
, document.createElement('div'));
+ }).toThrow('Component type is invalid, got: undefined');
+
+ const App = () => {
+ return
;
+ };
+
+ let AppChild = () => {
+ return (
+
+ );
+ };
+
+ expect(() => {
+ Horizon.render(
, document.createElement('div'));
+ }).toThrow('Component type is invalid, got: null');
+
+ AppChild = () => {
+ return (
+
+ );
+ };
+
+ expect(() => {
+ Horizon.render(
, document.createElement('div'));
+ }).toThrow('Component type is invalid, got: undefined');
+ });
+});
\ No newline at end of file
diff --git a/scripts/__tests__/ComponentTest/FragmentComponent.test.js b/scripts/__tests__/ComponentTest/FragmentComponent.test.js
new file mode 100755
index 00000000..eee9ceb4
--- /dev/null
+++ b/scripts/__tests__/ComponentTest/FragmentComponent.test.js
@@ -0,0 +1,474 @@
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import { Text } from '../jest/commonComponents';
+import { getLogUtils } from '../jest/testUtils';
+
+describe('Fragment', () => {
+ const LogUtils = getLogUtils();
+ const {
+ useEffect,
+ useRef,
+ act,
+ } = Horizon;
+ it('可以渲染空元素', () => {
+ const element = (
+
+ );
+
+ Horizon.render(element, container);
+
+ expect(container.textContent).toBe('');
+ });
+ it('可以渲染单个元素', () => {
+ const element = (
+
+
+
+ );
+
+ Horizon.render(element, container);
+
+ expect(LogUtils.getAndClear()).toEqual(['Fragment']);
+ expect(container.textContent).toBe('Fragment');
+ });
+
+ it('可以渲染混合元素', () => {
+ const element = (
+
+ Java and
+
+ );
+
+ Horizon.render(element, container);
+
+ expect(LogUtils.getAndClear()).toEqual(['JavaScript']);
+ expect(container.textContent).toBe('Java and JavaScript');
+ });
+
+ it('可以渲染集合元素', () => {
+ const App = [
,
];
+ const element = (
+ <>
+ {App}
+ >
+ );
+
+ Horizon.render(element, container);
+
+ expect(LogUtils.getAndClear()).toEqual(['Java', 'JavaScript']);
+ expect(container.textContent).toBe('JavaJavaScript');
+ });
+
+ it('元素被放进不同层级Fragment里时,状态不会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+ <>
+
+ >
+
+ ) : (
+ <>
+ <>
+
+ >
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 切换到不同层级Fragment时,副作用状态不会保留
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('元素被放进单层Fragment里,且在Fragment的顶部时,状态会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+
+ ) : (
+ <>
+
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态会保留
+ expect(LogUtils.getNotClear()).toEqual(['useEffect']);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual(['useEffect', 'useEffect']);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('元素被放进单层Fragment里,但不在Fragment的顶部时,状态不会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+
+ ) : (
+ <>
+
123
+
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态不会保留
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('1232');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('元素被放进多层Fragment里时,状态不会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+
+ ) : (
+ <>
+ <>
+ <>
+
+ >
+ >
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态不会保留
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('元素被切换放进同级Fragment里时,状态会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+ <>
+ <>
+ <>
+
+ >
+ >
+ >
+ ) : (
+ <>
+ <>
+ <>
+
+ >
+ >
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态会保留
+ expect(LogUtils.getNotClear()).toEqual(['useEffect']);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual(['useEffect', 'useEffect']);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('元素被切换放进同级Fragment,且在数组顶层时,状态会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+ <>
+ <>
+ <>
+
+ >
+ >
+ >
+ ) : (
+ <>
+ <>
+ <>
+ {[
]}
+ >
+ >
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态会保留
+ expect(LogUtils.getNotClear()).toEqual(['useEffect']);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual(['useEffect', 'useEffect']);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('数组里的顶层元素被切换放进单级Fragment时,状态会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+ [
]
+ ) : (
+ <>
+
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态会保留
+ expect(LogUtils.getNotClear()).toEqual(['useEffect']);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual(['useEffect', 'useEffect']);
+ expect(container.textContent).toBe('1');
+ });
+
+ it('Fragment里的顶层数组里的顶层元素被切换放进不同级Fragment时,状态不会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+ <>
+ [
]
+ >
+ ) : (
+ <>
+ <>
+
+ >
+ >
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态会保留
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('[1]');
+ });
+
+ it('Fragment的key值不同时,状态不会保留', () => {
+ const ChildApp = (props) => {
+ const flag = useRef(true);
+ useEffect(() => {
+ if (flag.current) {
+ flag.current = false;
+ } else {
+ LogUtils.log('useEffect');
+ }
+ });
+
+ return
{props.logo}
;
+ };
+
+ const App = (props) => {
+ return props.change ? (
+
+
+
+ ) : (
+
+
+
+ );
+ };
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ act(() => {
+ Horizon.render(
, container);
+ });
+ // 状态不会保留
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('2');
+
+ act(() => {
+ Horizon.render(
, container);
+ });
+ expect(LogUtils.getNotClear()).toEqual([]);
+ expect(container.textContent).toBe('1');
+ });
+});
diff --git a/scripts/__tests__/ComponentTest/LazyComponent.test.js b/scripts/__tests__/ComponentTest/LazyComponent.test.js
new file mode 100755
index 00000000..704dca45
--- /dev/null
+++ b/scripts/__tests__/ComponentTest/LazyComponent.test.js
@@ -0,0 +1,187 @@
+import * as Horizon from '@cloudsop/horizon/index.ts';
+import { Text } from '../jest/commonComponents';
+import { getLogUtils } from '../jest/testUtils';
+
+describe('LazyComponent Test', () => {
+ const LogUtils = getLogUtils();
+ const mockImport = jest.fn(async (component) => {
+ return { default: component };
+ });
+
+ it('Horizon.lazy()', async () => {
+ class LazyComponent extends Horizon.Component {
+ static defaultProps = { language: 'Java' };
+
+ render() {
+ const text = `${this.props.greeting}: ${this.props.language}`;
+ return
{text};
+ }
+ }
+
+ const Lazy = Horizon.lazy(() => mockImport(LazyComponent));
+
+ Horizon.render(
+
}>
+
+ ,
+ container
+ );
+
+ expect(LogUtils.getAndClear()).toEqual(['Loading...']);
+ expect(container.textContent).toBe('Loading...');
+ expect(container.querySelector('span')).toBe(null);
+
+ await Promise.resolve();
+ Horizon.render(
+
}>
+
+ ,
+ container
+ );
+
+ expect(LogUtils.getAndClear()).toEqual([]);
+ expect(container.querySelector('span').innerHTML).toBe('Goodbye: Java');
+ });
+
+ it('同步解析', async () => {
+ const LazyApp = Horizon.lazy(() => ({
+ then(cb) {
+ cb({ default: Text });
+ },
+ }));
+
+ Horizon.render(
+
Loading... }>
+