@matter/testing 0.14.1-alpha.0-20250607-a93593303 → 0.15.0-alpha.0-20250613-a55f991d4
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/dist/cjs/chip/config.d.ts.map +1 -1
- package/dist/cjs/chip/config.js +2 -6
- package/dist/cjs/chip/config.js.map +1 -1
- package/dist/cjs/chip/container-command-pipe.d.ts +1 -0
- package/dist/cjs/chip/container-command-pipe.d.ts.map +1 -1
- package/dist/cjs/chip/container-command-pipe.js +2 -1
- package/dist/cjs/chip/container-command-pipe.js.map +1 -1
- package/dist/cjs/cli.d.ts.map +1 -1
- package/dist/cjs/cli.js +10 -0
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/global-declarations.d.ts +9 -2
- package/dist/cjs/global-declarations.d.ts.map +1 -1
- package/dist/cjs/global-definitions.js +5 -1
- package/dist/cjs/global-definitions.js.map +1 -1
- package/dist/cjs/mocha.d.ts.map +1 -1
- package/dist/cjs/mocha.js +10 -6
- package/dist/cjs/mocha.js.map +1 -1
- package/dist/cjs/mocks/boot.d.ts +4 -1
- package/dist/cjs/mocks/boot.d.ts.map +1 -1
- package/dist/cjs/mocks/boot.js +5 -5
- package/dist/cjs/mocks/boot.js.map +1 -1
- package/dist/cjs/mocks/crypto.d.ts +27 -1
- package/dist/cjs/mocks/crypto.d.ts.map +1 -1
- package/dist/cjs/mocks/crypto.js +56 -43
- package/dist/cjs/mocks/crypto.js.map +1 -1
- package/dist/cjs/mocks/logging.d.ts +1 -1
- package/dist/cjs/mocks/logging.d.ts.map +1 -1
- package/dist/cjs/mocks/logging.js +5 -5
- package/dist/cjs/mocks/logging.js.map +1 -1
- package/dist/cjs/mocks/time.d.ts +16 -1
- package/dist/cjs/mocks/time.d.ts.map +1 -1
- package/dist/cjs/mocks/time.js +48 -9
- package/dist/cjs/mocks/time.js.map +2 -2
- package/dist/cjs/nodejs.d.ts.map +1 -1
- package/dist/cjs/nodejs.js +2 -0
- package/dist/cjs/nodejs.js.map +1 -1
- package/dist/esm/chip/config.d.ts.map +1 -1
- package/dist/esm/chip/config.js +2 -6
- package/dist/esm/chip/config.js.map +1 -1
- package/dist/esm/chip/container-command-pipe.d.ts +1 -0
- package/dist/esm/chip/container-command-pipe.d.ts.map +1 -1
- package/dist/esm/chip/container-command-pipe.js +2 -1
- package/dist/esm/chip/container-command-pipe.js.map +1 -1
- package/dist/esm/cli.d.ts.map +1 -1
- package/dist/esm/cli.js +11 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/global-declarations.d.ts +9 -2
- package/dist/esm/global-declarations.d.ts.map +1 -1
- package/dist/esm/global-definitions.js +7 -3
- package/dist/esm/global-definitions.js.map +1 -1
- package/dist/esm/mocha.d.ts.map +1 -1
- package/dist/esm/mocha.js +10 -6
- package/dist/esm/mocha.js.map +1 -1
- package/dist/esm/mocks/boot.d.ts +4 -1
- package/dist/esm/mocks/boot.d.ts.map +1 -1
- package/dist/esm/mocks/boot.js +5 -5
- package/dist/esm/mocks/boot.js.map +1 -1
- package/dist/esm/mocks/crypto.d.ts +27 -1
- package/dist/esm/mocks/crypto.d.ts.map +1 -1
- package/dist/esm/mocks/crypto.js +56 -43
- package/dist/esm/mocks/crypto.js.map +1 -1
- package/dist/esm/mocks/logging.d.ts +1 -1
- package/dist/esm/mocks/logging.d.ts.map +1 -1
- package/dist/esm/mocks/logging.js +5 -5
- package/dist/esm/mocks/logging.js.map +1 -1
- package/dist/esm/mocks/time.d.ts +16 -1
- package/dist/esm/mocks/time.d.ts.map +1 -1
- package/dist/esm/mocks/time.js +48 -9
- package/dist/esm/mocks/time.js.map +2 -2
- package/dist/esm/nodejs.d.ts.map +1 -1
- package/dist/esm/nodejs.js +2 -0
- package/dist/esm/nodejs.js.map +1 -1
- package/package.json +4 -4
- package/src/chip/config.ts +2 -6
- package/src/chip/container-command-pipe.ts +1 -1
- package/src/cli.ts +13 -1
- package/src/global-declarations.ts +10 -2
- package/src/global-definitions.ts +10 -3
- package/src/mocha.ts +14 -9
- package/src/mocks/boot.ts +15 -5
- package/src/mocks/crypto.ts +95 -49
- package/src/mocks/logging.ts +4 -4
- package/src/mocks/time.ts +56 -11
- package/src/nodejs.ts +3 -0
package/src/mocks/crypto.ts
CHANGED
|
@@ -4,67 +4,113 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import { Boot } from "./boot.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* An
|
|
11
|
-
*
|
|
12
|
-
* Only supports those subsets of crypto required to complete matter.js tests.
|
|
10
|
+
* An arbitrary fill byte for mock random data. At some point a pseudo-random function may make sense but for now this
|
|
11
|
+
* suffices. Do not choose 0 or 0xff because that will interfere with logic that disallows 0 or -1.
|
|
13
12
|
*/
|
|
14
|
-
const
|
|
15
|
-
getRandomData: (length: number) => {
|
|
16
|
-
// Make random data deterministic
|
|
17
|
-
const bytes = new Uint8Array(length);
|
|
13
|
+
const FILL_BYTE = 0x80;
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
interface CryptoInstance {
|
|
16
|
+
getRandomData(length: number): Uint8Array;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface CryptoNamespace {
|
|
20
|
+
default: CryptoInstance;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let RealCrypto: undefined | CryptoNamespace;
|
|
24
|
+
|
|
25
|
+
let restoreRandomness: undefined | (() => void);
|
|
26
|
+
|
|
27
|
+
export const MockCrypto: MockCrypto = {
|
|
28
|
+
set random(value: boolean) {
|
|
29
|
+
if (RealCrypto === undefined) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (value === this.random) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
restoreRandomness?.();
|
|
38
|
+
if (!value) {
|
|
39
|
+
const instance = RealCrypto.default;
|
|
40
|
+
|
|
41
|
+
const realGetRandomData = instance.getRandomData;
|
|
42
|
+
instance.getRandomData = length => {
|
|
43
|
+
const result = new Uint8Array(length);
|
|
44
|
+
result.fill(FILL_BYTE);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
restoreRandomness = () => {
|
|
49
|
+
instance.getRandomData = realGetRandomData;
|
|
50
|
+
restoreRandomness = undefined;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
20
53
|
},
|
|
21
54
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const bits = await subtle.deriveBits(
|
|
25
|
-
{
|
|
26
|
-
name: "PBKDF2",
|
|
27
|
-
hash: "SHA-256",
|
|
28
|
-
salt: salt,
|
|
29
|
-
iterations: iteration,
|
|
30
|
-
},
|
|
31
|
-
key,
|
|
32
|
-
keyLength * 8,
|
|
33
|
-
);
|
|
34
|
-
return new Uint8Array(bits);
|
|
55
|
+
get random() {
|
|
56
|
+
return !restoreRandomness;
|
|
35
57
|
},
|
|
36
58
|
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
59
|
+
withRandom<T>(value: boolean, actor: () => T): T {
|
|
60
|
+
const revertTo = !!restoreRandomness;
|
|
61
|
+
let isAsync = false;
|
|
62
|
+
try {
|
|
63
|
+
MockCrypto.random = value;
|
|
64
|
+
const result = actor();
|
|
65
|
+
if (typeof (result as any)?.then === "function") {
|
|
66
|
+
isAsync = true;
|
|
67
|
+
return Promise.resolve(result).finally(() => {
|
|
68
|
+
MockCrypto.random = revertTo;
|
|
69
|
+
}) as T;
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
} finally {
|
|
73
|
+
if (!isAsync) {
|
|
74
|
+
MockCrypto.random = revertTo;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
51
77
|
},
|
|
52
78
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return;
|
|
79
|
+
enable() {
|
|
80
|
+
MockCrypto.random = false;
|
|
56
81
|
},
|
|
57
82
|
|
|
58
|
-
|
|
83
|
+
init() {
|
|
84
|
+
if (MockCrypto.random) {
|
|
85
|
+
MockCrypto.enable();
|
|
86
|
+
}
|
|
87
|
+
},
|
|
59
88
|
};
|
|
60
89
|
|
|
61
|
-
export function cryptoSetup(Crypto:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
export function cryptoSetup(Crypto: CryptoNamespace) {
|
|
91
|
+
RealCrypto = Crypto;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Boot.init(() => (MockCrypto.random = true));
|
|
95
|
+
|
|
96
|
+
export interface MockCrypto {
|
|
97
|
+
/**
|
|
98
|
+
* If false, crypto functions return all zeros instead of random data. Resets to true for each test file.
|
|
99
|
+
*/
|
|
100
|
+
random: boolean;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Set {@link random} to false.
|
|
104
|
+
*/
|
|
105
|
+
enable(): void;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Enabled if not already enabled.
|
|
109
|
+
*/
|
|
110
|
+
init(): void;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Perform an operation with altered {@link random} then revert.
|
|
114
|
+
*/
|
|
115
|
+
withRandom<T>(value: boolean, actor: () => T): T;
|
|
70
116
|
}
|
package/src/mocks/logging.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface MockLogger {
|
|
|
25
25
|
injectExternalMessage: (source: string, text: string) => void;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export const
|
|
28
|
+
export const MockLogger: MockLogger = {
|
|
29
29
|
emitAll: false,
|
|
30
30
|
injectExternalMessage: (source: string, text: string) => console.log(formatExternalMessage(source, text)),
|
|
31
31
|
};
|
|
@@ -67,7 +67,7 @@ export function loggerSetup(Logger: LoggerLike) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
function interceptingWriter(...args: [string, DiagnosticMessageLike]) {
|
|
70
|
-
let emitAll =
|
|
70
|
+
let emitAll = MockLogger.emitAll;
|
|
71
71
|
if (MatterHooks?.loggerSink) {
|
|
72
72
|
MatterHooks.loggerSink(...args);
|
|
73
73
|
} else if (!emitAll) {
|
|
@@ -83,14 +83,14 @@ export function loggerSetup(Logger: LoggerLike) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
MockLogger.injectExternalMessage = (source, text) =>
|
|
87
87
|
interceptingWriter(formatExternalMessage(source, text), { level: 0 });
|
|
88
88
|
|
|
89
89
|
Logger.destinations.default.write = interceptingWriter;
|
|
90
90
|
|
|
91
91
|
// Divert log messages for test duration
|
|
92
92
|
LoggerHooks.beforeEach.push(function () {
|
|
93
|
-
if (!
|
|
93
|
+
if (!MockLogger.emitAll) {
|
|
94
94
|
messageBuffer = [];
|
|
95
95
|
}
|
|
96
96
|
});
|
package/src/mocks/time.ts
CHANGED
|
@@ -83,30 +83,74 @@ function isAsync(fn: (...args: any) => any): fn is (...args: any) => Promise<any
|
|
|
83
83
|
let callbacks = new Array<{ atMs: number; callback: TimerCallback }>();
|
|
84
84
|
let nowMs = 0;
|
|
85
85
|
let real = undefined as unknown;
|
|
86
|
-
let enabled =
|
|
86
|
+
let enabled = false;
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
/**
|
|
89
|
+
* An arbitrary start for our mock timeline. Starting at zero causes problems with Matter dates that cannot encode back
|
|
90
|
+
* to the UNIX epoch
|
|
91
|
+
*/
|
|
92
|
+
const epoch = new Date("2025-01-01 12:34:56Z");
|
|
93
|
+
|
|
94
|
+
// Must match matter.js Time interface (with extensions)
|
|
89
95
|
export const MockTime = {
|
|
96
|
+
epoch,
|
|
97
|
+
|
|
90
98
|
get activeImplementation(): unknown {
|
|
91
99
|
return enabled ? this : (real ?? this);
|
|
92
100
|
},
|
|
93
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Revert to standard time implementation.
|
|
104
|
+
*/
|
|
94
105
|
disable() {
|
|
95
106
|
enabled = false;
|
|
96
|
-
|
|
107
|
+
installActiveImplementation?.();
|
|
97
108
|
},
|
|
98
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Enable time mocking. Reverts to disabled for each test file.
|
|
112
|
+
*/
|
|
99
113
|
enable() {
|
|
100
114
|
enabled = true;
|
|
101
|
-
|
|
115
|
+
installActiveImplementation?.();
|
|
102
116
|
},
|
|
103
117
|
|
|
104
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Sets mock time to specific time and enable the mock.
|
|
120
|
+
*/
|
|
121
|
+
reset(time: ConstructorParameters<typeof Date>[0] = epoch) {
|
|
105
122
|
callbacks = [];
|
|
106
|
-
nowMs = time;
|
|
123
|
+
nowMs = new Date(time).getTime();
|
|
124
|
+
MockTime.enable();
|
|
125
|
+
},
|
|
107
126
|
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Enable and reset if not already enabled.
|
|
129
|
+
*/
|
|
130
|
+
init() {
|
|
131
|
+
if (!enabled) {
|
|
132
|
+
MockTime.enable();
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
atTime<T>(time: number | Date, actor: () => T): T {
|
|
137
|
+
const revertTo = nowMs;
|
|
138
|
+
let isAsync = false;
|
|
139
|
+
try {
|
|
140
|
+
nowMs = typeof time === "number" ? time : time.getTime();
|
|
141
|
+
const result = actor();
|
|
142
|
+
if (typeof (result as any)?.then === "function") {
|
|
143
|
+
isAsync = true;
|
|
144
|
+
return Promise.resolve(result).finally(() => {
|
|
145
|
+
nowMs = revertTo;
|
|
146
|
+
}) as T;
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
} finally {
|
|
150
|
+
if (!isAsync) {
|
|
151
|
+
nowMs = revertTo;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
110
154
|
},
|
|
111
155
|
|
|
112
156
|
now(): Date {
|
|
@@ -305,7 +349,7 @@ export const MockTime = {
|
|
|
305
349
|
},
|
|
306
350
|
};
|
|
307
351
|
|
|
308
|
-
let
|
|
352
|
+
let installActiveImplementation: undefined | (() => void);
|
|
309
353
|
|
|
310
354
|
export function timeSetup(Time: {
|
|
311
355
|
startup: { systemMs: number; processMs: number };
|
|
@@ -320,12 +364,13 @@ export function timeSetup(Time: {
|
|
|
320
364
|
Time.startup.systemMs = Time.startup.processMs = 0;
|
|
321
365
|
real = Time.get();
|
|
322
366
|
(MockTime as any).sleep = (real as any).sleep;
|
|
323
|
-
|
|
324
|
-
|
|
367
|
+
installActiveImplementation = () => (Time.get = () => MockTime.activeImplementation);
|
|
368
|
+
installActiveImplementation();
|
|
325
369
|
}
|
|
326
370
|
|
|
327
371
|
Object.assign(globalThis, { MockTime });
|
|
328
372
|
|
|
329
373
|
Boot.init(() => {
|
|
330
374
|
MockTime.reset();
|
|
375
|
+
MockTime.disable();
|
|
331
376
|
});
|
package/src/nodejs.ts
CHANGED
|
@@ -15,11 +15,14 @@ import type { TestRunner } from "./runner.js";
|
|
|
15
15
|
// Load globals so settings get applied
|
|
16
16
|
import { FailureDetail } from "./failure-detail.js";
|
|
17
17
|
import "./global-definitions.js";
|
|
18
|
+
import { Boot } from "./mocks/boot.js";
|
|
18
19
|
import { TestDescriptor } from "./test-descriptor.js";
|
|
19
20
|
|
|
20
21
|
extendApi(Mocha);
|
|
21
22
|
|
|
22
23
|
export async function testNodejs(runner: TestRunner, format: "cjs" | "esm") {
|
|
24
|
+
Boot.format = format;
|
|
25
|
+
|
|
23
26
|
// Grr Mocha (as of 10.2.0) classifies certain unhandled rejections as "mocha". For others, it uninstalls its
|
|
24
27
|
// unhandled rejection handler and re-emits the "unhandledRejection" event. But since it already handled the event,
|
|
25
28
|
// Node knows nothing about this and the event disappears silently.
|