@fluidframework/core-utils 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.0
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/CHANGELOG.md +23 -0
- package/dist/legacy.d.ts +20 -0
- package/dist/public.d.ts +12 -0
- package/internal.d.ts +11 -0
- package/legacy.d.ts +11 -0
- package/lib/legacy.d.ts +20 -0
- package/lib/public.d.ts +12 -0
- package/package.json +24 -45
- package/api-extractor-cjs.json +0 -8
- package/dist/core-utils-alpha.d.ts +0 -195
- package/dist/core-utils-beta.d.ts +0 -45
- package/dist/core-utils-public.d.ts +0 -45
- package/dist/core-utils-untrimmed.d.ts +0 -432
- package/lib/core-utils-alpha.d.ts +0 -195
- package/lib/core-utils-beta.d.ts +0 -45
- package/lib/core-utils-public.d.ts +0 -45
- package/lib/core-utils-untrimmed.d.ts +0 -432
- package/lib/test/assert.spec.js +0 -21
- package/lib/test/assert.spec.js.map +0 -1
- package/lib/test/bench/compareArrays.bench.spec.js +0 -105
- package/lib/test/bench/compareArrays.bench.spec.js.map +0 -1
- package/lib/test/compareArrays.spec.js +0 -43
- package/lib/test/compareArrays.spec.js.map +0 -1
- package/lib/test/promiseCache.spec.js +0 -244
- package/lib/test/promiseCache.spec.js.map +0 -1
- package/lib/test/timer.spec.js +0 -274
- package/lib/test/timer.spec.js.map +0 -1
- package/lib/test/types/compareArrays.type.js +0 -21
- package/lib/test/types/compareArrays.type.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { useFakeTimers } from "sinon";
|
|
7
|
-
import { PromiseCache } from "@fluidframework/core-utils";
|
|
8
|
-
describe("PromiseCache", () => {
|
|
9
|
-
describe("Basic Cache Mechanism", () => {
|
|
10
|
-
let pc;
|
|
11
|
-
it("addOrGet", async () => {
|
|
12
|
-
pc = new PromiseCache();
|
|
13
|
-
const contains_WhenAbsent = pc.has(1);
|
|
14
|
-
assert.equal(contains_WhenAbsent, false);
|
|
15
|
-
const get_WhenAbsent = pc.get(1);
|
|
16
|
-
assert.equal(get_WhenAbsent, undefined);
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
18
|
-
assert.equal(await get_WhenAbsent, undefined);
|
|
19
|
-
const remove_WhenAbsent = pc.remove(1);
|
|
20
|
-
assert.equal(remove_WhenAbsent, false);
|
|
21
|
-
const addOrGet_WhenAbsent = await pc.addOrGet(1, async () => "one");
|
|
22
|
-
assert.equal(addOrGet_WhenAbsent, "one");
|
|
23
|
-
const contains_WhenPresent = pc.has(1);
|
|
24
|
-
assert.equal(contains_WhenPresent, true);
|
|
25
|
-
const get_WhenPresent = await pc.get(1);
|
|
26
|
-
assert.equal(get_WhenPresent, "one");
|
|
27
|
-
const addOrGet_WhenPresent = await pc.addOrGet(1, async () => {
|
|
28
|
-
throw new Error("Test error");
|
|
29
|
-
});
|
|
30
|
-
assert.equal(addOrGet_WhenPresent, "one");
|
|
31
|
-
const remove_WhenPresent = pc.remove(1);
|
|
32
|
-
assert.equal(remove_WhenPresent, true);
|
|
33
|
-
const get_AfterRemove = pc.get(1);
|
|
34
|
-
assert.equal(get_AfterRemove, undefined);
|
|
35
|
-
const contains_AfterRemove = pc.has(1);
|
|
36
|
-
assert.equal(contains_AfterRemove, false);
|
|
37
|
-
});
|
|
38
|
-
it("addValueOrGet", async () => {
|
|
39
|
-
pc = new PromiseCache();
|
|
40
|
-
const addValueOrGet_Result = await pc.addValueOrGet(1, "one");
|
|
41
|
-
assert.equal(addValueOrGet_Result, "one");
|
|
42
|
-
});
|
|
43
|
-
it("add", async () => {
|
|
44
|
-
pc = new PromiseCache();
|
|
45
|
-
const add_WhenAbsent = pc.add(1, async () => "one");
|
|
46
|
-
assert.equal(add_WhenAbsent, true);
|
|
47
|
-
const add_WhenPresent = pc.add(1, async () => {
|
|
48
|
-
throw new Error("Test error");
|
|
49
|
-
});
|
|
50
|
-
assert.equal(add_WhenPresent, false);
|
|
51
|
-
const get_AfterAdd = await pc.get(1);
|
|
52
|
-
assert.equal(get_AfterAdd, "one");
|
|
53
|
-
});
|
|
54
|
-
it("addValue", async () => {
|
|
55
|
-
pc = new PromiseCache();
|
|
56
|
-
const addValue_Result = pc.addValue(1, "one");
|
|
57
|
-
assert.equal(addValue_Result, true);
|
|
58
|
-
const get_AfterAddValue = await pc.get(1);
|
|
59
|
-
assert.equal(get_AfterAddValue, "one");
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe("asyncFn behavior", () => {
|
|
63
|
-
const thrower = async (removeOnError) => {
|
|
64
|
-
throw new Error(removeOnError ? "remove" : "Don't remove");
|
|
65
|
-
};
|
|
66
|
-
const removeOnErrorByMessage = (error) => error.message === "remove";
|
|
67
|
-
let pc;
|
|
68
|
-
it("asyncFn run immediately and only if key not set", () => {
|
|
69
|
-
pc = new PromiseCache();
|
|
70
|
-
let callCount = 0;
|
|
71
|
-
const fn = async () => {
|
|
72
|
-
++callCount;
|
|
73
|
-
return "hello!";
|
|
74
|
-
};
|
|
75
|
-
// fn runs immediately...
|
|
76
|
-
pc.add(1, fn);
|
|
77
|
-
assert.equal(callCount, 1);
|
|
78
|
-
// ...but not if the key is already set...
|
|
79
|
-
pc.add(1, fn);
|
|
80
|
-
assert.equal(callCount, 1);
|
|
81
|
-
// ...even if set by value
|
|
82
|
-
callCount = 0;
|
|
83
|
-
pc.addValue(2, "Some value");
|
|
84
|
-
pc.add(2, fn);
|
|
85
|
-
assert.equal(callCount, 0);
|
|
86
|
-
});
|
|
87
|
-
it("asyncFn throws: addOrGet, non-async, removeOnError=false", async () => {
|
|
88
|
-
pc = new PromiseCache({
|
|
89
|
-
removeOnError: removeOnErrorByMessage,
|
|
90
|
-
});
|
|
91
|
-
const asyncFn = async () => thrower(false /* removeOnError */);
|
|
92
|
-
const addOrGet1 = pc.addOrGet(1, asyncFn);
|
|
93
|
-
await assert.rejects(addOrGet1);
|
|
94
|
-
const contains1 = pc.has(1);
|
|
95
|
-
assert.equal(contains1, true);
|
|
96
|
-
});
|
|
97
|
-
it("asyncFn throws: add, non-async, removeOnError=false", async () => {
|
|
98
|
-
pc = new PromiseCache({
|
|
99
|
-
removeOnError: removeOnErrorByMessage,
|
|
100
|
-
});
|
|
101
|
-
const asyncFn = async () => thrower(false /* removeOnError */);
|
|
102
|
-
const add2 = pc.add(2, asyncFn);
|
|
103
|
-
assert.equal(add2, true);
|
|
104
|
-
const get2 = pc.get(2);
|
|
105
|
-
if (get2 === undefined) {
|
|
106
|
-
assert.fail();
|
|
107
|
-
}
|
|
108
|
-
await assert.rejects(get2);
|
|
109
|
-
});
|
|
110
|
-
it("asyncFn throws: addOrGet, async, removeOnError=false", async () => {
|
|
111
|
-
pc = new PromiseCache({
|
|
112
|
-
removeOnError: removeOnErrorByMessage,
|
|
113
|
-
});
|
|
114
|
-
const asyncFn = async () => thrower(false /* removeOnError */);
|
|
115
|
-
const p3 = pc.addOrGet(3, asyncFn);
|
|
116
|
-
await assert.rejects(p3);
|
|
117
|
-
const contains3 = pc.has(3);
|
|
118
|
-
assert.equal(contains3, true);
|
|
119
|
-
});
|
|
120
|
-
it("asyncFn throws: add, async, removeOnError=false", async () => {
|
|
121
|
-
pc = new PromiseCache({
|
|
122
|
-
removeOnError: removeOnErrorByMessage,
|
|
123
|
-
});
|
|
124
|
-
const asyncFn = async () => thrower(false /* removeOnError */);
|
|
125
|
-
const add4 = pc.add(4, asyncFn);
|
|
126
|
-
assert.equal(add4, true);
|
|
127
|
-
const get4 = pc.get(4);
|
|
128
|
-
if (get4 === undefined) {
|
|
129
|
-
assert.fail();
|
|
130
|
-
}
|
|
131
|
-
await assert.rejects(get4);
|
|
132
|
-
});
|
|
133
|
-
it("asyncFn throws: addOrGet, non-async, removeOnError=true", async () => {
|
|
134
|
-
pc = new PromiseCache({
|
|
135
|
-
removeOnError: removeOnErrorByMessage,
|
|
136
|
-
});
|
|
137
|
-
const asyncFn = async () => thrower(true /* removeOnError */);
|
|
138
|
-
const p5 = pc.addOrGet(5, asyncFn);
|
|
139
|
-
const contains5a = pc.has(5);
|
|
140
|
-
assert.equal(contains5a, true, "Shouldn't be removed yet; hasn't run yet");
|
|
141
|
-
await assert.rejects(p5);
|
|
142
|
-
const contains5b = pc.has(5);
|
|
143
|
-
assert.equal(contains5b, false, "Should be removed after rejecting");
|
|
144
|
-
});
|
|
145
|
-
it("asyncFn throws: add, non-async, removeOnError=true", async () => {
|
|
146
|
-
pc = new PromiseCache({
|
|
147
|
-
removeOnError: removeOnErrorByMessage,
|
|
148
|
-
});
|
|
149
|
-
const asyncFn = async () => thrower(true /* removeOnError */);
|
|
150
|
-
const add6 = pc.add(6, asyncFn);
|
|
151
|
-
assert.equal(add6, true);
|
|
152
|
-
const get6 = pc.get(6);
|
|
153
|
-
if (get6 === undefined) {
|
|
154
|
-
assert.fail("Shouldn't be removed yet; hasn't run yet");
|
|
155
|
-
}
|
|
156
|
-
await assert.rejects(get6);
|
|
157
|
-
const contains6 = pc.has(6);
|
|
158
|
-
assert.equal(contains6, false, "Should be removed after rejecting");
|
|
159
|
-
});
|
|
160
|
-
it("asyncFn throws: addOrGet, async, removeOnError=true", async () => {
|
|
161
|
-
pc = new PromiseCache({
|
|
162
|
-
removeOnError: removeOnErrorByMessage,
|
|
163
|
-
});
|
|
164
|
-
const asyncFn = async () => thrower(true /* removeOnError */);
|
|
165
|
-
const p7 = pc.addOrGet(7, asyncFn);
|
|
166
|
-
const contains7a = pc.has(7);
|
|
167
|
-
assert.equal(contains7a, true, "Shouldn't be removed yet; hasn't run yet");
|
|
168
|
-
await assert.rejects(p7);
|
|
169
|
-
const contains7b = pc.has(7);
|
|
170
|
-
assert.equal(contains7b, false, "Should be removed after rejecting");
|
|
171
|
-
});
|
|
172
|
-
it("asyncFn throws: add, async, removeOnError=true", async () => {
|
|
173
|
-
pc = new PromiseCache({
|
|
174
|
-
removeOnError: removeOnErrorByMessage,
|
|
175
|
-
});
|
|
176
|
-
const asyncFn = async () => thrower(true /* removeOnError */);
|
|
177
|
-
const add8 = pc.add(8, asyncFn);
|
|
178
|
-
assert.equal(add8, true);
|
|
179
|
-
const get8 = pc.get(8);
|
|
180
|
-
if (get8 === undefined) {
|
|
181
|
-
assert.fail("Shouldn't be removed yet; hasn't run yet");
|
|
182
|
-
}
|
|
183
|
-
await assert.rejects(get8);
|
|
184
|
-
const contains8 = pc.has(8);
|
|
185
|
-
assert.equal(contains8, false, "Should be removed after rejecting");
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
describe("Garbage Collection and Expiry", () => {
|
|
189
|
-
let clock;
|
|
190
|
-
let pc;
|
|
191
|
-
// Useful for debugging the tests
|
|
192
|
-
const enableLogging = false; // Set to true to see timing logs
|
|
193
|
-
function logClock(m) {
|
|
194
|
-
if (enableLogging) {
|
|
195
|
-
console.log(`${m} ${clock.now}`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
before(() => {
|
|
199
|
-
clock = useFakeTimers();
|
|
200
|
-
});
|
|
201
|
-
after(() => {
|
|
202
|
-
clock.restore();
|
|
203
|
-
});
|
|
204
|
-
it("absolute expiry", async () => {
|
|
205
|
-
pc = new PromiseCache({
|
|
206
|
-
expiry: { policy: "absolute", durationMs: 15 },
|
|
207
|
-
});
|
|
208
|
-
pc.addValue(1, "one");
|
|
209
|
-
clock.tick(10);
|
|
210
|
-
assert.equal(pc.has(1), true);
|
|
211
|
-
await pc.addValueOrGet(1, "one");
|
|
212
|
-
clock.tick(10);
|
|
213
|
-
assert.equal(pc.has(1), false);
|
|
214
|
-
});
|
|
215
|
-
it("sliding expiry", async () => {
|
|
216
|
-
const expiration = 15;
|
|
217
|
-
pc = new PromiseCache({
|
|
218
|
-
expiry: { policy: "sliding", durationMs: expiration },
|
|
219
|
-
});
|
|
220
|
-
const startTime = clock.now;
|
|
221
|
-
logClock("start");
|
|
222
|
-
// Each of these operations should reset the sliding expiry
|
|
223
|
-
pc.add(1, async () => "one");
|
|
224
|
-
clock.tick(10);
|
|
225
|
-
pc.addValue(1, "one");
|
|
226
|
-
clock.tick(10);
|
|
227
|
-
await pc.addOrGet(1, async () => "one");
|
|
228
|
-
clock.tick(10);
|
|
229
|
-
await pc.addValueOrGet(1, "one");
|
|
230
|
-
clock.tick(10);
|
|
231
|
-
await pc.get(1);
|
|
232
|
-
clock.tick(10);
|
|
233
|
-
const endTime = clock.now;
|
|
234
|
-
logClock("endtime");
|
|
235
|
-
// More than the initial expiry elapsed but the entry wasn't evicted
|
|
236
|
-
assert.equal(endTime - startTime > expiration, true);
|
|
237
|
-
assert.equal(pc.has(1), true);
|
|
238
|
-
clock.tick(expiration);
|
|
239
|
-
logClock("later");
|
|
240
|
-
assert.equal(pc.has(1), false);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
//# sourceMappingURL=promiseCache.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"promiseCache.spec.js","sourceRoot":"","sources":["../../src/test/promiseCache.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport type { SinonFakeTimers } from \"sinon\";\nimport { useFakeTimers } from \"sinon\";\nimport { PromiseCache } from \"@fluidframework/core-utils\";\n\ndescribe(\"PromiseCache\", () => {\n\tdescribe(\"Basic Cache Mechanism\", () => {\n\t\tlet pc: PromiseCache<number, string> | undefined;\n\n\t\tit(\"addOrGet\", async () => {\n\t\t\tpc = new PromiseCache<number, string>();\n\n\t\t\tconst contains_WhenAbsent = pc.has(1);\n\t\t\tassert.equal(contains_WhenAbsent, false);\n\n\t\t\tconst get_WhenAbsent = pc.get(1);\n\t\t\tassert.equal(get_WhenAbsent, undefined);\n\t\t\t// eslint-disable-next-line @typescript-eslint/await-thenable\n\t\t\tassert.equal(await get_WhenAbsent, undefined);\n\n\t\t\tconst remove_WhenAbsent = pc.remove(1);\n\t\t\tassert.equal(remove_WhenAbsent, false);\n\n\t\t\tconst addOrGet_WhenAbsent = await pc.addOrGet(1, async () => \"one\");\n\t\t\tassert.equal(addOrGet_WhenAbsent, \"one\");\n\n\t\t\tconst contains_WhenPresent = pc.has(1);\n\t\t\tassert.equal(contains_WhenPresent, true);\n\n\t\t\tconst get_WhenPresent = await pc.get(1);\n\t\t\tassert.equal(get_WhenPresent, \"one\");\n\n\t\t\tconst addOrGet_WhenPresent = await pc.addOrGet(1, async () => {\n\t\t\t\tthrow new Error(\"Test error\");\n\t\t\t});\n\t\t\tassert.equal(addOrGet_WhenPresent, \"one\");\n\n\t\t\tconst remove_WhenPresent = pc.remove(1);\n\t\t\tassert.equal(remove_WhenPresent, true);\n\n\t\t\tconst get_AfterRemove = pc.get(1);\n\t\t\tassert.equal(get_AfterRemove, undefined);\n\n\t\t\tconst contains_AfterRemove = pc.has(1);\n\t\t\tassert.equal(contains_AfterRemove, false);\n\t\t});\n\n\t\tit(\"addValueOrGet\", async () => {\n\t\t\tpc = new PromiseCache<number, string>();\n\n\t\t\tconst addValueOrGet_Result = await pc.addValueOrGet(1, \"one\");\n\t\t\tassert.equal(addValueOrGet_Result, \"one\");\n\t\t});\n\n\t\tit(\"add\", async () => {\n\t\t\tpc = new PromiseCache<number, string>();\n\n\t\t\tconst add_WhenAbsent = pc.add(1, async () => \"one\");\n\t\t\tassert.equal(add_WhenAbsent, true);\n\n\t\t\tconst add_WhenPresent = pc.add(1, async () => {\n\t\t\t\tthrow new Error(\"Test error\");\n\t\t\t});\n\t\t\tassert.equal(add_WhenPresent, false);\n\n\t\t\tconst get_AfterAdd = await pc.get(1);\n\t\t\tassert.equal(get_AfterAdd, \"one\");\n\t\t});\n\n\t\tit(\"addValue\", async () => {\n\t\t\tpc = new PromiseCache<number, string>();\n\n\t\t\tconst addValue_Result = pc.addValue(1, \"one\");\n\t\t\tassert.equal(addValue_Result, true);\n\n\t\t\tconst get_AfterAddValue = await pc.get(1);\n\t\t\tassert.equal(get_AfterAddValue, \"one\");\n\t\t});\n\t});\n\n\tdescribe(\"asyncFn behavior\", () => {\n\t\tconst thrower = async (removeOnError: boolean): Promise<string> => {\n\t\t\tthrow new Error(removeOnError ? \"remove\" : \"Don't remove\");\n\t\t};\n\n\t\tconst removeOnErrorByMessage = (error: Error): boolean => error.message === \"remove\";\n\t\tlet pc: PromiseCache<number, string> | undefined;\n\n\t\tit(\"asyncFn run immediately and only if key not set\", () => {\n\t\t\tpc = new PromiseCache<number, string>();\n\n\t\t\tlet callCount = 0;\n\t\t\tconst fn = async (): Promise<string> => {\n\t\t\t\t++callCount;\n\t\t\t\treturn \"hello!\";\n\t\t\t};\n\n\t\t\t// fn runs immediately...\n\t\t\tpc.add(1, fn);\n\t\t\tassert.equal(callCount, 1);\n\n\t\t\t// ...but not if the key is already set...\n\t\t\tpc.add(1, fn);\n\t\t\tassert.equal(callCount, 1);\n\n\t\t\t// ...even if set by value\n\t\t\tcallCount = 0;\n\t\t\tpc.addValue(2, \"Some value\");\n\t\t\tpc.add(2, fn);\n\t\t\tassert.equal(callCount, 0);\n\t\t});\n\n\t\tit(\"asyncFn throws: addOrGet, non-async, removeOnError=false\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(false /* removeOnError */);\n\n\t\t\tconst addOrGet1 = pc.addOrGet(1, asyncFn);\n\t\t\tawait assert.rejects(addOrGet1);\n\t\t\tconst contains1 = pc.has(1);\n\t\t\tassert.equal(contains1, true);\n\t\t});\n\n\t\tit(\"asyncFn throws: add, non-async, removeOnError=false\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(false /* removeOnError */);\n\n\t\t\tconst add2 = pc.add(2, asyncFn);\n\t\t\tassert.equal(add2, true);\n\t\t\tconst get2 = pc.get(2);\n\t\t\tif (get2 === undefined) {\n\t\t\t\tassert.fail();\n\t\t\t}\n\t\t\tawait assert.rejects(get2);\n\t\t});\n\n\t\tit(\"asyncFn throws: addOrGet, async, removeOnError=false\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(false /* removeOnError */);\n\n\t\t\tconst p3 = pc.addOrGet(3, asyncFn);\n\t\t\tawait assert.rejects(p3);\n\t\t\tconst contains3 = pc.has(3);\n\t\t\tassert.equal(contains3, true);\n\t\t});\n\n\t\tit(\"asyncFn throws: add, async, removeOnError=false\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(false /* removeOnError */);\n\n\t\t\tconst add4 = pc.add(4, asyncFn);\n\t\t\tassert.equal(add4, true);\n\t\t\tconst get4 = pc.get(4);\n\t\t\tif (get4 === undefined) {\n\t\t\t\tassert.fail();\n\t\t\t}\n\t\t\tawait assert.rejects(get4);\n\t\t});\n\n\t\tit(\"asyncFn throws: addOrGet, non-async, removeOnError=true\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(true /* removeOnError */);\n\n\t\t\tconst p5 = pc.addOrGet(5, asyncFn);\n\t\t\tconst contains5a = pc.has(5);\n\t\t\tassert.equal(contains5a, true, \"Shouldn't be removed yet; hasn't run yet\");\n\n\t\t\tawait assert.rejects(p5);\n\t\t\tconst contains5b = pc.has(5);\n\t\t\tassert.equal(contains5b, false, \"Should be removed after rejecting\");\n\t\t});\n\n\t\tit(\"asyncFn throws: add, non-async, removeOnError=true\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(true /* removeOnError */);\n\n\t\t\tconst add6 = pc.add(6, asyncFn);\n\t\t\tassert.equal(add6, true);\n\t\t\tconst get6 = pc.get(6);\n\t\t\tif (get6 === undefined) {\n\t\t\t\tassert.fail(\"Shouldn't be removed yet; hasn't run yet\");\n\t\t\t}\n\n\t\t\tawait assert.rejects(get6);\n\t\t\tconst contains6 = pc.has(6);\n\t\t\tassert.equal(contains6, false, \"Should be removed after rejecting\");\n\t\t});\n\n\t\tit(\"asyncFn throws: addOrGet, async, removeOnError=true\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(true /* removeOnError */);\n\n\t\t\tconst p7 = pc.addOrGet(7, asyncFn);\n\t\t\tconst contains7a = pc.has(7);\n\t\t\tassert.equal(contains7a, true, \"Shouldn't be removed yet; hasn't run yet\");\n\n\t\t\tawait assert.rejects(p7);\n\t\t\tconst contains7b = pc.has(7);\n\t\t\tassert.equal(contains7b, false, \"Should be removed after rejecting\");\n\t\t});\n\n\t\tit(\"asyncFn throws: add, async, removeOnError=true\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\tremoveOnError: removeOnErrorByMessage,\n\t\t\t});\n\t\t\tconst asyncFn = async (): Promise<string> => thrower(true /* removeOnError */);\n\n\t\t\tconst add8 = pc.add(8, asyncFn);\n\t\t\tassert.equal(add8, true);\n\t\t\tconst get8 = pc.get(8);\n\t\t\tif (get8 === undefined) {\n\t\t\t\tassert.fail(\"Shouldn't be removed yet; hasn't run yet\");\n\t\t\t}\n\n\t\t\tawait assert.rejects(get8);\n\t\t\tconst contains8 = pc.has(8);\n\t\t\tassert.equal(contains8, false, \"Should be removed after rejecting\");\n\t\t});\n\t});\n\n\tdescribe(\"Garbage Collection and Expiry\", () => {\n\t\tlet clock: SinonFakeTimers;\n\t\tlet pc: PromiseCache<number, string> | undefined;\n\n\t\t// Useful for debugging the tests\n\t\tconst enableLogging: boolean = false; // Set to true to see timing logs\n\t\tfunction logClock(m: string): void {\n\t\t\tif (enableLogging) {\n\t\t\t\tconsole.log(`${m} ${clock.now}`);\n\t\t\t}\n\t\t}\n\n\t\tbefore(() => {\n\t\t\tclock = useFakeTimers();\n\t\t});\n\n\t\tafter(() => {\n\t\t\tclock.restore();\n\t\t});\n\n\t\tit(\"absolute expiry\", async () => {\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\texpiry: { policy: \"absolute\", durationMs: 15 },\n\t\t\t});\n\n\t\t\tpc.addValue(1, \"one\");\n\n\t\t\tclock.tick(10);\n\t\t\tassert.equal(pc.has(1), true);\n\n\t\t\tawait pc.addValueOrGet(1, \"one\");\n\n\t\t\tclock.tick(10);\n\t\t\tassert.equal(pc.has(1), false);\n\t\t});\n\n\t\tit(\"sliding expiry\", async () => {\n\t\t\tconst expiration = 15;\n\t\t\tpc = new PromiseCache<number, string>({\n\t\t\t\texpiry: { policy: \"sliding\", durationMs: expiration },\n\t\t\t});\n\n\t\t\tconst startTime = clock.now;\n\t\t\tlogClock(\"start\");\n\n\t\t\t// Each of these operations should reset the sliding expiry\n\t\t\tpc.add(1, async () => \"one\");\n\t\t\tclock.tick(10);\n\t\t\tpc.addValue(1, \"one\");\n\t\t\tclock.tick(10);\n\t\t\tawait pc.addOrGet(1, async () => \"one\");\n\t\t\tclock.tick(10);\n\t\t\tawait pc.addValueOrGet(1, \"one\");\n\t\t\tclock.tick(10);\n\t\t\tawait pc.get(1);\n\t\t\tclock.tick(10);\n\n\t\t\tconst endTime = clock.now;\n\t\t\tlogClock(\"endtime\");\n\n\t\t\t// More than the initial expiry elapsed but the entry wasn't evicted\n\t\t\tassert.equal(endTime - startTime > expiration, true);\n\t\t\tassert.equal(pc.has(1), true);\n\n\t\t\tclock.tick(expiration);\n\t\t\tlogClock(\"later\");\n\n\t\t\tassert.equal(pc.has(1), false);\n\t\t});\n\t});\n});\n"]}
|
package/lib/test/timer.spec.js
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import process from "node:process";
|
|
7
|
-
import { useFakeTimers, createSandbox } from "sinon";
|
|
8
|
-
import { PromiseTimer, Timer } from "@fluidframework/core-utils";
|
|
9
|
-
const flushPromises = async () => new Promise((resolve) => process.nextTick(resolve));
|
|
10
|
-
describe("Timers", () => {
|
|
11
|
-
let clock;
|
|
12
|
-
let sandbox;
|
|
13
|
-
let timeoutSpy;
|
|
14
|
-
before(() => {
|
|
15
|
-
clock = useFakeTimers();
|
|
16
|
-
sandbox = createSandbox();
|
|
17
|
-
});
|
|
18
|
-
beforeEach("createTimeoutSpy", () => {
|
|
19
|
-
timeoutSpy = sandbox.spy(global, "setTimeout");
|
|
20
|
-
});
|
|
21
|
-
afterEach(() => {
|
|
22
|
-
clock.reset();
|
|
23
|
-
sandbox.restore();
|
|
24
|
-
});
|
|
25
|
-
after(() => {
|
|
26
|
-
clock.restore();
|
|
27
|
-
});
|
|
28
|
-
describe("Timer", () => {
|
|
29
|
-
let runCount = 0;
|
|
30
|
-
const defaultTimeout = 1000;
|
|
31
|
-
const defaultHandler = () => runCount++;
|
|
32
|
-
let timer;
|
|
33
|
-
beforeEach("createTimer", () => {
|
|
34
|
-
runCount = 0;
|
|
35
|
-
timer = new Timer(defaultTimeout, defaultHandler);
|
|
36
|
-
});
|
|
37
|
-
afterEach(() => {
|
|
38
|
-
timer.clear();
|
|
39
|
-
});
|
|
40
|
-
const assertShouldNotRunYet = (initialRunCount = 0, getRunCount = () => runCount) => {
|
|
41
|
-
assert.strictEqual(getRunCount(), initialRunCount, "Should not run yet");
|
|
42
|
-
};
|
|
43
|
-
const assertShouldNotRunAgainAfterRestart = () => {
|
|
44
|
-
// Make sure only executes once
|
|
45
|
-
clock.tick(defaultTimeout + 1);
|
|
46
|
-
assert.strictEqual(runCount, 1, "Should not run additional times after restart");
|
|
47
|
-
};
|
|
48
|
-
const testExactTimeout = (time, getRunCount = () => runCount) => {
|
|
49
|
-
const initialRunCount = getRunCount();
|
|
50
|
-
clock.tick(time - 1);
|
|
51
|
-
assertShouldNotRunYet(initialRunCount, getRunCount);
|
|
52
|
-
clock.tick(1);
|
|
53
|
-
assert.strictEqual(getRunCount(), initialRunCount + 1, "Should run exactly once");
|
|
54
|
-
};
|
|
55
|
-
it("Should timeout at default time", () => {
|
|
56
|
-
timer.start();
|
|
57
|
-
testExactTimeout(defaultTimeout);
|
|
58
|
-
});
|
|
59
|
-
it("Should timeout at extremely long time", () => {
|
|
60
|
-
const overrideTimeout = 365 * 24 * 60 * 60 * 1000; // 1 year
|
|
61
|
-
timer.start(overrideTimeout);
|
|
62
|
-
testExactTimeout(overrideTimeout);
|
|
63
|
-
});
|
|
64
|
-
it("Should timeout at longer explicit time", () => {
|
|
65
|
-
const overrideTimeout = defaultTimeout * 2;
|
|
66
|
-
timer.start(overrideTimeout);
|
|
67
|
-
testExactTimeout(overrideTimeout);
|
|
68
|
-
});
|
|
69
|
-
it("Should timeout at shorter explicit time", () => {
|
|
70
|
-
const overrideTimeout = defaultTimeout - 10;
|
|
71
|
-
timer.start(overrideTimeout);
|
|
72
|
-
testExactTimeout(overrideTimeout);
|
|
73
|
-
});
|
|
74
|
-
it("Should immediately execute with negative numbers if setTimeout is called", () => {
|
|
75
|
-
const initialRunCount = runCount;
|
|
76
|
-
timer.start(-10);
|
|
77
|
-
clock.tick(defaultTimeout);
|
|
78
|
-
timer.restart(-1);
|
|
79
|
-
clock.tick(defaultTimeout * 2);
|
|
80
|
-
assert.strictEqual(runCount, initialRunCount + 2, "Should have executed immediately because the handler was late");
|
|
81
|
-
const calls = timeoutSpy.getCalls();
|
|
82
|
-
for (const call of calls) {
|
|
83
|
-
assert(call.args[1] >= 0, "setTimeout should have never been called with a negative number!");
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
it("Should immediately execute if the handler is late even accounting for the restart", () => {
|
|
87
|
-
const initialRunCount = runCount;
|
|
88
|
-
timer.start(defaultTimeout);
|
|
89
|
-
// Restart right before we execute the handler.
|
|
90
|
-
clock.tick(defaultTimeout - 1);
|
|
91
|
-
timer.restart();
|
|
92
|
-
// Advance the clock by a lot, that way, we ensure that the
|
|
93
|
-
// first time our timer executes its handler, it is late by design.
|
|
94
|
-
clock.tick(defaultTimeout * 2);
|
|
95
|
-
flushPromises().then(() => { }, () => {
|
|
96
|
-
assert.fail("Promise flushing failed");
|
|
97
|
-
});
|
|
98
|
-
assert.strictEqual(runCount, initialRunCount + 1, "Should have executed immediately because the handler was late");
|
|
99
|
-
const calls = timeoutSpy.getCalls();
|
|
100
|
-
for (const call of calls) {
|
|
101
|
-
assert(call.args[1] >= 0, "SetLongTimeout should have never been called with a negative number!");
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
it("Should be reusable multiple times", () => {
|
|
105
|
-
timer.start();
|
|
106
|
-
testExactTimeout(defaultTimeout);
|
|
107
|
-
const overrideTimeout = defaultTimeout + 10;
|
|
108
|
-
timer.start(overrideTimeout);
|
|
109
|
-
testExactTimeout(overrideTimeout);
|
|
110
|
-
timer.start();
|
|
111
|
-
testExactTimeout(defaultTimeout);
|
|
112
|
-
});
|
|
113
|
-
it("Should clear running timeout", () => {
|
|
114
|
-
timer.start();
|
|
115
|
-
clock.tick(defaultTimeout - 1);
|
|
116
|
-
assertShouldNotRunYet();
|
|
117
|
-
timer.clear();
|
|
118
|
-
clock.tick(1);
|
|
119
|
-
assert.strictEqual(runCount, 0, "Should not run after cleared");
|
|
120
|
-
// Make extra sure
|
|
121
|
-
clock.tick(defaultTimeout + 1);
|
|
122
|
-
assert.strictEqual(runCount, 0, "Should never run after cleared");
|
|
123
|
-
});
|
|
124
|
-
it("Should restart with defaults", () => {
|
|
125
|
-
// Elapse all but 10ms, then restart
|
|
126
|
-
timer.start();
|
|
127
|
-
clock.tick(defaultTimeout - 10);
|
|
128
|
-
assertShouldNotRunYet();
|
|
129
|
-
timer.restart();
|
|
130
|
-
testExactTimeout(defaultTimeout);
|
|
131
|
-
assertShouldNotRunAgainAfterRestart();
|
|
132
|
-
});
|
|
133
|
-
it("Should restart with previously overridden handler", () => {
|
|
134
|
-
let specialRunCount = 0;
|
|
135
|
-
timer.start(undefined, () => specialRunCount++);
|
|
136
|
-
clock.tick(defaultTimeout - 10);
|
|
137
|
-
assertShouldNotRunYet(0, () => specialRunCount);
|
|
138
|
-
timer.restart();
|
|
139
|
-
testExactTimeout(defaultTimeout, () => specialRunCount);
|
|
140
|
-
assert.strictEqual(runCount, 0, "Should not run default handler");
|
|
141
|
-
});
|
|
142
|
-
it("Should restart with explicit handler", () => {
|
|
143
|
-
let specialRunCount = 0;
|
|
144
|
-
timer.start();
|
|
145
|
-
clock.tick(defaultTimeout - 10);
|
|
146
|
-
assertShouldNotRunYet();
|
|
147
|
-
timer.restart(undefined, () => specialRunCount++);
|
|
148
|
-
testExactTimeout(defaultTimeout, () => specialRunCount);
|
|
149
|
-
assert.strictEqual(runCount, 0, "Should not run default handler");
|
|
150
|
-
});
|
|
151
|
-
it("Should restart with override time > remaining time", () => {
|
|
152
|
-
// Test: restart duration (15) > remaining time (10)
|
|
153
|
-
const restartTimeout = 15;
|
|
154
|
-
timer.start();
|
|
155
|
-
clock.tick(defaultTimeout - 10);
|
|
156
|
-
assertShouldNotRunYet();
|
|
157
|
-
timer.restart(restartTimeout);
|
|
158
|
-
testExactTimeout(restartTimeout);
|
|
159
|
-
assertShouldNotRunAgainAfterRestart();
|
|
160
|
-
});
|
|
161
|
-
it("Should restart with override time < remaining time", () => {
|
|
162
|
-
// Test: restart duration (5) < remaining time (10)
|
|
163
|
-
const restartTimeout = 5;
|
|
164
|
-
timer.start();
|
|
165
|
-
clock.tick(defaultTimeout - 10);
|
|
166
|
-
assertShouldNotRunYet();
|
|
167
|
-
timer.restart(restartTimeout);
|
|
168
|
-
testExactTimeout(restartTimeout);
|
|
169
|
-
assertShouldNotRunAgainAfterRestart();
|
|
170
|
-
});
|
|
171
|
-
it("Should handle consecutive restarts", () => {
|
|
172
|
-
timer.start();
|
|
173
|
-
clock.tick(defaultTimeout - 10);
|
|
174
|
-
assertShouldNotRunYet();
|
|
175
|
-
// 10 ms remaining
|
|
176
|
-
timer.restart();
|
|
177
|
-
clock.tick(defaultTimeout - 5);
|
|
178
|
-
assertShouldNotRunYet();
|
|
179
|
-
// 5 ms remaining
|
|
180
|
-
timer.restart();
|
|
181
|
-
clock.tick(defaultTimeout - 2);
|
|
182
|
-
assertShouldNotRunYet();
|
|
183
|
-
// 2 ms remaining
|
|
184
|
-
timer.restart();
|
|
185
|
-
clock.tick(defaultTimeout - 1);
|
|
186
|
-
assertShouldNotRunYet();
|
|
187
|
-
// 1 ms remaining
|
|
188
|
-
timer.restart();
|
|
189
|
-
testExactTimeout(defaultTimeout);
|
|
190
|
-
// 0 ms remaining; should behave as regular start now
|
|
191
|
-
timer.restart();
|
|
192
|
-
testExactTimeout(defaultTimeout);
|
|
193
|
-
});
|
|
194
|
-
it("Should use override handler of latest restart by default", () => {
|
|
195
|
-
let specialRunCount = 0;
|
|
196
|
-
timer.start();
|
|
197
|
-
clock.tick(defaultTimeout - 10);
|
|
198
|
-
assertShouldNotRunYet();
|
|
199
|
-
// Override handler for restart
|
|
200
|
-
timer.restart(undefined, () => specialRunCount++);
|
|
201
|
-
clock.tick(5); // Make sure < 10 ms passes for test
|
|
202
|
-
assertShouldNotRunYet();
|
|
203
|
-
assertShouldNotRunYet(0, () => specialRunCount);
|
|
204
|
-
// Now subsequent restart should use previous restart handler
|
|
205
|
-
timer.restart();
|
|
206
|
-
testExactTimeout(defaultTimeout, () => specialRunCount);
|
|
207
|
-
assert.strictEqual(runCount, 0, "Should not run default handler");
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
describe("PromiseTimer", () => {
|
|
211
|
-
let runCount = 0;
|
|
212
|
-
let resolveResult;
|
|
213
|
-
const defaultTimeout = 1000;
|
|
214
|
-
const defaultHandler = () => runCount++;
|
|
215
|
-
let timer;
|
|
216
|
-
beforeEach("createTimer", () => {
|
|
217
|
-
runCount = 0;
|
|
218
|
-
resolveResult = undefined;
|
|
219
|
-
timer = new PromiseTimer(defaultTimeout, defaultHandler);
|
|
220
|
-
});
|
|
221
|
-
afterEach(() => {
|
|
222
|
-
timer.clear();
|
|
223
|
-
});
|
|
224
|
-
function startWithThen(ms, handler) {
|
|
225
|
-
timer.start(ms, handler).then((result) => {
|
|
226
|
-
resolveResult = result.timerResult;
|
|
227
|
-
}, (error) => assert.fail(error));
|
|
228
|
-
}
|
|
229
|
-
async function tickAndFlush(ms) {
|
|
230
|
-
clock.tick(ms);
|
|
231
|
-
await flushPromises();
|
|
232
|
-
}
|
|
233
|
-
const assertShouldNotRunYet = (initialRunCount = 0, getRunCount = () => runCount) => {
|
|
234
|
-
assert.strictEqual(getRunCount(), initialRunCount, "Should not run yet");
|
|
235
|
-
assert.strictEqual(resolveResult, undefined, "Run promise should not be resolved yet");
|
|
236
|
-
};
|
|
237
|
-
const testExactTimeout = async (time) => {
|
|
238
|
-
const initialRunCount = runCount;
|
|
239
|
-
await tickAndFlush(time - 1);
|
|
240
|
-
assertShouldNotRunYet(initialRunCount);
|
|
241
|
-
await tickAndFlush(1);
|
|
242
|
-
assert.strictEqual(runCount, initialRunCount + 1, "Should run exactly once");
|
|
243
|
-
assert(resolveResult === "timeout", "Run promise should be resolved");
|
|
244
|
-
};
|
|
245
|
-
it("Should timeout at default time and resolve", async () => {
|
|
246
|
-
startWithThen();
|
|
247
|
-
await testExactTimeout(defaultTimeout);
|
|
248
|
-
});
|
|
249
|
-
it("Should timeout at longer explicit timeout and resolve", async () => {
|
|
250
|
-
const overrideTimeout = defaultTimeout * 2;
|
|
251
|
-
startWithThen(overrideTimeout);
|
|
252
|
-
await testExactTimeout(overrideTimeout);
|
|
253
|
-
});
|
|
254
|
-
it("Should timeout at shorter explicit timeout and resolve", async () => {
|
|
255
|
-
const overrideTimeout = defaultTimeout - 10;
|
|
256
|
-
startWithThen(overrideTimeout);
|
|
257
|
-
await testExactTimeout(overrideTimeout);
|
|
258
|
-
});
|
|
259
|
-
it("Should clear running timeout and resolve as canceled", async () => {
|
|
260
|
-
startWithThen();
|
|
261
|
-
await tickAndFlush(defaultTimeout - 1);
|
|
262
|
-
assertShouldNotRunYet();
|
|
263
|
-
timer.clear();
|
|
264
|
-
await flushPromises();
|
|
265
|
-
assert(resolveResult === "cancel", "Run promise should be resolved as cancel");
|
|
266
|
-
await tickAndFlush(1);
|
|
267
|
-
assert.strictEqual(runCount, 0, "Should not run after cleared");
|
|
268
|
-
// Make extra sure
|
|
269
|
-
await tickAndFlush(defaultTimeout + 1);
|
|
270
|
-
assert.strictEqual(runCount, 0, "Should never run after cleared");
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
//# sourceMappingURL=timer.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timer.spec.js","sourceRoot":"","sources":["../../src/test/timer.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport process from \"node:process\";\nimport type { SinonFakeTimers, SinonSandbox, SinonSpy } from \"sinon\";\nimport { useFakeTimers, createSandbox } from \"sinon\";\nimport type { IPromiseTimerResult } from \"@fluidframework/core-utils\";\nimport { PromiseTimer, Timer } from \"@fluidframework/core-utils\";\n\nconst flushPromises = async (): Promise<void> =>\n\tnew Promise((resolve) => process.nextTick(resolve));\ntype PromiseTimerResultString = IPromiseTimerResult[\"timerResult\"];\n\ndescribe(\"Timers\", () => {\n\tlet clock: SinonFakeTimers;\n\tlet sandbox: SinonSandbox;\n\tlet timeoutSpy: SinonSpy;\n\n\tbefore(() => {\n\t\tclock = useFakeTimers();\n\t\tsandbox = createSandbox();\n\t});\n\n\tbeforeEach(\"createTimeoutSpy\", () => {\n\t\ttimeoutSpy = sandbox.spy(global, \"setTimeout\");\n\t});\n\n\tafterEach(() => {\n\t\tclock.reset();\n\t\tsandbox.restore();\n\t});\n\n\tafter(() => {\n\t\tclock.restore();\n\t});\n\n\tdescribe(\"Timer\", () => {\n\t\tlet runCount = 0;\n\t\tconst defaultTimeout = 1000;\n\t\tconst defaultHandler = (): number => runCount++;\n\t\tlet timer: Timer;\n\n\t\tbeforeEach(\"createTimer\", () => {\n\t\t\trunCount = 0;\n\t\t\ttimer = new Timer(defaultTimeout, defaultHandler);\n\t\t});\n\n\t\tafterEach(() => {\n\t\t\ttimer.clear();\n\t\t});\n\n\t\tconst assertShouldNotRunYet = (\n\t\t\tinitialRunCount = 0,\n\t\t\tgetRunCount = (): number => runCount,\n\t\t): void => {\n\t\t\tassert.strictEqual(getRunCount(), initialRunCount, \"Should not run yet\");\n\t\t};\n\n\t\tconst assertShouldNotRunAgainAfterRestart = (): void => {\n\t\t\t// Make sure only executes once\n\t\t\tclock.tick(defaultTimeout + 1);\n\t\t\tassert.strictEqual(runCount, 1, \"Should not run additional times after restart\");\n\t\t};\n\n\t\tconst testExactTimeout = (time: number, getRunCount = (): number => runCount): void => {\n\t\t\tconst initialRunCount = getRunCount();\n\t\t\tclock.tick(time - 1);\n\t\t\tassertShouldNotRunYet(initialRunCount, getRunCount);\n\t\t\tclock.tick(1);\n\t\t\tassert.strictEqual(getRunCount(), initialRunCount + 1, \"Should run exactly once\");\n\t\t};\n\n\t\tit(\"Should timeout at default time\", () => {\n\t\t\ttimer.start();\n\t\t\ttestExactTimeout(defaultTimeout);\n\t\t});\n\n\t\tit(\"Should timeout at extremely long time\", () => {\n\t\t\tconst overrideTimeout = 365 * 24 * 60 * 60 * 1000; // 1 year\n\t\t\ttimer.start(overrideTimeout);\n\t\t\ttestExactTimeout(overrideTimeout);\n\t\t});\n\n\t\tit(\"Should timeout at longer explicit time\", () => {\n\t\t\tconst overrideTimeout = defaultTimeout * 2;\n\t\t\ttimer.start(overrideTimeout);\n\t\t\ttestExactTimeout(overrideTimeout);\n\t\t});\n\n\t\tit(\"Should timeout at shorter explicit time\", () => {\n\t\t\tconst overrideTimeout = defaultTimeout - 10;\n\t\t\ttimer.start(overrideTimeout);\n\t\t\ttestExactTimeout(overrideTimeout);\n\t\t});\n\n\t\tit(\"Should immediately execute with negative numbers if setTimeout is called\", () => {\n\t\t\tconst initialRunCount = runCount;\n\t\t\ttimer.start(-10);\n\n\t\t\tclock.tick(defaultTimeout);\n\t\t\ttimer.restart(-1);\n\t\t\tclock.tick(defaultTimeout * 2);\n\n\t\t\tassert.strictEqual(\n\t\t\t\trunCount,\n\t\t\t\tinitialRunCount + 2,\n\t\t\t\t\"Should have executed immediately because the handler was late\",\n\t\t\t);\n\n\t\t\tconst calls = timeoutSpy.getCalls();\n\t\t\tfor (const call of calls) {\n\t\t\t\tassert(\n\t\t\t\t\tcall.args[1] >= 0,\n\t\t\t\t\t\"setTimeout should have never been called with a negative number!\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tit(\"Should immediately execute if the handler is late even accounting for the restart\", () => {\n\t\t\tconst initialRunCount = runCount;\n\t\t\ttimer.start(defaultTimeout);\n\n\t\t\t// Restart right before we execute the handler.\n\t\t\tclock.tick(defaultTimeout - 1);\n\t\t\ttimer.restart();\n\n\t\t\t// Advance the clock by a lot, that way, we ensure that the\n\t\t\t// first time our timer executes its handler, it is late by design.\n\t\t\tclock.tick(defaultTimeout * 2);\n\n\t\t\tflushPromises().then(\n\t\t\t\t() => {},\n\t\t\t\t() => {\n\t\t\t\t\tassert.fail(\"Promise flushing failed\");\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tassert.strictEqual(\n\t\t\t\trunCount,\n\t\t\t\tinitialRunCount + 1,\n\t\t\t\t\"Should have executed immediately because the handler was late\",\n\t\t\t);\n\n\t\t\tconst calls = timeoutSpy.getCalls();\n\t\t\tfor (const call of calls) {\n\t\t\t\tassert(\n\t\t\t\t\tcall.args[1] >= 0,\n\t\t\t\t\t\"SetLongTimeout should have never been called with a negative number!\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tit(\"Should be reusable multiple times\", () => {\n\t\t\ttimer.start();\n\t\t\ttestExactTimeout(defaultTimeout);\n\n\t\t\tconst overrideTimeout = defaultTimeout + 10;\n\t\t\ttimer.start(overrideTimeout);\n\t\t\ttestExactTimeout(overrideTimeout);\n\n\t\t\ttimer.start();\n\t\t\ttestExactTimeout(defaultTimeout);\n\t\t});\n\n\t\tit(\"Should clear running timeout\", () => {\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 1);\n\t\t\tassertShouldNotRunYet();\n\t\t\ttimer.clear();\n\t\t\tclock.tick(1);\n\t\t\tassert.strictEqual(runCount, 0, \"Should not run after cleared\");\n\n\t\t\t// Make extra sure\n\t\t\tclock.tick(defaultTimeout + 1);\n\t\t\tassert.strictEqual(runCount, 0, \"Should never run after cleared\");\n\t\t});\n\n\t\tit(\"Should restart with defaults\", () => {\n\t\t\t// Elapse all but 10ms, then restart\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\ttimer.restart();\n\t\t\ttestExactTimeout(defaultTimeout);\n\n\t\t\tassertShouldNotRunAgainAfterRestart();\n\t\t});\n\n\t\tit(\"Should restart with previously overridden handler\", () => {\n\t\t\tlet specialRunCount = 0;\n\t\t\ttimer.start(undefined, () => specialRunCount++);\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet(0, () => specialRunCount);\n\n\t\t\ttimer.restart();\n\t\t\ttestExactTimeout(defaultTimeout, () => specialRunCount);\n\t\t\tassert.strictEqual(runCount, 0, \"Should not run default handler\");\n\t\t});\n\n\t\tit(\"Should restart with explicit handler\", () => {\n\t\t\tlet specialRunCount = 0;\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\ttimer.restart(undefined, () => specialRunCount++);\n\t\t\ttestExactTimeout(defaultTimeout, () => specialRunCount);\n\t\t\tassert.strictEqual(runCount, 0, \"Should not run default handler\");\n\t\t});\n\n\t\tit(\"Should restart with override time > remaining time\", () => {\n\t\t\t// Test: restart duration (15) > remaining time (10)\n\t\t\tconst restartTimeout = 15;\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\ttimer.restart(restartTimeout);\n\t\t\ttestExactTimeout(restartTimeout);\n\n\t\t\tassertShouldNotRunAgainAfterRestart();\n\t\t});\n\n\t\tit(\"Should restart with override time < remaining time\", () => {\n\t\t\t// Test: restart duration (5) < remaining time (10)\n\t\t\tconst restartTimeout = 5;\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\ttimer.restart(restartTimeout);\n\t\t\ttestExactTimeout(restartTimeout);\n\n\t\t\tassertShouldNotRunAgainAfterRestart();\n\t\t});\n\n\t\tit(\"Should handle consecutive restarts\", () => {\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\t// 10 ms remaining\n\t\t\ttimer.restart();\n\t\t\tclock.tick(defaultTimeout - 5);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\t// 5 ms remaining\n\t\t\ttimer.restart();\n\t\t\tclock.tick(defaultTimeout - 2);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\t// 2 ms remaining\n\t\t\ttimer.restart();\n\t\t\tclock.tick(defaultTimeout - 1);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\t// 1 ms remaining\n\t\t\ttimer.restart();\n\t\t\ttestExactTimeout(defaultTimeout);\n\n\t\t\t// 0 ms remaining; should behave as regular start now\n\t\t\ttimer.restart();\n\t\t\ttestExactTimeout(defaultTimeout);\n\t\t});\n\n\t\tit(\"Should use override handler of latest restart by default\", () => {\n\t\t\tlet specialRunCount = 0;\n\t\t\ttimer.start();\n\t\t\tclock.tick(defaultTimeout - 10);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\t// Override handler for restart\n\t\t\ttimer.restart(undefined, () => specialRunCount++);\n\t\t\tclock.tick(5); // Make sure < 10 ms passes for test\n\t\t\tassertShouldNotRunYet();\n\t\t\tassertShouldNotRunYet(0, () => specialRunCount);\n\n\t\t\t// Now subsequent restart should use previous restart handler\n\t\t\ttimer.restart();\n\t\t\ttestExactTimeout(defaultTimeout, () => specialRunCount);\n\t\t\tassert.strictEqual(runCount, 0, \"Should not run default handler\");\n\t\t});\n\t});\n\n\tdescribe(\"PromiseTimer\", () => {\n\t\tlet runCount = 0;\n\t\tlet resolveResult: PromiseTimerResultString | undefined;\n\t\tconst defaultTimeout = 1000;\n\t\tconst defaultHandler = (): number => runCount++;\n\t\tlet timer: PromiseTimer;\n\n\t\tbeforeEach(\"createTimer\", () => {\n\t\t\trunCount = 0;\n\t\t\tresolveResult = undefined;\n\t\t\ttimer = new PromiseTimer(defaultTimeout, defaultHandler);\n\t\t});\n\n\t\tafterEach(() => {\n\t\t\ttimer.clear();\n\t\t});\n\n\t\tfunction startWithThen(ms?: number, handler?: () => void): void {\n\t\t\ttimer.start(ms, handler).then(\n\t\t\t\t(result) => {\n\t\t\t\t\tresolveResult = result.timerResult;\n\t\t\t\t},\n\t\t\t\t(error: Error) => assert.fail(error),\n\t\t\t);\n\t\t}\n\n\t\tasync function tickAndFlush(ms: number): Promise<void> {\n\t\t\tclock.tick(ms);\n\t\t\tawait flushPromises();\n\t\t}\n\n\t\tconst assertShouldNotRunYet = (\n\t\t\tinitialRunCount = 0,\n\t\t\tgetRunCount = (): number => runCount,\n\t\t): void => {\n\t\t\tassert.strictEqual(getRunCount(), initialRunCount, \"Should not run yet\");\n\t\t\tassert.strictEqual(resolveResult, undefined, \"Run promise should not be resolved yet\");\n\t\t};\n\n\t\tconst testExactTimeout = async (time: number): Promise<void> => {\n\t\t\tconst initialRunCount = runCount;\n\t\t\tawait tickAndFlush(time - 1);\n\t\t\tassertShouldNotRunYet(initialRunCount);\n\t\t\tawait tickAndFlush(1);\n\t\t\tassert.strictEqual(runCount, initialRunCount + 1, \"Should run exactly once\");\n\t\t\tassert(resolveResult === \"timeout\", \"Run promise should be resolved\");\n\t\t};\n\n\t\tit(\"Should timeout at default time and resolve\", async () => {\n\t\t\tstartWithThen();\n\t\t\tawait testExactTimeout(defaultTimeout);\n\t\t});\n\n\t\tit(\"Should timeout at longer explicit timeout and resolve\", async () => {\n\t\t\tconst overrideTimeout = defaultTimeout * 2;\n\t\t\tstartWithThen(overrideTimeout);\n\n\t\t\tawait testExactTimeout(overrideTimeout);\n\t\t});\n\n\t\tit(\"Should timeout at shorter explicit timeout and resolve\", async () => {\n\t\t\tconst overrideTimeout = defaultTimeout - 10;\n\t\t\tstartWithThen(overrideTimeout);\n\n\t\t\tawait testExactTimeout(overrideTimeout);\n\t\t});\n\n\t\tit(\"Should clear running timeout and resolve as canceled\", async () => {\n\t\t\tstartWithThen();\n\t\t\tawait tickAndFlush(defaultTimeout - 1);\n\t\t\tassertShouldNotRunYet();\n\n\t\t\ttimer.clear();\n\t\t\tawait flushPromises();\n\t\t\tassert(resolveResult === \"cancel\", \"Run promise should be resolved as cancel\");\n\n\t\t\tawait tickAndFlush(1);\n\t\t\tassert.strictEqual(runCount, 0, \"Should not run after cleared\");\n\n\t\t\t// Make extra sure\n\t\t\tawait tickAndFlush(defaultTimeout + 1);\n\t\t\tassert.strictEqual(runCount, 0, \"Should never run after cleared\");\n\t\t});\n\t});\n});\n"]}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { compareArrays } from "@fluidframework/core-utils";
|
|
6
|
-
// Paranoid check that typing will prevent comparing with non-Array types like 'compareArrays(null, null)',
|
|
7
|
-
// which would otherwise pass the trivial acceptance clause.
|
|
8
|
-
// @ts-expect-error 'undefined' is not an array
|
|
9
|
-
compareArrays(undefined, undefined);
|
|
10
|
-
// @ts-expect-error 'null' is not an array
|
|
11
|
-
compareArrays(null, null); // eslint-disable-line unicorn/no-null
|
|
12
|
-
const s = Symbol();
|
|
13
|
-
// @ts-expect-error 'Symbol()' is not an array
|
|
14
|
-
compareArrays(s, s);
|
|
15
|
-
// @ts-expect-error 'true' is not an array
|
|
16
|
-
compareArrays(true, true);
|
|
17
|
-
// @ts-expect-error '0' is not an array
|
|
18
|
-
compareArrays(0, 0);
|
|
19
|
-
// @ts-expect-error 'string' is not an array
|
|
20
|
-
compareArrays("", "");
|
|
21
|
-
//# sourceMappingURL=compareArrays.type.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compareArrays.type.js","sourceRoot":"","sources":["../../../src/test/types/compareArrays.type.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,2GAA2G;AAC3G,4DAA4D;AAE5D,+CAA+C;AAC/C,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAEpC,0CAA0C;AAC1C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,sCAAsC;AAEjE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;AACnB,8CAA8C;AAC9C,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEpB,0CAA0C;AAC1C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAE1B,uCAAuC;AACvC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAEpB,4CAA4C;AAC5C,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { compareArrays } from \"@fluidframework/core-utils\";\n\n// Paranoid check that typing will prevent comparing with non-Array types like 'compareArrays(null, null)',\n// which would otherwise pass the trivial acceptance clause.\n\n// @ts-expect-error 'undefined' is not an array\ncompareArrays(undefined, undefined);\n\n// @ts-expect-error 'null' is not an array\ncompareArrays(null, null); // eslint-disable-line unicorn/no-null\n\nconst s = Symbol();\n// @ts-expect-error 'Symbol()' is not an array\ncompareArrays(s, s);\n\n// @ts-expect-error 'true' is not an array\ncompareArrays(true, true);\n\n// @ts-expect-error '0' is not an array\ncompareArrays(0, 0);\n\n// @ts-expect-error 'string' is not an array\ncompareArrays(\"\", \"\");\n"]}
|
|
File without changes
|