From f22a6d12855dc8c20ef5f52f74365b2618d22ab4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AD=99=E4=B8=80=E5=86=B0?=
<14512567+sunyibing@user.noreply.gitee.com>
Date: Fri, 16 Aug 2024 11:23:07 +0800
Subject: [PATCH] test: add watch and jsx test cases
---
packages/inula-next/test/jsxSlice.test.tsx | 161 ++++++++++
packages/inula-next/test/watch.test.tsx | 325 +++++++++++++++++++++
2 files changed, 486 insertions(+)
create mode 100644 packages/inula-next/test/watch.test.tsx
diff --git a/packages/inula-next/test/jsxSlice.test.tsx b/packages/inula-next/test/jsxSlice.test.tsx
index bdb70434..c5a6caee 100644
--- a/packages/inula-next/test/jsxSlice.test.tsx
+++ b/packages/inula-next/test/jsxSlice.test.tsx
@@ -111,6 +111,167 @@ describe('JSX Element Usage in Various Contexts', () => {
render(App, container);
expect(container.innerHTML).toBe('
Dark Theme
');
});
+ it('should render string literals', ({ container }) => {
+ function App() {
+ return {'Hello, World!'}
;
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Hello, World!
');
+ });
+
+ it('should render numbers', ({ container }) => {
+ function App() {
+ return {42}
;
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('42
');
+ });
+
+ it.fails('should render booleans (as empty string)', ({ container }) => {
+ function App() {
+ return {true}
;
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('');
+ });
+
+ it.fails('should render null and undefined (as empty string)', ({ container }) => {
+ function App() {
+ return (
+
+ {null}
+ {undefined}
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('');
+ });
+
+ it.fails('should render arrays of elements', ({ container }) => {
+ function App() {
+ return {[One, Two]}
;
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('OneTwo
');
+ });
+
+ it('should render function components', ({ container }) => {
+ function Child() {
+ return Child Component;
+ }
+ function App() {
+ return (
+
+
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Child Component
');
+ });
+
+ it('should render fragments', ({ container }) => {
+ function App() {
+ return (
+ <>
+ First
+ Second
+ >
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('FirstSecond');
+ });
+
+ it('should render elements with props', ({ container }) => {
+ function App() {
+ return (
+
+ Content
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Content
');
+ });
+
+ it('should render elements with children prop', ({ container }) => {
+ function Wrapper({ children }: { children: React.ReactNode }) {
+ return {children}
;
+ }
+ function App() {
+ return (
+
+ Child Content
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Child Content
');
+ });
+
+ it('should correctly render nested HTML elements', ({ container }) => {
+ function App() {
+ return (
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('');
+ });
+
+ it.fails('should correctly render a mix of HTML elements and text', ({ container }) => {
+ function App() {
+ return (
+
+ Text before Element Text after
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Text before Element Text after
');
+ });
+
+ it.fails('should correctly render text on both sides of an element', ({ container }) => {
+ function App() {
+ return (
+
+ Left side text Bold text Right side text
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe('Left side text Bold text Right side text
');
+ });
+
+ it.fails(
+ 'should correctly render a mix of curly braces, text, and elements in different orders',
+ ({ container }) => {
+ function App() {
+ const name = 'World';
+ return (
+
+ {/* Curly braces, then text, then element */}
+ {name}, Hello !
+ {/* Element, then curly braces, then text */}
+ Greetings {name} to you
+ {/* Text, then element, then curly braces */}
+ Welcome dear {name}
+
+ );
+ }
+ render(App, container);
+ expect(container.innerHTML).toBe(
+ 'World, Hello !Greetings World to you' +
+ 'Welcome dear World
'
+ );
+ }
+ );
});
describe('update', () => {
it('should support variable assignment of JSX elements and updates', ({ container }) => {
diff --git a/packages/inula-next/test/watch.test.tsx b/packages/inula-next/test/watch.test.tsx
new file mode 100644
index 00000000..0a87a38e
--- /dev/null
+++ b/packages/inula-next/test/watch.test.tsx
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2024 Huawei Technologies Co.,Ltd.
+ *
+ * openInula is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ *
+ * http://license.coscl.org.cn/MulanPSL2
+ *
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+import { describe, expect, vi } from 'vitest';
+import { domTest as it } from './utils';
+import { render, View } from '../src';
+
+vi.mock('../src/scheduler', async () => {
+ return {
+ schedule: (task: () => void) => {
+ task();
+ },
+ };
+});
+
+describe('Watch', () => {
+ it('Should correctly watch variable', ({ container }) => {
+ let increment: () => void;
+ function TrafficLight() {
+ let lightIndex = 0;
+ let index = 0;
+ increment = () => {
+ lightIndex = lightIndex + 1;
+ };
+
+ watch(() => {
+ index = lightIndex;
+ });
+ return {index}
;
+ }
+ render(TrafficLight, container);
+ expect(container.innerHTML).toBe('0
');
+ increment();
+ expect(container.innerHTML).toBe('1
');
+ });
+ it('Should correctly watch and update based on string state changes', ({ container }) => {
+ let updateState: (newState: string) => void;
+ function StringComponent() {
+ let state = 'initial';
+ let watchedState = '';
+ updateState = (newState: string) => {
+ state = newState;
+ };
+ watch(() => {
+ watchedState = state;
+ });
+ return {watchedState}
;
+ }
+ render(StringComponent, container);
+ expect(container.innerHTML).toBe('initial
');
+ updateState('updated');
+ expect(container.innerHTML).toBe('updated
');
+ });
+
+ it('Should correctly watch and update based on number state changes', ({ container }) => {
+ let updateState: (newState: number) => void;
+ function NumberComponent() {
+ let state = 0;
+ let watchedState = 0;
+ updateState = (newState: number) => {
+ state = newState;
+ };
+ watch(() => {
+ watchedState = state;
+ });
+ return {watchedState}
;
+ }
+ render(NumberComponent, container);
+ expect(container.innerHTML).toBe('0
');
+ updateState(42);
+ expect(container.innerHTML).toBe('42
');
+ });
+
+ it('Should correctly watch and update based on boolean state changes', ({ container }) => {
+ let updateState: (newState: boolean) => void;
+ function BooleanComponent() {
+ let state = false;
+ let watchedState = false;
+ updateState = (newState: boolean) => {
+ state = newState;
+ };
+ watch(() => {
+ watchedState = state;
+ });
+ return {watchedState.toString()}
;
+ }
+ render(BooleanComponent, container);
+ expect(container.innerHTML).toBe('false
');
+ updateState(true);
+ expect(container.innerHTML).toBe('true
');
+ });
+
+ it('Should correctly watch and update based on array state changes', ({ container }) => {
+ let updateState: (newState: number[]) => void;
+ function ArrayComponent() {
+ let state: number[] = [];
+ let watchedState: number[] = [];
+ updateState = (newState: number[]) => {
+ state = newState;
+ };
+ watch(() => {
+ watchedState = [...state];
+ });
+ return {watchedState.join(',')}
;
+ }
+ render(ArrayComponent, container);
+ expect(container.innerHTML).toBe('');
+ updateState([1, 2, 3]);
+ expect(container.innerHTML).toBe('1,2,3
');
+ });
+
+ it('Should correctly watch and update based on object state changes', ({ container }) => {
+ let updateState: (newState: { [key: string]: any }) => void;
+ function ObjectComponent() {
+ let state = {};
+ let watchedState = {};
+ updateState = (newState: { [key: string]: any }) => {
+ state = newState;
+ };
+ watch(() => {
+ watchedState = { ...state };
+ });
+ return {JSON.stringify(watchedState)}
;
+ }
+ render(ObjectComponent, container);
+ expect(container.innerHTML).toBe('{}
');
+ updateState({ key: 'value' });
+ expect(container.innerHTML).toBe('{"key":"value"}
');
+ });
+
+ it('Should correctly watch conditional expressions', ({ container }) => {
+ let updateX: (value: number) => void;
+ function ConditionalComponent() {
+ let x = 5;
+ let result = '';
+ updateX = (value: number) => {
+ x = value;
+ };
+ watch(() => {
+ result = x > 10 ? 'Greater than 10' : 'Less than or equal to 10';
+ });
+ return {result}
;
+ }
+ render(ConditionalComponent, container);
+ expect(container.innerHTML).toBe('Less than or equal to 10
');
+ updateX(15);
+ expect(container.innerHTML).toBe('Greater than 10
');
+ });
+
+ it('Should correctly watch template strings', ({ container }) => {
+ let updateName: (value: string) => void;
+ let updateAge: (value: number) => void;
+ function TemplateStringComponent() {
+ let name = 'John';
+ let age = 30;
+ let message = '';
+ updateName = (value: string) => {
+ name = value;
+ };
+ updateAge = (value: number) => {
+ age = value;
+ };
+ watch(() => {
+ message = `${name} is ${age} years old`;
+ });
+ return {message}
;
+ }
+ render(TemplateStringComponent, container);
+ expect(container.innerHTML).toBe('John is 30 years old
');
+ updateName('Jane');
+ updateAge(25);
+ expect(container.innerHTML).toBe('Jane is 25 years old
');
+ });
+
+ it('Should correctly watch arithmetic operations', ({ container }) => {
+ let updateX: (value: number) => void;
+ let updateY: (value: number) => void;
+ function ArithmeticComponent() {
+ let x = 5;
+ let y = 3;
+ let result = 0;
+ updateX = (value: number) => {
+ x = value;
+ };
+ updateY = (value: number) => {
+ y = value;
+ };
+ watch(() => {
+ result = x + y * 2 - x / y;
+ });
+ return {result}
;
+ }
+ render(ArithmeticComponent, container);
+ expect(container.innerHTML).toBe('9.333333333333334
');
+ updateX(10);
+ updateY(5);
+ expect(container.innerHTML).toBe('18
');
+ });
+
+ it('Should correctly watch property access and indexing', ({ container }) => {
+ let updateObj: (value: { [key: string]: any }) => void;
+ let updateArr: (value: number[]) => void;
+ function AccessComponent() {
+ let obj = { a: 1, b: 2 };
+ let arr = [1, 2, 3];
+ let result = 0;
+ updateObj = (value: { [key: string]: any }) => {
+ obj = value;
+ };
+ updateArr = (value: number[]) => {
+ arr = value;
+ };
+ watch(() => {
+ result = obj.a + arr[1];
+ });
+ return {result}
;
+ }
+ render(AccessComponent, container);
+ expect(container.innerHTML).toBe('3
');
+ updateObj({ a: 5, b: 6 });
+ updateArr([0, 10, 20]);
+ expect(container.innerHTML).toBe('15
');
+ });
+
+ it('Should correctly watch function calls', ({ container }) => {
+ let updateX: (value: number) => void;
+ function FunctionCallComponent() {
+ let x = 5;
+ let result = 0;
+ const square = (n: number) => n * n;
+ updateX = (value: number) => {
+ x = value;
+ };
+ watch(() => {
+ result = square(x);
+ });
+ return {result}
;
+ }
+ render(FunctionCallComponent, container);
+ expect(container.innerHTML).toBe('25
');
+ updateX(10);
+ expect(container.innerHTML).toBe('100
');
+ });
+
+ it('Should correctly watch various number operations', ({ container }) => {
+ let updateX: (value: number) => void;
+ function NumberOpsComponent() {
+ let x = 16;
+ let result = '';
+ updateX = (value: number) => {
+ x = value;
+ };
+ watch(() => {
+ result = `sqrt: ${Math.sqrt(x)}, floor: ${Math.floor(x / 3)}, pow: ${Math.pow(x, 2)}`;
+ });
+ return {result}
;
+ }
+ render(NumberOpsComponent, container);
+ expect(container.innerHTML).toBe('sqrt: 4, floor: 5, pow: 256
');
+ updateX(25);
+ expect(container.innerHTML).toBe('sqrt: 5, floor: 8, pow: 625
');
+ });
+
+ it('Should correctly watch map operations', ({ container }) => {
+ let updateArr: (value: number[]) => void;
+ function MapComponent() {
+ let arr = [1, 2, 3, 4, 5];
+ let result: number[] = [];
+ updateArr = (value: number[]) => {
+ arr = value;
+ };
+ watch(() => {
+ result = arr.map(x => x * 2);
+ });
+ return {result.join(', ')}
;
+ }
+ render(MapComponent, container);
+ expect(container.innerHTML).toBe('2, 4, 6, 8, 10
');
+ updateArr([10, 20, 30]);
+ expect(container.innerHTML).toBe('20, 40, 60
');
+ });
+
+ it('Should correctly watch multiple variables', ({ container }) => {
+ let updateX: (value: number) => void;
+ let updateY: (value: string) => void;
+ let updateZ: (value: boolean) => void;
+ function MultiWatchComponent() {
+ let x = 5;
+ let y = 'hello';
+ let z = true;
+ let result = '';
+ updateX = (value: number) => {
+ x = value;
+ };
+ updateY = (value: string) => {
+ y = value;
+ };
+ updateZ = (value: boolean) => {
+ z = value;
+ };
+ watch(() => {
+ result = `x: ${x}, y: ${y}, z: ${z}`;
+ });
+ return {result}
;
+ }
+ render(MultiWatchComponent, container);
+ expect(container.innerHTML).toBe('x: 5, y: hello, z: true
');
+ updateX(10);
+ updateY('world');
+ updateZ(false);
+ expect(container.innerHTML).toBe('x: 10, y: world, z: false
');
+ });
+});
--
Gitee