rask-ui 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vdom/AbstractVNode.d.ts +20 -1
- package/dist/vdom/AbstractVNode.d.ts.map +1 -1
- package/dist/vdom/AbstractVNode.js +142 -11
- package/dist/vdom/ComponentVNode.d.ts +2 -2
- package/dist/vdom/ComponentVNode.d.ts.map +1 -1
- package/dist/vdom/ComponentVNode.js +10 -5
- package/dist/vdom/ElementVNode.d.ts +2 -8
- package/dist/vdom/ElementVNode.d.ts.map +1 -1
- package/dist/vdom/ElementVNode.js +11 -31
- package/dist/vdom/FragmentVNode.d.ts +2 -2
- package/dist/vdom/FragmentVNode.d.ts.map +1 -1
- package/dist/vdom/FragmentVNode.js +11 -6
- package/dist/vdom/RootVNode.d.ts +2 -2
- package/dist/vdom/RootVNode.d.ts.map +1 -1
- package/dist/vdom/RootVNode.js +7 -5
- package/package.json +1 -1
- package/dist/component.d.ts +0 -38
- package/dist/component.d.ts.map +0 -1
- package/dist/component.js +0 -130
- package/dist/context.d.ts +0 -5
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -29
- package/dist/createAsync.test.d.ts +0 -2
- package/dist/createAsync.test.d.ts.map +0 -1
- package/dist/createAsync.test.js +0 -110
- package/dist/createAsyncState.d.ts +0 -16
- package/dist/createAsyncState.d.ts.map +0 -1
- package/dist/createAsyncState.js +0 -24
- package/dist/createContext.test.d.ts +0 -2
- package/dist/createContext.test.d.ts.map +0 -1
- package/dist/createContext.test.js +0 -136
- package/dist/createMutation.test.d.ts +0 -2
- package/dist/createMutation.test.d.ts.map +0 -1
- package/dist/createMutation.test.js +0 -168
- package/dist/createQuery.test.d.ts +0 -2
- package/dist/createQuery.test.d.ts.map +0 -1
- package/dist/createQuery.test.js +0 -156
- package/dist/createRef.test.d.ts +0 -2
- package/dist/createRef.test.d.ts.map +0 -1
- package/dist/createRef.test.js +0 -80
- package/dist/createState.test.d.ts +0 -2
- package/dist/createState.test.d.ts.map +0 -1
- package/dist/createState.test.js +0 -111
- package/dist/createView.test.d.ts +0 -2
- package/dist/createView.test.d.ts.map +0 -1
- package/dist/createView.test.js +0 -203
- package/dist/error.test.d.ts +0 -2
- package/dist/error.test.d.ts.map +0 -1
- package/dist/error.test.js +0 -144
- package/dist/integration.test.d.ts +0 -2
- package/dist/integration.test.d.ts.map +0 -1
- package/dist/integration.test.js +0 -155
- package/dist/jsx.d.ts.map +0 -1
- package/dist/jsx.js +0 -42
- package/dist/observation.test.d.ts +0 -2
- package/dist/observation.test.d.ts.map +0 -1
- package/dist/observation.test.js +0 -113
- package/dist/render-test.d.ts +0 -2
- package/dist/render-test.d.ts.map +0 -1
- package/dist/render-test.js +0 -21
- package/dist/render.d.ts +0 -7
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -77
- package/dist/suspense.d.ts +0 -25
- package/dist/suspense.d.ts.map +0 -1
- package/dist/suspense.js +0 -97
- package/dist/tests/class.test.d.ts +0 -2
- package/dist/tests/class.test.d.ts.map +0 -1
- package/dist/tests/class.test.js +0 -185
- package/dist/tests/complex-rendering.test.d.ts +0 -2
- package/dist/tests/complex-rendering.test.d.ts.map +0 -1
- package/dist/tests/complex-rendering.test.js +0 -400
- package/dist/tests/component.cleanup.test.d.ts +0 -2
- package/dist/tests/component.cleanup.test.d.ts.map +0 -1
- package/dist/tests/component.cleanup.test.js +0 -325
- package/dist/tests/component.counter.test.d.ts +0 -2
- package/dist/tests/component.counter.test.d.ts.map +0 -1
- package/dist/tests/component.counter.test.js +0 -124
- package/dist/tests/component.interaction.test.d.ts +0 -2
- package/dist/tests/component.interaction.test.d.ts.map +0 -1
- package/dist/tests/component.interaction.test.js +0 -73
- package/dist/tests/component.props.test.d.ts +0 -2
- package/dist/tests/component.props.test.d.ts.map +0 -1
- package/dist/tests/component.props.test.js +0 -334
- package/dist/tests/component.return-types.test.d.ts +0 -2
- package/dist/tests/component.return-types.test.d.ts.map +0 -1
- package/dist/tests/component.return-types.test.js +0 -357
- package/dist/tests/component.state.test.d.ts +0 -2
- package/dist/tests/component.state.test.d.ts.map +0 -1
- package/dist/tests/component.state.test.js +0 -135
- package/dist/tests/component.test.d.ts +0 -2
- package/dist/tests/component.test.d.ts.map +0 -1
- package/dist/tests/component.test.js +0 -63
- package/dist/tests/createAsync.test.d.ts +0 -2
- package/dist/tests/createAsync.test.d.ts.map +0 -1
- package/dist/tests/createAsync.test.js +0 -110
- package/dist/tests/createContext.test.d.ts +0 -2
- package/dist/tests/createContext.test.d.ts.map +0 -1
- package/dist/tests/createContext.test.js +0 -141
- package/dist/tests/createMutation.test.d.ts +0 -2
- package/dist/tests/createMutation.test.d.ts.map +0 -1
- package/dist/tests/createMutation.test.js +0 -168
- package/dist/tests/createQuery.test.d.ts +0 -2
- package/dist/tests/createQuery.test.d.ts.map +0 -1
- package/dist/tests/createQuery.test.js +0 -156
- package/dist/tests/createRef.test.d.ts +0 -2
- package/dist/tests/createRef.test.d.ts.map +0 -1
- package/dist/tests/createRef.test.js +0 -84
- package/dist/tests/createState.test.d.ts +0 -2
- package/dist/tests/createState.test.d.ts.map +0 -1
- package/dist/tests/createState.test.js +0 -103
- package/dist/tests/createView.test.d.ts +0 -2
- package/dist/tests/createView.test.d.ts.map +0 -1
- package/dist/tests/createView.test.js +0 -203
- package/dist/tests/edge-cases.test.d.ts +0 -2
- package/dist/tests/edge-cases.test.d.ts.map +0 -1
- package/dist/tests/edge-cases.test.js +0 -637
- package/dist/tests/error-no-boundary.test.d.ts +0 -2
- package/dist/tests/error-no-boundary.test.d.ts.map +0 -1
- package/dist/tests/error-no-boundary.test.js +0 -174
- package/dist/tests/error.test.d.ts +0 -2
- package/dist/tests/error.test.d.ts.map +0 -1
- package/dist/tests/error.test.js +0 -199
- package/dist/tests/fragment.test.d.ts +0 -2
- package/dist/tests/fragment.test.d.ts.map +0 -1
- package/dist/tests/fragment.test.js +0 -618
- package/dist/tests/integration.test.d.ts +0 -2
- package/dist/tests/integration.test.d.ts.map +0 -1
- package/dist/tests/integration.test.js +0 -192
- package/dist/tests/keys.test.d.ts +0 -2
- package/dist/tests/keys.test.d.ts.map +0 -1
- package/dist/tests/keys.test.js +0 -293
- package/dist/tests/mount.test.d.ts +0 -2
- package/dist/tests/mount.test.d.ts.map +0 -1
- package/dist/tests/mount.test.js +0 -91
- package/dist/tests/observation.test.d.ts +0 -2
- package/dist/tests/observation.test.d.ts.map +0 -1
- package/dist/tests/observation.test.js +0 -113
- package/dist/tests/patch.test.d.ts +0 -2
- package/dist/tests/patch.test.d.ts.map +0 -1
- package/dist/tests/patch.test.js +0 -498
- package/dist/tests/patchChildren.test.d.ts +0 -2
- package/dist/tests/patchChildren.test.d.ts.map +0 -1
- package/dist/tests/patchChildren.test.js +0 -405
- package/dist/tests/primitives.test.d.ts +0 -2
- package/dist/tests/primitives.test.d.ts.map +0 -1
- package/dist/tests/primitives.test.js +0 -132
- package/dist/vdom/class.test.d.ts +0 -2
- package/dist/vdom/class.test.d.ts.map +0 -1
- package/dist/vdom/class.test.js +0 -143
- package/dist/vdom/complex-rendering.test.d.ts +0 -2
- package/dist/vdom/complex-rendering.test.d.ts.map +0 -1
- package/dist/vdom/complex-rendering.test.js +0 -400
- package/dist/vdom/component.cleanup.test.d.ts +0 -2
- package/dist/vdom/component.cleanup.test.d.ts.map +0 -1
- package/dist/vdom/component.cleanup.test.js +0 -323
- package/dist/vdom/component.counter.test.d.ts +0 -2
- package/dist/vdom/component.counter.test.d.ts.map +0 -1
- package/dist/vdom/component.counter.test.js +0 -124
- package/dist/vdom/component.interaction.test.d.ts +0 -2
- package/dist/vdom/component.interaction.test.d.ts.map +0 -1
- package/dist/vdom/component.interaction.test.js +0 -73
- package/dist/vdom/component.props.test.d.ts +0 -2
- package/dist/vdom/component.props.test.d.ts.map +0 -1
- package/dist/vdom/component.props.test.js +0 -88
- package/dist/vdom/component.return-types.test.d.ts +0 -2
- package/dist/vdom/component.return-types.test.d.ts.map +0 -1
- package/dist/vdom/component.return-types.test.js +0 -357
- package/dist/vdom/component.state.test.d.ts +0 -2
- package/dist/vdom/component.state.test.d.ts.map +0 -1
- package/dist/vdom/component.state.test.js +0 -129
- package/dist/vdom/component.test.d.ts +0 -2
- package/dist/vdom/component.test.d.ts.map +0 -1
- package/dist/vdom/component.test.js +0 -63
- package/dist/vdom/edge-cases.test.d.ts +0 -2
- package/dist/vdom/edge-cases.test.d.ts.map +0 -1
- package/dist/vdom/edge-cases.test.js +0 -637
- package/dist/vdom/fragment.test.d.ts +0 -2
- package/dist/vdom/fragment.test.d.ts.map +0 -1
- package/dist/vdom/fragment.test.js +0 -618
- package/dist/vdom/keys.test.d.ts +0 -2
- package/dist/vdom/keys.test.d.ts.map +0 -1
- package/dist/vdom/keys.test.js +0 -293
- package/dist/vdom/mount.test.d.ts +0 -2
- package/dist/vdom/mount.test.d.ts.map +0 -1
- package/dist/vdom/mount.test.js +0 -91
- package/dist/vdom/patch.test.d.ts +0 -2
- package/dist/vdom/patch.test.d.ts.map +0 -1
- package/dist/vdom/patch.test.js +0 -498
- package/dist/vdom/patchChildren.test.d.ts +0 -2
- package/dist/vdom/patchChildren.test.d.ts.map +0 -1
- package/dist/vdom/patchChildren.test.js +0 -392
- package/dist/vdom/primitives.test.d.ts +0 -2
- package/dist/vdom/primitives.test.d.ts.map +0 -1
- package/dist/vdom/primitives.test.js +0 -132
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { jsx, render } from "../vdom";
|
|
3
|
-
import { createState } from "../createState";
|
|
4
|
-
import { Fragment } from "../vdom/FragmentVNode";
|
|
5
|
-
describe("Component Return Types", () => {
|
|
6
|
-
describe("Static Return Values", () => {
|
|
7
|
-
it("should handle component returning a single element", () => {
|
|
8
|
-
const container = document.createElement("div");
|
|
9
|
-
const MyComponent = () => {
|
|
10
|
-
return () => jsx("div", { children: "Hello" });
|
|
11
|
-
};
|
|
12
|
-
render(jsx(MyComponent, {}), container);
|
|
13
|
-
expect(container.children).toHaveLength(1);
|
|
14
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
15
|
-
expect(container.children[0].textContent).toBe("Hello");
|
|
16
|
-
});
|
|
17
|
-
it("should handle component returning a text string", () => {
|
|
18
|
-
const container = document.createElement("div");
|
|
19
|
-
const MyComponent = () => {
|
|
20
|
-
return () => "Hello World";
|
|
21
|
-
};
|
|
22
|
-
render(jsx(MyComponent, {}), container);
|
|
23
|
-
expect(container.childNodes).toHaveLength(1);
|
|
24
|
-
expect(container.childNodes[0]).toBeInstanceOf(Text);
|
|
25
|
-
expect(container.textContent).toBe("Hello World");
|
|
26
|
-
});
|
|
27
|
-
it("should handle component returning a number", () => {
|
|
28
|
-
const container = document.createElement("div");
|
|
29
|
-
const MyComponent = () => {
|
|
30
|
-
return () => 42;
|
|
31
|
-
};
|
|
32
|
-
render(jsx(MyComponent, {}), container);
|
|
33
|
-
expect(container.childNodes).toHaveLength(1);
|
|
34
|
-
expect(container.textContent).toBe("42");
|
|
35
|
-
});
|
|
36
|
-
it("should handle component returning null", () => {
|
|
37
|
-
const container = document.createElement("div");
|
|
38
|
-
const MyComponent = () => {
|
|
39
|
-
return () => null;
|
|
40
|
-
};
|
|
41
|
-
render(jsx(MyComponent, {}), container);
|
|
42
|
-
// Null should render as empty fragment or empty array
|
|
43
|
-
expect(container.childNodes.length).toBe(0);
|
|
44
|
-
});
|
|
45
|
-
it("should handle component returning undefined", () => {
|
|
46
|
-
const container = document.createElement("div");
|
|
47
|
-
const MyComponent = () => {
|
|
48
|
-
return () => undefined;
|
|
49
|
-
};
|
|
50
|
-
render(jsx(MyComponent, {}), container);
|
|
51
|
-
// Undefined should render as empty fragment or empty array
|
|
52
|
-
expect(container.childNodes.length).toBe(0);
|
|
53
|
-
});
|
|
54
|
-
it("should handle component returning a fragment with multiple children", () => {
|
|
55
|
-
const container = document.createElement("div");
|
|
56
|
-
const MyComponent = () => {
|
|
57
|
-
return () => jsx(Fragment, {
|
|
58
|
-
children: [
|
|
59
|
-
jsx("div", { children: "First" }),
|
|
60
|
-
jsx("div", { children: "Second" }),
|
|
61
|
-
jsx("div", { children: "Third" }),
|
|
62
|
-
],
|
|
63
|
-
});
|
|
64
|
-
};
|
|
65
|
-
render(jsx(MyComponent, {}), container);
|
|
66
|
-
expect(container.children.length).toBeGreaterThanOrEqual(3);
|
|
67
|
-
});
|
|
68
|
-
it("should handle component returning an array of elements", () => {
|
|
69
|
-
const container = document.createElement("div");
|
|
70
|
-
const MyComponent = () => {
|
|
71
|
-
return () => [
|
|
72
|
-
jsx("span", { children: "A" }),
|
|
73
|
-
jsx("span", { children: "B" }),
|
|
74
|
-
jsx("span", { children: "C" }),
|
|
75
|
-
];
|
|
76
|
-
};
|
|
77
|
-
render(jsx(MyComponent, {}), container);
|
|
78
|
-
expect(container.children.length).toBeGreaterThanOrEqual(3);
|
|
79
|
-
});
|
|
80
|
-
it("should handle component returning nested components", () => {
|
|
81
|
-
const container = document.createElement("div");
|
|
82
|
-
const InnerComponent = () => {
|
|
83
|
-
return () => jsx("span", { children: "Inner" });
|
|
84
|
-
};
|
|
85
|
-
const OuterComponent = () => {
|
|
86
|
-
return () => jsx(InnerComponent, {});
|
|
87
|
-
};
|
|
88
|
-
render(jsx(OuterComponent, {}), container);
|
|
89
|
-
expect(container.children).toHaveLength(1);
|
|
90
|
-
expect(container.textContent).toBe("Inner");
|
|
91
|
-
});
|
|
92
|
-
it("should handle component returning boolean false", () => {
|
|
93
|
-
const container = document.createElement("div");
|
|
94
|
-
const MyComponent = () => {
|
|
95
|
-
return () => false;
|
|
96
|
-
};
|
|
97
|
-
render(jsx(MyComponent, {}), container);
|
|
98
|
-
// False should render as empty or be filtered out
|
|
99
|
-
expect(container.childNodes.length).toBe(0);
|
|
100
|
-
});
|
|
101
|
-
it("should handle component returning boolean true", () => {
|
|
102
|
-
const container = document.createElement("div");
|
|
103
|
-
const MyComponent = () => {
|
|
104
|
-
return () => true;
|
|
105
|
-
};
|
|
106
|
-
render(jsx(MyComponent, {}), container);
|
|
107
|
-
// True should render as empty or be filtered out
|
|
108
|
-
expect(container.childNodes.length).toBe(0);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
describe("Dynamic Return Values", () => {
|
|
112
|
-
it("should handle component switching from element to string", async () => {
|
|
113
|
-
const container = document.createElement("div");
|
|
114
|
-
let stateFn;
|
|
115
|
-
const MyComponent = () => {
|
|
116
|
-
const state = createState({ showElement: true });
|
|
117
|
-
stateFn = state;
|
|
118
|
-
return () => state.showElement ? jsx("div", { children: "Element" }) : "Just text";
|
|
119
|
-
};
|
|
120
|
-
render(jsx(MyComponent, {}), container);
|
|
121
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
122
|
-
stateFn.showElement = false;
|
|
123
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
124
|
-
expect(container.childNodes[0]).toBeInstanceOf(Text);
|
|
125
|
-
expect(container.textContent).toBe("Just text");
|
|
126
|
-
});
|
|
127
|
-
it("should handle component switching from null to element", async () => {
|
|
128
|
-
const container = document.createElement("div");
|
|
129
|
-
let stateFn;
|
|
130
|
-
const MyComponent = () => {
|
|
131
|
-
const state = createState({ show: false });
|
|
132
|
-
stateFn = state;
|
|
133
|
-
return () => (state.show ? jsx("div", { children: "Visible" }) : null);
|
|
134
|
-
};
|
|
135
|
-
render(jsx(MyComponent, {}), container);
|
|
136
|
-
expect(container.childNodes.length).toBe(0);
|
|
137
|
-
stateFn.show = true;
|
|
138
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
139
|
-
expect(container.children.length).toBeGreaterThan(0);
|
|
140
|
-
expect(container.textContent).toBe("Visible");
|
|
141
|
-
});
|
|
142
|
-
it("should handle component switching from element to null", async () => {
|
|
143
|
-
const container = document.createElement("div");
|
|
144
|
-
let stateFn;
|
|
145
|
-
const MyComponent = () => {
|
|
146
|
-
const state = createState({ show: true });
|
|
147
|
-
stateFn = state;
|
|
148
|
-
return () => (state.show ? jsx("div", { children: "Visible" }) : null);
|
|
149
|
-
};
|
|
150
|
-
render(jsx(MyComponent, {}), container);
|
|
151
|
-
expect(container.children.length).toBe(1);
|
|
152
|
-
stateFn.show = false;
|
|
153
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
154
|
-
expect(container.childNodes.length).toBe(0);
|
|
155
|
-
});
|
|
156
|
-
it("should handle component switching between different element types", async () => {
|
|
157
|
-
const container = document.createElement("div");
|
|
158
|
-
let stateFn;
|
|
159
|
-
const MyComponent = () => {
|
|
160
|
-
const state = createState({
|
|
161
|
-
type: "div",
|
|
162
|
-
});
|
|
163
|
-
stateFn = state;
|
|
164
|
-
return () => jsx(state.type, { children: "Content" });
|
|
165
|
-
};
|
|
166
|
-
render(jsx(MyComponent, {}), container);
|
|
167
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
168
|
-
stateFn.type = "span";
|
|
169
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
170
|
-
expect(container.children[0]).toBeInstanceOf(HTMLSpanElement);
|
|
171
|
-
stateFn.type = "p";
|
|
172
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
173
|
-
expect(container.children[0]).toBeInstanceOf(HTMLParagraphElement);
|
|
174
|
-
});
|
|
175
|
-
it("should handle component switching from single element to array", async () => {
|
|
176
|
-
const container = document.createElement("div");
|
|
177
|
-
let stateFn;
|
|
178
|
-
const MyComponent = () => {
|
|
179
|
-
const state = createState({ multiple: false });
|
|
180
|
-
stateFn = state;
|
|
181
|
-
return () => state.multiple
|
|
182
|
-
? [
|
|
183
|
-
jsx("div", { children: "First" }),
|
|
184
|
-
jsx("div", { children: "Second" }),
|
|
185
|
-
]
|
|
186
|
-
: jsx("div", { children: "Single" });
|
|
187
|
-
};
|
|
188
|
-
render(jsx(MyComponent, {}), container);
|
|
189
|
-
expect(container.children.length).toBe(1);
|
|
190
|
-
stateFn.multiple = true;
|
|
191
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
192
|
-
expect(container.children.length).toBeGreaterThanOrEqual(2);
|
|
193
|
-
});
|
|
194
|
-
it("should handle component switching from array to single element", async () => {
|
|
195
|
-
const container = document.createElement("div");
|
|
196
|
-
let stateFn;
|
|
197
|
-
const MyComponent = () => {
|
|
198
|
-
const state = createState({ multiple: true });
|
|
199
|
-
stateFn = state;
|
|
200
|
-
return () => state.multiple
|
|
201
|
-
? [
|
|
202
|
-
jsx("div", { children: "First" }),
|
|
203
|
-
jsx("div", { children: "Second" }),
|
|
204
|
-
]
|
|
205
|
-
: jsx("div", { children: "Single" });
|
|
206
|
-
};
|
|
207
|
-
render(jsx(MyComponent, {}), container);
|
|
208
|
-
expect(container.children.length).toBe(2);
|
|
209
|
-
stateFn.multiple = false;
|
|
210
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
211
|
-
expect(container.children).toHaveLength(1);
|
|
212
|
-
expect(container.textContent).toBe("Single");
|
|
213
|
-
});
|
|
214
|
-
it("should handle component dynamically changing array length", async () => {
|
|
215
|
-
const container = document.createElement("div");
|
|
216
|
-
let stateFn;
|
|
217
|
-
const MyComponent = () => {
|
|
218
|
-
const state = createState({ count: 2 });
|
|
219
|
-
stateFn = state;
|
|
220
|
-
return () => Array.from({ length: state.count }, (_, i) => jsx("div", { children: `Item ${i}` }));
|
|
221
|
-
};
|
|
222
|
-
render(jsx(MyComponent, {}), container);
|
|
223
|
-
expect(container.children.length).toBe(2);
|
|
224
|
-
stateFn.count = 5;
|
|
225
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
226
|
-
expect(container.children.length).toBe(5);
|
|
227
|
-
stateFn.count = 1;
|
|
228
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
229
|
-
expect(container.children.length).toBe(1);
|
|
230
|
-
});
|
|
231
|
-
it("should handle component switching between string and number", async () => {
|
|
232
|
-
const container = document.createElement("div");
|
|
233
|
-
let stateFn;
|
|
234
|
-
const MyComponent = () => {
|
|
235
|
-
const state = createState({
|
|
236
|
-
value: "Hello",
|
|
237
|
-
});
|
|
238
|
-
stateFn = state;
|
|
239
|
-
return () => state.value;
|
|
240
|
-
};
|
|
241
|
-
render(jsx(MyComponent, {}), container);
|
|
242
|
-
expect(container.textContent).toBe("Hello");
|
|
243
|
-
stateFn.value = 42;
|
|
244
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
245
|
-
expect(container.textContent).toBe("42");
|
|
246
|
-
});
|
|
247
|
-
it("should handle component conditionally returning component or element", async () => {
|
|
248
|
-
const container = document.createElement("div");
|
|
249
|
-
let stateFn;
|
|
250
|
-
const InnerComponent = () => {
|
|
251
|
-
return () => jsx("span", { children: "Component" });
|
|
252
|
-
};
|
|
253
|
-
const MyComponent = () => {
|
|
254
|
-
const state = createState({ useComponent: true });
|
|
255
|
-
stateFn = state;
|
|
256
|
-
return () => state.useComponent
|
|
257
|
-
? jsx(InnerComponent, {})
|
|
258
|
-
: jsx("div", { children: "Element" });
|
|
259
|
-
};
|
|
260
|
-
render(jsx(MyComponent, {}), container);
|
|
261
|
-
expect(container.children[0]).toBeInstanceOf(HTMLSpanElement);
|
|
262
|
-
expect(container.textContent).toBe("Component");
|
|
263
|
-
stateFn.useComponent = false;
|
|
264
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
265
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
266
|
-
expect(container.textContent).toBe("Element");
|
|
267
|
-
});
|
|
268
|
-
it("should handle rapid switching between return types", async () => {
|
|
269
|
-
const container = document.createElement("div");
|
|
270
|
-
let stateFn;
|
|
271
|
-
const MyComponent = () => {
|
|
272
|
-
const state = createState({
|
|
273
|
-
type: "element",
|
|
274
|
-
});
|
|
275
|
-
stateFn = state;
|
|
276
|
-
return () => {
|
|
277
|
-
if (state.type === "element") {
|
|
278
|
-
return jsx("div", { children: "Element" });
|
|
279
|
-
}
|
|
280
|
-
if (state.type === "string") {
|
|
281
|
-
return "String";
|
|
282
|
-
}
|
|
283
|
-
return null;
|
|
284
|
-
};
|
|
285
|
-
};
|
|
286
|
-
render(jsx(MyComponent, {}), container);
|
|
287
|
-
expect(container.children.length).toBe(1);
|
|
288
|
-
stateFn.type = "string";
|
|
289
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
290
|
-
expect(container.textContent).toBe("String");
|
|
291
|
-
stateFn.type = "null";
|
|
292
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
293
|
-
expect(container.childNodes.length).toBe(0);
|
|
294
|
-
stateFn.type = "element";
|
|
295
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
296
|
-
expect(container.children.length).toBe(1);
|
|
297
|
-
expect(container.textContent).toBe("Element");
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
describe("Edge Cases", () => {
|
|
301
|
-
it("should handle component returning empty array", () => {
|
|
302
|
-
const container = document.createElement("div");
|
|
303
|
-
const MyComponent = () => {
|
|
304
|
-
return () => [];
|
|
305
|
-
};
|
|
306
|
-
render(jsx(MyComponent, {}), container);
|
|
307
|
-
expect(container.childNodes.length).toBe(0);
|
|
308
|
-
});
|
|
309
|
-
it("should handle component returning array with nulls", () => {
|
|
310
|
-
const container = document.createElement("div");
|
|
311
|
-
const MyComponent = () => {
|
|
312
|
-
return () => [
|
|
313
|
-
jsx("div", { children: "First" }),
|
|
314
|
-
null,
|
|
315
|
-
jsx("div", { children: "Third" }),
|
|
316
|
-
];
|
|
317
|
-
};
|
|
318
|
-
render(jsx(MyComponent, {}), container);
|
|
319
|
-
expect(container.children.length).toBeGreaterThanOrEqual(2);
|
|
320
|
-
});
|
|
321
|
-
it("should handle component returning mixed array types", () => {
|
|
322
|
-
const container = document.createElement("div");
|
|
323
|
-
const MyComponent = () => {
|
|
324
|
-
return () => [
|
|
325
|
-
jsx("div", { children: "Element" }),
|
|
326
|
-
"String",
|
|
327
|
-
42,
|
|
328
|
-
jsx("span", { children: "Another" }),
|
|
329
|
-
];
|
|
330
|
-
};
|
|
331
|
-
render(jsx(MyComponent, {}), container);
|
|
332
|
-
expect(container.childNodes.length).toBeGreaterThan(0);
|
|
333
|
-
});
|
|
334
|
-
it("should handle deeply nested return values", () => {
|
|
335
|
-
const container = document.createElement("div");
|
|
336
|
-
const Level3 = () => () => jsx("span", { children: "Deep" });
|
|
337
|
-
const Level2 = () => () => jsx(Level3, {});
|
|
338
|
-
const Level1 = () => () => jsx(Level2, {});
|
|
339
|
-
render(jsx(Level1, {}), container);
|
|
340
|
-
expect(container.textContent).toBe("Deep");
|
|
341
|
-
});
|
|
342
|
-
it("should handle component switching from empty array to elements", async () => {
|
|
343
|
-
const container = document.createElement("div");
|
|
344
|
-
let stateFn;
|
|
345
|
-
const MyComponent = () => {
|
|
346
|
-
const state = createState({ items: [] });
|
|
347
|
-
stateFn = state;
|
|
348
|
-
return () => state.items.map((item) => jsx("div", { children: item }));
|
|
349
|
-
};
|
|
350
|
-
render(jsx(MyComponent, {}), container);
|
|
351
|
-
expect(container.children.length).toBe(0);
|
|
352
|
-
stateFn.items = ["A", "B", "C"];
|
|
353
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
354
|
-
expect(container.children.length).toBeGreaterThanOrEqual(3);
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"component.state.test.d.ts","sourceRoot":"","sources":["../../src/tests/component.state.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { jsx, render } from "../vdom";
|
|
3
|
-
import { createState } from "../createState";
|
|
4
|
-
describe("Component State", () => {
|
|
5
|
-
it("should initialize state with default value", () => {
|
|
6
|
-
const container = document.createElement("div");
|
|
7
|
-
const MyComponent = () => {
|
|
8
|
-
const state = createState({ count: 0 });
|
|
9
|
-
return () => jsx("div", { children: String(state.count) });
|
|
10
|
-
};
|
|
11
|
-
render(jsx(MyComponent, {}), container);
|
|
12
|
-
expect(container.children[0].textContent).toBe("0");
|
|
13
|
-
});
|
|
14
|
-
it("should update state when value changes", async () => {
|
|
15
|
-
const container = document.createElement("div");
|
|
16
|
-
let stateFn;
|
|
17
|
-
const MyComponent = () => {
|
|
18
|
-
const state = createState({ count: 0 });
|
|
19
|
-
stateFn = state;
|
|
20
|
-
return () => jsx("div", { children: String(state.count) });
|
|
21
|
-
};
|
|
22
|
-
render(jsx(MyComponent, {}), container);
|
|
23
|
-
expect(container.children[0].textContent).toBe("0");
|
|
24
|
-
stateFn.count = 5;
|
|
25
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
26
|
-
expect(container.children[0].textContent).toBe("5");
|
|
27
|
-
});
|
|
28
|
-
it("should support multiple state values", () => {
|
|
29
|
-
const container = document.createElement("div");
|
|
30
|
-
const MyComponent = () => {
|
|
31
|
-
const state = createState({ count: 0, name: "John" });
|
|
32
|
-
return () => jsx("div", {
|
|
33
|
-
children: [
|
|
34
|
-
jsx("span", { children: String(state.count) }),
|
|
35
|
-
jsx("span", { children: state.name }),
|
|
36
|
-
],
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
render(jsx(MyComponent, {}), container);
|
|
40
|
-
const div = container.children[0];
|
|
41
|
-
expect(div.children[0].textContent).toBe("0");
|
|
42
|
-
expect(div.children[1].textContent).toBe("John");
|
|
43
|
-
});
|
|
44
|
-
it("should support incremental state updates", async () => {
|
|
45
|
-
const container = document.createElement("div");
|
|
46
|
-
let stateFn;
|
|
47
|
-
const MyComponent = () => {
|
|
48
|
-
const state = createState({ count: 0 });
|
|
49
|
-
stateFn = state;
|
|
50
|
-
return () => jsx("div", { children: String(state.count) });
|
|
51
|
-
};
|
|
52
|
-
render(jsx(MyComponent, {}), container);
|
|
53
|
-
expect(container.children[0].textContent).toBe("0");
|
|
54
|
-
stateFn.count = stateFn.count + 1;
|
|
55
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
56
|
-
expect(container.children[0].textContent).toBe("1");
|
|
57
|
-
});
|
|
58
|
-
it("should preserve state between re-renders", async () => {
|
|
59
|
-
const container = document.createElement("div");
|
|
60
|
-
let stateFn;
|
|
61
|
-
const MyComponent = () => {
|
|
62
|
-
const state = createState({ count: 0 });
|
|
63
|
-
stateFn = state;
|
|
64
|
-
return () => jsx("div", { children: String(state.count) });
|
|
65
|
-
};
|
|
66
|
-
render(jsx(MyComponent, {}), container);
|
|
67
|
-
expect(container.children[0].textContent).toBe("0");
|
|
68
|
-
stateFn.count = 1;
|
|
69
|
-
stateFn.count = 2;
|
|
70
|
-
stateFn.count = 3;
|
|
71
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
72
|
-
expect(container.children[0].textContent).toBe("3");
|
|
73
|
-
});
|
|
74
|
-
it("should support nested objects as state", () => {
|
|
75
|
-
const container = document.createElement("div");
|
|
76
|
-
const MyComponent = () => {
|
|
77
|
-
const state = createState({ user: { name: "John", age: 30 } });
|
|
78
|
-
return () => jsx("div", {
|
|
79
|
-
children: `${state.user.name} is ${state.user.age} years old`,
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
render(jsx(MyComponent, {}), container);
|
|
83
|
-
expect(container.children[0].textContent).toBe("John is 30 years old");
|
|
84
|
-
});
|
|
85
|
-
it("should support arrays as state", () => {
|
|
86
|
-
const container = document.createElement("div");
|
|
87
|
-
const MyComponent = () => {
|
|
88
|
-
const state = createState({ items: [1, 2, 3] });
|
|
89
|
-
return () => jsx("ul", {
|
|
90
|
-
children: state.items.map((item) => jsx("li", { children: String(item) })),
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
render(jsx(MyComponent, {}), container);
|
|
94
|
-
const ul = container.children[0];
|
|
95
|
-
expect(ul.children).toHaveLength(3);
|
|
96
|
-
expect(ul.children[0].textContent).toBe("1");
|
|
97
|
-
expect(ul.children[1].textContent).toBe("2");
|
|
98
|
-
expect(ul.children[2].textContent).toBe("3");
|
|
99
|
-
});
|
|
100
|
-
it("should update nested state properties", async () => {
|
|
101
|
-
const container = document.createElement("div");
|
|
102
|
-
let stateFn;
|
|
103
|
-
const MyComponent = () => {
|
|
104
|
-
const state = createState({ user: { name: "Alice", age: 25 } });
|
|
105
|
-
stateFn = state;
|
|
106
|
-
return () => jsx("div", {
|
|
107
|
-
children: `${state.user.name} is ${state.user.age}`,
|
|
108
|
-
});
|
|
109
|
-
};
|
|
110
|
-
render(jsx(MyComponent, {}), container);
|
|
111
|
-
expect(container.children[0].textContent).toBe("Alice is 25");
|
|
112
|
-
stateFn.user.name = "Bob";
|
|
113
|
-
stateFn.user.age = 30;
|
|
114
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
115
|
-
expect(container.children[0].textContent).toBe("Bob is 30");
|
|
116
|
-
});
|
|
117
|
-
it("should support array mutations", async () => {
|
|
118
|
-
const container = document.createElement("div");
|
|
119
|
-
let stateFn;
|
|
120
|
-
const MyComponent = () => {
|
|
121
|
-
const state = createState({ items: [1, 2, 3] });
|
|
122
|
-
stateFn = state;
|
|
123
|
-
return () => jsx("ul", {
|
|
124
|
-
children: state.items.map((item) => jsx("li", { children: String(item) })),
|
|
125
|
-
});
|
|
126
|
-
};
|
|
127
|
-
render(jsx(MyComponent, {}), container);
|
|
128
|
-
const ul = container.children[0];
|
|
129
|
-
expect(ul.children).toHaveLength(3);
|
|
130
|
-
stateFn.items.push(4);
|
|
131
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
132
|
-
expect(ul.children).toHaveLength(4);
|
|
133
|
-
expect(ul.children[3].textContent).toBe("4");
|
|
134
|
-
});
|
|
135
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"component.test.d.ts","sourceRoot":"","sources":["../../src/tests/component.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { jsx, render } from "../vdom";
|
|
3
|
-
describe("ComponentVNode", () => {
|
|
4
|
-
it("should mount a component that returns an element", () => {
|
|
5
|
-
const container = document.createElement("div");
|
|
6
|
-
const MyComponent = () => {
|
|
7
|
-
return () => jsx("div", {});
|
|
8
|
-
};
|
|
9
|
-
render(jsx(MyComponent, {}), container);
|
|
10
|
-
expect(container.children).toHaveLength(1);
|
|
11
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
12
|
-
expect(container.children[0].tagName).toBe("DIV");
|
|
13
|
-
});
|
|
14
|
-
it("should mount a component with text content", () => {
|
|
15
|
-
const container = document.createElement("div");
|
|
16
|
-
const MyComponent = () => {
|
|
17
|
-
return () => jsx("div", { children: "Hello World" });
|
|
18
|
-
};
|
|
19
|
-
render(jsx(MyComponent, {}), container);
|
|
20
|
-
expect(container.children).toHaveLength(1);
|
|
21
|
-
expect(container.children[0].textContent).toBe("Hello World");
|
|
22
|
-
});
|
|
23
|
-
it("should mount a component with nested elements", () => {
|
|
24
|
-
const container = document.createElement("div");
|
|
25
|
-
const MyComponent = () => {
|
|
26
|
-
return () => jsx("div", {
|
|
27
|
-
children: [
|
|
28
|
-
jsx("h1", { children: "Title" }),
|
|
29
|
-
jsx("p", { children: "Paragraph" }),
|
|
30
|
-
],
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
render(jsx(MyComponent, {}), container);
|
|
34
|
-
expect(container.children).toHaveLength(1);
|
|
35
|
-
const div = container.children[0];
|
|
36
|
-
expect(div.children).toHaveLength(2);
|
|
37
|
-
expect(div.children[0].tagName).toBe("H1");
|
|
38
|
-
expect(div.children[0].textContent).toBe("Title");
|
|
39
|
-
expect(div.children[1].tagName).toBe("P");
|
|
40
|
-
expect(div.children[1].textContent).toBe("Paragraph");
|
|
41
|
-
});
|
|
42
|
-
it("should pass props to component", () => {
|
|
43
|
-
const container = document.createElement("div");
|
|
44
|
-
const MyComponent = (props) => {
|
|
45
|
-
return () => jsx("div", { children: props.message });
|
|
46
|
-
};
|
|
47
|
-
render(jsx(MyComponent, {
|
|
48
|
-
message: "Hello from props",
|
|
49
|
-
}), container);
|
|
50
|
-
expect(container.children[0].textContent).toBe("Hello from props");
|
|
51
|
-
});
|
|
52
|
-
it("should store parent reference after mount", () => {
|
|
53
|
-
const container = document.createElement("div");
|
|
54
|
-
const MyComponent = () => {
|
|
55
|
-
return () => jsx("div", {});
|
|
56
|
-
};
|
|
57
|
-
render(jsx(MyComponent, {}), container);
|
|
58
|
-
// After rendering, we can verify the component was mounted successfully
|
|
59
|
-
// by checking the container has the expected DOM structure
|
|
60
|
-
expect(container.children).toHaveLength(1);
|
|
61
|
-
expect(container.children[0]).toBeInstanceOf(HTMLDivElement);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createAsync.test.d.ts","sourceRoot":"","sources":["../../src/tests/createAsync.test.ts"],"names":[],"mappings":""}
|