@libp2p/interface-compliance-tests 3.0.7-05abd49f → 3.0.7-06f4901a

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.
Files changed (45) hide show
  1. package/dist/src/mocks/connection-manager.d.ts +2 -0
  2. package/dist/src/mocks/connection-manager.d.ts.map +1 -1
  3. package/dist/src/mocks/connection-manager.js.map +1 -1
  4. package/dist/src/pubsub/api.d.ts +6 -0
  5. package/dist/src/pubsub/api.d.ts.map +1 -0
  6. package/dist/src/pubsub/api.js +87 -0
  7. package/dist/src/pubsub/api.js.map +1 -0
  8. package/dist/src/pubsub/connection-handlers.d.ts +6 -0
  9. package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
  10. package/dist/src/pubsub/connection-handlers.js +329 -0
  11. package/dist/src/pubsub/connection-handlers.js.map +1 -0
  12. package/dist/src/pubsub/emit-self.d.ts +6 -0
  13. package/dist/src/pubsub/emit-self.d.ts.map +1 -0
  14. package/dist/src/pubsub/emit-self.js +80 -0
  15. package/dist/src/pubsub/emit-self.js.map +1 -0
  16. package/dist/src/pubsub/index.d.ts +18 -0
  17. package/dist/src/pubsub/index.d.ts.map +1 -0
  18. package/dist/src/pubsub/index.js +17 -0
  19. package/dist/src/pubsub/index.js.map +1 -0
  20. package/dist/src/pubsub/messages.d.ts +6 -0
  21. package/dist/src/pubsub/messages.d.ts.map +1 -0
  22. package/dist/src/pubsub/messages.js +48 -0
  23. package/dist/src/pubsub/messages.js.map +1 -0
  24. package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
  25. package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
  26. package/dist/src/pubsub/multiple-nodes.js +350 -0
  27. package/dist/src/pubsub/multiple-nodes.js.map +1 -0
  28. package/dist/src/pubsub/two-nodes.d.ts +6 -0
  29. package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
  30. package/dist/src/pubsub/two-nodes.js +217 -0
  31. package/dist/src/pubsub/two-nodes.js.map +1 -0
  32. package/dist/src/pubsub/utils.d.ts +6 -0
  33. package/dist/src/pubsub/utils.d.ts.map +1 -0
  34. package/dist/src/pubsub/utils.js +22 -0
  35. package/dist/src/pubsub/utils.js.map +1 -0
  36. package/package.json +13 -8
  37. package/src/mocks/connection-manager.ts +2 -0
  38. package/src/pubsub/api.ts +114 -0
  39. package/src/pubsub/connection-handlers.ts +413 -0
  40. package/src/pubsub/emit-self.ts +99 -0
  41. package/src/pubsub/index.ts +34 -0
  42. package/src/pubsub/messages.ts +59 -0
  43. package/src/pubsub/multiple-nodes.ts +440 -0
  44. package/src/pubsub/two-nodes.ts +273 -0
  45. package/src/pubsub/utils.ts +29 -0
@@ -0,0 +1,217 @@
1
+ /* eslint max-nested-callbacks: ["error", 6] */
2
+ import { TopicValidatorResult } from '@libp2p/interface/pubsub';
3
+ import { start, stop } from '@libp2p/interface/startable';
4
+ import { expect } from 'aegir/chai';
5
+ import pDefer from 'p-defer';
6
+ import pWaitFor from 'p-wait-for';
7
+ import sinon from 'sinon';
8
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
9
+ import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
10
+ import { mockNetwork } from '../mocks/index.js';
11
+ import { createComponents, waitForSubscriptionUpdate } from './utils.js';
12
+ const topic = 'foo';
13
+ function shouldNotHappen() {
14
+ expect.fail();
15
+ }
16
+ export default (common) => {
17
+ describe('pubsub with two nodes', () => {
18
+ let psA;
19
+ let psB;
20
+ let componentsA;
21
+ let componentsB;
22
+ // Create pubsub nodes and connect them
23
+ beforeEach(async () => {
24
+ mockNetwork.reset();
25
+ componentsA = await createComponents();
26
+ componentsB = await createComponents();
27
+ psA = componentsA.pubsub = await common.setup({
28
+ components: componentsA,
29
+ init: {
30
+ emitSelf: true
31
+ }
32
+ });
33
+ psB = componentsB.pubsub = await common.setup({
34
+ components: componentsB,
35
+ init: {
36
+ emitSelf: false
37
+ }
38
+ });
39
+ // Start pubsub and connect nodes
40
+ await start(...Object.values(componentsA), ...Object.values(componentsB));
41
+ expect(psA.getPeers()).to.be.empty();
42
+ expect(psB.getPeers()).to.be.empty();
43
+ await componentsA.connectionManager.openConnection(componentsB.peerId);
44
+ // Wait for peers to be ready in pubsub
45
+ await pWaitFor(() => psA.getPeers().length === 1 && psB.getPeers().length === 1);
46
+ });
47
+ afterEach(async () => {
48
+ sinon.restore();
49
+ await stop(...Object.values(componentsA), ...Object.values(componentsB));
50
+ await common.teardown();
51
+ mockNetwork.reset();
52
+ });
53
+ it('Subscribe to a topic in nodeA', async () => {
54
+ const defer = pDefer();
55
+ psB.addEventListener('subscription-change', (evt) => {
56
+ const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail;
57
+ expect(psA.getTopics()).to.deep.equal([topic]);
58
+ expect(psB.getPeers()).to.have.lengthOf(1);
59
+ expect(psB.getSubscribers(topic).map(p => p.toString())).to.deep.equal([componentsA.peerId.toString()]);
60
+ expect(changedPeerId).to.deep.equal(psB.getPeers()[0]);
61
+ expect(changedSubs).to.have.lengthOf(1);
62
+ expect(changedSubs[0].topic).to.equal(topic);
63
+ expect(changedSubs[0].subscribe).to.equal(true);
64
+ defer.resolve();
65
+ }, {
66
+ once: true
67
+ });
68
+ psA.subscribe(topic);
69
+ return defer.promise;
70
+ });
71
+ it('Publish to a topic in nodeA', async () => {
72
+ const defer = pDefer();
73
+ psA.addEventListener('message', (evt) => {
74
+ if (evt.detail.topic === topic) {
75
+ const msg = evt.detail;
76
+ expect(uint8ArrayToString(msg.data)).to.equal('hey');
77
+ psB.removeEventListener('message', shouldNotHappen);
78
+ defer.resolve();
79
+ }
80
+ }, {
81
+ once: true
82
+ });
83
+ psA.subscribe(topic);
84
+ psB.subscribe(topic);
85
+ await Promise.all([
86
+ waitForSubscriptionUpdate(psA, componentsB.peerId),
87
+ waitForSubscriptionUpdate(psB, componentsA.peerId)
88
+ ]);
89
+ await psA.publish(topic, uint8ArrayFromString('hey'));
90
+ return defer.promise;
91
+ });
92
+ it('Publish to a topic in nodeB', async () => {
93
+ const defer = pDefer();
94
+ psA.addEventListener('message', (evt) => {
95
+ if (evt.detail.topic !== topic) {
96
+ return;
97
+ }
98
+ const msg = evt.detail;
99
+ psA.addEventListener('message', (evt) => {
100
+ if (evt.detail.topic === topic) {
101
+ shouldNotHappen();
102
+ }
103
+ }, {
104
+ once: true
105
+ });
106
+ expect(uint8ArrayToString(msg.data)).to.equal('banana');
107
+ setTimeout(() => {
108
+ psA.removeEventListener('message');
109
+ psB.removeEventListener('message');
110
+ defer.resolve();
111
+ }, 100);
112
+ }, {
113
+ once: true
114
+ });
115
+ psB.addEventListener('message', shouldNotHappen);
116
+ psA.subscribe(topic);
117
+ psB.subscribe(topic);
118
+ await Promise.all([
119
+ waitForSubscriptionUpdate(psA, componentsB.peerId),
120
+ waitForSubscriptionUpdate(psB, componentsA.peerId)
121
+ ]);
122
+ await psB.publish(topic, uint8ArrayFromString('banana'));
123
+ return defer.promise;
124
+ });
125
+ it('validate topic message', async () => {
126
+ const defer = pDefer();
127
+ psA.subscribe(topic);
128
+ psB.topicValidators.set(topic, (peer, message) => {
129
+ if (!peer.equals(componentsA.peerId)) {
130
+ defer.reject(new Error('Invalid peer id in topic validator fn'));
131
+ return TopicValidatorResult.Reject;
132
+ }
133
+ if (uint8ArrayToString(message.data) !== 'hey') {
134
+ defer.reject(new Error('Invalid message in topic validator fn'));
135
+ return TopicValidatorResult.Reject;
136
+ }
137
+ defer.resolve();
138
+ return TopicValidatorResult.Accept;
139
+ });
140
+ psB.subscribe(topic);
141
+ await Promise.all([
142
+ waitForSubscriptionUpdate(psA, componentsB.peerId),
143
+ waitForSubscriptionUpdate(psB, componentsA.peerId)
144
+ ]);
145
+ await psA.publish(topic, uint8ArrayFromString('hey'));
146
+ return defer.promise;
147
+ });
148
+ it('Publish 10 msg to a topic in nodeB', async () => {
149
+ const defer = pDefer();
150
+ let counter = 0;
151
+ psB.addEventListener('message', shouldNotHappen);
152
+ psA.addEventListener('message', receivedMsg);
153
+ function receivedMsg(evt) {
154
+ const msg = evt.detail;
155
+ if (msg.type === 'unsigned') {
156
+ expect(uint8ArrayToString(msg.data)).to.equal('banana');
157
+ expect(msg.topic).to.be.equal(topic);
158
+ }
159
+ else {
160
+ expect(uint8ArrayToString(msg.data)).to.equal('banana');
161
+ expect(msg.from.toString()).to.equal(componentsB.peerId.toString());
162
+ expect(msg.sequenceNumber).to.be.a('BigInt');
163
+ expect(msg.topic).to.be.equal(topic);
164
+ }
165
+ if (++counter === 10) {
166
+ psA.removeEventListener('message', receivedMsg);
167
+ psB.removeEventListener('message', shouldNotHappen);
168
+ defer.resolve();
169
+ }
170
+ }
171
+ psA.subscribe(topic);
172
+ psB.subscribe(topic);
173
+ await Promise.all([
174
+ waitForSubscriptionUpdate(psA, componentsB.peerId),
175
+ waitForSubscriptionUpdate(psB, componentsA.peerId)
176
+ ]);
177
+ await Promise.all(Array.from({ length: 10 }, async (_, i) => {
178
+ await psB.publish(topic, uint8ArrayFromString('banana'));
179
+ }));
180
+ return defer.promise;
181
+ });
182
+ it('Unsubscribe from topic in nodeA', async () => {
183
+ const defer = pDefer();
184
+ let callCount = 0;
185
+ psB.addEventListener('subscription-change', (evt) => {
186
+ callCount++;
187
+ if (callCount === 1) {
188
+ // notice subscribe
189
+ const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail;
190
+ expect(psB.getPeers()).to.have.lengthOf(1);
191
+ expect(psB.getTopics()).to.be.empty();
192
+ expect(changedPeerId).to.deep.equal(psB.getPeers()[0]);
193
+ expect(changedSubs).to.have.lengthOf(1);
194
+ expect(changedSubs[0].topic).to.equal(topic);
195
+ expect(changedSubs[0].subscribe).to.equal(true);
196
+ }
197
+ else {
198
+ // notice unsubscribe
199
+ const { peerId: changedPeerId, subscriptions: changedSubs } = evt.detail;
200
+ expect(psB.getPeers()).to.have.lengthOf(1);
201
+ expect(psB.getTopics()).to.be.empty();
202
+ expect(changedPeerId).to.deep.equal(psB.getPeers()[0]);
203
+ expect(changedSubs).to.have.lengthOf(1);
204
+ expect(changedSubs[0].topic).to.equal(topic);
205
+ expect(changedSubs[0].subscribe).to.equal(false);
206
+ defer.resolve();
207
+ }
208
+ });
209
+ psA.subscribe(topic);
210
+ expect(psA.getTopics()).to.not.be.empty();
211
+ psA.unsubscribe(topic);
212
+ expect(psA.getTopics()).to.be.empty();
213
+ return defer.promise;
214
+ });
215
+ });
216
+ };
217
+ //# sourceMappingURL=two-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"two-nodes.js","sourceRoot":"","sources":["../../../src/pubsub/two-nodes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { MockNetworkComponents } from '../mocks/index.js';
2
+ import type { PeerId } from '@libp2p/interface/peer-id';
3
+ import type { PubSub } from '@libp2p/interface/pubsub';
4
+ export declare function waitForSubscriptionUpdate(a: PubSub, b: PeerId): Promise<void>;
5
+ export declare function createComponents(): Promise<MockNetworkComponents>;
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/pubsub/utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAA0B,MAAM,0BAA0B,CAAA;AAE9E,wBAAsB,yBAAyB,CAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpF;AAED,wBAAsB,gBAAgB,IAAK,OAAO,CAAC,qBAAqB,CAAC,CAWxE"}
@@ -0,0 +1,22 @@
1
+ import { EventEmitter } from '@libp2p/interface/events';
2
+ import { createEd25519PeerId } from '@libp2p/peer-id-factory';
3
+ import { pEvent } from 'p-event';
4
+ import pWaitFor from 'p-wait-for';
5
+ import { mockConnectionManager, mockRegistrar, mockNetwork } from '../mocks/index.js';
6
+ export async function waitForSubscriptionUpdate(a, b) {
7
+ await pWaitFor(async () => {
8
+ const event = await pEvent(a, 'subscription-change');
9
+ return event.detail.peerId.equals(b);
10
+ });
11
+ }
12
+ export async function createComponents() {
13
+ const components = {
14
+ peerId: await createEd25519PeerId(),
15
+ registrar: mockRegistrar(),
16
+ events: new EventEmitter()
17
+ };
18
+ components.connectionManager = mockConnectionManager(components);
19
+ mockNetwork.addNode(components);
20
+ return components;
21
+ }
22
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/pubsub/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAKrF,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAE,CAAS,EAAE,CAAS;IACnE,MAAM,QAAQ,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,KAAK,GAAG,MAAM,MAAM,CAA6D,CAAC,EAAE,qBAAqB,CAAC,CAAA;QAEhH,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,UAAU,GAAQ;QACtB,MAAM,EAAE,MAAM,mBAAmB,EAAE;QACnC,SAAS,EAAE,aAAa,EAAE;QAC1B,MAAM,EAAE,IAAI,YAAY,EAAE;KAC3B,CAAA;IACD,UAAU,CAAC,iBAAiB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAA;IAEhE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAE/B,OAAO,UAAU,CAAA;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/interface-compliance-tests",
3
- "version": "3.0.7-05abd49f",
3
+ "version": "3.0.7-06f4901a",
4
4
  "description": "Compliance tests for JS libp2p interfaces",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/interface-compliance-tests#readme",
@@ -68,6 +68,10 @@
68
68
  "types": "./dist/src/peers.d.ts",
69
69
  "import": "./dist/src/peers.js"
70
70
  },
71
+ "./pubsub": {
72
+ "types": "./dist/src/pubsub/index.d.ts",
73
+ "import": "./dist/src/pubsub/index.js"
74
+ },
71
75
  "./stream-muxer": {
72
76
  "types": "./dist/src/stream-muxer/index.d.ts",
73
77
  "import": "./dist/src/stream-muxer/index.js"
@@ -97,13 +101,13 @@
97
101
  "test:electron-main": "aegir test -t electron-main"
98
102
  },
99
103
  "dependencies": {
100
- "@libp2p/interface": "0.0.1-05abd49f",
101
- "@libp2p/interface-internal": "0.0.1-05abd49f",
102
- "@libp2p/logger": "2.1.1-05abd49f",
103
- "@libp2p/multistream-select": "3.1.9-05abd49f",
104
- "@libp2p/peer-collections": "3.0.2-05abd49f",
105
- "@libp2p/peer-id": "2.0.3-05abd49f",
106
- "@libp2p/peer-id-factory": "2.0.3-05abd49f",
104
+ "@libp2p/interface": "0.0.1-06f4901a",
105
+ "@libp2p/interface-internal": "0.0.1-06f4901a",
106
+ "@libp2p/logger": "2.1.1-06f4901a",
107
+ "@libp2p/multistream-select": "3.1.9-06f4901a",
108
+ "@libp2p/peer-collections": "3.0.2-06f4901a",
109
+ "@libp2p/peer-id": "2.0.3-06f4901a",
110
+ "@libp2p/peer-id-factory": "2.0.3-06f4901a",
107
111
  "@multiformats/multiaddr": "^12.1.3",
108
112
  "abortable-iterator": "^5.0.1",
109
113
  "any-signal": "^4.1.1",
@@ -119,6 +123,7 @@
119
123
  "it-stream-types": "^2.0.1",
120
124
  "merge-options": "^3.0.4",
121
125
  "p-defer": "^4.0.0",
126
+ "p-event": "^6.0.0",
122
127
  "p-limit": "^4.0.0",
123
128
  "p-wait-for": "^5.0.2",
124
129
  "sinon": "^15.1.2",
@@ -7,6 +7,7 @@ import { connectionPair } from './connection.js'
7
7
  import type { Libp2pEvents } from '@libp2p/interface'
8
8
  import type { Connection } from '@libp2p/interface/connection'
9
9
  import type { EventEmitter } from '@libp2p/interface/events'
10
+ import type { PubSub } from '@libp2p/interface/pubsub'
10
11
  import type { Startable } from '@libp2p/interface/startable'
11
12
  import type { ConnectionManager, PendingDial } from '@libp2p/interface-internal/connection-manager'
12
13
  import type { Registrar } from '@libp2p/interface-internal/registrar'
@@ -16,6 +17,7 @@ export interface MockNetworkComponents {
16
17
  registrar: Registrar
17
18
  connectionManager: ConnectionManager
18
19
  events: EventEmitter<Libp2pEvents>
20
+ pubsub?: PubSub
19
21
  }
20
22
 
21
23
  class MockNetwork {
@@ -0,0 +1,114 @@
1
+ import { isStartable, start, stop } from '@libp2p/interface/startable'
2
+ import { expect } from 'aegir/chai'
3
+ import delay from 'delay'
4
+ import pDefer from 'p-defer'
5
+ import pWaitFor from 'p-wait-for'
6
+ import sinon from 'sinon'
7
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
8
+ import { mockNetwork } from '../mocks/index.js'
9
+ import { createComponents } from './utils.js'
10
+ import type { PubSubArgs, PubSubComponents } from './index.js'
11
+ import type { TestSetup } from '../index.js'
12
+ import type { PubSub } from '@libp2p/interface/pubsub'
13
+
14
+ const topic = 'foo'
15
+ const data = uint8ArrayFromString('bar')
16
+
17
+ export default (common: TestSetup<PubSub, PubSubArgs>): void => {
18
+ describe('pubsub api', () => {
19
+ let pubsub: PubSub
20
+ let components: PubSubComponents
21
+
22
+ // Create pubsub router
23
+ beforeEach(async () => {
24
+ mockNetwork.reset()
25
+ components = await createComponents()
26
+
27
+ pubsub = components.pubsub = await common.setup({
28
+ components,
29
+ init: {
30
+ emitSelf: true
31
+ }
32
+ })
33
+ })
34
+
35
+ afterEach(async () => {
36
+ sinon.restore()
37
+ await stop(...Object.values(components))
38
+ await common.teardown()
39
+ mockNetwork.reset()
40
+ })
41
+
42
+ it('can start correctly', async () => {
43
+ if (!isStartable(pubsub)) {
44
+ return
45
+ }
46
+
47
+ sinon.spy(components.registrar, 'register')
48
+
49
+ await start(...Object.values(components))
50
+
51
+ expect(pubsub.isStarted()).to.equal(true)
52
+ expect(components.registrar.register).to.have.property('callCount', 1)
53
+ })
54
+
55
+ it('can stop correctly', async () => {
56
+ if (!isStartable(pubsub)) {
57
+ return
58
+ }
59
+
60
+ sinon.spy(components.registrar, 'unregister')
61
+
62
+ await start(...Object.values(components))
63
+ await stop(...Object.values(components))
64
+
65
+ expect(pubsub.isStarted()).to.equal(false)
66
+ expect(components.registrar.unregister).to.have.property('callCount', 1)
67
+ })
68
+
69
+ it('can subscribe and unsubscribe correctly', async () => {
70
+ const handler = (): void => {
71
+ throw new Error('a message should not be received')
72
+ }
73
+
74
+ await start(...Object.values(components))
75
+ pubsub.subscribe(topic)
76
+ pubsub.addEventListener('message', handler)
77
+
78
+ await pWaitFor(() => {
79
+ const topics = pubsub.getTopics()
80
+ return topics.length === 1 && topics[0] === topic
81
+ })
82
+
83
+ pubsub.removeEventListener('message', handler)
84
+ pubsub.unsubscribe(topic)
85
+
86
+ await pWaitFor(() => pubsub.getTopics().length === 0)
87
+
88
+ // Publish to guarantee the handler is not called
89
+ await pubsub.publish(topic, data)
90
+
91
+ // handlers are called async
92
+ await delay(100)
93
+
94
+ await stop(...Object.values(components))
95
+ })
96
+
97
+ it('can subscribe and publish correctly', async () => {
98
+ const defer = pDefer()
99
+
100
+ await start(...Object.values(components))
101
+
102
+ pubsub.subscribe(topic)
103
+ pubsub.addEventListener('message', (evt) => {
104
+ expect(evt).to.have.nested.property('detail.topic', topic)
105
+ expect(evt).to.have.deep.nested.property('detail.data', data)
106
+ defer.resolve()
107
+ })
108
+ await pubsub.publish(topic, data)
109
+ await defer.promise
110
+
111
+ await stop(...Object.values(components))
112
+ })
113
+ })
114
+ }