matterbridge-test 1.3.0-dev-20251016-f158fac → 2.0.0-dev-20251025-d87e883

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 CHANGED
@@ -23,6 +23,19 @@ If you like this project and find it useful, please consider giving it a star on
23
23
  <img src="bmc-button.svg" alt="Buy me a coffee" width="120">
24
24
  </a>
25
25
 
26
+ ## [2.0.0] - 2025-10-24
27
+
28
+ ### Changed
29
+
30
+ - [package]: Bumped platform to v. 2.0.0.
31
+ - [package]: Updated dependencies.
32
+ - [package]: Bumped package to automator v. 2.0.9.
33
+ - [jest]: Updated jestHelpers to v. 1.0.9.
34
+
35
+ <a href="https://www.buymeacoffee.com/luligugithub">
36
+ <img src="bmc-button.svg" alt="Buy me a coffee" width="80">
37
+ </a>
38
+
26
39
  ## [1.3.0] - 2025-10-15
27
40
 
28
41
  ### Changed
@@ -5,12 +5,16 @@ import { jest } from '@jest/globals';
5
5
  import { DeviceTypeId, Endpoint, Environment, MdnsService, ServerNode, ServerNodeStore, VendorId, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Lifecycle, } from 'matterbridge/matter';
6
6
  import { RootEndpoint, AggregatorEndpoint } from 'matterbridge/matter/endpoints';
7
7
  import { AnsiLogger } from 'matterbridge/logger';
8
+ import { MATTER_STORAGE_NAME, Matterbridge } from 'matterbridge';
8
9
  export let loggerLogSpy;
9
10
  export let consoleLogSpy;
10
11
  export let consoleDebugSpy;
11
12
  export let consoleInfoSpy;
12
13
  export let consoleWarnSpy;
13
14
  export let consoleErrorSpy;
15
+ export const addBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'addBridgedEndpoint');
16
+ export const removeBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'removeBridgedEndpoint');
17
+ export const removeAllBridgedEndpointSpy = jest.spyOn(Matterbridge.prototype, 'removeAllBridgedEndpoints');
14
18
  export function setupTest(name, debug = false) {
15
19
  expect(name).toBeDefined();
16
20
  expect(typeof name).toBe('string');
@@ -57,20 +61,97 @@ export function setDebug(debug) {
57
61
  consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
58
62
  }
59
63
  }
60
- export function createTestEnvironment(homeDir) {
61
- expect(homeDir).toBeDefined();
62
- expect(typeof homeDir).toBe('string');
63
- expect(homeDir.length).toBeGreaterThanOrEqual(4);
64
- rmSync(homeDir, { recursive: true, force: true });
64
+ export async function createMatterbridgeEnvironment(name) {
65
+ const matterbridge = await Matterbridge.loadInstance(false);
66
+ expect(matterbridge).toBeDefined();
67
+ expect(matterbridge).toBeInstanceOf(Matterbridge);
68
+ matterbridge.matterbridgeVersion = '3.3.0';
69
+ matterbridge.bridgeMode = 'bridge';
70
+ matterbridge.rootDirectory = path.join('jest', name);
71
+ matterbridge.homeDirectory = path.join('jest', name);
72
+ matterbridge.matterbridgeDirectory = path.join('jest', name, '.matterbridge');
73
+ matterbridge.matterbridgePluginDirectory = path.join('jest', name, 'Matterbridge');
74
+ matterbridge.matterbridgeCertDirectory = path.join('jest', name, '.mattercert');
75
+ matterbridge.environment = createTestEnvironment(name);
76
+ expect(matterbridge.environment).toBeDefined();
77
+ expect(matterbridge.environment).toBeInstanceOf(Environment);
78
+ return matterbridge;
79
+ }
80
+ export async function startMatterbridgeEnvironment(matterbridge, port = 5540) {
81
+ await matterbridge.startMatterStorage();
82
+ expect(matterbridge.matterStorageService).toBeDefined();
83
+ expect(matterbridge.matterStorageManager).toBeDefined();
84
+ expect(matterbridge.matterbridgeContext).toBeDefined();
85
+ const server = await matterbridge.createServerNode(matterbridge.matterbridgeContext, port);
86
+ expect(server).toBeDefined();
87
+ expect(server).toBeDefined();
88
+ expect(server.lifecycle.isReady).toBeTruthy();
89
+ matterbridge.serverNode = server;
90
+ const aggregator = await matterbridge.createAggregatorNode(matterbridge.matterbridgeContext);
91
+ expect(aggregator).toBeDefined();
92
+ matterbridge.aggregatorNode = aggregator;
93
+ expect(await server.add(aggregator)).toBeDefined();
94
+ expect(server.parts.has(aggregator.id)).toBeTruthy();
95
+ expect(server.parts.has(aggregator)).toBeTruthy();
96
+ expect(aggregator.lifecycle.isReady).toBeTruthy();
97
+ expect(server.lifecycle.isOnline).toBeFalsy();
98
+ await new Promise((resolve) => {
99
+ server.lifecycle.online.on(async () => {
100
+ resolve();
101
+ });
102
+ server.start();
103
+ });
104
+ expect(server.lifecycle.isReady).toBeTruthy();
105
+ expect(server.lifecycle.isOnline).toBeTruthy();
106
+ expect(server.lifecycle.isCommissioned).toBeFalsy();
107
+ expect(server.lifecycle.isPartsReady).toBeTruthy();
108
+ expect(server.lifecycle.hasId).toBeTruthy();
109
+ expect(server.lifecycle.hasNumber).toBeTruthy();
110
+ expect(aggregator.lifecycle.isReady).toBeTruthy();
111
+ expect(aggregator.lifecycle.isInstalled).toBeTruthy();
112
+ expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
113
+ expect(aggregator.lifecycle.hasId).toBeTruthy();
114
+ expect(aggregator.lifecycle.hasNumber).toBeTruthy();
115
+ await flushAsync();
116
+ return [server, aggregator];
117
+ }
118
+ export async function stopMatterbridgeEnvironment(matterbridge, server, aggregator) {
119
+ expect(matterbridge).toBeDefined();
120
+ expect(server).toBeDefined();
121
+ expect(aggregator).toBeDefined();
122
+ await flushAllEndpointNumberPersistence(server);
123
+ await assertAllEndpointNumbersPersisted(server);
124
+ expect(server.lifecycle.isReady).toBeTruthy();
125
+ expect(server.lifecycle.isOnline).toBeTruthy();
126
+ await server.close();
127
+ expect(server.lifecycle.isReady).toBeTruthy();
128
+ expect(server.lifecycle.isOnline).toBeFalsy();
129
+ await server.env.get(MdnsService)[Symbol.asyncDispose]();
130
+ await matterbridge.stopMatterStorage();
131
+ expect(matterbridge.matterStorageService).not.toBeDefined();
132
+ expect(matterbridge.matterStorageManager).not.toBeDefined();
133
+ expect(matterbridge.matterbridgeContext).not.toBeDefined();
134
+ await flushAsync();
135
+ }
136
+ export async function destroyMatterbridgeEnvironment(matterbridge) {
137
+ await matterbridge.destroyInstance(10);
138
+ Matterbridge.instance = undefined;
139
+ }
140
+ export function createTestEnvironment(name) {
141
+ expect(name).toBeDefined();
142
+ expect(typeof name).toBe('string');
143
+ expect(name.length).toBeGreaterThanOrEqual(4);
144
+ rmSync(path.join('jest', name), { recursive: true, force: true });
65
145
  const environment = Environment.default;
66
146
  environment.vars.set('log.level', MatterLogLevel.DEBUG);
67
147
  environment.vars.set('log.format', MatterLogFormat.ANSI);
68
- environment.vars.set('path.root', homeDir);
148
+ environment.vars.set('path.root', path.join('jest', name, '.matterbridge', MATTER_STORAGE_NAME));
69
149
  environment.vars.set('runtime.signals', false);
70
150
  environment.vars.set('runtime.exitcode', false);
151
+ new MdnsService(environment);
71
152
  return environment;
72
153
  }
73
- export async function flushAsync(ticks = 3, microTurns = 10, pause = 100) {
154
+ export async function flushAsync(ticks = 3, microTurns = 10, pause = 250) {
74
155
  for (let i = 0; i < ticks; i++)
75
156
  await new Promise((resolve) => setImmediate(resolve));
76
157
  for (let i = 0; i < microTurns; i++)
@@ -113,9 +194,10 @@ export async function assertAllEndpointNumbersPersisted(targetServer) {
113
194
  }
114
195
  return all.length;
115
196
  }
116
- export async function startServerNode(name, port) {
197
+ export async function startServerNode(name, port, environment) {
117
198
  const server = await ServerNode.create({
118
199
  id: name + 'ServerNode',
200
+ environment: environment,
119
201
  productDescription: {
120
202
  name: name + 'ServerNode',
121
203
  deviceType: DeviceTypeId(RootEndpoint.deviceType),
@@ -164,7 +246,7 @@ export async function startServerNode(name, port) {
164
246
  expect(aggregator.lifecycle.isPartsReady).toBeTruthy();
165
247
  expect(aggregator.lifecycle.hasId).toBeTruthy();
166
248
  expect(aggregator.lifecycle.hasNumber).toBeTruthy();
167
- await flushAsync(undefined, undefined, 200);
249
+ await flushAsync();
168
250
  return [server, aggregator];
169
251
  }
170
252
  export async function stopServerNode(server) {
@@ -177,7 +259,7 @@ export async function stopServerNode(server) {
177
259
  expect(server.lifecycle.isReady).toBeTruthy();
178
260
  expect(server.lifecycle.isOnline).toBeFalsy();
179
261
  await server.env.get(MdnsService)[Symbol.asyncDispose]();
180
- await flushAsync(undefined, undefined, 200);
262
+ await flushAsync();
181
263
  }
182
264
  export async function addDevice(owner, device, pause = 10) {
183
265
  expect(owner).toBeDefined();
@@ -201,7 +283,7 @@ export async function addDevice(owner, device, pause = 10) {
201
283
  expect(device.lifecycle.hasId).toBeTruthy();
202
284
  expect(device.lifecycle.hasNumber).toBeTruthy();
203
285
  expect(device.construction.status).toBe(Lifecycle.Status.Active);
204
- await flushAsync(1, 1, pause);
286
+ await flushAsync(undefined, undefined, pause);
205
287
  return true;
206
288
  }
207
289
  export async function deleteDevice(owner, device, pause = 10) {
@@ -226,6 +308,6 @@ export async function deleteDevice(owner, device, pause = 10) {
226
308
  expect(device.lifecycle.hasId).toBeTruthy();
227
309
  expect(device.lifecycle.hasNumber).toBeTruthy();
228
310
  expect(device.construction.status).toBe(Lifecycle.Status.Destroyed);
229
- await flushAsync(1, 1, pause);
311
+ await flushAsync(undefined, undefined, pause);
230
312
  return true;
231
313
  }
@@ -2,6 +2,9 @@ import { MatterbridgeDynamicPlatform, bridgedNode, electricalSensor, onOffSwitch
2
2
  import { isValidString, waiter } from 'matterbridge/utils';
3
3
  import { CYAN, er, nf } from 'matterbridge/logger';
4
4
  import { OnOffCluster, ElectricalPowerMeasurementCluster, ElectricalEnergyMeasurementCluster, ModeSelectCluster, PowerSource, BridgedDeviceBasicInformationCluster, } from 'matterbridge/matter/clusters';
5
+ export default function initializePlugin(matterbridge, log, config) {
6
+ return new TestPlatform(matterbridge, log, config);
7
+ }
5
8
  export class TestPlatform extends MatterbridgeDynamicPlatform {
6
9
  config;
7
10
  interval;
@@ -179,6 +182,14 @@ export class TestPlatform extends MatterbridgeDynamicPlatform {
179
182
  this.log.info(`- device ${device.deviceName} with serial ${device.serialNumber}`);
180
183
  }
181
184
  }
185
+ addPowerSource(device, type) {
186
+ if (type === 'wired')
187
+ device.createDefaultPowerSourceWiredClusterServer(PowerSource.WiredCurrentType.Ac);
188
+ else if (type === 'replaceable')
189
+ device.createDefaultPowerSourceReplaceableBatteryClusterServer(100);
190
+ else if (type === 'rechargeable')
191
+ device.createDefaultPowerSourceRechargeableBatteryClusterServer(100);
192
+ }
182
193
  addElectricalMeasurements(device) {
183
194
  device.createDefaultPowerTopologyClusterServer();
184
195
  device.createDefaultElectricalPowerMeasurementClusterServer(220 * 1000, 2.5 * 1000, 220 * 2.5 * 1000, 50 * 1000);
@@ -190,14 +201,6 @@ export class TestPlatform extends MatterbridgeDynamicPlatform {
190
201
  { label: 'Led OFF', mode: 2, semanticTags: [] },
191
202
  ], 1, 1);
192
203
  }
193
- addPowerSource(device, type) {
194
- if (type === 'wired')
195
- device.createDefaultPowerSourceWiredClusterServer(PowerSource.WiredCurrentType.Ac);
196
- else if (type === 'replaceable')
197
- device.createDefaultPowerSourceReplaceableBatteryClusterServer(100);
198
- else if (type === 'rechargeable')
199
- device.createDefaultPowerSourceRechargeableBatteryClusterServer(100);
200
- }
201
204
  async onConfigure() {
202
205
  await super.onConfigure();
203
206
  this.log.info('onConfigure called');
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "matterbridge-test",
3
- "version": "1.3.0-dev-20251016-f158fac",
3
+ "version": "2.0.0-dev-20251025-d87e883",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-test",
9
- "version": "1.3.0-dev-20251016-f158fac",
9
+ "version": "2.0.0-dev-20251025-d87e883",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.1.1",
13
13
  "node-persist-manager": "2.0.0"
14
14
  },
15
15
  "engines": {
16
- "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
16
+ "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
17
17
  },
18
18
  "funding": {
19
19
  "type": "buymeacoffee",
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-test",
3
- "version": "1.3.0-dev-20251016-f158fac",
3
+ "version": "2.0.0-dev-20251025-d87e883",
4
4
  "description": "Matterbridge test plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
7
7
  "homepage": "https://www.npmjs.com/package/matterbridge-test",
8
8
  "type": "module",
9
- "main": "dist/index.js",
9
+ "main": "dist/module.js",
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "git+https://github.com/Luligu/matterbridge-test.git"
@@ -31,7 +31,7 @@
31
31
  "shelly"
32
32
  ],
33
33
  "engines": {
34
- "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
34
+ "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
35
35
  },
36
36
  "dependencies": {
37
37
  "node-ansi-logger": "3.1.1",
package/dist/index.js DELETED
@@ -1,4 +0,0 @@
1
- import { TestPlatform } from './platform.js';
2
- export default function initializePlugin(matterbridge, log, config) {
3
- return new TestPlatform(matterbridge, log, config);
4
- }