@adviser/cement 0.2.29 → 0.2.30

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.
@@ -1,321 +0,0 @@
1
- import { KeyedResolvOnce, ResolveOnce, ResolveSeq } from "@adviser/cement";
2
-
3
- describe("resolve-once", () => {
4
- it("sequence", async () => {
5
- const once = new ResolveOnce<number>();
6
-
7
- const reallyOnce = vi.fn(async () => {
8
- return new Promise<number>((resolve) => {
9
- setTimeout(() => {
10
- resolve(42);
11
- }, 100);
12
- });
13
- });
14
- const start = Date.now();
15
- const fn = (): Promise<number> => once.once(async () => reallyOnce());
16
- expect(reallyOnce).toHaveBeenCalledTimes(0);
17
- expect(await fn()).toBe(42);
18
- expect(reallyOnce).toHaveBeenCalledTimes(1);
19
- expect(await fn()).toBe(42);
20
- expect(reallyOnce).toHaveBeenCalledTimes(1);
21
- expect(await fn()).toBe(42);
22
- expect(reallyOnce).toHaveBeenCalledTimes(1);
23
- const diff = Date.now() - start;
24
- expect(diff).toBeGreaterThanOrEqual(99);
25
- expect(diff).toBeLessThan(150);
26
- });
27
- it("parallel", async () => {
28
- const once = new ResolveOnce<number>();
29
- const reallyOnce = vi.fn(async () => {
30
- return new Promise<number>((resolve) => {
31
- setTimeout(() => {
32
- resolve(42);
33
- }, 100);
34
- });
35
- });
36
- const fn = (): Promise<number> => once.once(async () => reallyOnce());
37
- const start = Date.now();
38
- expect(
39
- await Promise.all(
40
- Array(100)
41
- .fill(fn)
42
- .map((fn) => fn()),
43
- ),
44
- ).toEqual(Array(100).fill(42));
45
- expect(reallyOnce).toHaveBeenCalledTimes(1);
46
- const diff = Date.now() - start;
47
- expect(diff).toBeGreaterThanOrEqual(99);
48
- expect(diff).toBeLessThan(150);
49
- });
50
-
51
- it("works with void", async () => {
52
- const once = new ResolveOnce<void>();
53
- const reallyOnce = vi.fn(async () => {
54
- return new Promise<void>((resolve) => {
55
- setTimeout(() => {
56
- resolve();
57
- }, 100);
58
- });
59
- });
60
- const fn = (): Promise<void> => once.once(async () => reallyOnce());
61
- const start = Date.now();
62
- expect(
63
- await Promise.all(
64
- Array(100)
65
- .fill(fn)
66
- .map((fn) => fn()),
67
- ),
68
- ).toEqual(Array(100).fill(undefined));
69
- expect(reallyOnce).toHaveBeenCalledTimes(1);
70
- const diff = Date.now() - start;
71
- expect(diff).toBeGreaterThanOrEqual(99);
72
- expect(diff).toBeLessThan(150);
73
- });
74
-
75
- it("throws", async () => {
76
- const once = new ResolveOnce<number>();
77
- const reallyOnce = vi.fn(async () => {
78
- return new Promise<number>((rs, rj) => {
79
- setTimeout(() => {
80
- rj(new Error("nope"));
81
- }, 100);
82
- });
83
- });
84
- const fn = (): Promise<number> => once.once(async () => reallyOnce());
85
- const start = Date.now();
86
- await new Promise((rs) => {
87
- for (let i = 0; i < 100; i++) {
88
- fn()
89
- .then(() => {
90
- assert.fail("should not happen");
91
- })
92
- .catch((e) => {
93
- expect(e).toEqual(new Error("nope"));
94
- expect(reallyOnce).toHaveBeenCalledTimes(1);
95
- if (i === 99) {
96
- rs(undefined);
97
- }
98
- });
99
- }
100
- });
101
- const diff = Date.now() - start;
102
- expect(diff).toBeGreaterThanOrEqual(99);
103
- expect(diff).toBeLessThan(150);
104
- });
105
-
106
- it("preserves order", async () => {
107
- const once = new ResolveOnce<number>();
108
- const reallyOnce = vi.fn(async () => {
109
- return new Promise<number>((resolve) => {
110
- setTimeout(() => {
111
- resolve(42);
112
- }, 100);
113
- });
114
- });
115
- let order = 0;
116
- const fn = async (): Promise<string> => {
117
- const o = order++;
118
- const ret = await once.once(async () => reallyOnce());
119
- return `${o}:${ret}`;
120
- };
121
- const start = Date.now();
122
- expect(
123
- await Promise.all(
124
- Array(100)
125
- .fill(fn)
126
- .map((fn) => fn()),
127
- ),
128
- ).toEqual(
129
- Array(100)
130
- .fill(undefined)
131
- .map((_, i) => `${i}:42`),
132
- );
133
- expect(reallyOnce).toHaveBeenCalledTimes(1);
134
- const diff = Date.now() - start;
135
- expect(diff).toBeGreaterThanOrEqual(99);
136
- expect(diff).toBeLessThan(150);
137
- });
138
-
139
- it("preserves call order to resolv order", async () => {
140
- const once = new ResolveOnce<number>();
141
- const reallyOnce = vi.fn(async () => {
142
- return new Promise<number>((resolve) => {
143
- setTimeout(() => {
144
- resolve(42);
145
- }, 100);
146
- });
147
- });
148
- const start = Date.now();
149
- const orderFn = vi.fn();
150
- const fns = Array(100)
151
- .fill(0)
152
- .map((_, i) => {
153
- return once
154
- .once(() => reallyOnce())
155
- .then((once) => {
156
- orderFn(i, once);
157
- // expect(i).toBe(order++);
158
- return `${i}:${once}`;
159
- });
160
- });
161
- expect(await Promise.all(fns)).toEqual(
162
- Array(100)
163
- .fill(undefined)
164
- .map((_, i) => `${i}:42`),
165
- );
166
- expect(reallyOnce).toHaveBeenCalledTimes(1);
167
- const diff = Date.now() - start;
168
- expect(diff).toBeGreaterThanOrEqual(99);
169
- expect(diff).toBeLessThan(150);
170
- expect(orderFn).toHaveBeenCalledTimes(100);
171
- expect(orderFn.mock.calls.map(([i]) => i)).toEqual(
172
- Array(100)
173
- .fill(0)
174
- .map((_, i) => i),
175
- );
176
- });
177
-
178
- it("reset", async () => {
179
- const once = new ResolveOnce<number>();
180
- const orderFn = vi.fn(async () => 42);
181
- once.once(orderFn);
182
- once.once(orderFn);
183
- once.once(orderFn);
184
- once.reset();
185
- once.once(orderFn);
186
- once.once(orderFn);
187
- once.reset();
188
- once.once(orderFn);
189
- once.once(orderFn);
190
- once.reset();
191
- expect(orderFn).toHaveBeenCalledTimes(3);
192
- });
193
-
194
- it("keyed", async () => {
195
- const keyed = new KeyedResolvOnce<number>();
196
- const a_orderFn = vi.fn(async () => 42);
197
- const b_orderFn = vi.fn(async () => 42);
198
- for (let i = 0; i < 5; i++) {
199
- keyed.get("a").once(a_orderFn);
200
- keyed.get(() => "a").once(a_orderFn);
201
- keyed.get("b").once(b_orderFn);
202
- keyed.get(() => "b").once(b_orderFn);
203
- expect(a_orderFn).toHaveBeenCalledTimes(i + 1);
204
- expect(b_orderFn).toHaveBeenCalledTimes(i + 1);
205
- keyed.reset();
206
- }
207
- });
208
-
209
- it("keyed with pass ctx", async () => {
210
- const keyed = new KeyedResolvOnce<number>();
211
- const a_orderFn = vi.fn(async (key) => key);
212
- const b_orderFn = vi.fn(async (key) => key);
213
- await Promise.all([
214
- keyed.get("a").once(a_orderFn),
215
- keyed.get(() => "a").once(a_orderFn),
216
- keyed.get("b").once(b_orderFn),
217
- keyed.get(() => "b").once(b_orderFn),
218
- ]);
219
- expect(a_orderFn).toHaveBeenCalledTimes(1);
220
- expect(a_orderFn).toHaveBeenCalledWith("a");
221
- expect(b_orderFn).toHaveBeenCalledTimes(1);
222
- expect(b_orderFn).toHaveBeenCalledWith("b");
223
- });
224
-
225
- it("keyed asyncGet", async () => {
226
- const keyed = new KeyedResolvOnce<number>();
227
- const a_orderFn = vi.fn(async (key) => key);
228
- const b_orderFn = vi.fn(async (key) => key);
229
- await Promise.all([
230
- keyed
231
- .asyncGet(async () => {
232
- await new Promise((resolve) => setTimeout(resolve, 100));
233
- return "a";
234
- })
235
- .then((resolveOnce) => {
236
- resolveOnce.once(a_orderFn);
237
- }),
238
- keyed
239
- .asyncGet(async () => {
240
- await new Promise((resolve) => setTimeout(resolve, 50));
241
- return "b";
242
- })
243
- .then((resolveOnce) => {
244
- resolveOnce.once(b_orderFn);
245
- }),
246
- ]);
247
- expect(a_orderFn).toHaveBeenCalledTimes(1);
248
- expect(a_orderFn).toHaveBeenCalledWith("a");
249
- expect(b_orderFn).toHaveBeenCalledTimes(1);
250
- expect(b_orderFn).toHaveBeenCalledWith("b");
251
- });
252
-
253
- function shuffle<T>(array: T[]): T[] {
254
- let currentIndex = array.length;
255
-
256
- // While there remain elements to shuffle...
257
- while (currentIndex != 0) {
258
- // Pick a remaining element...
259
- const randomIndex = Math.floor(Math.random() * currentIndex);
260
- currentIndex--;
261
-
262
- // And swap it with the current element.
263
- [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
264
- }
265
- return array;
266
- }
267
-
268
- it("ResolveSeq", async () => {
269
- const seq = new ResolveSeq<number>();
270
- let enter = 0;
271
- let leave = 0;
272
- const actions = Array(10)
273
- .fill(0)
274
- .map((_, i) => {
275
- return seq.add(async () => {
276
- expect(enter++).toBe(i);
277
- await new Promise((resolve) => setTimeout(resolve, i * 3));
278
- await new Promise((resolve) => setTimeout(resolve, i * 2));
279
- expect(leave++).toBe(i);
280
- expect(leave).toBe(enter);
281
- return i;
282
- }, i);
283
- });
284
- const ret = await Promise.all(shuffle(actions));
285
- expect(ret.length).toBe(10);
286
- expect(enter).toBe(10);
287
- expect(leave).toBe(10);
288
- });
289
-
290
- it("with promise", async () => {
291
- const once = new ResolveOnce<number>();
292
- let val = 42;
293
- const fn = async (): Promise<number> => {
294
- return new Promise<number>((resolve) => {
295
- setTimeout(() => {
296
- resolve(val++);
297
- }, 10);
298
- });
299
- };
300
- expect(await once.once(fn)).toBe(42);
301
- expect(await once.once(fn)).toBe(42);
302
- });
303
-
304
- it("without promise", () => {
305
- const once = new ResolveOnce<number>();
306
- let val = 42;
307
- const fn = (): number => val++;
308
- expect(once.once(fn)).toBe(42);
309
- expect(once.once(fn)).toBe(42);
310
- });
311
-
312
- it("without promise but exception", () => {
313
- const once = new ResolveOnce<number>();
314
- let val = 42;
315
- const fn = (): Promise<number> => {
316
- throw new Error(`nope ${val++}`);
317
- };
318
- expect(() => once.once(fn)).toThrowError("nope 42");
319
- expect(() => once.once(fn)).toThrowError("nope 42");
320
- });
321
- });
@@ -1,102 +0,0 @@
1
- import { exception2Result, Result, WithoutResult } from "@adviser/cement";
2
- // import { it } from "vitest/globals";
3
-
4
- it("ResultOk", () => {
5
- const result = Result.Ok(1);
6
- expect(result.isOk()).toBe(true);
7
- expect(result.is_ok()).toBe(true);
8
- expect(result.Ok()).toBe(1);
9
- expect(result.unwrap()).toBe(1);
10
-
11
- expect(result.isErr()).toBe(false);
12
- expect(result.is_err()).toBe(false);
13
- expect(() => result.Err()).toThrow();
14
- expect(() => result.unwrap_err()).toThrow();
15
- });
16
-
17
- it("ResultErr", () => {
18
- const result = Result.Err("xxx");
19
- expect(result.isOk()).toBe(false);
20
- expect(result.is_ok()).toBe(false);
21
- expect(result.Err().message).toEqual("xxx");
22
- expect(result.unwrap_err().message).toBe("xxx");
23
-
24
- expect(result.isErr()).toBe(true);
25
- expect(result.is_err()).toBe(true);
26
- expect(() => result.Ok()).toThrow();
27
- expect(() => result.unwrap()).toThrow();
28
- });
29
-
30
- // eslint-disable-next-line @typescript-eslint/no-extraneous-class
31
- class xResult {}
32
- class fakeResult {
33
- is_ok(): boolean {
34
- return true;
35
- }
36
- is_err(): boolean {
37
- return false;
38
- }
39
- unwrap(): number {
40
- return 1;
41
- }
42
- unwrap_err(): Error {
43
- throw new Error("Result is Ok");
44
- }
45
- }
46
- it("is Result", () => {
47
- expect(Result.Is(Result.Ok(1))).toBe(true);
48
- expect(Result.Is(Result.Err("xxx"))).toEqual(true);
49
- expect(Result.Is(new fakeResult())).toBe(true);
50
- expect(Result.Is(new xResult())).toBe(false);
51
- });
52
-
53
- it("WithoutResult", () => {
54
- const result = Result.Ok({ a: 1 });
55
- const a1: Partial<WithoutResult<typeof result>> = {};
56
- a1.a = 1;
57
- expect(a1.a).toEqual(1);
58
- expect(result.Ok().a).toEqual(1);
59
- });
60
-
61
- it("sync exception2Result ok", () => {
62
- expect(exception2Result(() => 1)).toEqual(Result.Ok(1));
63
- });
64
-
65
- it("sync exception2Result throw", () => {
66
- expect(
67
- exception2Result(() => {
68
- throw new Error("x");
69
- }),
70
- ).toEqual(Result.Err("x"));
71
- });
72
-
73
- it("async exception2Result ok", async () => {
74
- expect(await exception2Result(async () => 1)).toEqual(Result.Ok(1));
75
- });
76
-
77
- it("async exception2Result throw", async () => {
78
- expect(
79
- await exception2Result(async () => {
80
- throw new Error("x");
81
- }),
82
- ).toEqual(Result.Err("x"));
83
- });
84
-
85
- it("result typ", () => {
86
- function ok(): Result<number> {
87
- return Result.Ok(1);
88
- }
89
- function err(): Result<number> {
90
- return Result.Err("x");
91
- }
92
- expect(ok().Ok()).toBe(1);
93
- expect(err().Err().message).toBe("x");
94
- });
95
-
96
- // it("Result.OK with void", () => {
97
- // const result = Result.Ok();
98
- // expect(result.isOk()).toBe(true);
99
- // expect(result.is_ok()).toBe(true);
100
- // expect(result.isErr()).toBe(false);
101
- // expect(result.is_err()).toBe(false);
102
- // }
@@ -1,53 +0,0 @@
1
- import { BrowserEnvActions, EnvImpl, envFactory } from "@adviser/cement";
2
-
3
- describe("sys_env", () => {
4
- let key: string;
5
- const envImpl = envFactory();
6
- beforeEach(() => {
7
- key = `key-${Math.random()}`;
8
- });
9
- it("actions", () => {
10
- expect(envImpl.get(key)).toBeUndefined();
11
- envImpl.set(key, "value");
12
- expect(envImpl.get(key)).toBe("value");
13
- envImpl.set(key);
14
- expect(envImpl.get(key)).toBe("value");
15
- envImpl.delete(key);
16
- expect(envImpl.get(key)).toBeUndefined();
17
- });
18
- it("preset", () => {
19
- const env = new EnvImpl(new BrowserEnvActions({}), {
20
- presetEnv: new Map([[key, "value"]]),
21
- });
22
- expect(env.get(key)).toBe("value");
23
- env.delete(key);
24
- expect(env.get(key)).toBeUndefined();
25
- });
26
- it("onSet wild card", () => {
27
- const fn = vi.fn();
28
- envImpl.onSet(fn);
29
- expect(fn).toBeCalledTimes(envImpl.keys().length);
30
- expect(fn.mock.calls.map((i) => i[0]).sort()).toEqual(envImpl.keys().sort());
31
- expect(fn.mock.calls.map((i) => i[1]).sort()).toEqual(
32
- envImpl
33
- .keys()
34
- .map((i) => envImpl.get(i))
35
- .sort(),
36
- );
37
- });
38
- it("onSet filter", () => {
39
- const env = new EnvImpl(new BrowserEnvActions({}), {
40
- presetEnv: new Map([[key, "value"]]),
41
- });
42
- const fn = vi.fn();
43
- env.onSet(fn, key);
44
- expect(fn).toBeCalledTimes(1);
45
- expect(fn.mock.calls[0]).toEqual([key, "value"]);
46
- env.set(key, "value2");
47
- expect(fn).toBeCalledTimes(2);
48
- expect(fn.mock.calls[1]).toEqual([key, "value2"]);
49
- env.delete(key);
50
- expect(fn).toBeCalledTimes(3);
51
- expect(fn.mock.calls[2]).toEqual([key, undefined]);
52
- });
53
- });