@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.
@@ -2,43 +2,44 @@ import { expect } from "./helper";
2
2
  import { memo, DIV, app, createState, SPAN, H1, BR, P, UL, LI, Component } from "../index";
3
3
 
4
4
  export default {
5
- "memo(): throws when compare is not an array": () => {
5
+ "memo(): throws when compare is not an array": async () => {
6
6
  const err = expect(() => memo(null as any, (s: any) => [DIV]))
7
7
  .toFail();
8
- expect(err.message)
8
+ await expect(err.message)
9
9
  .toEqual("first argument to memo() must be an array of values to compare");
10
10
  },
11
11
 
12
- "memo(): throws when componentOrProps is not a function": () => {
12
+ "memo(): throws when componentOrProps is not a function": async () => {
13
13
  const err = expect(() => memo([1], null as any))
14
14
  .toFail();
15
- expect(err.message)
15
+ await expect(err.message)
16
16
  .toEqual("second argument to memo() must be a function that returns a child vode");
17
17
  },
18
18
 
19
- "memo(): integration with app prevents re-render when deps match": () => {
19
+ "memo(): integration with app prevents re-render when deps match": async () => {
20
20
  const state = createState({ count: 12 });
21
21
  const root = document.createElement("div");
22
22
  const container = document.createElement("div");
23
23
  root.appendChild(container);
24
24
 
25
- let callCount = 0;
25
+ let box: { callCount: number } = { callCount: 0 };
26
26
  app<typeof state>(container, state, (s) => [DIV, memo(
27
27
  [s.count],
28
28
  (s) => {
29
- callCount++;
29
+ box.callCount++;
30
30
  return [DIV, [SPAN, `${s.count}`]];
31
31
  }
32
32
  )]);
33
33
 
34
34
 
35
- expect(callCount).toEqual(1);
35
+ await expect(box).toEqual({ callCount: 1 });
36
36
 
37
37
  state.patch({ count: 12 }); //same value, should not re-render
38
- expect(callCount).toEqual(1);
38
+ await expect(box).toEqual({ callCount: 1 });
39
39
  state.patch({ count: 13 }); //different value, should re-render
40
- expect(callCount).toEqual(2);
41
- expect(container).toMatch(
40
+
41
+ await expect(box).toEqual({ callCount: 2 });
42
+ await expect(container).toMatch(
42
43
  [DIV,
43
44
  [DIV,
44
45
  [SPAN, "13"]
@@ -47,7 +48,7 @@ export default {
47
48
  );
48
49
  },
49
50
 
50
- "memo(): can be used with a nested component function": () => {
51
+ "memo(): can be used with a nested component function": async () => {
51
52
  const state = createState({ count: 12 });
52
53
  const root = document.createElement("div");
53
54
  const container = document.createElement("div");
@@ -64,20 +65,20 @@ export default {
64
65
  )]);
65
66
 
66
67
 
67
- expect(callCount).toEqual(1);
68
+ await expect(callCount).toEqual(1);
68
69
  state.patch({ count: 12 }); //same value, should not re-render
69
- expect(callCount).toEqual(1);
70
+ await expect(callCount).toEqual(1);
70
71
  },
71
72
 
72
- "memo(): can be used with the same component function": () => {
73
+ "memo(): can be used with the same component function": async () => {
73
74
  const state = createState({ test: "foo" });
74
75
  const root = document.createElement("div");
75
76
  const container = document.createElement("div");
76
77
  root.appendChild(container);
77
78
 
78
- let callCount = 0;
79
+ let box: { callCount: number } = { callCount: 0 };
79
80
  const Comp: Component<typeof state> = (s) => {
80
- callCount++;
81
+ box.callCount++;
81
82
  return [DIV, [SPAN, s.test]];
82
83
  };
83
84
  app<typeof state>(container, state, (s) => [DIV,
@@ -92,11 +93,11 @@ export default {
92
93
  ]);
93
94
 
94
95
 
95
- expect(callCount).toEqual(2);
96
+ await expect(box).toEqual({ callCount: 2 }, "Each memo should call the component function once on initial render, even if they are the same function");
96
97
  state.patch({ test: "foo" });
97
- expect(callCount).toEqual(2);
98
+ await expect(box).toEqual({ callCount: 2 }, "Patching with the same value should not cause a re-render");
98
99
  state.patch({ test: "bar" });
99
- expect(callCount).toEqual(4);
100
+ await expect(box).toEqual({ callCount: 4 }, "Patching with a different value should cause both memos to re-render, even if they use the same component function");
100
101
  },
101
102
 
102
103
  "memo(): memo with many item list": () => {
@@ -129,15 +130,15 @@ export default {
129
130
  ]);
130
131
  },
131
132
 
132
- "memo(): double-wrapping ignores the inner memo dependencies, only the outer memo is checked": () => {
133
+ "memo(): double-wrapping ignores the inner memo dependencies, only the outer memo is checked": async () => {
133
134
  const state = createState({ outer: 1, inner: 1 });
134
135
  const root = document.createElement("div");
135
136
  const container = document.createElement("div");
136
137
  root.appendChild(container);
137
138
 
138
- let callCount = 0;
139
+ let box: { callCount: number } = { callCount: 0 };
139
140
  const comp = (s: typeof state) => {
140
- callCount++;
141
+ box.callCount++;
141
142
  return [DIV, `${s.outer}`];
142
143
  };
143
144
 
@@ -147,14 +148,14 @@ export default {
147
148
  expect(() => app(container, state, () => [DIV, doubleMemoed]))
148
149
  .toSucceed();
149
150
 
150
- expect(callCount).toEqual(1);
151
- expect(container).toMatch([DIV, [DIV, "1"]]);
151
+ await expect(box).toEqual({ callCount: 1 });
152
+ await expect(container).toMatch([DIV, [DIV, "1"]]);
152
153
 
153
154
  state.patch({ outer: 2 });
154
- expect(callCount).toEqual(2);
155
+ await expect(box).toEqual({ callCount: 2 });
155
156
  state.patch({ inner: 2 });
156
- expect(callCount).toEqual(2);
157
+ await expect(box).toEqual({ callCount: 2 });
157
158
  state.patch({ outer: 3 });
158
- expect(callCount).toEqual(3);
159
+ await expect(box).toEqual({ callCount: 3 });
159
160
  },
160
161
  };
@@ -2,62 +2,62 @@ import { mergeClass } from "../index";
2
2
  import { expect } from "./helper";
3
3
 
4
4
  export default {
5
- "mergeClass(): no args returns null": () => {
6
- expect(mergeClass()).toEqual(null);
5
+ "mergeClass(): no args returns null": async () => {
6
+ await expect(mergeClass()).toEqual(null);
7
7
  },
8
8
 
9
- "mergeClass(): single string returns it": () => {
10
- expect(mergeClass("foo")).toEqual("foo");
9
+ "mergeClass(): single string returns it": async () => {
10
+ await expect(mergeClass("foo")).toEqual("foo");
11
11
  },
12
12
 
13
- "mergeClass(): two strings are joined and deduplicated": () => {
14
- expect(mergeClass("foo", "bar")).toEqual("foo bar");
15
- expect(mergeClass("foo bar", "bar baz")).toEqual("foo bar baz");
13
+ "mergeClass(): two strings are joined and deduplicated": async () => {
14
+ await expect(mergeClass("foo", "bar")).toEqual("foo bar");
15
+ await expect(mergeClass("foo bar", "bar baz")).toEqual("foo bar baz");
16
16
  },
17
17
 
18
- "mergeClass(): string and array": () => {
19
- expect(mergeClass("foo", ["bar", "baz"])).toEqual("bar baz foo");
18
+ "mergeClass(): string and array": async () => {
19
+ await expect(mergeClass("foo", ["bar", "baz"])).toEqual("bar baz foo");
20
20
  },
21
21
 
22
- "mergeClass(): array and string": () => {
23
- expect(mergeClass(["foo", "bar"], "baz")).toEqual("foo bar baz");
22
+ "mergeClass(): array and string": async () => {
23
+ await expect(mergeClass(["foo", "bar"], "baz")).toEqual("foo bar baz");
24
24
  },
25
25
 
26
- "mergeClass(): two arrays": () => {
27
- expect(mergeClass(["foo", "bar"], ["baz", "qux"])).toEqual("foo bar baz qux");
26
+ "mergeClass(): two arrays": async () => {
27
+ await expect(mergeClass(["foo", "bar"], ["baz", "qux"])).toEqual("foo bar baz qux");
28
28
  },
29
29
 
30
- "mergeClass(): two string arrays with duplicates": () => {
31
- expect(mergeClass(["foo", "bar"], ["bar", "baz"])).toEqual("foo bar baz");
30
+ "mergeClass(): two string arrays with duplicates": async () => {
31
+ await expect(mergeClass(["foo", "bar"], ["bar", "baz"])).toEqual("foo bar baz");
32
32
  },
33
33
 
34
- "mergeClass(): string and object": () => {
35
- expect(mergeClass("foo", { bar: true, baz: false })).toEqual({ foo: true, bar: true, baz: false });
34
+ "mergeClass(): string and object": async () => {
35
+ await expect(mergeClass("foo", { bar: true, baz: false })).toEqual({ foo: true, bar: true, baz: false });
36
36
  },
37
37
 
38
- "mergeClass(): object and string": () => {
39
- expect(mergeClass({ foo: true, bar: false }, "baz")).toEqual({ foo: true, bar: false, baz: true });
38
+ "mergeClass(): object and string": async () => {
39
+ await expect(mergeClass({ foo: true, bar: false }, "baz")).toEqual({ foo: true, bar: false, baz: true });
40
40
  },
41
41
 
42
- "mergeClass(): two objects": () => {
43
- expect(mergeClass({ foo: true, bar: true }, { bar: false, baz: true })).toEqual({ foo: true, bar: false, baz: true });
42
+ "mergeClass(): two objects": async () => {
43
+ await expect(mergeClass({ foo: true, bar: true }, { bar: false, baz: true })).toEqual({ foo: true, bar: false, baz: true });
44
44
  },
45
45
 
46
- "mergeClass(): object and array": () => {
47
- expect(mergeClass({ foo: true }, ["bar", "baz"])).toEqual({ foo: true, 0: "bar", 1: "baz" });
46
+ "mergeClass(): object and array": async () => {
47
+ await expect(mergeClass({ foo: true }, ["bar", "baz"])).toEqual({ foo: true, 0: "bar", 1: "baz" });
48
48
  },
49
49
 
50
- "mergeClass(): array and object": () => {
51
- expect(mergeClass(["foo", "bar"], { baz: true, qux: false })).toEqual({ 0: "foo", 1: "bar", baz: true, qux: false });
50
+ "mergeClass(): array and object": async () => {
51
+ await expect(mergeClass(["foo", "bar"], { baz: true, qux: false })).toEqual({ 0: "foo", 1: "bar", baz: true, qux: false });
52
52
  },
53
53
 
54
- "mergeClass(): falsy entries are skipped": () => {
55
- expect(mergeClass("foo", null, "bar")).toEqual("foo bar");
56
- expect(mergeClass(null, "foo", undefined, "bar")).toEqual("foo bar");
54
+ "mergeClass(): falsy entries are skipped": async () => {
55
+ await expect(mergeClass("foo", null, "bar")).toEqual("foo bar");
56
+ await expect(mergeClass(null, "foo", undefined, "bar")).toEqual("foo bar");
57
57
  },
58
58
 
59
- "mergeClass(): multiple args (3+)": () => {
60
- expect(mergeClass("a", "b", "c")).toEqual("a b c");
61
- expect(mergeClass("x", null, ["y", "z"], "w")).toEqual("y z x w");
59
+ "mergeClass(): multiple args (3+)": async () => {
60
+ await expect(mergeClass("a", "b", "c")).toEqual("a b c");
61
+ await expect(mergeClass("x", null, ["y", "z"], "w")).toEqual("y z x w");
62
62
  }
63
63
  };
@@ -2,42 +2,42 @@ import { mergeProps, Props } from "../index";
2
2
  import { expect } from "./helper";
3
3
 
4
4
  export default {
5
- "mergeProps(): no args returns undefined": () => {
6
- expect(mergeProps()).toEqual(undefined);
5
+ "mergeProps(): no args returns undefined": async () => {
6
+ await expect(mergeProps()).toEqual(undefined);
7
7
  },
8
8
 
9
- "mergeProps(): single arg returned as-is": () => {
9
+ "mergeProps(): single arg returned as-is": async () => {
10
10
  const p = { class: "foo" };
11
- expect(mergeProps(p) === p).toEqual(true);
11
+ await expect(mergeProps(p) === p).toEqual(true);
12
12
  },
13
13
 
14
- "mergeProps(): two plain objects merged": () => {
15
- expect(mergeProps({ a: 1 }, { b: 2 })).toEqual({ a: 1, b: 2 });
14
+ "mergeProps(): two plain objects merged": async () => {
15
+ await expect(mergeProps({ a: 1 }, { b: 2 })).toEqual({ a: 1, b: 2 });
16
16
  },
17
17
 
18
- "mergeProps(): right overwrites left for simple keys": () => {
19
- expect(mergeProps({ a: 1, b: "x" }, { b: 2 })).toEqual({ a: 1, b: 2 });
18
+ "mergeProps(): right overwrites left for simple keys": async () => {
19
+ await expect(mergeProps({ a: 1, b: "x" }, { b: 2 })).toEqual({ a: 1, b: 2 });
20
20
  },
21
21
 
22
- "mergeProps(): class merged via mergeClass": () => {
23
- expect(mergeProps({ class: "foo" }, { class: "bar" })).toEqual({ class: "foo bar" });
22
+ "mergeProps(): class merged via mergeClass": async () => {
23
+ await expect(mergeProps({ class: "foo" }, { class: "bar" })).toEqual({ class: "foo bar" });
24
24
  },
25
25
 
26
- "mergeProps(): style merged via mergeStyle (strings)": () => {
26
+ "mergeProps(): style merged via mergeStyle (strings)": async () => {
27
27
  const result = mergeProps({ style: "color: red" }, { style: "font-size: 14px" }) as Props;
28
- expect((<string>result.style!).includes("color: red")).toEqual(true);
29
- expect((<string>result.style!).includes("font-size: 14px")).toEqual(true);
28
+ await expect((<string>result.style!).includes("color: red")).toEqual(true);
29
+ await expect((<string>result.style!).includes("font-size: 14px")).toEqual(true);
30
30
  },
31
31
 
32
- "mergeProps(): null and undefined entries skipped": () => {
33
- expect(mergeProps({ a: 1 }, null, { b: 2 }, undefined)).toEqual({ a: 1, b: 2 });
32
+ "mergeProps(): null and undefined entries skipped": async () => {
33
+ await expect(mergeProps({ a: 1 }, null, { b: 2 }, undefined)).toEqual({ a: 1, b: 2 });
34
34
  },
35
35
 
36
- "mergeProps(): multiple args (3+)": () => {
37
- expect(mergeProps({ a: 1 }, { b: 2 }, { c: 3 })).toEqual({ a: 1, b: 2, c: 3 });
36
+ "mergeProps(): multiple args (3+)": async () => {
37
+ await expect(mergeProps({ a: 1 }, { b: 2 }, { c: 3 })).toEqual({ a: 1, b: 2, c: 3 });
38
38
  },
39
39
 
40
- "mergeProps(): first arg null returns defined from later args": () => {
41
- expect(mergeProps(null, { a: 1 })).toEqual({ a: 1 });
40
+ "mergeProps(): first arg null returns defined from later args": async () => {
41
+ await expect(mergeProps(null, { a: 1 })).toEqual({ a: 1 });
42
42
  }
43
43
  };
@@ -1,39 +1,53 @@
1
1
  import { mergeStyle } from "../index";
2
2
  import { expect } from "./helper";
3
3
 
4
+ // Helper to normalize style strings for comparison (browser normalizes CSS differently)
5
+ function normalizeStyle(s: string): string {
6
+ return s.replace(/;\s*/g, ';').replace(/:\s*/g, ':').replace(/^;/, '').replace(/;$/, '').toLowerCase();
7
+ }
8
+
9
+ function hasStyle(result: string, prop: string, value: string): boolean {
10
+ const normalized = normalizeStyle(result);
11
+ return normalized.includes(`${prop}:${value}`.toLowerCase());
12
+ }
13
+
4
14
  export default {
5
- "mergeStyle(): no args returns empty string": () => {
6
- expect(mergeStyle()).toEqual("");
15
+ "mergeStyle(): no args returns empty string": async () => {
16
+ await expect(mergeStyle()).toEqual("");
7
17
  },
8
18
 
9
- "mergeStyle(): object style sets properties, returns cssText": () => {
19
+ "mergeStyle(): object style sets properties, returns cssText": async () => {
10
20
  const result = mergeStyle({ color: "red", fontSize: "14px" });
11
- expect(typeof result).toEqual("string");
21
+ await expect(typeof result).toEqual("string");
12
22
  },
13
23
 
14
- "mergeStyle(): single string starts with semicolon": () => {
15
- expect(mergeStyle("color: red")).toEqual(";color: red");
24
+ "mergeStyle(): single string includes the style": async () => {
25
+ const result = mergeStyle("color: red") as string;
26
+ await expect(hasStyle(result, "color", "red")).toEqual(true);
16
27
  },
17
28
 
18
- "mergeStyle(): two strings are concatenated": () => {
19
- expect(mergeStyle("color: red", "font-size: 14px")).toEqual(";color: red;font-size: 14px");
29
+ "mergeStyle(): two strings are concatenated": async () => {
30
+ const result = mergeStyle("color: red", "font-size: 14px") as string;
31
+ await expect(hasStyle(result, "color", "red")).toEqual(true);
32
+ await expect(hasStyle(result, "font-size", "14px")).toEqual(true);
20
33
  },
21
34
 
22
- "mergeStyle(): object then string": () => {
35
+ "mergeStyle(): object then string": async () => {
23
36
  const result = mergeStyle({ color: "red" }, "font-size: 14px") as string;
24
- expect(result.indexOf("font-size: 14px") > 0).toEqual(true);
37
+ await expect(hasStyle(result, "font-size", "14px")).toEqual(true);
25
38
  },
26
39
 
27
- "mergeStyle(): null and undefined entries are skipped": () => {
28
- expect(mergeStyle(null, "color: red", undefined)).toEqual(";color: red");
40
+ "mergeStyle(): null and undefined entries are skipped": async () => {
41
+ const result = mergeStyle(null, "color: red", undefined) as string;
42
+ await expect(hasStyle(result, "color", "red")).toEqual(true);
29
43
  },
30
44
 
31
- "mergeStyle(): multiple objects and strings alternate": () => {
45
+ "mergeStyle(): multiple objects and strings alternate": async () => {
32
46
  const result = mergeStyle(
33
47
  { color: "red" },
34
48
  "font-size: 14px",
35
49
  { background: "blue" }
36
50
  ) as string;
37
- expect(result.includes("font-size: 14px")).toEqual(true);
51
+ await expect(hasStyle(result, "font-size", "14px")).toEqual(true);
38
52
  }
39
53
  };