matterbridge 3.3.8 → 3.3.9-dev-20251119-ea13a99
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 +18 -0
- package/README-DEV.md +20 -25
- package/dist/broadcastServer.js +1 -93
- package/dist/broadcastServerTypes.js +0 -24
- package/dist/cli.js +1 -97
- package/dist/cliEmitter.js +0 -37
- package/dist/cliHistory.js +0 -38
- package/dist/clusters/export.js +0 -2
- package/dist/defaultConfigSchema.js +0 -24
- package/dist/deviceManager.js +1 -105
- package/dist/devices/airConditioner.js +0 -57
- package/dist/devices/batteryStorage.js +1 -48
- package/dist/devices/cooktop.js +0 -55
- package/dist/devices/dishwasher.js +0 -57
- package/dist/devices/evse.js +10 -74
- package/dist/devices/export.js +0 -5
- package/dist/devices/extractorHood.js +0 -43
- package/dist/devices/heatPump.js +2 -50
- package/dist/devices/laundryDryer.js +3 -62
- package/dist/devices/laundryWasher.js +4 -70
- package/dist/devices/microwaveOven.js +5 -88
- package/dist/devices/oven.js +0 -85
- package/dist/devices/refrigerator.js +0 -102
- package/dist/devices/roboticVacuumCleaner.js +9 -100
- package/dist/devices/solarPower.js +0 -38
- package/dist/devices/speaker.js +0 -84
- package/dist/devices/temperatureControl.js +3 -24
- package/dist/devices/waterHeater.js +2 -82
- package/dist/dgram/coap.js +13 -126
- package/dist/dgram/dgram.js +2 -114
- package/dist/dgram/mb_coap.js +3 -41
- package/dist/dgram/mb_mdns.js +15 -80
- package/dist/dgram/mdns.js +137 -299
- package/dist/dgram/multicast.js +1 -62
- package/dist/dgram/unicast.js +0 -54
- package/dist/frontend.js +39 -454
- package/dist/frontendTypes.js +0 -45
- package/dist/helpers.js +0 -53
- package/dist/index.js +0 -25
- package/dist/jestutils/export.js +0 -1
- package/dist/jestutils/jestHelpers.js +104 -278
- package/dist/logger/export.js +0 -1
- package/dist/matter/behaviors.js +0 -2
- package/dist/matter/clusters.js +0 -2
- package/dist/matter/devices.js +0 -2
- package/dist/matter/endpoints.js +0 -2
- package/dist/matter/export.js +0 -3
- package/dist/matter/types.js +0 -3
- package/dist/matterbridge.js +51 -792
- package/dist/matterbridgeAccessoryPlatform.js +0 -38
- package/dist/matterbridgeBehaviors.js +5 -68
- package/dist/matterbridgeDeviceTypes.js +14 -635
- package/dist/matterbridgeDynamicPlatform.js +0 -38
- package/dist/matterbridgeEndpoint.js +82 -1445
- package/dist/matterbridgeEndpointHelpers.js +21 -483
- package/dist/matterbridgeEndpointTypes.js +0 -25
- package/dist/matterbridgePlatform.js +16 -355
- package/dist/matterbridgeTypes.js +0 -26
- package/dist/pluginManager.js +11 -346
- package/dist/shelly.js +7 -168
- package/dist/storage/export.js +0 -1
- package/dist/update.js +0 -69
- package/dist/utils/colorUtils.js +2 -97
- package/dist/utils/commandLine.js +0 -60
- package/dist/utils/copyDirectory.js +1 -38
- package/dist/utils/createDirectory.js +0 -33
- package/dist/utils/createZip.js +2 -47
- package/dist/utils/deepCopy.js +0 -39
- package/dist/utils/deepEqual.js +1 -72
- package/dist/utils/error.js +0 -41
- package/dist/utils/export.js +0 -1
- package/dist/utils/format.js +0 -49
- package/dist/utils/hex.js +0 -124
- package/dist/utils/inspector.js +1 -69
- package/dist/utils/isvalid.js +0 -101
- package/dist/utils/network.js +5 -96
- package/dist/utils/spawn.js +0 -71
- package/dist/utils/tracker.js +1 -64
- package/dist/utils/wait.js +8 -60
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -2
- package/dist/broadcastServer.d.ts +0 -115
- package/dist/broadcastServer.d.ts.map +0 -1
- package/dist/broadcastServer.js.map +0 -1
- package/dist/broadcastServerTypes.d.ts +0 -806
- package/dist/broadcastServerTypes.d.ts.map +0 -1
- package/dist/broadcastServerTypes.js.map +0 -1
- package/dist/cli.d.ts +0 -30
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cliEmitter.d.ts +0 -50
- package/dist/cliEmitter.d.ts.map +0 -1
- package/dist/cliEmitter.js.map +0 -1
- package/dist/cliHistory.d.ts +0 -48
- package/dist/cliHistory.d.ts.map +0 -1
- package/dist/cliHistory.js.map +0 -1
- package/dist/clusters/export.d.ts +0 -2
- package/dist/clusters/export.d.ts.map +0 -1
- package/dist/clusters/export.js.map +0 -1
- package/dist/defaultConfigSchema.d.ts +0 -28
- package/dist/defaultConfigSchema.d.ts.map +0 -1
- package/dist/defaultConfigSchema.js.map +0 -1
- package/dist/deviceManager.d.ts +0 -128
- package/dist/deviceManager.d.ts.map +0 -1
- package/dist/deviceManager.js.map +0 -1
- package/dist/devices/airConditioner.d.ts +0 -98
- package/dist/devices/airConditioner.d.ts.map +0 -1
- package/dist/devices/airConditioner.js.map +0 -1
- package/dist/devices/batteryStorage.d.ts +0 -48
- package/dist/devices/batteryStorage.d.ts.map +0 -1
- package/dist/devices/batteryStorage.js.map +0 -1
- package/dist/devices/cooktop.d.ts +0 -60
- package/dist/devices/cooktop.d.ts.map +0 -1
- package/dist/devices/cooktop.js.map +0 -1
- package/dist/devices/dishwasher.d.ts +0 -71
- package/dist/devices/dishwasher.d.ts.map +0 -1
- package/dist/devices/dishwasher.js.map +0 -1
- package/dist/devices/evse.d.ts +0 -76
- package/dist/devices/evse.d.ts.map +0 -1
- package/dist/devices/evse.js.map +0 -1
- package/dist/devices/export.d.ts +0 -17
- package/dist/devices/export.d.ts.map +0 -1
- package/dist/devices/export.js.map +0 -1
- package/dist/devices/extractorHood.d.ts +0 -46
- package/dist/devices/extractorHood.d.ts.map +0 -1
- package/dist/devices/extractorHood.js.map +0 -1
- package/dist/devices/heatPump.d.ts +0 -47
- package/dist/devices/heatPump.d.ts.map +0 -1
- package/dist/devices/heatPump.js.map +0 -1
- package/dist/devices/laundryDryer.d.ts +0 -67
- package/dist/devices/laundryDryer.d.ts.map +0 -1
- package/dist/devices/laundryDryer.js.map +0 -1
- package/dist/devices/laundryWasher.d.ts +0 -81
- package/dist/devices/laundryWasher.d.ts.map +0 -1
- package/dist/devices/laundryWasher.js.map +0 -1
- package/dist/devices/microwaveOven.d.ts +0 -168
- package/dist/devices/microwaveOven.d.ts.map +0 -1
- package/dist/devices/microwaveOven.js.map +0 -1
- package/dist/devices/oven.d.ts +0 -105
- package/dist/devices/oven.d.ts.map +0 -1
- package/dist/devices/oven.js.map +0 -1
- package/dist/devices/refrigerator.d.ts +0 -118
- package/dist/devices/refrigerator.d.ts.map +0 -1
- package/dist/devices/refrigerator.js.map +0 -1
- package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
- package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
- package/dist/devices/roboticVacuumCleaner.js.map +0 -1
- package/dist/devices/solarPower.d.ts +0 -40
- package/dist/devices/solarPower.d.ts.map +0 -1
- package/dist/devices/solarPower.js.map +0 -1
- package/dist/devices/speaker.d.ts +0 -87
- package/dist/devices/speaker.d.ts.map +0 -1
- package/dist/devices/speaker.js.map +0 -1
- package/dist/devices/temperatureControl.d.ts +0 -166
- package/dist/devices/temperatureControl.d.ts.map +0 -1
- package/dist/devices/temperatureControl.js.map +0 -1
- package/dist/devices/waterHeater.d.ts +0 -111
- package/dist/devices/waterHeater.d.ts.map +0 -1
- package/dist/devices/waterHeater.js.map +0 -1
- package/dist/dgram/coap.d.ts +0 -205
- package/dist/dgram/coap.d.ts.map +0 -1
- package/dist/dgram/coap.js.map +0 -1
- package/dist/dgram/dgram.d.ts +0 -141
- package/dist/dgram/dgram.d.ts.map +0 -1
- package/dist/dgram/dgram.js.map +0 -1
- package/dist/dgram/mb_coap.d.ts +0 -24
- package/dist/dgram/mb_coap.d.ts.map +0 -1
- package/dist/dgram/mb_coap.js.map +0 -1
- package/dist/dgram/mb_mdns.d.ts +0 -24
- package/dist/dgram/mb_mdns.d.ts.map +0 -1
- package/dist/dgram/mb_mdns.js.map +0 -1
- package/dist/dgram/mdns.d.ts +0 -290
- package/dist/dgram/mdns.d.ts.map +0 -1
- package/dist/dgram/mdns.js.map +0 -1
- package/dist/dgram/multicast.d.ts +0 -67
- package/dist/dgram/multicast.d.ts.map +0 -1
- package/dist/dgram/multicast.js.map +0 -1
- package/dist/dgram/unicast.d.ts +0 -56
- package/dist/dgram/unicast.d.ts.map +0 -1
- package/dist/dgram/unicast.js.map +0 -1
- package/dist/frontend.d.ts +0 -238
- package/dist/frontend.d.ts.map +0 -1
- package/dist/frontend.js.map +0 -1
- package/dist/frontendTypes.d.ts +0 -529
- package/dist/frontendTypes.d.ts.map +0 -1
- package/dist/frontendTypes.js.map +0 -1
- package/dist/helpers.d.ts +0 -48
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js.map +0 -1
- package/dist/index.d.ts +0 -34
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jestutils/export.d.ts +0 -2
- package/dist/jestutils/export.d.ts.map +0 -1
- package/dist/jestutils/export.js.map +0 -1
- package/dist/jestutils/jestHelpers.d.ts +0 -250
- package/dist/jestutils/jestHelpers.d.ts.map +0 -1
- package/dist/jestutils/jestHelpers.js.map +0 -1
- package/dist/logger/export.d.ts +0 -2
- package/dist/logger/export.d.ts.map +0 -1
- package/dist/logger/export.js.map +0 -1
- package/dist/matter/behaviors.d.ts +0 -2
- package/dist/matter/behaviors.d.ts.map +0 -1
- package/dist/matter/behaviors.js.map +0 -1
- package/dist/matter/clusters.d.ts +0 -2
- package/dist/matter/clusters.d.ts.map +0 -1
- package/dist/matter/clusters.js.map +0 -1
- package/dist/matter/devices.d.ts +0 -2
- package/dist/matter/devices.d.ts.map +0 -1
- package/dist/matter/devices.js.map +0 -1
- package/dist/matter/endpoints.d.ts +0 -2
- package/dist/matter/endpoints.d.ts.map +0 -1
- package/dist/matter/endpoints.js.map +0 -1
- package/dist/matter/export.d.ts +0 -5
- package/dist/matter/export.d.ts.map +0 -1
- package/dist/matter/export.js.map +0 -1
- package/dist/matter/types.d.ts +0 -3
- package/dist/matter/types.d.ts.map +0 -1
- package/dist/matter/types.js.map +0 -1
- package/dist/matterbridge.d.ts +0 -469
- package/dist/matterbridge.d.ts.map +0 -1
- package/dist/matterbridge.js.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.d.ts +0 -41
- package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
- package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
- package/dist/matterbridgeBehaviors.d.ts +0 -2404
- package/dist/matterbridgeBehaviors.d.ts.map +0 -1
- package/dist/matterbridgeBehaviors.js.map +0 -1
- package/dist/matterbridgeDeviceTypes.d.ts +0 -698
- package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
- package/dist/matterbridgeDeviceTypes.js.map +0 -1
- package/dist/matterbridgeDynamicPlatform.d.ts +0 -41
- package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
- package/dist/matterbridgeDynamicPlatform.js.map +0 -1
- package/dist/matterbridgeEndpoint.d.ts +0 -1490
- package/dist/matterbridgeEndpoint.d.ts.map +0 -1
- package/dist/matterbridgeEndpoint.js.map +0 -1
- package/dist/matterbridgeEndpointHelpers.d.ts +0 -787
- package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
- package/dist/matterbridgeEndpointHelpers.js.map +0 -1
- package/dist/matterbridgeEndpointTypes.d.ts +0 -197
- package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
- package/dist/matterbridgeEndpointTypes.js.map +0 -1
- package/dist/matterbridgePlatform.d.ts +0 -415
- package/dist/matterbridgePlatform.d.ts.map +0 -1
- package/dist/matterbridgePlatform.js.map +0 -1
- package/dist/matterbridgeTypes.d.ts +0 -239
- package/dist/matterbridgeTypes.d.ts.map +0 -1
- package/dist/matterbridgeTypes.js.map +0 -1
- package/dist/pluginManager.d.ts +0 -371
- package/dist/pluginManager.d.ts.map +0 -1
- package/dist/pluginManager.js.map +0 -1
- package/dist/shelly.d.ts +0 -174
- package/dist/shelly.d.ts.map +0 -1
- package/dist/shelly.js.map +0 -1
- package/dist/storage/export.d.ts +0 -2
- package/dist/storage/export.d.ts.map +0 -1
- package/dist/storage/export.js.map +0 -1
- package/dist/update.d.ts +0 -75
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- package/dist/utils/colorUtils.d.ts +0 -101
- package/dist/utils/colorUtils.d.ts.map +0 -1
- package/dist/utils/colorUtils.js.map +0 -1
- package/dist/utils/commandLine.d.ts +0 -66
- package/dist/utils/commandLine.d.ts.map +0 -1
- package/dist/utils/commandLine.js.map +0 -1
- package/dist/utils/copyDirectory.d.ts +0 -33
- package/dist/utils/copyDirectory.d.ts.map +0 -1
- package/dist/utils/copyDirectory.js.map +0 -1
- package/dist/utils/createDirectory.d.ts +0 -34
- package/dist/utils/createDirectory.d.ts.map +0 -1
- package/dist/utils/createDirectory.js.map +0 -1
- package/dist/utils/createZip.d.ts +0 -39
- package/dist/utils/createZip.d.ts.map +0 -1
- package/dist/utils/createZip.js.map +0 -1
- package/dist/utils/deepCopy.d.ts +0 -32
- package/dist/utils/deepCopy.d.ts.map +0 -1
- package/dist/utils/deepCopy.js.map +0 -1
- package/dist/utils/deepEqual.d.ts +0 -54
- package/dist/utils/deepEqual.d.ts.map +0 -1
- package/dist/utils/deepEqual.js.map +0 -1
- package/dist/utils/error.d.ts +0 -44
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js.map +0 -1
- package/dist/utils/export.d.ts +0 -13
- package/dist/utils/export.d.ts.map +0 -1
- package/dist/utils/export.js.map +0 -1
- package/dist/utils/format.d.ts +0 -53
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/hex.d.ts +0 -89
- package/dist/utils/hex.d.ts.map +0 -1
- package/dist/utils/hex.js.map +0 -1
- package/dist/utils/inspector.d.ts +0 -87
- package/dist/utils/inspector.d.ts.map +0 -1
- package/dist/utils/inspector.js.map +0 -1
- package/dist/utils/isvalid.d.ts +0 -103
- package/dist/utils/isvalid.d.ts.map +0 -1
- package/dist/utils/isvalid.js.map +0 -1
- package/dist/utils/network.d.ts +0 -101
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/network.js.map +0 -1
- package/dist/utils/spawn.d.ts +0 -35
- package/dist/utils/spawn.d.ts.map +0 -1
- package/dist/utils/spawn.js.map +0 -1
- package/dist/utils/tracker.d.ts +0 -108
- package/dist/utils/tracker.d.ts.map +0 -1
- package/dist/utils/tracker.js.map +0 -1
- package/dist/utils/wait.d.ts +0 -54
- package/dist/utils/wait.d.ts.map +0 -1
- package/dist/utils/wait.js.map +0 -1
|
@@ -1,44 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description This file contains the Jest helpers.
|
|
3
|
-
* @file src/helpers.test.ts
|
|
4
|
-
* @author Luca Liguori
|
|
5
|
-
* @created 2025-09-03
|
|
6
|
-
* @version 1.0.12
|
|
7
|
-
* @license Apache-2.0
|
|
8
|
-
*
|
|
9
|
-
* Copyright 2025, 2026, 2027 Luca Liguori.
|
|
10
|
-
*
|
|
11
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
12
|
-
* you may not use this file except in compliance with the License.
|
|
13
|
-
* You may obtain a copy of the License at
|
|
14
|
-
*
|
|
15
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
16
|
-
*
|
|
17
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
-
* See the License for the specific language governing permissions and
|
|
21
|
-
* limitations under the License.
|
|
22
|
-
*/
|
|
23
1
|
import { rmSync } from 'node:fs';
|
|
24
2
|
import { inspect } from 'node:util';
|
|
25
3
|
import path from 'node:path';
|
|
26
|
-
|
|
27
|
-
import { AnsiLogger, er, rs } from 'node-ansi-logger';
|
|
4
|
+
import { AnsiLogger, er, rs, UNDERLINE, UNDERLINEOFF } from 'node-ansi-logger';
|
|
28
5
|
import { LogLevel as MatterLogLevel, LogFormat as MatterLogFormat, Environment, Lifecycle } from '@matter/general';
|
|
29
6
|
import { Endpoint, ServerNode, ServerNodeStore } from '@matter/node';
|
|
30
7
|
import { DeviceTypeId, VendorId } from '@matter/types/datatype';
|
|
31
8
|
import { AggregatorEndpoint } from '@matter/node/endpoints';
|
|
32
9
|
import { MdnsService } from '@matter/main/protocol';
|
|
10
|
+
import { NodeStorageManager } from 'node-persist-manager';
|
|
33
11
|
import { Matterbridge } from '../matterbridge.js';
|
|
34
|
-
import { MATTER_STORAGE_NAME } from '../matterbridgeTypes.js';
|
|
12
|
+
import { MATTER_STORAGE_NAME, NODE_STORAGE_DIR } from '../matterbridgeTypes.js';
|
|
35
13
|
import { bridge } from '../matterbridgeDeviceTypes.js';
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
import { DeviceTypeId, Endpoint, Environment, MdnsService, ServerNode, ServerNodeStore, VendorId, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Lifecycle } from 'matterbridge/matter';
|
|
39
|
-
import { RootEndpoint, AggregatorEndpoint } from 'matterbridge/matter/endpoints';
|
|
40
|
-
import { MATTER_STORAGE_NAME, Matterbridge, MatterbridgePlatform } from 'matterbridge';
|
|
41
|
-
*/
|
|
14
|
+
export const originalProcessArgv = Object.freeze([...process.argv]);
|
|
15
|
+
export const originalProcessEnv = Object.freeze({ ...process.env });
|
|
42
16
|
export let loggerLogSpy;
|
|
43
17
|
export let loggerDebugSpy;
|
|
44
18
|
export let loggerInfoSpy;
|
|
@@ -54,34 +28,23 @@ export let consoleErrorSpy;
|
|
|
54
28
|
export let addBridgedEndpointSpy;
|
|
55
29
|
export let removeBridgedEndpointSpy;
|
|
56
30
|
export let removeAllBridgedEndpointsSpy;
|
|
31
|
+
export let NAME;
|
|
32
|
+
export let HOMEDIR;
|
|
57
33
|
export let matterbridge;
|
|
34
|
+
export let frontend;
|
|
35
|
+
export let plugins;
|
|
36
|
+
export let devices;
|
|
58
37
|
export let environment;
|
|
59
38
|
export let server;
|
|
60
39
|
export let aggregator;
|
|
61
40
|
export let log;
|
|
62
|
-
/**
|
|
63
|
-
* Setup the Jest environment:
|
|
64
|
-
* - it will remove any existing home directory
|
|
65
|
-
* - setup the spies for logging
|
|
66
|
-
*
|
|
67
|
-
* @param {string} name The name of the test suite.
|
|
68
|
-
* @param {boolean} debug If true, the logging is not mocked.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```typescript
|
|
72
|
-
* import { consoleDebugSpy, consoleErrorSpy, consoleInfoSpy, consoleLogSpy, consoleWarnSpy, loggerLogSpy, setDebug, setupTest } from './jestutils/jestHelpers.js';
|
|
73
|
-
*
|
|
74
|
-
* // Setup the test environment
|
|
75
|
-
* setupTest(NAME, false);
|
|
76
|
-
*
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
41
|
export async function setupTest(name, debug = false) {
|
|
80
42
|
expect(name).toBeDefined();
|
|
81
43
|
expect(typeof name).toBe('string');
|
|
82
44
|
expect(name.length).toBeGreaterThanOrEqual(4);
|
|
83
|
-
|
|
84
|
-
|
|
45
|
+
NAME = name;
|
|
46
|
+
HOMEDIR = path.join('jest', name);
|
|
47
|
+
rmSync(HOMEDIR, { recursive: true, force: true });
|
|
85
48
|
const { jest } = await import('@jest/globals');
|
|
86
49
|
loggerDebugSpy = jest.spyOn(AnsiLogger.prototype, 'debug');
|
|
87
50
|
loggerInfoSpy = jest.spyOn(AnsiLogger.prototype, 'info');
|
|
@@ -109,22 +72,6 @@ export async function setupTest(name, debug = false) {
|
|
|
109
72
|
removeBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'removeBridgedEndpoint');
|
|
110
73
|
removeAllBridgedEndpointsSpy = jest.spyOn(Matterbridge.prototype, 'removeAllBridgedEndpoints');
|
|
111
74
|
}
|
|
112
|
-
/**
|
|
113
|
-
* Set or unset the debug mode.
|
|
114
|
-
*
|
|
115
|
-
* @param {boolean} debug If true, the logging is not mocked.
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* // Set the debug mode in test environment
|
|
120
|
-
* setDebug(true);
|
|
121
|
-
* ```
|
|
122
|
-
*
|
|
123
|
-
* ```typescript
|
|
124
|
-
* // Reset the debug mode in test environment
|
|
125
|
-
* setDebug(false);
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
75
|
export async function setDebug(debug) {
|
|
129
76
|
const { jest } = await import('@jest/globals');
|
|
130
77
|
if (debug) {
|
|
@@ -150,21 +97,90 @@ export async function setDebug(debug) {
|
|
|
150
97
|
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
151
98
|
}
|
|
152
99
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
100
|
+
export async function startMatterbridge(bridgeMode = 'bridge', frontendPort = 8283, matterPort = 5540, passcode = 20252026, discriminator = 3840, pluginSize = 0, devicesSize = 0) {
|
|
101
|
+
process.env['MATTERBRIDGE_START_MATTER_INTERVAL_MS'] = '100';
|
|
102
|
+
process.env['MATTERBRIDGE_PAUSE_MATTER_INTERVAL_MS'] = '100';
|
|
103
|
+
process.argv.length = 0;
|
|
104
|
+
process.argv.push(...originalProcessArgv, '-novirtual', '-debug', '-verbose', '-logger', 'debug', '-matterlogger', 'debug', bridgeMode === '' ? '-test' : '-' + bridgeMode, '-homedir', HOMEDIR, '-frontend', frontendPort.toString(), '-port', matterPort.toString(), '-passcode', passcode.toString(), '-discriminator', discriminator.toString());
|
|
105
|
+
matterbridge = await Matterbridge.loadInstance(true);
|
|
106
|
+
expect(matterbridge).toBeDefined();
|
|
107
|
+
expect(matterbridge.profile).toBeUndefined();
|
|
108
|
+
expect(matterbridge.bridgeMode).toBe(bridgeMode);
|
|
109
|
+
frontend = matterbridge.frontend;
|
|
110
|
+
plugins = matterbridge.plugins;
|
|
111
|
+
devices = matterbridge.devices;
|
|
112
|
+
expect(matterbridge.initialized).toBeTruthy();
|
|
113
|
+
expect(matterbridge.log).toBeDefined();
|
|
114
|
+
expect(matterbridge.rootDirectory).toBe(path.resolve('./'));
|
|
115
|
+
expect(matterbridge.homeDirectory).toBe(path.join('jest', NAME));
|
|
116
|
+
expect(matterbridge.matterbridgeDirectory).toBe(path.join('jest', NAME, '.matterbridge'));
|
|
117
|
+
expect(matterbridge.matterbridgePluginDirectory).toBe(path.join('jest', NAME, 'Matterbridge'));
|
|
118
|
+
expect(matterbridge.matterbridgeCertDirectory).toBe(path.join('jest', NAME, '.mattercert'));
|
|
119
|
+
expect(plugins).toBeDefined();
|
|
120
|
+
expect(plugins.size).toBe(pluginSize);
|
|
121
|
+
expect(devices).toBeDefined();
|
|
122
|
+
expect(devices.size).toBe(devicesSize);
|
|
123
|
+
expect(frontend).toBeDefined();
|
|
124
|
+
expect(frontend.listening).toBeTruthy();
|
|
125
|
+
expect(frontend.httpServer).toBeDefined();
|
|
126
|
+
expect(frontend.httpsServer).toBeUndefined();
|
|
127
|
+
expect(frontend.expressApp).toBeDefined();
|
|
128
|
+
expect(frontend.webSocketServer).toBeDefined();
|
|
129
|
+
expect(matterbridge.nodeStorage).toBeDefined();
|
|
130
|
+
expect(matterbridge.nodeContext).toBeDefined();
|
|
131
|
+
expect(Environment.default.vars.get('path.root')).toBe(path.join(matterbridge.matterbridgeDirectory, MATTER_STORAGE_NAME));
|
|
132
|
+
expect(matterbridge.matterStorageService).toBeDefined();
|
|
133
|
+
expect(matterbridge.matterStorageManager).toBeDefined();
|
|
134
|
+
expect(matterbridge.matterbridgeContext).toBeDefined();
|
|
135
|
+
expect(matterbridge.controllerContext).toBeUndefined();
|
|
136
|
+
if (bridgeMode === 'bridge') {
|
|
137
|
+
expect(matterbridge.serverNode).toBeDefined();
|
|
138
|
+
expect(matterbridge.aggregatorNode).toBeDefined();
|
|
139
|
+
}
|
|
140
|
+
expect(matterbridge.mdnsInterface).toBe(undefined);
|
|
141
|
+
expect(matterbridge.port).toBe(matterPort + (bridgeMode === 'bridge' ? 1 : 0));
|
|
142
|
+
expect(matterbridge.passcode).toBe(passcode + (bridgeMode === 'bridge' ? 1 : 0));
|
|
143
|
+
expect(matterbridge.discriminator).toBe(discriminator + (bridgeMode === 'bridge' ? 1 : 0));
|
|
144
|
+
if (bridgeMode === 'bridge') {
|
|
145
|
+
const started = new Promise((resolve) => {
|
|
146
|
+
matterbridge.once('bridge_started', () => {
|
|
147
|
+
resolve();
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
const online = new Promise((resolve) => {
|
|
151
|
+
matterbridge.once('online', (name) => {
|
|
152
|
+
if (name === 'Matterbridge')
|
|
153
|
+
resolve();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
await Promise.all([started, online]);
|
|
157
|
+
}
|
|
158
|
+
else if (bridgeMode === 'childbridge') {
|
|
159
|
+
await new Promise((resolve) => {
|
|
160
|
+
matterbridge.once('childbridge_started', () => {
|
|
161
|
+
resolve();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("info", `The frontend http server is listening on ${UNDERLINE}http://${matterbridge.systemInformation.ipv4Address}:${frontendPort}${UNDERLINEOFF}${rs}`);
|
|
166
|
+
if (bridgeMode === 'bridge') {
|
|
167
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Starting Matterbridge server node`);
|
|
168
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Server node for Matterbridge is online`);
|
|
169
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Starting start matter interval in bridge mode...`);
|
|
170
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Cleared startMatterInterval interval in bridge mode`);
|
|
171
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Matterbridge bridge started successfully`);
|
|
172
|
+
}
|
|
173
|
+
else if (bridgeMode === 'childbridge') {
|
|
174
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Starting start matter interval in childbridge mode...`);
|
|
175
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("debug", `Cleared startMatterInterval interval in childbridge mode`);
|
|
176
|
+
expect(loggerLogSpy).toHaveBeenCalledWith("notice", `Matterbridge childbridge started successfully`);
|
|
177
|
+
}
|
|
178
|
+
return matterbridge;
|
|
179
|
+
}
|
|
180
|
+
export async function stopMatterbridge(cleanupPause = 10, destroyPause = 250) {
|
|
181
|
+
await destroyMatterbridgeEnvironment(cleanupPause, destroyPause);
|
|
182
|
+
}
|
|
166
183
|
export async function createMatterbridgeEnvironment(name) {
|
|
167
|
-
// Create a MatterbridgeEdge instance
|
|
168
184
|
matterbridge = await Matterbridge.loadInstance(false);
|
|
169
185
|
expect(matterbridge).toBeDefined();
|
|
170
186
|
expect(matterbridge).toBeInstanceOf(Matterbridge);
|
|
@@ -175,43 +191,25 @@ export async function createMatterbridgeEnvironment(name) {
|
|
|
175
191
|
matterbridge.matterbridgeDirectory = path.join('jest', name, '.matterbridge');
|
|
176
192
|
matterbridge.matterbridgePluginDirectory = path.join('jest', name, 'Matterbridge');
|
|
177
193
|
matterbridge.matterbridgeCertDirectory = path.join('jest', name, '.mattercert');
|
|
178
|
-
matterbridge.log.logLevel = "debug"
|
|
179
|
-
log = new AnsiLogger({ logName: 'Plugin platform', logTimestampFormat: 4
|
|
180
|
-
// Setup matter environment
|
|
181
|
-
// @ts-expect-error - access to private member for testing
|
|
194
|
+
matterbridge.log.logLevel = "debug";
|
|
195
|
+
log = new AnsiLogger({ logName: 'Plugin platform', logTimestampFormat: 4, logLevel: "debug" });
|
|
182
196
|
matterbridge.environment = createTestEnvironment(name);
|
|
183
|
-
// @ts-expect-error - access to private member for testing
|
|
184
197
|
expect(matterbridge.environment).toBeDefined();
|
|
185
|
-
// @ts-expect-error - access to private member for testing
|
|
186
198
|
expect(matterbridge.environment).toBeInstanceOf(Environment);
|
|
187
199
|
return matterbridge;
|
|
188
200
|
}
|
|
189
|
-
/**
|
|
190
|
-
* Start the matterbridge environment
|
|
191
|
-
*
|
|
192
|
-
* @param {number} port The matter server port.
|
|
193
|
-
* @returns {Promise<[ServerNode<ServerNode.RootEndpoint>, Endpoint<AggregatorEndpoint>]>} The started server and aggregator.
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* ```typescript
|
|
197
|
-
* // Create Matterbridge environment
|
|
198
|
-
* await createMatterbridgeEnvironment(NAME);
|
|
199
|
-
* await startMatterbridgeEnvironment(MATTER_PORT);
|
|
200
|
-
* ```
|
|
201
|
-
*/
|
|
202
201
|
export async function startMatterbridgeEnvironment(port = 5540) {
|
|
203
|
-
|
|
202
|
+
matterbridge.nodeStorage = new NodeStorageManager({ dir: path.join(matterbridge.matterbridgeDirectory, NODE_STORAGE_DIR), writeQueue: false, expiredInterval: undefined, logging: false });
|
|
203
|
+
matterbridge.nodeContext = await matterbridge.nodeStorage.createStorage('matterbridge');
|
|
204
204
|
await matterbridge.startMatterStorage();
|
|
205
205
|
expect(matterbridge.matterStorageService).toBeDefined();
|
|
206
206
|
expect(matterbridge.matterStorageManager).toBeDefined();
|
|
207
207
|
expect(matterbridge.matterbridgeContext).toBeDefined();
|
|
208
|
-
// @ts-expect-error - access to private member for testing
|
|
209
208
|
server = await matterbridge.createServerNode(matterbridge.matterbridgeContext, port);
|
|
210
209
|
expect(server).toBeDefined();
|
|
211
210
|
expect(server).toBeDefined();
|
|
212
211
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
213
212
|
matterbridge.serverNode = server;
|
|
214
|
-
// @ts-expect-error - access to private member for testing
|
|
215
213
|
aggregator = await matterbridge.createAggregatorNode(matterbridge.matterbridgeContext);
|
|
216
214
|
expect(aggregator).toBeDefined();
|
|
217
215
|
matterbridge.aggregatorNode = aggregator;
|
|
@@ -219,7 +217,6 @@ export async function startMatterbridgeEnvironment(port = 5540) {
|
|
|
219
217
|
expect(server.parts.has(aggregator.id)).toBeTruthy();
|
|
220
218
|
expect(server.parts.has(aggregator)).toBeTruthy();
|
|
221
219
|
expect(aggregator.lifecycle.isReady).toBeTruthy();
|
|
222
|
-
// Wait for the server to be online
|
|
223
220
|
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
224
221
|
await new Promise((resolve) => {
|
|
225
222
|
server.lifecycle.online.on(async () => {
|
|
@@ -227,7 +224,6 @@ export async function startMatterbridgeEnvironment(port = 5540) {
|
|
|
227
224
|
});
|
|
228
225
|
server.start();
|
|
229
226
|
});
|
|
230
|
-
// Check if the server is online
|
|
231
227
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
232
228
|
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
233
229
|
expect(server.lifecycle.isCommissioned).toBeFalsy();
|
|
@@ -239,23 +235,9 @@ export async function startMatterbridgeEnvironment(port = 5540) {
|
|
|
239
235
|
expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
|
|
240
236
|
expect(aggregator.lifecycle.hasId).toBeTruthy();
|
|
241
237
|
expect(aggregator.lifecycle.hasNumber).toBeTruthy();
|
|
242
|
-
// Ensure the queue is empty and pause
|
|
243
238
|
await flushAsync();
|
|
244
239
|
return [server, aggregator];
|
|
245
240
|
}
|
|
246
|
-
/**
|
|
247
|
-
* Add a matterbridge platform for testing.
|
|
248
|
-
*
|
|
249
|
-
* @param {MatterbridgePlatform} platform The platform to add.
|
|
250
|
-
* @param {string} [name] Optional name of the platform.
|
|
251
|
-
*
|
|
252
|
-
* @example
|
|
253
|
-
* ```typescript
|
|
254
|
-
* platform = new Platform(matterbridge, log, config);
|
|
255
|
-
* // Add the platform to the Matterbridge environment
|
|
256
|
-
* addMatterbridgePlatform(platform);
|
|
257
|
-
* ```
|
|
258
|
-
*/
|
|
259
241
|
export function addMatterbridgePlatform(platform, name) {
|
|
260
242
|
if (name)
|
|
261
243
|
platform.config.name = name;
|
|
@@ -267,7 +249,6 @@ export function addMatterbridgePlatform(platform, name) {
|
|
|
267
249
|
expect(platform.version).toBeDefined();
|
|
268
250
|
expect(platform.config.debug).toBeDefined();
|
|
269
251
|
expect(platform.config.unregisterOnShutdown).toBeDefined();
|
|
270
|
-
// @ts-expect-error accessing private member for testing
|
|
271
252
|
matterbridge.plugins._plugins.set(platform.config.name, {
|
|
272
253
|
name: platform.config.name,
|
|
273
254
|
path: './',
|
|
@@ -279,130 +260,56 @@ export function addMatterbridgePlatform(platform, name) {
|
|
|
279
260
|
});
|
|
280
261
|
platform['name'] = platform.config.name;
|
|
281
262
|
}
|
|
282
|
-
/**
|
|
283
|
-
* Stop the matterbridge environment
|
|
284
|
-
*
|
|
285
|
-
* @example
|
|
286
|
-
* ```typescript
|
|
287
|
-
* // Destroy Matterbridge environment
|
|
288
|
-
* await stopMatterbridgeEnvironment();
|
|
289
|
-
* await destroyMatterbridgeEnvironment();
|
|
290
|
-
* ```
|
|
291
|
-
*/
|
|
292
263
|
export async function stopMatterbridgeEnvironment() {
|
|
293
264
|
expect(matterbridge).toBeDefined();
|
|
294
265
|
expect(server).toBeDefined();
|
|
295
266
|
expect(aggregator).toBeDefined();
|
|
296
|
-
// Flush any pending endpoint number persistence
|
|
297
267
|
await flushAllEndpointNumberPersistence(server);
|
|
298
|
-
// Ensure all endpoint numbers are persisted
|
|
299
268
|
await assertAllEndpointNumbersPersisted(server);
|
|
300
|
-
// Close the server node
|
|
301
269
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
302
270
|
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
303
271
|
await server.close();
|
|
304
272
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
305
273
|
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
306
|
-
// stop the mDNS service
|
|
307
|
-
// await server.env.get(MdnsService)[Symbol.asyncDispose]();
|
|
308
|
-
// Stop the matter storage
|
|
309
|
-
// @ts-expect-error - access to private member for testing
|
|
310
274
|
await matterbridge.stopMatterStorage();
|
|
311
275
|
expect(matterbridge.matterStorageService).not.toBeDefined();
|
|
312
276
|
expect(matterbridge.matterStorageManager).not.toBeDefined();
|
|
313
277
|
expect(matterbridge.matterbridgeContext).not.toBeDefined();
|
|
314
|
-
|
|
278
|
+
await matterbridge.nodeContext?.close();
|
|
279
|
+
await matterbridge.nodeStorage?.close();
|
|
315
280
|
await flushAsync();
|
|
316
281
|
}
|
|
317
|
-
/**
|
|
318
|
-
* Destroy the matterbridge environment
|
|
319
|
-
*
|
|
320
|
-
* @param {number} cleanupPause The timeout for the destroy operation (default 250ms).
|
|
321
|
-
* @param {number} destroyPause The pause duration after cleanup before destroying the instance (default 250ms).
|
|
322
|
-
*
|
|
323
|
-
* @example
|
|
324
|
-
* ```typescript
|
|
325
|
-
* // Destroy Matterbridge environment
|
|
326
|
-
* await stopMatterbridgeEnvironment();
|
|
327
|
-
* await destroyMatterbridgeEnvironment();
|
|
328
|
-
* ```
|
|
329
|
-
*/
|
|
330
282
|
export async function destroyMatterbridgeEnvironment(cleanupPause = 10, destroyPause = 250) {
|
|
331
|
-
// Destroy a matterbridge instance
|
|
332
283
|
await destroyInstance(matterbridge, cleanupPause, destroyPause);
|
|
333
|
-
// Close the mDNS service
|
|
334
284
|
await closeMdnsInstance(matterbridge);
|
|
335
|
-
// Reset the singleton instance
|
|
336
|
-
// @ts-expect-error - accessing private member for testing
|
|
337
285
|
Matterbridge.instance = undefined;
|
|
338
286
|
}
|
|
339
|
-
/**
|
|
340
|
-
* Destroy a matterbridge instance
|
|
341
|
-
*
|
|
342
|
-
* @param {Matterbridge} matterbridge The matterbridge instance to destroy.
|
|
343
|
-
* @param {number} cleanupPause The pause duration to wait for the cleanup to complete in milliseconds (default 10ms).
|
|
344
|
-
* @param {number} destroyPause The pause duration to wait after cleanup before destroying the instance in milliseconds (default 250ms).
|
|
345
|
-
*/
|
|
346
287
|
export async function destroyInstance(matterbridge, cleanupPause = 10, destroyPause = 250) {
|
|
347
|
-
// Cleanup the Matterbridge instance
|
|
348
|
-
// @ts-expect-error - accessing private member for testing
|
|
349
288
|
await matterbridge.cleanup('destroying instance...', false, cleanupPause);
|
|
350
|
-
// Pause before destroying the instance
|
|
351
289
|
if (destroyPause > 0)
|
|
352
290
|
await flushAsync(undefined, undefined, destroyPause);
|
|
353
291
|
}
|
|
354
|
-
/**
|
|
355
|
-
* Close the mDNS instance in the matterbridge environment.
|
|
356
|
-
*
|
|
357
|
-
* @param {Matterbridge} matterbridge The matterbridge instance.
|
|
358
|
-
* @returns {Promise<void>} A promise that resolves when the mDNS instance is closed.
|
|
359
|
-
*/
|
|
360
292
|
export async function closeMdnsInstance(matterbridge) {
|
|
361
|
-
// @ts-expect-error - accessing private member for testing
|
|
362
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
363
293
|
const mdns = matterbridge.environment.get(MdnsService);
|
|
364
294
|
if (mdns && mdns[Symbol.asyncDispose] && typeof mdns[Symbol.asyncDispose] === 'function')
|
|
365
295
|
await mdns[Symbol.asyncDispose]();
|
|
366
296
|
if (mdns && mdns.close && typeof mdns.close === 'function')
|
|
367
297
|
await mdns.close();
|
|
368
298
|
}
|
|
369
|
-
/**
|
|
370
|
-
* Create a matter Environment for testing:
|
|
371
|
-
* - it will remove any existing home directory
|
|
372
|
-
* - setup the matter environment with name, debug logging and ANSI format
|
|
373
|
-
*
|
|
374
|
-
* @param {string} name - Name for the environment (jest/name).
|
|
375
|
-
* @returns {Environment} - The default matter environment.
|
|
376
|
-
*/
|
|
377
299
|
export function createTestEnvironment(name) {
|
|
378
300
|
expect(name).toBeDefined();
|
|
379
301
|
expect(typeof name).toBe('string');
|
|
380
|
-
expect(name.length).toBeGreaterThanOrEqual(4);
|
|
381
|
-
// Cleanup any existing home directory
|
|
302
|
+
expect(name.length).toBeGreaterThanOrEqual(4);
|
|
382
303
|
rmSync(path.join('jest', name), { recursive: true, force: true });
|
|
383
|
-
// Setup the matter environment
|
|
384
304
|
environment = Environment.default;
|
|
385
305
|
environment.vars.set('log.level', MatterLogLevel.DEBUG);
|
|
386
306
|
environment.vars.set('log.format', MatterLogFormat.ANSI);
|
|
387
307
|
environment.vars.set('path.root', path.join('jest', name, '.matterbridge', MATTER_STORAGE_NAME));
|
|
388
308
|
environment.vars.set('runtime.signals', false);
|
|
389
309
|
environment.vars.set('runtime.exitcode', false);
|
|
390
|
-
// Setup the mDNS service in the environment
|
|
391
310
|
new MdnsService(environment);
|
|
392
311
|
return environment;
|
|
393
312
|
}
|
|
394
|
-
/**
|
|
395
|
-
* Advance the Node.js event loop deterministically to allow chained asynchronous work (Promises scheduled in
|
|
396
|
-
* microtasks and follow‑up macrotasks) to complete inside tests without adding arbitrary long timeouts.
|
|
397
|
-
*
|
|
398
|
-
* NOTE: This does not guarantee OS level network IO completion—only JavaScript task queue progression inside the
|
|
399
|
-
* current process.
|
|
400
|
-
*
|
|
401
|
-
* @param {number} ticks Number of macrotask (setImmediate) turns to yield (default 3).
|
|
402
|
-
* @param {number} microTurns Number of microtask drains (Promise.resolve chains) after macrotask yielding (default 10).
|
|
403
|
-
* @param {number} pause Final timer delay in ms; set 0 to disable (default 250ms).
|
|
404
|
-
* @returns {Promise<void>} Resolves after the requested event loop advancement has completed.
|
|
405
|
-
*/
|
|
406
313
|
export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
|
|
407
314
|
for (let i = 0; i < ticks; i++)
|
|
408
315
|
await new Promise((resolve) => setImmediate(resolve));
|
|
@@ -411,19 +318,6 @@ export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
|
|
|
411
318
|
if (pause)
|
|
412
319
|
await new Promise((resolve) => setTimeout(resolve, pause));
|
|
413
320
|
}
|
|
414
|
-
/**
|
|
415
|
-
* Flush (await) the lazy endpoint number persistence mechanism used by matter.js.
|
|
416
|
-
*
|
|
417
|
-
* Background:
|
|
418
|
-
* assignNumber() batches persistence (store.saveNumber + updating __nextNumber__) via an internal promise (#numbersPersisted).
|
|
419
|
-
* Calling endpointStores.close() waits for the current batch only. If new endpoints were added in the same macrotask
|
|
420
|
-
* cycle additional micro/macro turns might be needed to ensure the batch started. We defensively yield macrotasks
|
|
421
|
-
* (setImmediate) and then await close() multiple rounds.
|
|
422
|
-
*
|
|
423
|
-
* @param {ServerNode} targetServer The server whose endpoint numbering persistence should be flushed.
|
|
424
|
-
* @param {number} rounds Number of macrotask + close cycles to run (2 is usually sufficient; 1 often works).
|
|
425
|
-
* @returns {Promise<void>} Resolves when pending number persistence batches have completed.
|
|
426
|
-
*/
|
|
427
321
|
export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2) {
|
|
428
322
|
const nodeStore = targetServer.env.get(ServerNodeStore);
|
|
429
323
|
for (let i = 0; i < rounds; i++) {
|
|
@@ -431,12 +325,6 @@ export async function flushAllEndpointNumberPersistence(targetServer, rounds = 2
|
|
|
431
325
|
await nodeStore.endpointStores.close();
|
|
432
326
|
}
|
|
433
327
|
}
|
|
434
|
-
/**
|
|
435
|
-
* Collect all endpoints in the server endpoint tree (root -> descendants).
|
|
436
|
-
*
|
|
437
|
-
* @param {Endpoint} root Root endpoint (typically the ServerNode root endpoint cast as Endpoint).
|
|
438
|
-
* @returns {Endpoint[]} Flat array including the root and every descendant once.
|
|
439
|
-
*/
|
|
440
328
|
function collectAllEndpoints(root) {
|
|
441
329
|
const list = [];
|
|
442
330
|
const walk = (ep) => {
|
|
@@ -450,26 +338,14 @@ function collectAllEndpoints(root) {
|
|
|
450
338
|
walk(root);
|
|
451
339
|
return list;
|
|
452
340
|
}
|
|
453
|
-
/**
|
|
454
|
-
* Assert that every endpoint attached to the server has an assigned and (batch-)persisted endpoint number.
|
|
455
|
-
*
|
|
456
|
-
* This waits for any outstanding number persistence batch (endpointStores.close()), then traverses the endpoint
|
|
457
|
-
* graph and asserts:
|
|
458
|
-
* - Root endpoint: number is 0 (allowing undefined to coerce to 0 via nullish coalescing check).
|
|
459
|
-
* - All other endpoints: number > 0.
|
|
460
|
-
*
|
|
461
|
-
* @param {ServerNode} targetServer The server whose endpoint numbers are verified.
|
|
462
|
-
* @returns {Promise<void>} Resolves when assertions complete.
|
|
463
|
-
*/
|
|
464
341
|
export async function assertAllEndpointNumbersPersisted(targetServer) {
|
|
465
342
|
const nodeStore = targetServer.env.get(ServerNodeStore);
|
|
466
|
-
// Ensure any pending persistence finished (flush any in-flight batch promise)
|
|
467
343
|
await nodeStore.endpointStores.close();
|
|
468
344
|
const all = collectAllEndpoints(targetServer);
|
|
469
345
|
for (const ep of all) {
|
|
470
346
|
const store = nodeStore.storeForEndpoint(ep);
|
|
471
347
|
if (ep.maybeNumber === 0) {
|
|
472
|
-
expect(store.number ?? 0).toBe(0);
|
|
348
|
+
expect(store.number ?? 0).toBe(0);
|
|
473
349
|
}
|
|
474
350
|
else {
|
|
475
351
|
expect(store.number).toBeGreaterThan(0);
|
|
@@ -477,29 +353,18 @@ export async function assertAllEndpointNumbersPersisted(targetServer) {
|
|
|
477
353
|
}
|
|
478
354
|
return all.length;
|
|
479
355
|
}
|
|
480
|
-
/**
|
|
481
|
-
* Start a matter server node for testing.
|
|
482
|
-
*
|
|
483
|
-
* @param {string} name Name of the server (used for logging and product description).
|
|
484
|
-
* @param {number} port TCP port to listen on.
|
|
485
|
-
* @param {DeviceTypeId} deviceType Device type identifier for the server node.
|
|
486
|
-
* @returns {Promise<[ServerNode<ServerNode.RootEndpoint>, Endpoint<AggregatorEndpoint>]>} Resolves to an array containing the created ServerNode and its AggregatorNode.
|
|
487
|
-
*/
|
|
488
356
|
export async function startServerNode(name, port, deviceType = bridge.code) {
|
|
489
357
|
const { randomBytes } = await import('node:crypto');
|
|
490
358
|
const random = randomBytes(8).toString('hex');
|
|
491
|
-
// Create the server node
|
|
492
359
|
server = await ServerNode.create({
|
|
493
360
|
id: name + 'ServerNode',
|
|
494
361
|
environment,
|
|
495
|
-
// Provide Node announcement settings
|
|
496
362
|
productDescription: {
|
|
497
363
|
name: name + 'ServerNode',
|
|
498
364
|
deviceType: DeviceTypeId(deviceType),
|
|
499
365
|
vendorId: VendorId(0xfff1),
|
|
500
366
|
productId: 0x8000,
|
|
501
367
|
},
|
|
502
|
-
// Provide defaults for the BasicInformation cluster on the Root endpoint
|
|
503
368
|
basicInformation: {
|
|
504
369
|
vendorId: VendorId(0xfff1),
|
|
505
370
|
vendorName: 'Matterbridge',
|
|
@@ -512,39 +377,32 @@ export async function startServerNode(name, port, deviceType = bridge.code) {
|
|
|
512
377
|
serialNumber: 'SN' + random,
|
|
513
378
|
uniqueId: 'UI' + random,
|
|
514
379
|
},
|
|
515
|
-
// Provide Network relevant configuration like the port
|
|
516
380
|
network: {
|
|
517
381
|
listeningAddressIpv4: undefined,
|
|
518
382
|
listeningAddressIpv6: undefined,
|
|
519
383
|
port,
|
|
520
384
|
},
|
|
521
|
-
// Provide the certificate for the device
|
|
522
385
|
operationalCredentials: {
|
|
523
386
|
certification: undefined,
|
|
524
387
|
},
|
|
525
388
|
});
|
|
526
389
|
expect(server).toBeDefined();
|
|
527
390
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
528
|
-
// Create the aggregator node
|
|
529
391
|
aggregator = new Endpoint(AggregatorEndpoint, {
|
|
530
392
|
id: name + 'AggregatorNode',
|
|
531
393
|
});
|
|
532
394
|
expect(aggregator).toBeDefined();
|
|
533
|
-
// Add the aggregator to the server
|
|
534
395
|
await server.add(aggregator);
|
|
535
396
|
expect(server.parts.has(aggregator.id)).toBeTruthy();
|
|
536
397
|
expect(server.parts.has(aggregator)).toBeTruthy();
|
|
537
398
|
expect(aggregator.lifecycle.isReady).toBeTruthy();
|
|
538
|
-
// Run the server
|
|
539
399
|
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
540
|
-
// Wait for the server to be online
|
|
541
400
|
await new Promise((resolve) => {
|
|
542
401
|
server.lifecycle.online.on(async () => {
|
|
543
402
|
resolve();
|
|
544
403
|
});
|
|
545
404
|
server.start();
|
|
546
405
|
});
|
|
547
|
-
// Check if the server is online
|
|
548
406
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
549
407
|
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
550
408
|
expect(server.lifecycle.isCommissioned).toBeFalsy();
|
|
@@ -556,53 +414,31 @@ export async function startServerNode(name, port, deviceType = bridge.code) {
|
|
|
556
414
|
expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
|
|
557
415
|
expect(aggregator.lifecycle.hasId).toBeTruthy();
|
|
558
416
|
expect(aggregator.lifecycle.hasNumber).toBeTruthy();
|
|
559
|
-
// Ensure the queue is empty and pause 250ms
|
|
560
417
|
await flushAsync();
|
|
561
418
|
return [server, aggregator];
|
|
562
419
|
}
|
|
563
|
-
/**
|
|
564
|
-
* Stop a matter server node.
|
|
565
|
-
*
|
|
566
|
-
* @param {ServerNode<ServerNode.RootEndpoint>} server The server to stop.
|
|
567
|
-
* @returns {Promise<void>} Resolves when the server has stopped.
|
|
568
|
-
*/
|
|
569
420
|
export async function stopServerNode(server) {
|
|
570
|
-
// Flush any pending endpoint number persistence
|
|
571
421
|
await flushAllEndpointNumberPersistence(server);
|
|
572
|
-
// Ensure all endpoint numbers are persisted
|
|
573
422
|
await assertAllEndpointNumbersPersisted(server);
|
|
574
|
-
// Stop the server
|
|
575
423
|
expect(server).toBeDefined();
|
|
576
424
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
577
425
|
expect(server.lifecycle.isOnline).toBeTruthy();
|
|
578
426
|
await server.close();
|
|
579
427
|
expect(server.lifecycle.isReady).toBeTruthy();
|
|
580
428
|
expect(server.lifecycle.isOnline).toBeFalsy();
|
|
581
|
-
// stop the mDNS service
|
|
582
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
583
429
|
const mdns = environment.get(MdnsService);
|
|
584
430
|
if (mdns && typeof mdns[Symbol.asyncDispose] === 'function')
|
|
585
431
|
await mdns[Symbol.asyncDispose]();
|
|
586
432
|
if (mdns && typeof mdns.close === 'function')
|
|
587
433
|
await mdns.close();
|
|
588
|
-
// Ensure the queue is empty and pause 100ms
|
|
589
434
|
await flushAsync();
|
|
590
435
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Add a device (endpoint) to a matter server node or an aggregator.
|
|
593
|
-
*
|
|
594
|
-
* @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to add the device to.
|
|
595
|
-
* @param {Endpoint} device The device to add.
|
|
596
|
-
* @param {number} pause The pause time in milliseconds after addition (default 10ms).
|
|
597
|
-
* @returns {Promise<void>} Resolves when the device has been added and is ready.
|
|
598
|
-
*/
|
|
599
436
|
export async function addDevice(owner, device, pause = 10) {
|
|
600
437
|
expect(owner).toBeDefined();
|
|
601
438
|
expect(device).toBeDefined();
|
|
602
439
|
expect(owner.lifecycle.isReady).toBeTruthy();
|
|
603
440
|
expect(owner.construction.status).toBe(Lifecycle.Status.Active);
|
|
604
441
|
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
605
|
-
// istanbul ignore next
|
|
606
442
|
try {
|
|
607
443
|
await owner.add(device);
|
|
608
444
|
}
|
|
@@ -622,21 +458,12 @@ export async function addDevice(owner, device, pause = 10) {
|
|
|
622
458
|
await flushAsync(undefined, undefined, pause);
|
|
623
459
|
return true;
|
|
624
460
|
}
|
|
625
|
-
/**
|
|
626
|
-
* Delete a device (endpoint) from a matter server node or an aggregator.
|
|
627
|
-
*
|
|
628
|
-
* @param {ServerNode<ServerNode.RootEndpoint> | Endpoint<AggregatorEndpoint>} owner The server or aggregator to remove the device from.
|
|
629
|
-
* @param {Endpoint} device The device to remove.
|
|
630
|
-
* @param {number} pause The pause time in milliseconds after deletion (default 10ms).
|
|
631
|
-
* @returns {Promise<void>} Resolves when the device has been removed and is no longer ready.
|
|
632
|
-
*/
|
|
633
461
|
export async function deleteDevice(owner, device, pause = 10) {
|
|
634
462
|
expect(owner).toBeDefined();
|
|
635
463
|
expect(device).toBeDefined();
|
|
636
464
|
expect(owner.lifecycle.isReady).toBeTruthy();
|
|
637
465
|
expect(owner.construction.status).toBe(Lifecycle.Status.Active);
|
|
638
466
|
expect(owner.lifecycle.isPartsReady).toBeTruthy();
|
|
639
|
-
// istanbul ignore next
|
|
640
467
|
try {
|
|
641
468
|
await device.delete();
|
|
642
469
|
}
|
|
@@ -656,4 +483,3 @@ export async function deleteDevice(owner, device, pause = 10) {
|
|
|
656
483
|
await flushAsync(undefined, undefined, pause);
|
|
657
484
|
return true;
|
|
658
485
|
}
|
|
659
|
-
//# sourceMappingURL=jestHelpers.js.map
|
package/dist/logger/export.js
CHANGED
package/dist/matter/behaviors.js
CHANGED
package/dist/matter/clusters.js
CHANGED
package/dist/matter/devices.js
CHANGED