@ryupold/vode 1.8.8 → 1.8.11
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/.github/workflows/publish.yml +5 -0
- package/.github/workflows/tests.yml +1 -0
- package/README.md +36 -2
- package/dist/vode.cjs.min.js +1 -1
- package/dist/vode.d.ts +5 -6
- package/dist/vode.es5.min.js +1 -1
- package/dist/vode.js +54 -44
- package/dist/vode.min.js +1 -1
- package/dist/vode.min.mjs +1 -1
- package/dist/vode.mjs +54 -44
- package/dist/vode.tests.mjs +5475 -0
- package/log.txt +1 -0
- package/package.json +5 -5
- package/src/vode.ts +63 -52
- package/test/helper.ts +299 -146
- package/test/index.ts +2 -64
- package/test/mocks.ts +83 -9
- package/test/run-tests.ts +61 -0
- package/test/tests-app.ts +48 -48
- package/test/tests-catch.ts +15 -15
- package/test/tests-children.ts +31 -31
- package/test/tests-createPatch.ts +12 -12
- package/test/tests-createState.ts +11 -11
- package/test/tests-defuse.ts +18 -18
- package/test/tests-examples.ts +87 -88
- package/test/tests-hydrate.ts +28 -28
- package/test/tests-memo.ts +29 -28
- package/test/tests-mergeClass.ts +31 -31
- package/test/tests-mergeProps.ts +19 -19
- package/test/tests-mergeStyle.ts +28 -14
- package/test/tests-mount-unmount.ts +368 -268
- package/test/tests-patch-advanced.ts +127 -19
- package/test/tests-patch-merge.ts +15 -15
- package/test/tests-props.ts +15 -15
- package/test/tests-state-context.ts +33 -33
- package/test/tests-tag.ts +14 -14
- package/test/tests-vode.ts +6 -6
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { expect } from "./helper";
|
|
2
|
-
import { app, createState, DIV } from "../index";
|
|
1
|
+
import { delay, expect } from "./helper";
|
|
2
|
+
import { app, ContainerNode, createState, DIV } from "../index";
|
|
3
3
|
|
|
4
4
|
function setup() {
|
|
5
5
|
const root = document.createElement("div");
|
|
6
6
|
const container = document.createElement("div");
|
|
7
7
|
root.appendChild(container);
|
|
8
|
-
return container;
|
|
8
|
+
return container as unknown as ContainerNode;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default {
|
|
@@ -14,7 +14,7 @@ export default {
|
|
|
14
14
|
const state: any = createState({ count: 0 });
|
|
15
15
|
app(container, state, (s: any) => [DIV, String(s.count)]);
|
|
16
16
|
|
|
17
|
-
expect(state.count).toEqual(0);
|
|
17
|
+
await expect(state.count).toEqual(0);
|
|
18
18
|
|
|
19
19
|
state.patch(function* () {
|
|
20
20
|
yield { count: 1 };
|
|
@@ -24,8 +24,8 @@ export default {
|
|
|
24
24
|
|
|
25
25
|
await new Promise(r => setTimeout(r, 0));
|
|
26
26
|
|
|
27
|
-
expect(state.count).toEqual(3);
|
|
28
|
-
expect(container).toMatch([DIV, "3"]);
|
|
27
|
+
await expect(state.count).toEqual(3);
|
|
28
|
+
await expect(container).toMatch([DIV, "3"]);
|
|
29
29
|
},
|
|
30
30
|
|
|
31
31
|
"patch(): async generator yields over time": async () => {
|
|
@@ -33,19 +33,22 @@ export default {
|
|
|
33
33
|
const state: any = createState({ phase: "start", value: 0 });
|
|
34
34
|
app(container, state, (s: any) => [DIV, s.phase, String(s.value)]);
|
|
35
35
|
|
|
36
|
-
expect(state.phase).toEqual("start");
|
|
36
|
+
await expect(state.phase).toEqual("start");
|
|
37
37
|
|
|
38
38
|
state.patch(async function* () {
|
|
39
|
+
await expect(container._vode.stats.syncRenderPatchCount).toEqual(0);
|
|
39
40
|
yield { phase: "working", value: 10 };
|
|
41
|
+
await expect(container._vode.stats.syncRenderPatchCount).toEqual(1);
|
|
40
42
|
yield { phase: "almost", value: 20 };
|
|
43
|
+
await expect(container._vode.stats.syncRenderPatchCount).toEqual(2);
|
|
41
44
|
return { phase: "done", value: 30 };
|
|
42
45
|
}());
|
|
43
46
|
|
|
44
47
|
await new Promise(r => setTimeout(r, 0));
|
|
45
48
|
|
|
46
|
-
expect(state.phase).toEqual("done");
|
|
47
|
-
expect(state.value).toEqual(30);
|
|
48
|
-
expect(container).toMatch([DIV, "done", "30"]);
|
|
49
|
+
await expect(state.phase).toEqual("done");
|
|
50
|
+
await expect(state.value).toEqual(30);
|
|
51
|
+
await expect(container).toMatch([DIV, "done", "30"]);
|
|
49
52
|
},
|
|
50
53
|
|
|
51
54
|
"patch(): Promise resolves and applies patch": async () => {
|
|
@@ -55,30 +58,135 @@ export default {
|
|
|
55
58
|
|
|
56
59
|
state.patch(Promise.resolve({ msg: "after" }));
|
|
57
60
|
|
|
58
|
-
await
|
|
61
|
+
await delay(10);
|
|
59
62
|
|
|
60
|
-
expect(state.msg).toEqual("after");
|
|
61
|
-
expect(container).toMatch([DIV, "after"]);
|
|
63
|
+
await expect(state.msg).toEqual("after");
|
|
64
|
+
await expect(container).toMatch([DIV, "after"]);
|
|
62
65
|
},
|
|
63
66
|
|
|
64
|
-
"patch(): array with empty patches applies nothing": () => {
|
|
67
|
+
"patch(): array with empty patches applies nothing": async () => {
|
|
65
68
|
const container = setup();
|
|
66
69
|
const state: any = createState({ x: 1, y: 2 });
|
|
67
70
|
app(container, state, (s: any) => [DIV]);
|
|
68
71
|
|
|
69
72
|
state.patch([{}, {}]);
|
|
70
|
-
expect(state.x).toEqual(1);
|
|
71
|
-
expect(state.y).toEqual(2);
|
|
73
|
+
await expect(state.x).toEqual(1);
|
|
74
|
+
await expect(state.y).toEqual(2);
|
|
72
75
|
},
|
|
73
76
|
|
|
74
|
-
"patch(): array with null/undefined items skips them": () => {
|
|
77
|
+
"patch(): array with null/undefined items skips them": async () => {
|
|
75
78
|
const container = setup();
|
|
76
79
|
const state: any = createState({ x: 0, y: 0 });
|
|
77
80
|
app(container, state, (s: any) => [DIV, String(s.x), String(s.y)]);
|
|
78
81
|
|
|
79
82
|
state.patch([null, { x: 10 }, undefined, { y: 20 }]);
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
await delay(10);
|
|
85
|
+
|
|
86
|
+
await expect(state.x).toEqual(10);
|
|
87
|
+
await expect(state.y).toEqual(20);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
"patch(): returns Promise for generator functions, can be awaited": async () => {
|
|
91
|
+
const container = setup();
|
|
92
|
+
const state = createState({ count: 0 });
|
|
93
|
+
app<typeof state>(container, state, (s) => [DIV, String(s.count)]);
|
|
94
|
+
|
|
95
|
+
await expect(container._vode.stats.patchCount).toEqual(0);
|
|
96
|
+
const result = state.patch(function* () {
|
|
97
|
+
yield { count: 1 };
|
|
98
|
+
return { count: 2 };
|
|
99
|
+
});
|
|
100
|
+
await expect(container._vode.stats.patchCount).toEqual(1);
|
|
101
|
+
|
|
102
|
+
expect(result).toBeA("object");
|
|
103
|
+
await expect(result instanceof Promise).toEqual(true);
|
|
104
|
+
|
|
105
|
+
await result;
|
|
106
|
+
await expect(container._vode.stats.patchCount).toEqual(3);
|
|
107
|
+
|
|
108
|
+
await expect(state.count).toEqual(2);
|
|
109
|
+
await expect(container).toMatch([DIV, "2"]);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
"patch(): returns Promise for Promise patches, can be awaited": async () => {
|
|
113
|
+
const container = setup();
|
|
114
|
+
const state = createState({ msg: "before" });
|
|
115
|
+
app<typeof state>(container, state, (s) => [DIV, s.msg]);
|
|
116
|
+
|
|
117
|
+
const result = state.patch(Promise.resolve({ msg: "after" }));
|
|
118
|
+
|
|
119
|
+
expect(result).toBeA("object");
|
|
120
|
+
await expect(result instanceof Promise).toEqual(true);
|
|
121
|
+
|
|
122
|
+
await result;
|
|
123
|
+
|
|
124
|
+
await expect(state.msg).toEqual("after");
|
|
125
|
+
await expect(container).toMatch([DIV, "after"]);
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
"patch(): returns void for object patches": async () => {
|
|
129
|
+
const container = setup();
|
|
130
|
+
const state = createState({ x: 1 });
|
|
131
|
+
app<typeof state>(container, state, (s) => [DIV, String(s.x)]);
|
|
132
|
+
|
|
133
|
+
const result = state.patch({ x: 2 });
|
|
134
|
+
|
|
135
|
+
expect(result).toBeA("undefined");
|
|
136
|
+
|
|
137
|
+
await expect(state.x).toEqual(2);
|
|
138
|
+
await expect(container).toMatch([DIV, "2"]);
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
"patch(): forward promise error when one happens during patch": async () => {
|
|
142
|
+
const container = setup();
|
|
143
|
+
const state = createState({ msg: "before" });
|
|
144
|
+
app<typeof state>(container, state, (s) => [DIV, s.msg]);
|
|
145
|
+
|
|
146
|
+
const mockPromise = Promise.withResolvers<void>();
|
|
147
|
+
const promisePatchResult = state.patch(mockPromise.promise);
|
|
148
|
+
mockPromise.reject(new Error("promise error"));
|
|
149
|
+
|
|
150
|
+
let err = await expect(() => promisePatchResult)
|
|
151
|
+
.toFailAsync("promise (1) error expected");
|
|
152
|
+
expect(err.message).toEqual("promise error");
|
|
153
|
+
|
|
154
|
+
err = await expect(() => state.patch(async () => {
|
|
155
|
+
await delay(1);
|
|
156
|
+
throw new Error("promise error")
|
|
157
|
+
})).toFailAsync("promise (2) error expected");
|
|
158
|
+
expect(err.message).toEqual("promise error");
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
"patch(): forward generator error when one happens during patch": async () => {
|
|
162
|
+
const container = setup();
|
|
163
|
+
const state = createState({ msg: "before" });
|
|
164
|
+
app<typeof state>(container, state, (s) => [DIV, s.msg]);
|
|
165
|
+
|
|
166
|
+
const err = await expect(
|
|
167
|
+
() => state.patch(
|
|
168
|
+
async function* () {
|
|
169
|
+
yield {};
|
|
170
|
+
await delay(1);
|
|
171
|
+
yield {};
|
|
172
|
+
throw new Error("generator error");
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
).toFailAsync("generator error expected");
|
|
176
|
+
expect(err.message).toEqual("generator error");
|
|
177
|
+
},
|
|
178
|
+
"patch(): forward error when one happens during patch": async () => {
|
|
179
|
+
const container = setup();
|
|
180
|
+
const state = createState({ msg: "before" });
|
|
181
|
+
app<typeof state>(container, state, (s) => [DIV, s.msg]);
|
|
182
|
+
|
|
183
|
+
const err = await expect(
|
|
184
|
+
() => state.patch(
|
|
185
|
+
() => {
|
|
186
|
+
throw new Error("void error");
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
).toFailAsync("void error expected");
|
|
190
|
+
expect(err.message).toEqual("void error");
|
|
83
191
|
},
|
|
84
192
|
};
|
|
@@ -9,58 +9,58 @@ function setup() {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
|
-
"patch-merge: array property replaces existing array": () => {
|
|
12
|
+
"patch-merge: array property replaces existing array": async () => {
|
|
13
13
|
const container = setup();
|
|
14
14
|
const state: any = createState({ items: [1, 2, 3] });
|
|
15
15
|
app(container, state, () => [DIV]);
|
|
16
16
|
|
|
17
17
|
state.patch({ items: [4, 5, 6] });
|
|
18
18
|
|
|
19
|
-
expect(state.items).toEqual([4, 5, 6]);
|
|
19
|
+
await expect(state.items).toEqual([4, 5, 6]);
|
|
20
20
|
},
|
|
21
21
|
|
|
22
|
-
"patch-merge: Date property stores correctly": () => {
|
|
22
|
+
"patch-merge: Date property stores correctly": async () => {
|
|
23
23
|
const container = setup();
|
|
24
24
|
const state: any = createState({ date: new Date("2024-01-01") });
|
|
25
25
|
app(container, state, () => [DIV]);
|
|
26
26
|
|
|
27
27
|
state.patch({ date: new Date("2025-06-15") });
|
|
28
28
|
|
|
29
|
-
expect(state.date instanceof Date).toEqual(true);
|
|
30
|
-
expect(state.date.getFullYear()).toEqual(2025);
|
|
31
|
-
expect(state.date.getMonth()).toEqual(5);
|
|
32
|
-
expect(state.date.getDate()).toEqual(15);
|
|
29
|
+
await expect(state.date instanceof Date).toEqual(true);
|
|
30
|
+
await expect(state.date.getFullYear()).toEqual(2025);
|
|
31
|
+
await expect(state.date.getMonth()).toEqual(5);
|
|
32
|
+
await expect(state.date.getDate()).toEqual(15);
|
|
33
33
|
},
|
|
34
34
|
|
|
35
|
-
"patch-merge: object replaces existing array property": () => {
|
|
35
|
+
"patch-merge: object replaces existing array property": async () => {
|
|
36
36
|
const container = setup();
|
|
37
37
|
const state: any = createState({ data: [1, 2, 3] });
|
|
38
38
|
app(container, state, () => [DIV]);
|
|
39
39
|
|
|
40
40
|
state.patch({ data: { key: "value" } });
|
|
41
41
|
|
|
42
|
-
expect(Array.isArray(state.data)).toEqual(false);
|
|
43
|
-
expect(state.data.key).toEqual("value");
|
|
42
|
+
await expect(Array.isArray(state.data)).toEqual(false);
|
|
43
|
+
await expect(state.data.key).toEqual("value");
|
|
44
44
|
},
|
|
45
45
|
|
|
46
|
-
"patch-merge: object replaces existing primitive property": () => {
|
|
46
|
+
"patch-merge: object replaces existing primitive property": async () => {
|
|
47
47
|
const container = setup();
|
|
48
48
|
const state: any = createState({ value: 42 });
|
|
49
49
|
app(container, state, () => [DIV]);
|
|
50
50
|
|
|
51
51
|
state.patch({ value: { nested: true } });
|
|
52
52
|
|
|
53
|
-
expect(state.value.nested).toEqual(true);
|
|
53
|
+
await expect(state.value.nested).toEqual(true);
|
|
54
54
|
},
|
|
55
55
|
|
|
56
|
-
"patch-merge: new array property via patch": () => {
|
|
56
|
+
"patch-merge: new array property via patch": async () => {
|
|
57
57
|
const container = setup();
|
|
58
58
|
const state: any = createState({ name: "test" });
|
|
59
59
|
app(container, state, () => [DIV]);
|
|
60
60
|
|
|
61
61
|
state.patch({ tags: ["a", "b", "c"] });
|
|
62
62
|
|
|
63
|
-
expect(Array.isArray(state.tags)).toEqual(true);
|
|
64
|
-
expect(state.tags).toEqual(["a", "b", "c"]);
|
|
63
|
+
await expect(Array.isArray(state.tags)).toEqual(true);
|
|
64
|
+
await expect(state.tags).toEqual(["a", "b", "c"]);
|
|
65
65
|
},
|
|
66
66
|
};
|
package/test/tests-props.ts
CHANGED
|
@@ -2,33 +2,33 @@ import { props, DIV, SPAN } from "../index";
|
|
|
2
2
|
import { expect } from "./helper";
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
"props(): on vode with props returns props object": () => {
|
|
6
|
-
expect(props([DIV, { class: "foo" }, "hello"]))
|
|
5
|
+
"props(): on vode with props returns props object": async () => {
|
|
6
|
+
await expect(props([DIV, { class: "foo" }, "hello"]))
|
|
7
7
|
.toEqual({ class: "foo" });
|
|
8
8
|
},
|
|
9
9
|
|
|
10
|
-
"props(): on just-tag vode returns undefined": () => {
|
|
11
|
-
expect(props([DIV])).toEqual(undefined);
|
|
10
|
+
"props(): on just-tag vode returns undefined": async () => {
|
|
11
|
+
await expect(props([DIV])).toEqual(undefined);
|
|
12
12
|
},
|
|
13
13
|
|
|
14
|
-
"props(): on text vode returns undefined": () => {
|
|
15
|
-
expect(props("hello")).toEqual(undefined);
|
|
14
|
+
"props(): on text vode returns undefined": async () => {
|
|
15
|
+
await expect(props("hello")).toEqual(undefined);
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
-
"props(): on vode where second element is an array (child) returns undefined": () => {
|
|
19
|
-
expect(props([DIV, [SPAN]] as any)).toEqual(undefined);
|
|
18
|
+
"props(): on vode where second element is an array (child) returns undefined": async () => {
|
|
19
|
+
await expect(props([DIV, [SPAN]] as any)).toEqual(undefined);
|
|
20
20
|
},
|
|
21
21
|
|
|
22
|
-
"props(): on vode where second element is null returns undefined": () => {
|
|
23
|
-
expect(props([DIV, null as any, "hi"])).toEqual(undefined);
|
|
22
|
+
"props(): on vode where second element is null returns undefined": async () => {
|
|
23
|
+
await expect(props([DIV, null as any, "hi"])).toEqual(undefined);
|
|
24
24
|
},
|
|
25
25
|
|
|
26
|
-
"props(): on falsy input returns undefined": () => {
|
|
27
|
-
expect(props(null as any)).toEqual(undefined);
|
|
28
|
-
expect(props(undefined as any)).toEqual(undefined);
|
|
26
|
+
"props(): on falsy input returns undefined": async () => {
|
|
27
|
+
await expect(props(null as any)).toEqual(undefined);
|
|
28
|
+
await expect(props(undefined as any)).toEqual(undefined);
|
|
29
29
|
},
|
|
30
30
|
|
|
31
|
-
"props(): on vode with length 1 returns undefined": () => {
|
|
32
|
-
expect(props([DIV] as any)).toEqual(undefined);
|
|
31
|
+
"props(): on vode with length 1 returns undefined": async () => {
|
|
32
|
+
await expect(props([DIV] as any)).toEqual(undefined);
|
|
33
33
|
}
|
|
34
34
|
};
|
|
@@ -3,135 +3,135 @@ import { context, ProxySubContext } from "../src/state-context";
|
|
|
3
3
|
import { createState } from "../src/vode";
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
|
-
"StateContext.state: returns the state reference": () => {
|
|
6
|
+
"StateContext.state: returns the state reference": async () => {
|
|
7
7
|
const state = createState({ x: 10 });
|
|
8
8
|
const ctx = context(state);
|
|
9
9
|
|
|
10
|
-
expect((ctx).state === state)
|
|
10
|
+
await expect((ctx).state === state)
|
|
11
11
|
.toEqual(true);
|
|
12
12
|
},
|
|
13
13
|
|
|
14
|
-
"StateContext.get() returns whole state": () => {
|
|
14
|
+
"StateContext.get() returns whole state": async () => {
|
|
15
15
|
const state = createState({ a: 1, b: 2 });
|
|
16
16
|
const ctx = context(state);
|
|
17
17
|
|
|
18
|
-
expect(ctx.get())
|
|
18
|
+
await expect(ctx.get())
|
|
19
19
|
.toEqual({ a: 1, b: 2 });
|
|
20
20
|
},
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
"StateContext.get(): deep nested": () => {
|
|
23
|
+
"StateContext.get(): deep nested": async () => {
|
|
24
24
|
const state = createState({ a: { b: { c: 42 } } });
|
|
25
25
|
const ctx = context(state);
|
|
26
26
|
|
|
27
|
-
expect(ctx.a.b.c.get())
|
|
27
|
+
await expect(ctx.a.b.c.get())
|
|
28
28
|
.toEqual(42);
|
|
29
29
|
},
|
|
30
30
|
|
|
31
|
-
"StateContext.get(): missing nested path returns undefined": () => {
|
|
31
|
+
"StateContext.get(): missing nested path returns undefined": async () => {
|
|
32
32
|
const state = createState({ a: {} });
|
|
33
33
|
const ctx = context(state);
|
|
34
34
|
|
|
35
|
-
expect((ctx.a as any).b.get())
|
|
35
|
+
await expect((ctx.a as any).b.get())
|
|
36
36
|
.toEqual(undefined);
|
|
37
37
|
},
|
|
38
38
|
|
|
39
|
-
"StateContext.put(): silently mutates state": () => {
|
|
39
|
+
"StateContext.put(): silently mutates state": async () => {
|
|
40
40
|
const state = createState({ a: { b: 1 } });
|
|
41
41
|
const ctx = context(state);
|
|
42
42
|
ctx.a.b.put(2);
|
|
43
43
|
|
|
44
|
-
expect(state.a.b)
|
|
44
|
+
await expect(state.a.b)
|
|
45
45
|
.toEqual(2);
|
|
46
46
|
},
|
|
47
47
|
|
|
48
|
-
"StateContext.put() on nested object replaces the sub-object": () => {
|
|
48
|
+
"StateContext.put() on nested object replaces the sub-object": async () => {
|
|
49
49
|
const state = createState({ a: { b: { x: 1, y: 2 } } });
|
|
50
50
|
const ctx = context(state);
|
|
51
51
|
ctx.a.b.put({ y: 99 });
|
|
52
52
|
|
|
53
|
-
expect(state.a.b)
|
|
53
|
+
await expect(state.a.b)
|
|
54
54
|
.toEqual({ y: 99 });
|
|
55
55
|
},
|
|
56
56
|
|
|
57
|
-
"StateContext.put() at root level with empty keys": () => {
|
|
57
|
+
"StateContext.put() at root level with empty keys": async () => {
|
|
58
58
|
const state = createState({ a: 1, b: 2 });
|
|
59
59
|
const ctx = context(state);
|
|
60
60
|
ctx.put({ b: undefined });
|
|
61
61
|
|
|
62
|
-
expect(state)
|
|
62
|
+
await expect(state)
|
|
63
63
|
.toEqual({ a: 1 });
|
|
64
64
|
},
|
|
65
65
|
|
|
66
|
-
"StateContext.patch(): calls state.patch with proper deep partial": () => {
|
|
66
|
+
"StateContext.patch(): calls state.patch with proper deep partial": async () => {
|
|
67
67
|
const state = createState({ a: { b: 1 } });
|
|
68
68
|
const ctx = context(state);
|
|
69
69
|
ctx.a.b.patch(2);
|
|
70
70
|
|
|
71
71
|
const patches = (state as any).patch.initialPatches;
|
|
72
72
|
|
|
73
|
-
expect(patches.length)
|
|
73
|
+
await expect(patches.length)
|
|
74
74
|
.toEqual(1);
|
|
75
|
-
expect(patches[0])
|
|
75
|
+
await expect(patches[0])
|
|
76
76
|
.toEqual({ a: { b: 2 } });
|
|
77
77
|
},
|
|
78
78
|
|
|
79
|
-
"StateContext.patch(): async wraps in array": () => {
|
|
79
|
+
"StateContext.patch(): async wraps in array": async () => {
|
|
80
80
|
const state = createState({ a: { b: 1 } });
|
|
81
81
|
const ctx = context(state);
|
|
82
82
|
ctx.a.b.patch(2, true);
|
|
83
83
|
|
|
84
84
|
const patches = (state as any).patch.initialPatches;
|
|
85
85
|
|
|
86
|
-
expect(patches.length)
|
|
86
|
+
await expect(patches.length)
|
|
87
87
|
.toEqual(1);
|
|
88
|
-
expect(Array.isArray(patches[0]))
|
|
88
|
+
await expect(Array.isArray(patches[0]))
|
|
89
89
|
.toEqual(true);
|
|
90
|
-
expect(patches[0][0])
|
|
90
|
+
await expect(patches[0][0])
|
|
91
91
|
.toEqual({ a: { b: 2 } });
|
|
92
92
|
},
|
|
93
93
|
|
|
94
|
-
"StateContext.patch() on nested deep path three levels": () => {
|
|
94
|
+
"StateContext.patch() on nested deep path three levels": async () => {
|
|
95
95
|
const state = createState({ x: { y: { z: 0 } } });
|
|
96
96
|
const ctx = context(state);
|
|
97
97
|
ctx.x.y.z.patch(100);
|
|
98
98
|
|
|
99
99
|
const patches = (state as any).patch.initialPatches;
|
|
100
100
|
|
|
101
|
-
expect(patches.length)
|
|
101
|
+
await expect(patches.length)
|
|
102
102
|
.toEqual(1);
|
|
103
|
-
expect(patches[0])
|
|
103
|
+
await expect(patches[0])
|
|
104
104
|
.toEqual({ x: { y: { z: 100 } } });
|
|
105
105
|
},
|
|
106
106
|
|
|
107
|
-
"StateContext.put() with intermediate null creates objects along the path": () => {
|
|
107
|
+
"StateContext.put() with intermediate null creates objects along the path": async () => {
|
|
108
108
|
const state = createState({ a: null as { b: number } | null });
|
|
109
109
|
const ctx = context(state);
|
|
110
110
|
|
|
111
111
|
ctx.a.b.put(42);
|
|
112
|
-
expect(state.a?.b).toEqual(42);
|
|
112
|
+
await expect(state.a?.b).toEqual(42);
|
|
113
113
|
|
|
114
114
|
ctx.a.put(null);
|
|
115
|
-
expect(state.a).toEqual(null);
|
|
116
|
-
expect(state.a?.b).toEqual(undefined);
|
|
115
|
+
await expect(state.a).toEqual(null);
|
|
116
|
+
await expect(state.a?.b).toEqual(undefined);
|
|
117
117
|
},
|
|
118
118
|
|
|
119
|
-
"StateContext.put() with three-level intermediate null": () => {
|
|
119
|
+
"StateContext.put() with three-level intermediate null": async () => {
|
|
120
120
|
const state = createState({ a: null as { b: { c: number } } | null });
|
|
121
121
|
const ctx = context(state);
|
|
122
122
|
|
|
123
123
|
ctx.a.b.c.put(99);
|
|
124
124
|
|
|
125
|
-
expect(state.a?.b.c).toEqual(99);
|
|
125
|
+
await expect(state.a?.b.c).toEqual(99);
|
|
126
126
|
},
|
|
127
127
|
|
|
128
|
-
"StateContext.put() with multiple intermediate nulls": () => {
|
|
128
|
+
"StateContext.put() with multiple intermediate nulls": async () => {
|
|
129
129
|
const state = createState({ a: { x: null as { z: string } | null, y: 1 } });
|
|
130
130
|
const ctx = context(state);
|
|
131
131
|
|
|
132
132
|
ctx.a.x.z.put("deep");
|
|
133
133
|
|
|
134
|
-
expect(state.a.x?.z).toEqual("deep");
|
|
135
|
-
expect(state.a.y).toEqual(1);
|
|
134
|
+
await expect(state.a.x?.z).toEqual("deep");
|
|
135
|
+
await expect(state.a.y).toEqual(1);
|
|
136
136
|
},
|
|
137
137
|
};
|
package/test/tests-tag.ts
CHANGED
|
@@ -2,32 +2,32 @@ import { tag, DIV, SPAN } from "../index";
|
|
|
2
2
|
import { expect } from "./helper";
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
"tag(): on a vode returns the tag name": () => {
|
|
6
|
-
expect(tag([DIV]))
|
|
5
|
+
"tag(): on a vode returns the tag name": async () => {
|
|
6
|
+
await expect(tag([DIV]))
|
|
7
7
|
.toEqual("div");
|
|
8
8
|
},
|
|
9
9
|
|
|
10
|
-
"tag(): on a vode with props and children": () => {
|
|
11
|
-
expect(tag([DIV, { class: "foo" }, [SPAN, "hi"]]))
|
|
10
|
+
"tag(): on a vode with props and children": async () => {
|
|
11
|
+
await expect(tag([DIV, { class: "foo" }, [SPAN, "hi"]]))
|
|
12
12
|
.toEqual("div");
|
|
13
13
|
},
|
|
14
14
|
|
|
15
|
-
"tag(): on a text vode (string) returns #text": () => {
|
|
16
|
-
expect(tag("hello"))
|
|
15
|
+
"tag(): on a text vode (string) returns #text": async () => {
|
|
16
|
+
await expect(tag("hello"))
|
|
17
17
|
.toEqual("#text");
|
|
18
18
|
},
|
|
19
19
|
|
|
20
|
-
"tag(): on falsy values returns undefined": () => {
|
|
21
|
-
expect(tag(null)).toEqual(undefined);
|
|
22
|
-
expect(tag(undefined)).toEqual(undefined);
|
|
20
|
+
"tag(): on falsy values returns undefined": async () => {
|
|
21
|
+
await expect(tag(null)).toEqual(undefined);
|
|
22
|
+
await expect(tag(undefined)).toEqual(undefined);
|
|
23
23
|
},
|
|
24
24
|
|
|
25
|
-
"tag(): on no-vode values returns undefined": () => {
|
|
26
|
-
expect(tag(0)).toEqual(undefined);
|
|
27
|
-
expect(tag(true)).toEqual(undefined);
|
|
25
|
+
"tag(): on no-vode values returns undefined": async () => {
|
|
26
|
+
await expect(tag(0)).toEqual(undefined);
|
|
27
|
+
await expect(tag(true)).toEqual(undefined);
|
|
28
28
|
},
|
|
29
29
|
|
|
30
|
-
"tag(): on empty array returns undefined": () => {
|
|
31
|
-
expect(tag([])).toEqual(undefined);
|
|
30
|
+
"tag(): on empty array returns undefined": async () => {
|
|
31
|
+
await expect(tag([])).toEqual(undefined);
|
|
32
32
|
}
|
|
33
33
|
};
|
package/test/tests-vode.ts
CHANGED
|
@@ -2,14 +2,14 @@ import { vode, DIV, Vode, SPAN, STRONG } from "../index";
|
|
|
2
2
|
import { expect } from "./helper";
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
"vode(): passing an already constructed vode returns it": () => {
|
|
5
|
+
"vode(): passing an already constructed vode returns it": async () => {
|
|
6
6
|
const testVode: Vode = [DIV, { class: 'test' }, "hello world"];
|
|
7
7
|
|
|
8
|
-
expect(vode(testVode)).toEqual(testVode);
|
|
8
|
+
await expect(vode(testVode)).toEqual(testVode);
|
|
9
9
|
},
|
|
10
10
|
|
|
11
|
-
"vode(): constructing a vode from parts": () => {
|
|
12
|
-
expect(
|
|
11
|
+
"vode(): constructing a vode from parts": async () => {
|
|
12
|
+
await expect(
|
|
13
13
|
vode(DIV, { class: 'test' },
|
|
14
14
|
[SPAN, "hello"],
|
|
15
15
|
[STRONG, { style: 'color: green' }, "world"])
|
|
@@ -20,8 +20,8 @@ export default {
|
|
|
20
20
|
);
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
"vode(): passing an invalid tag fails": () => {
|
|
23
|
+
"vode(): passing an invalid tag fails": async () => {
|
|
24
24
|
const err = expect(() => vode(null as any)).toFail();
|
|
25
|
-
expect(err.message).toEqual("first argument to vode() must be a tag name or a vode");
|
|
25
|
+
await expect(err.message).toEqual("first argument to vode() must be a tag name or a vode");
|
|
26
26
|
}
|
|
27
27
|
};
|