@matter/testing 0.13.0-alpha.0-20250318-c1aa38b08 → 0.13.0-alpha.0-20250322-f085fa576
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/.mocharc.cjs +7 -0
- package/dist/cjs/mocks/time.d.ts +24 -20
- package/dist/cjs/mocks/time.d.ts.map +1 -1
- package/dist/cjs/mocks/time.js +60 -37
- package/dist/cjs/mocks/time.js.map +1 -1
- package/dist/cjs/nodejs-reporter.js +1 -1
- package/dist/cjs/nodejs-reporter.js.map +1 -1
- package/dist/cjs/runner.d.ts +1 -1
- package/dist/cjs/runner.d.ts.map +1 -1
- package/dist/cjs/runner.js +64 -4
- package/dist/cjs/runner.js.map +2 -2
- package/dist/esm/mocks/time.d.ts +24 -20
- package/dist/esm/mocks/time.d.ts.map +1 -1
- package/dist/esm/mocks/time.js +60 -37
- package/dist/esm/mocks/time.js.map +1 -1
- package/dist/esm/nodejs-reporter.js +1 -1
- package/dist/esm/nodejs-reporter.js.map +1 -1
- package/dist/esm/runner.d.ts +1 -1
- package/dist/esm/runner.d.ts.map +1 -1
- package/dist/esm/runner.js +65 -5
- package/dist/esm/runner.js.map +1 -1
- package/package.json +2 -2
- package/src/mocks/time.ts +71 -41
- package/src/nodejs-reporter.ts +1 -1
- package/src/runner.ts +87 -5
package/dist/esm/mocks/time.js
CHANGED
|
@@ -4,10 +4,26 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { Boot } from "./boot.js";
|
|
7
|
+
const registry = {
|
|
8
|
+
timers: /* @__PURE__ */ new Set(),
|
|
9
|
+
register(_timer) {
|
|
10
|
+
},
|
|
11
|
+
unregister(_timer) {
|
|
12
|
+
}
|
|
13
|
+
};
|
|
7
14
|
class MockTimer {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
15
|
+
name = "Test";
|
|
16
|
+
systemId = 0;
|
|
17
|
+
intervalMs = 0;
|
|
18
|
+
isPeriodic = false;
|
|
19
|
+
#mockTime;
|
|
20
|
+
#durationMs;
|
|
21
|
+
isRunning = false;
|
|
22
|
+
callback;
|
|
23
|
+
constructor(mockTime, name, durationMs, callback) {
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.#mockTime = mockTime;
|
|
26
|
+
this.#durationMs = durationMs;
|
|
11
27
|
if (this instanceof MockInterval) {
|
|
12
28
|
this.callback = callback;
|
|
13
29
|
} else {
|
|
@@ -17,30 +33,26 @@ class MockTimer {
|
|
|
17
33
|
};
|
|
18
34
|
}
|
|
19
35
|
}
|
|
20
|
-
name = "Test";
|
|
21
|
-
systemId = 0;
|
|
22
|
-
intervalMs = 0;
|
|
23
|
-
isPeriodic = false;
|
|
24
|
-
isRunning = false;
|
|
25
|
-
callback;
|
|
26
36
|
start() {
|
|
27
|
-
|
|
37
|
+
registry.register(this);
|
|
38
|
+
this.#mockTime.callbackAtTime(this.#mockTime.nowMs() + this.#durationMs, this.callback);
|
|
28
39
|
this.isRunning = true;
|
|
29
40
|
return this;
|
|
30
41
|
}
|
|
31
42
|
stop() {
|
|
32
|
-
|
|
43
|
+
registry.unregister(this);
|
|
44
|
+
this.#mockTime.removeCallback(this.callback);
|
|
33
45
|
this.isRunning = false;
|
|
34
46
|
return this;
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
class MockInterval extends MockTimer {
|
|
38
|
-
constructor(mockTime, durationMs, callback) {
|
|
50
|
+
constructor(mockTime, name, durationMs, callback) {
|
|
39
51
|
const intervalCallback = async () => {
|
|
40
52
|
mockTime.callbackAtTime(mockTime.nowMs() + durationMs, intervalCallback);
|
|
41
53
|
await callback();
|
|
42
54
|
};
|
|
43
|
-
super(mockTime, durationMs, intervalCallback);
|
|
55
|
+
super(mockTime, name, durationMs, intervalCallback);
|
|
44
56
|
}
|
|
45
57
|
}
|
|
46
58
|
function isAsync(fn) {
|
|
@@ -73,18 +85,18 @@ const MockTime = {
|
|
|
73
85
|
nowMs() {
|
|
74
86
|
return nowMs;
|
|
75
87
|
},
|
|
76
|
-
getTimer(
|
|
77
|
-
return new MockTimer(this, durationMs, callback);
|
|
88
|
+
getTimer(name, durationMs, callback) {
|
|
89
|
+
return new MockTimer(this, name, durationMs, callback);
|
|
78
90
|
},
|
|
79
|
-
getPeriodicTimer(
|
|
80
|
-
return new MockInterval(this, intervalMs, callback);
|
|
91
|
+
getPeriodicTimer(name, intervalMs, callback) {
|
|
92
|
+
return new MockInterval(this, name, intervalMs, callback);
|
|
81
93
|
},
|
|
82
94
|
/**
|
|
83
95
|
* Resolve a promise with time dependency.
|
|
84
96
|
*
|
|
85
97
|
* Moves time forward until the promise resolves.
|
|
86
98
|
*/
|
|
87
|
-
async resolve(promise) {
|
|
99
|
+
async resolve(promise, { stepMs, macrotasks } = {}) {
|
|
88
100
|
let resolved = false;
|
|
89
101
|
let result;
|
|
90
102
|
let error;
|
|
@@ -100,7 +112,11 @@ const MockTime = {
|
|
|
100
112
|
);
|
|
101
113
|
let timeAdvanced = 0;
|
|
102
114
|
while (!resolved) {
|
|
103
|
-
|
|
115
|
+
if (macrotasks) {
|
|
116
|
+
await new Promise((resolve) => setTimeout(() => resolve(), 0));
|
|
117
|
+
} else {
|
|
118
|
+
await MockTime.yield();
|
|
119
|
+
}
|
|
104
120
|
if (resolved) {
|
|
105
121
|
break;
|
|
106
122
|
}
|
|
@@ -109,8 +125,12 @@ const MockTime = {
|
|
|
109
125
|
"Mock timeout: Promise did not resolve within one (virtual) hour, probably not going to happen"
|
|
110
126
|
);
|
|
111
127
|
}
|
|
112
|
-
|
|
113
|
-
|
|
128
|
+
if (stepMs) {
|
|
129
|
+
await this.advance(stepMs);
|
|
130
|
+
} else {
|
|
131
|
+
await this.advance(1e3);
|
|
132
|
+
timeAdvanced += 1e3;
|
|
133
|
+
}
|
|
114
134
|
if (resolved) {
|
|
115
135
|
break;
|
|
116
136
|
}
|
|
@@ -126,8 +146,7 @@ const MockTime = {
|
|
|
126
146
|
*/
|
|
127
147
|
async advance(ms) {
|
|
128
148
|
const newTimeMs = nowMs + ms;
|
|
129
|
-
while (
|
|
130
|
-
if (callbacks.length === 0) break;
|
|
149
|
+
while (callbacks.length) {
|
|
131
150
|
const { atMs, callback } = callbacks[0];
|
|
132
151
|
if (atMs > newTimeMs) break;
|
|
133
152
|
callbacks.shift();
|
|
@@ -137,20 +156,17 @@ const MockTime = {
|
|
|
137
156
|
nowMs = newTimeMs;
|
|
138
157
|
},
|
|
139
158
|
/**
|
|
140
|
-
* Yield to scheduled microtasks. This means that all code paths waiting
|
|
141
|
-
*
|
|
142
|
-
* returns.
|
|
159
|
+
* Yield to scheduled microtasks. This means that all code paths waiting on resolved promises (including await)
|
|
160
|
+
* will proceed before this method returns.
|
|
143
161
|
*/
|
|
144
162
|
async yield() {
|
|
145
163
|
await Promise.resolve();
|
|
146
164
|
},
|
|
147
165
|
/**
|
|
148
|
-
* Due to its implementation, an older version of yield() would actually
|
|
149
|
-
*
|
|
150
|
-
* functionality -- one yield could trigger up to three nested awaits.
|
|
166
|
+
* Due to its implementation, an older version of yield() would actually yield to microtasks three times. Our tests
|
|
167
|
+
* then depended on this functionality -- one yield could trigger up to three nested awaits.
|
|
151
168
|
*
|
|
152
|
-
* To make this clear, the version of yield() that emulates old behavior
|
|
153
|
-
* is called "yield3".
|
|
169
|
+
* To make this clear, the version of yield() that emulates old behavior is called "yield3".
|
|
154
170
|
*/
|
|
155
171
|
async yield3() {
|
|
156
172
|
await Promise.resolve();
|
|
@@ -158,14 +174,12 @@ const MockTime = {
|
|
|
158
174
|
await Promise.resolve();
|
|
159
175
|
},
|
|
160
176
|
/**
|
|
161
|
-
* Hook a method and invoke a callback just before the method completes.
|
|
162
|
-
* Unhooks after completion.
|
|
177
|
+
* Hook a method and invoke a callback just before the method completes. Unhooks after completion.
|
|
163
178
|
*
|
|
164
|
-
* Handles both synchronous and asynchronous methods. The interceptor
|
|
165
|
-
*
|
|
179
|
+
* Handles both synchronous and asynchronous methods. The interceptor should match the async-ness of the
|
|
180
|
+
* intercepted method.
|
|
166
181
|
*
|
|
167
|
-
* The interceptor can optionally access and/or replace the resolve/reject
|
|
168
|
-
* value.
|
|
182
|
+
* The interceptor can optionally access and/or replace the resolve/reject value.
|
|
169
183
|
*/
|
|
170
184
|
interceptOnce(obj, method, interceptor) {
|
|
171
185
|
const original = obj[method];
|
|
@@ -207,6 +221,12 @@ const MockTime = {
|
|
|
207
221
|
};
|
|
208
222
|
}
|
|
209
223
|
},
|
|
224
|
+
/**
|
|
225
|
+
* Count the number of registered timers with a specific name.
|
|
226
|
+
*/
|
|
227
|
+
timerCountFor(name) {
|
|
228
|
+
return [...registry.timers].filter((timer) => timer.name === name).length;
|
|
229
|
+
},
|
|
210
230
|
callbackAtTime(atMs, callback) {
|
|
211
231
|
callbacks.push({ atMs, callback });
|
|
212
232
|
callbacks.sort(({ atMs: atMsA }, { atMs: atMsB }) => atMsA - atMsB);
|
|
@@ -219,6 +239,9 @@ const MockTime = {
|
|
|
219
239
|
};
|
|
220
240
|
let reinstallTime;
|
|
221
241
|
function timeSetup(Time) {
|
|
242
|
+
registry.register = Time.register;
|
|
243
|
+
registry.unregister = Time.unregister;
|
|
244
|
+
registry.timers = Time.timers;
|
|
222
245
|
Time.startup.systemMs = Time.startup.processMs = 0;
|
|
223
246
|
real = Time.get();
|
|
224
247
|
MockTime.sleep = real.sleep;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/mocks/time.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,YAAY;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -83,7 +83,7 @@ class NodejsReporter {
|
|
|
83
83
|
std.out("\n");
|
|
84
84
|
}
|
|
85
85
|
const failure = this.#failures[i];
|
|
86
|
-
const index =
|
|
86
|
+
const index = `\u26A0 Failure ${ansi.bold((i + 1).toString())} of ${this.#failures.length}`;
|
|
87
87
|
const title = `${index} ${this.#formatName(failure.suite, failure.test, failure.step)}`;
|
|
88
88
|
FailureReporter.report(std.out, failure.detail, title);
|
|
89
89
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/nodejs-reporter.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAmB,MAAM,WAAW;AAEpC,SAAS,uBAAuB;AAMzB,MAAe,eAAmC;AAAA,EASrD,YAAoB,UAAoB;AAApB;AAAA,EAAqB;AAAA,EARzC,OAAO;AAAA,EACP,SAAS,MAAc;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,MAAe;AAAA,EAC3B;AAAA,EAIA,SAAS,MAAc,OAA0B,iBAAiB,MAAY;AAC1E,SAAK,OAAO;AACZ,SAAK,SAAS,CAAC;AACf,SAAK,YAAY,CAAC;AAClB,QAAI,CAAC,gBAAgB;AACjB,WAAK,SAAS,OAAO,KAAK,WAAW,KAAK,CAAC;AAAA,IAC/C;AAAA,EACJ;AAAA,EAEA,WAAW,MAAsB;AAC7B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,UAAU,MAAc,OAAqB;AACzC,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,QAAQ;AAGb,UAAM,QAAQ,QAAQ,OAAO,QAAQ,KAAK,YAAY,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC;AACxF,SAAK,aAAa,KAAK;AAAA,EAC3B;AAAA,EAEA,UAAU,MAAoB;AAC1B,SAAK,QAAQ;AAEb,QAAI,QAAQ,OAAO,SAAS,KAAK,OAAO;AACpC,YAAM,QAAQ,KAAK,YAAY,KAAK,QAAQ,KAAK,OAAO,IAAI;AAC5D,WAAK,aAAa,KAAK;AAAA,IAC3B;AAAA,EACJ;AAAA,EAEA,aAAa,OAAe;AACxB,QAAI,UAAU,KAAK,YAAY;AAC3B;AAAA,IACJ;AACA,SAAK,aAAa;AAClB,SAAK,SAAS,OAAO,KAAK,WAAW,KAAK,MAAM,GAAG,KAAK;AAAA,EAC5D;AAAA,EAEA,SAAS,MAAc,QAAuB;AAC1C,SAAK,UAAU,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAIA,OAAO,OAAqB;AACxB,QAAI,KAAK,UAAU,QAAQ;AACvB,WAAK,SAAS,QAAQ,KAAK,WAAW,KAAK,CAAC;AAC5C,WAAK,cAAc;AAAA,IACvB,WAAW,SAAS,CAAC,MAAM,UAAU;AACjC,WAAK,SAAS,QAAQ,gBAAgB;AAAA,IAC1C,OAAO;AACH,WAAK,SAAS,QAAQ,KAAK,WAAW,KAAK,CAAC;AAAA,IAChD;AAAA,EACJ;AAAA,EAEA,WAAW,OAAe;AACtB,QAAI;AACJ,QAAI,OAAO;AACP,YAAM,WAAW,KAAK,IAAI,GAAG,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE;AAC5D,YAAM,WAAW,MAAM,WAAW,KAAK,OAAO,IAAI,IAAI,MAAM,SAAS,SAAS,CAAC,SAAS,IAAI;AAC5F,gBAAU,IAAI,QAAQ,GAAG,QAAQ;AAAA,IACrC,OAAO;AACH,gBAAU;AAAA,IACd;AAEA,WAAO,GAAG,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,OAAO;AAAA,EAC5C;AAAA,EAEA,gBAAgB;AACZ,aAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAK;AAC5C,UAAI,MAAM,GAAG;AACT,YAAI,IAAI,IAAI;AAAA,MAChB;AAEA,YAAM,UAAU,KAAK,UAAU,CAAC;AAChC,YAAM,QAAQ,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/esm/runner.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Package, Progress } from "#tools";
|
|
|
7
7
|
import { TestOptions } from "./options.js";
|
|
8
8
|
import { Reporter } from "./reporter.js";
|
|
9
9
|
export declare class TestRunner {
|
|
10
|
+
#private;
|
|
10
11
|
readonly pkg: Package;
|
|
11
12
|
readonly progress: Progress;
|
|
12
13
|
readonly options: TestOptions;
|
|
@@ -16,6 +17,5 @@ export declare class TestRunner {
|
|
|
16
17
|
runNode(format?: "esm" | "cjs"): Promise<void>;
|
|
17
18
|
runWeb(manual?: boolean): Promise<void>;
|
|
18
19
|
loadFiles(format: "esm" | "cjs"): Promise<string[]>;
|
|
19
|
-
private run;
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=runner.d.ts.map
|
package/dist/esm/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,OAAO,EAAE,QAAQ,EAAO,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,OAAO,EAAE,QAAQ,EAAO,MAAM,QAAQ,CAAC;AAStD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,qBAAa,UAAU;;IAKf,QAAQ,CAAC,GAAG,EAAE,OAAO;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ;IAC3B,QAAQ,CAAC,OAAO,EAAE,WAAW;IANjC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAmB;gBAGlB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW;IA8B3B,OAAO,CAAC,MAAM,GAAE,KAAK,GAAG,KAAa;IAIrC,MAAM,CAAC,MAAM,UAAQ;IAIrB,SAAS,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK;CA0GxC"}
|
package/dist/esm/runner.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ansi, Progress, std } from "#tools";
|
|
7
7
|
import debug from "debug";
|
|
8
|
-
import {
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { dirname, relative, resolve } from "node:path";
|
|
9
10
|
import { chip } from "./chip/chip.js";
|
|
10
11
|
import { FailureReporter } from "./failure-reporter.js";
|
|
11
12
|
import { NodejsReporter } from "./nodejs-reporter.js";
|
|
@@ -43,13 +44,13 @@ class TestRunner {
|
|
|
43
44
|
reporter;
|
|
44
45
|
spec = Array();
|
|
45
46
|
async runNode(format = "esm") {
|
|
46
|
-
await this
|
|
47
|
+
await this.#run(this.progress, () => testNodejs(this, format));
|
|
47
48
|
}
|
|
48
49
|
async runWeb(manual = false) {
|
|
49
|
-
await this
|
|
50
|
+
await this.#run(this.progress, () => testWeb(this, manual));
|
|
50
51
|
}
|
|
51
52
|
async loadFiles(format) {
|
|
52
|
-
const tests =
|
|
53
|
+
const tests = Array();
|
|
53
54
|
for (let spec of this.spec) {
|
|
54
55
|
spec = spec.replace(/\.ts$/, ".js");
|
|
55
56
|
spec = relative(this.pkg.path, spec);
|
|
@@ -58,17 +59,76 @@ class TestRunner {
|
|
|
58
59
|
}
|
|
59
60
|
tests.push(...await this.pkg.glob(spec));
|
|
60
61
|
}
|
|
62
|
+
for (let i = 0; i < tests.length; i++) {
|
|
63
|
+
if (tests[i].indexOf("/src/") === -1) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
tests[i] = await this.#mapSourceToTest(tests[i]);
|
|
67
|
+
}
|
|
61
68
|
if (!tests.length) {
|
|
62
69
|
fatal(`No files match ${this.spec.join(", ")}`);
|
|
63
70
|
}
|
|
64
71
|
return [...listSupportFiles(format), ...tests];
|
|
65
72
|
}
|
|
66
|
-
async run(progress, runner) {
|
|
73
|
+
async #run(progress, runner) {
|
|
67
74
|
await runner();
|
|
68
75
|
if (progress.status !== Progress.Status.Success) {
|
|
69
76
|
fatal(`Test ${progress.status.toLowerCase()}, aborting`);
|
|
70
77
|
}
|
|
71
78
|
}
|
|
79
|
+
async #mapSourceToTest(filename) {
|
|
80
|
+
try {
|
|
81
|
+
const src = await readFile(filename, "utf-8");
|
|
82
|
+
const [, args] = src.match(/\/\/ matter-test (.*)/) ?? [];
|
|
83
|
+
if (args) {
|
|
84
|
+
return this.#parseMarkerArgs(args, filename);
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {
|
|
87
|
+
}
|
|
88
|
+
return filename.replace("/src/", "/test/");
|
|
89
|
+
}
|
|
90
|
+
#parseMarkerArgs(args, filename) {
|
|
91
|
+
const parts = args.match(/[a-z]+=(?:"(?:[^"\\]|\\.)+"|[^"]\S+)/g);
|
|
92
|
+
if (!parts) {
|
|
93
|
+
throw new Error("No matter-test parameters detected");
|
|
94
|
+
}
|
|
95
|
+
let file;
|
|
96
|
+
let module;
|
|
97
|
+
for (const part of parts) {
|
|
98
|
+
const equalPos = part.indexOf("=");
|
|
99
|
+
const name = part.substring(0, equalPos);
|
|
100
|
+
let value = part.substring(equalPos + 1);
|
|
101
|
+
if (value[0] === '"') {
|
|
102
|
+
value = value.substring(1, value.length - 2).replace(/\\"/g, '"').replace(/\\\\/g, '"');
|
|
103
|
+
}
|
|
104
|
+
switch (name) {
|
|
105
|
+
case "file":
|
|
106
|
+
file = value;
|
|
107
|
+
break;
|
|
108
|
+
case "module":
|
|
109
|
+
module = value;
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
throw new Error(`Unrecognized matter-test parameter "${name}"`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (file === void 0) {
|
|
116
|
+
throw new Error(`matter-test parameter "file" is required`);
|
|
117
|
+
}
|
|
118
|
+
if (file.startsWith("./") || file.startsWith("../")) {
|
|
119
|
+
file = resolve(dirname(filename), file);
|
|
120
|
+
}
|
|
121
|
+
let testPkg;
|
|
122
|
+
if (module === void 0) {
|
|
123
|
+
testPkg = this.pkg;
|
|
124
|
+
} else {
|
|
125
|
+
testPkg = this.pkg.findPackage(module);
|
|
126
|
+
if (testPkg === void 0) {
|
|
127
|
+
throw new Error(`Unknown matter-test module "${module}"`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return testPkg.resolve("test", file);
|
|
131
|
+
}
|
|
72
132
|
}
|
|
73
133
|
function fatal(message) {
|
|
74
134
|
std.err.write(ansi.bright.red(`
|
package/dist/esm/runner.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runner.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,SAAS,MAAe,UAAU,WAAW;AAC7C,OAAO,WAAW;AAClB,SAAS,gBAAgB;AACzB,SAAS,YAAY;AAErB,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAG3B,SAAS,wBAAwB;AACjC,SAAS,eAAe;AAEjB,MAAM,WAAW;AAAA,EAIpB,YACa,KACA,UACA,SACX;AAHW;AACA;AACA;AAET,SAAK,SAAS;AAEd,SAAK,WAAW,IAAK,cAAc,eAAe;AAAA,MAC9C,cAAc;AACV,cAAM,QAAQ;AAAA,MAClB;AAAA,MAES,QAAQ,QAAuB;AACpC,YAAI,IAAI,MAAM,IAAI;AAClB,wBAAgB,OAAO,IAAI,KAAK,QAAQ,kBAAkB;AAC1D,YAAI,IAAI,MAAM,IAAI;AAClB,gBAAQ,KAAK,CAAC;AAAA,MAClB;AAAA,IACJ,EAAG;AAEH,QAAI,QAAQ,SAAS,QAAW;AAC5B,WAAK,OAAO,CAAC,kBAAkB;AAAA,IACnC,WAAW,MAAM,QAAQ,QAAQ,IAAI,GAAG;AACpC,WAAK,OAAO,QAAQ;AAAA,IACxB,OAAO;AACH,WAAK,OAAO,CAAC,QAAQ,IAAI;AAAA,IAC7B;AAEA,QAAI,QAAQ,OAAO;AACf,YAAM,OAAO,SAAS;AAAA,IAC1B;AAAA,EACJ;AAAA,EAlCS;AAAA,EACD,OAAO,MAAc;AAAA,EAmC7B,MAAM,QAAQ,SAAwB,OAAO;AACzC,UAAM,KAAK,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/testing",
|
|
3
|
-
"version": "0.13.0-alpha.0-
|
|
3
|
+
"version": "0.13.0-alpha.0-20250322-f085fa576",
|
|
4
4
|
"description": "Test harness for running JavaScript and Matter certification tests",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"#tools/ansi-text": "@matter/tools/ansi-text"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@matter/tools": "0.13.0-alpha.0-
|
|
48
|
+
"@matter/tools": "0.13.0-alpha.0-20250322-f085fa576",
|
|
49
49
|
"@types/express": "^5.0.0",
|
|
50
50
|
"ansi-colors": "^4.1.3",
|
|
51
51
|
"chai": "^4.5.0",
|
package/src/mocks/time.ts
CHANGED
|
@@ -11,6 +11,12 @@ type TimerCallback = () => any;
|
|
|
11
11
|
type MockTimeLike = typeof MockTime;
|
|
12
12
|
export interface MockTime extends MockTimeLike {}
|
|
13
13
|
|
|
14
|
+
const registry = {
|
|
15
|
+
timers: new Set<MockTimer>(),
|
|
16
|
+
register(_timer: MockTimer) {},
|
|
17
|
+
unregister(_timer: MockTimer) {},
|
|
18
|
+
};
|
|
19
|
+
|
|
14
20
|
// Must match matter.js Timer interface
|
|
15
21
|
class MockTimer {
|
|
16
22
|
name = "Test";
|
|
@@ -18,14 +24,18 @@ class MockTimer {
|
|
|
18
24
|
intervalMs = 0;
|
|
19
25
|
isPeriodic = false;
|
|
20
26
|
|
|
27
|
+
#mockTime: MockTime;
|
|
28
|
+
#durationMs: number;
|
|
29
|
+
|
|
21
30
|
isRunning = false;
|
|
22
31
|
private readonly callback: TimerCallback;
|
|
23
32
|
|
|
24
|
-
constructor(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
constructor(mockTime: MockTime, name: string, durationMs: number, callback: TimerCallback) {
|
|
34
|
+
this.name = name;
|
|
35
|
+
|
|
36
|
+
this.#mockTime = mockTime;
|
|
37
|
+
this.#durationMs = durationMs;
|
|
38
|
+
|
|
29
39
|
if (this instanceof MockInterval) {
|
|
30
40
|
this.callback = callback;
|
|
31
41
|
} else {
|
|
@@ -37,25 +47,27 @@ class MockTimer {
|
|
|
37
47
|
}
|
|
38
48
|
|
|
39
49
|
start() {
|
|
40
|
-
|
|
50
|
+
registry.register(this);
|
|
51
|
+
this.#mockTime.callbackAtTime(this.#mockTime.nowMs() + this.#durationMs, this.callback);
|
|
41
52
|
this.isRunning = true;
|
|
42
53
|
return this;
|
|
43
54
|
}
|
|
44
55
|
|
|
45
56
|
stop() {
|
|
46
|
-
|
|
57
|
+
registry.unregister(this);
|
|
58
|
+
this.#mockTime.removeCallback(this.callback);
|
|
47
59
|
this.isRunning = false;
|
|
48
60
|
return this;
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
class MockInterval extends MockTimer {
|
|
53
|
-
constructor(mockTime: MockTime, durationMs: number, callback: TimerCallback) {
|
|
65
|
+
constructor(mockTime: MockTime, name: string, durationMs: number, callback: TimerCallback) {
|
|
54
66
|
const intervalCallback = async () => {
|
|
55
67
|
mockTime.callbackAtTime(mockTime.nowMs() + durationMs, intervalCallback);
|
|
56
68
|
await callback();
|
|
57
69
|
};
|
|
58
|
-
super(mockTime, durationMs, intervalCallback);
|
|
70
|
+
super(mockTime, name, durationMs, intervalCallback);
|
|
59
71
|
}
|
|
60
72
|
}
|
|
61
73
|
|
|
@@ -105,12 +117,12 @@ export const MockTime = {
|
|
|
105
117
|
return nowMs;
|
|
106
118
|
},
|
|
107
119
|
|
|
108
|
-
getTimer(
|
|
109
|
-
return new MockTimer(this, durationMs, callback);
|
|
120
|
+
getTimer(name: string, durationMs: number, callback: TimerCallback): MockTimer {
|
|
121
|
+
return new MockTimer(this, name, durationMs, callback);
|
|
110
122
|
},
|
|
111
123
|
|
|
112
|
-
getPeriodicTimer(
|
|
113
|
-
return new MockInterval(this, intervalMs, callback);
|
|
124
|
+
getPeriodicTimer(name: string, intervalMs: number, callback: TimerCallback): MockTimer {
|
|
125
|
+
return new MockInterval(this, name, intervalMs, callback);
|
|
114
126
|
},
|
|
115
127
|
|
|
116
128
|
/**
|
|
@@ -118,7 +130,7 @@ export const MockTime = {
|
|
|
118
130
|
*
|
|
119
131
|
* Moves time forward until the promise resolves.
|
|
120
132
|
*/
|
|
121
|
-
async resolve<T>(promise: PromiseLike<T
|
|
133
|
+
async resolve<T>(promise: PromiseLike<T>, { stepMs, macrotasks }: { stepMs?: number; macrotasks?: boolean } = {}) {
|
|
122
134
|
let resolved = false;
|
|
123
135
|
let result: T | undefined;
|
|
124
136
|
let error: any;
|
|
@@ -137,10 +149,14 @@ export const MockTime = {
|
|
|
137
149
|
let timeAdvanced = 0;
|
|
138
150
|
while (!resolved) {
|
|
139
151
|
// Interestingly, a Time.yield() works in almost every case. However, on Node SubtleCrypto.deriveBits hangs
|
|
140
|
-
// if you only yield via microtask. It seems to require yielding via macrotask. So we use
|
|
141
|
-
// Probably related to entropy collection but I think it's safe to classify as a Node bug.
|
|
142
|
-
// version 20.11.0
|
|
143
|
-
|
|
152
|
+
// if you only yield via microtask. It seems to require yielding via macrotask. So we optionally use
|
|
153
|
+
// setTimeout here. Probably related to entropy collection but I think it's safe to classify as a Node bug.
|
|
154
|
+
// Tested on version 20.11.0
|
|
155
|
+
if (macrotasks) {
|
|
156
|
+
await new Promise<void>(resolve => setTimeout(() => resolve(), 0));
|
|
157
|
+
} else {
|
|
158
|
+
await MockTime.yield();
|
|
159
|
+
}
|
|
144
160
|
|
|
145
161
|
if (resolved) {
|
|
146
162
|
break;
|
|
@@ -153,12 +169,16 @@ export const MockTime = {
|
|
|
153
169
|
);
|
|
154
170
|
}
|
|
155
171
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
172
|
+
if (stepMs) {
|
|
173
|
+
await this.advance(stepMs);
|
|
174
|
+
} else {
|
|
175
|
+
// Advance time exponentially, trying for granularity but also OK performance. Note that we are not only
|
|
176
|
+
// advancing time but also yielding event loop. So it's possible if we run out of time it's just because
|
|
177
|
+
// there were too few yields in one virtual hour. As designed currently it's 360 macrotasks and 360
|
|
178
|
+
// microtasks (360 loops w/ 1 macro- and 1 micro-yield)
|
|
179
|
+
await this.advance(1000);
|
|
180
|
+
timeAdvanced += 1000;
|
|
181
|
+
}
|
|
162
182
|
|
|
163
183
|
if (resolved) {
|
|
164
184
|
break;
|
|
@@ -180,8 +200,7 @@ export const MockTime = {
|
|
|
180
200
|
async advance(ms: number) {
|
|
181
201
|
const newTimeMs = nowMs + ms;
|
|
182
202
|
|
|
183
|
-
while (
|
|
184
|
-
if (callbacks.length === 0) break;
|
|
203
|
+
while (callbacks.length) {
|
|
185
204
|
const { atMs, callback } = callbacks[0];
|
|
186
205
|
if (atMs > newTimeMs) break;
|
|
187
206
|
callbacks.shift();
|
|
@@ -193,21 +212,18 @@ export const MockTime = {
|
|
|
193
212
|
},
|
|
194
213
|
|
|
195
214
|
/**
|
|
196
|
-
* Yield to scheduled microtasks. This means that all code paths waiting
|
|
197
|
-
*
|
|
198
|
-
* returns.
|
|
215
|
+
* Yield to scheduled microtasks. This means that all code paths waiting on resolved promises (including await)
|
|
216
|
+
* will proceed before this method returns.
|
|
199
217
|
*/
|
|
200
218
|
async yield() {
|
|
201
219
|
await Promise.resolve();
|
|
202
220
|
},
|
|
203
221
|
|
|
204
222
|
/**
|
|
205
|
-
* Due to its implementation, an older version of yield() would actually
|
|
206
|
-
*
|
|
207
|
-
* functionality -- one yield could trigger up to three nested awaits.
|
|
223
|
+
* Due to its implementation, an older version of yield() would actually yield to microtasks three times. Our tests
|
|
224
|
+
* then depended on this functionality -- one yield could trigger up to three nested awaits.
|
|
208
225
|
*
|
|
209
|
-
* To make this clear, the version of yield() that emulates old behavior
|
|
210
|
-
* is called "yield3".
|
|
226
|
+
* To make this clear, the version of yield() that emulates old behavior is called "yield3".
|
|
211
227
|
*/
|
|
212
228
|
async yield3() {
|
|
213
229
|
await Promise.resolve();
|
|
@@ -216,14 +232,12 @@ export const MockTime = {
|
|
|
216
232
|
},
|
|
217
233
|
|
|
218
234
|
/**
|
|
219
|
-
* Hook a method and invoke a callback just before the method completes.
|
|
220
|
-
* Unhooks after completion.
|
|
235
|
+
* Hook a method and invoke a callback just before the method completes. Unhooks after completion.
|
|
221
236
|
*
|
|
222
|
-
* Handles both synchronous and asynchronous methods. The interceptor
|
|
223
|
-
*
|
|
237
|
+
* Handles both synchronous and asynchronous methods. The interceptor should match the async-ness of the
|
|
238
|
+
* intercepted method.
|
|
224
239
|
*
|
|
225
|
-
* The interceptor can optionally access and/or replace the resolve/reject
|
|
226
|
-
* value.
|
|
240
|
+
* The interceptor can optionally access and/or replace the resolve/reject value.
|
|
227
241
|
*/
|
|
228
242
|
interceptOnce<NameT extends string, ReturnT, ObjT extends { [N in NameT]: (...args: any) => ReturnT }>(
|
|
229
243
|
obj: ObjT,
|
|
@@ -272,6 +286,13 @@ export const MockTime = {
|
|
|
272
286
|
}
|
|
273
287
|
},
|
|
274
288
|
|
|
289
|
+
/**
|
|
290
|
+
* Count the number of registered timers with a specific name.
|
|
291
|
+
*/
|
|
292
|
+
timerCountFor(name: string) {
|
|
293
|
+
return [...registry.timers].filter(timer => timer.name === name).length;
|
|
294
|
+
},
|
|
295
|
+
|
|
275
296
|
callbackAtTime(atMs: number, callback: TimerCallback) {
|
|
276
297
|
callbacks.push({ atMs, callback });
|
|
277
298
|
callbacks.sort(({ atMs: atMsA }, { atMs: atMsB }) => atMsA - atMsB);
|
|
@@ -286,7 +307,16 @@ export const MockTime = {
|
|
|
286
307
|
|
|
287
308
|
let reinstallTime: undefined | (() => void);
|
|
288
309
|
|
|
289
|
-
export function timeSetup(Time: {
|
|
310
|
+
export function timeSetup(Time: {
|
|
311
|
+
startup: { systemMs: number; processMs: number };
|
|
312
|
+
get(): unknown;
|
|
313
|
+
register(timer: MockTimer): void;
|
|
314
|
+
unregister(timer: MockTimer): void;
|
|
315
|
+
timers: Set<MockTimer>;
|
|
316
|
+
}) {
|
|
317
|
+
registry.register = Time.register;
|
|
318
|
+
registry.unregister = Time.unregister;
|
|
319
|
+
registry.timers = Time.timers;
|
|
290
320
|
Time.startup.systemMs = Time.startup.processMs = 0;
|
|
291
321
|
real = Time.get();
|
|
292
322
|
(MockTime as any).sleep = (real as any).sleep;
|
package/src/nodejs-reporter.ts
CHANGED
|
@@ -105,7 +105,7 @@ export abstract class NodejsReporter implements Reporter {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
const failure = this.#failures[i];
|
|
108
|
-
const index =
|
|
108
|
+
const index = `⚠ Failure ${ansi.bold((i + 1).toString())} of ${this.#failures.length}`;
|
|
109
109
|
const title = `${index} ${this.#formatName(failure.suite, failure.test, failure.step)}`;
|
|
110
110
|
|
|
111
111
|
FailureReporter.report(std.out, failure.detail, title);
|