|
|
@@ -1,16 +1,20 @@
|
|
1
|
1
|
import { describe, it } from "mocha";
|
|
2
|
2
|
import { RPCServer, RPCSocket } from '../Index'
|
|
3
|
|
-import { RPCExporter } from "../src/Interfaces";
|
|
|
3
|
+import { RPCExporter, Socket } from "../src/Interfaces";
|
|
4
|
4
|
import { ConnectedSocket } from "../src/Types";
|
|
5
|
5
|
import * as log from 'why-is-node-running';
|
|
6
|
6
|
import * as http from 'http';
|
|
7
|
7
|
import * as express from 'express';
|
|
8
|
8
|
import * as fetch from 'node-fetch';
|
|
|
9
|
+import { PromiseIO } from "../src/PromiseIO/Server";
|
|
|
10
|
+import { PromiseIOClient } from "../src/PromiseIO/Client";
|
|
|
11
|
+
|
|
|
12
|
+const noop = (...args) => { }
|
|
9
|
13
|
|
|
10
|
14
|
const add = (...args: number[]) => { return args.reduce((a, b) => a + b, 0) }
|
|
11
|
|
-function makeServer() {
|
|
|
15
|
+function makeServer(onCallback = noop, connectionHandler = noop, hookCloseHandler = noop, closeHandler = noop, errorHandler = (socket, err) => { throw err }) {
|
|
12
|
16
|
let subcallback
|
|
13
|
|
- const sv = new RPCServer([{
|
|
|
17
|
+ const serv = new RPCServer([{
|
|
14
|
18
|
name: 'test',
|
|
15
|
19
|
RPCs: [
|
|
16
|
20
|
{
|
|
|
@@ -22,36 +26,92 @@ function makeServer() {
|
|
22
|
26
|
subcallback = callback
|
|
23
|
27
|
return { topic: "test" }
|
|
24
|
28
|
},
|
|
25
|
|
- onClose: (res) => { }
|
|
|
29
|
+ onDestroy: hookCloseHandler
|
|
26
|
30
|
}, {
|
|
27
|
31
|
name: 'subscribe',
|
|
28
|
32
|
hook: async (callback) => {
|
|
29
|
33
|
subcallback = callback
|
|
30
|
34
|
return { topic: "test" }
|
|
31
|
35
|
},
|
|
32
|
|
- onClose: (res, rpc) => {
|
|
33
|
|
- console.log("onClose", rpc.name === 'subscribe' && res ? "OK" : "")
|
|
34
|
|
- subcallback = null
|
|
35
|
|
- },
|
|
36
|
|
- onCallback: (...args: any) => {
|
|
37
|
|
- console.log("onCallback", args[0] === "test" && args[1] === "callback" ? "OK" : "")
|
|
38
|
|
- }
|
|
|
36
|
+ onDestroy: hookCloseHandler,
|
|
|
37
|
+ onCallback: onCallback
|
|
39
|
38
|
},
|
|
40
|
39
|
add,
|
|
41
|
40
|
function triggerCallback(...messages: any[]): number { return subcallback.apply({}, messages) },
|
|
|
41
|
+ function brokenRPC(){ throw new Error("Intended error") }
|
|
42
|
42
|
]
|
|
43
|
|
- }],
|
|
44
|
|
- {
|
|
45
|
|
- connectionHandler: (socket) => {
|
|
46
|
|
- },
|
|
47
|
|
- closeHandler: (socket) => { },
|
|
48
|
|
- errorHandler: (socket, err) => { throw err }
|
|
49
|
|
- })
|
|
50
|
|
- sv.listen(21010)
|
|
51
|
|
- return sv
|
|
|
43
|
+ }],
|
|
|
44
|
+ {
|
|
|
45
|
+ connectionHandler: connectionHandler,
|
|
|
46
|
+ closeHandler: closeHandler,
|
|
|
47
|
+ errorHandler: errorHandler
|
|
|
48
|
+ })
|
|
|
49
|
+ serv.listen(21010)
|
|
|
50
|
+ return serv
|
|
52
|
51
|
}
|
|
53
|
52
|
|
|
54
|
53
|
|
|
|
54
|
+describe('PromiseIO', () => {
|
|
|
55
|
+
|
|
|
56
|
+ it("bind + fire", (done) => {
|
|
|
57
|
+ const server = new PromiseIO()
|
|
|
58
|
+ server.attach(new http.Server())
|
|
|
59
|
+ server.on("socket", clientSocket => {
|
|
|
60
|
+ clientSocket.bind("test123", (p1,p2) => {
|
|
|
61
|
+ server.close()
|
|
|
62
|
+ if(p1 === "p1" && p2 === "p2")
|
|
|
63
|
+ done()
|
|
|
64
|
+ })
|
|
|
65
|
+ });
|
|
|
66
|
+
|
|
|
67
|
+ server.listen(21003)
|
|
|
68
|
+ PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
|
|
|
69
|
+ cli.fire("test123", "p1", "p2")
|
|
|
70
|
+ cli.close()
|
|
|
71
|
+ })
|
|
|
72
|
+ })
|
|
|
73
|
+
|
|
|
74
|
+ it("hook + call", (done) => {
|
|
|
75
|
+ const server = new PromiseIO()
|
|
|
76
|
+ server.attach(new http.Server())
|
|
|
77
|
+ server.on("socket", clientSocket => {
|
|
|
78
|
+ clientSocket.hook("test123", (p1,p2) => {
|
|
|
79
|
+ if(p1 === "p1" && p2 === "p2")
|
|
|
80
|
+ return "OK"
|
|
|
81
|
+ })
|
|
|
82
|
+ });
|
|
|
83
|
+
|
|
|
84
|
+ server.listen(21003)
|
|
|
85
|
+ PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
|
|
|
86
|
+ cli.call("test123", "p1", "p2").then(resp => {
|
|
|
87
|
+ cli.close()
|
|
|
88
|
+ server.close()
|
|
|
89
|
+
|
|
|
90
|
+ if(resp === "OK")
|
|
|
91
|
+ done()
|
|
|
92
|
+ })
|
|
|
93
|
+ })
|
|
|
94
|
+ })
|
|
|
95
|
+
|
|
|
96
|
+ it("on + emit", (done) => {
|
|
|
97
|
+ const server = new PromiseIO()
|
|
|
98
|
+ server.attach(new http.Server())
|
|
|
99
|
+ server.on("socket", clientSocket => {
|
|
|
100
|
+ clientSocket.on("test123", (p1,p2) => {
|
|
|
101
|
+ server.close()
|
|
|
102
|
+ if(p1 === "p1" && p2 === "p2")
|
|
|
103
|
+ done()
|
|
|
104
|
+ })
|
|
|
105
|
+ });
|
|
|
106
|
+
|
|
|
107
|
+ server.listen(21003)
|
|
|
108
|
+ PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
|
|
|
109
|
+ cli.emit("test123", "p1", "p2")
|
|
|
110
|
+ cli.close()
|
|
|
111
|
+ })
|
|
|
112
|
+ })
|
|
|
113
|
+})
|
|
|
114
|
+
|
|
55
|
115
|
describe('RPCServer', () => {
|
|
56
|
116
|
let client, server
|
|
57
|
117
|
const echo = (x) => x
|
|
|
@@ -133,21 +193,21 @@ describe('RPCServer with premade http server', () => {
|
|
133
|
193
|
{
|
|
134
|
194
|
name: 'Grp2',
|
|
135
|
195
|
RPCs: [
|
|
136
|
|
- function test(){ return "test" }
|
|
|
196
|
+ function test() { return "test" }
|
|
137
|
197
|
],
|
|
138
|
198
|
}
|
|
139
|
199
|
]
|
|
140
|
200
|
|
|
141
|
|
- let client:RPCSocket, server:RPCServer
|
|
|
201
|
+ let client: RPCSocket, server: RPCServer
|
|
142
|
202
|
|
|
143
|
203
|
before(done => {
|
|
144
|
204
|
const expressServer = express()
|
|
145
|
205
|
const httpServer = new http.Server(expressServer)
|
|
146
|
206
|
|
|
147
|
|
- expressServer.get('/REST_ping', (req, res)=>{
|
|
|
207
|
+ expressServer.get('/REST_ping', (req, res) => {
|
|
148
|
208
|
return res
|
|
149
|
|
- .send('REST_pong')
|
|
150
|
|
- .status(200)
|
|
|
209
|
+ .send('REST_pong')
|
|
|
210
|
+ .status(200)
|
|
151
|
211
|
})
|
|
152
|
212
|
|
|
153
|
213
|
server = new RPCServer(
|
|
|
@@ -157,7 +217,7 @@ describe('RPCServer with premade http server', () => {
|
|
157
|
217
|
httpServer.listen(8080)
|
|
158
|
218
|
|
|
159
|
219
|
client = new RPCSocket(8080, 'localhost')
|
|
160
|
|
-
|
|
|
220
|
+
|
|
161
|
221
|
done()
|
|
162
|
222
|
})
|
|
163
|
223
|
|
|
|
@@ -171,10 +231,10 @@ describe('RPCServer with premade http server', () => {
|
|
171
|
231
|
it('should serve REST', (done) => {
|
|
172
|
232
|
fetch('http://localhost:8080/REST_ping').then(response => {
|
|
173
|
233
|
response.text().then(text => {
|
|
174
|
|
- if(text === "REST_pong")
|
|
|
234
|
+ if (text === "REST_pong")
|
|
175
|
235
|
done()
|
|
176
|
236
|
else
|
|
177
|
|
- done(new Error("REST repsonse was "+text))
|
|
|
237
|
+ done(new Error("REST repsonse was " + text))
|
|
178
|
238
|
})
|
|
179
|
239
|
})
|
|
180
|
240
|
})
|
|
|
@@ -197,6 +257,54 @@ describe('RPCServer with premade http server', () => {
|
|
197
|
257
|
})
|
|
198
|
258
|
|
|
199
|
259
|
|
|
|
260
|
+describe('Serverside Triggers', () => {
|
|
|
261
|
+ let server, client
|
|
|
262
|
+ const closerFunction = (done) => () => {
|
|
|
263
|
+ client.close()
|
|
|
264
|
+ server.close()
|
|
|
265
|
+ done()
|
|
|
266
|
+ }
|
|
|
267
|
+
|
|
|
268
|
+ it('trigger onCallback', (done) => {
|
|
|
269
|
+ server = makeServer(closerFunction(done))
|
|
|
270
|
+ client = new RPCSocket(21010, "localhost")
|
|
|
271
|
+ client.connect().then(_ => {
|
|
|
272
|
+ client['test'].subscribe(noop).then(_ => client['test'].triggerCallback())
|
|
|
273
|
+ })
|
|
|
274
|
+ })
|
|
|
275
|
+
|
|
|
276
|
+ it('trigger connectionHandler', (done) => {
|
|
|
277
|
+ server = makeServer(undefined, closerFunction(done))
|
|
|
278
|
+ client = new RPCSocket(21010, "localhost")
|
|
|
279
|
+ client.connect()
|
|
|
280
|
+ })
|
|
|
281
|
+
|
|
|
282
|
+
|
|
|
283
|
+ it('trigger hook closeHandler', (done) => {
|
|
|
284
|
+ server = makeServer(undefined, undefined, closerFunction(done))
|
|
|
285
|
+ client = new RPCSocket(21010, "localhost")
|
|
|
286
|
+ client.connect().then(_ => {
|
|
|
287
|
+ client['test'].subscribe(function cb(){
|
|
|
288
|
+ cb['destroy']()
|
|
|
289
|
+ }).then(_ => client['test'].triggerCallback())
|
|
|
290
|
+ })
|
|
|
291
|
+ })
|
|
|
292
|
+
|
|
|
293
|
+
|
|
|
294
|
+ it('trigger global closeHandler', (done) => {
|
|
|
295
|
+ server = makeServer(undefined, undefined, undefined, () => {
|
|
|
296
|
+ server.close()
|
|
|
297
|
+ done()
|
|
|
298
|
+ })
|
|
|
299
|
+ client = new RPCSocket(21010, "localhost")
|
|
|
300
|
+ client.connect().then(_ => {
|
|
|
301
|
+ client['test'].subscribe(noop).then(_ => client.close())
|
|
|
302
|
+ })
|
|
|
303
|
+ })
|
|
|
304
|
+
|
|
|
305
|
+
|
|
|
306
|
+})
|
|
|
307
|
+
|
|
200
|
308
|
describe('RPCSocket', () => {
|
|
201
|
309
|
let client: RPCSocket
|
|
202
|
310
|
let server: RPCServer
|
|
|
@@ -266,6 +374,7 @@ describe('RPCSocket', () => {
|
|
266
|
374
|
})
|
|
267
|
375
|
})
|
|
268
|
376
|
|
|
|
377
|
+
|
|
269
|
378
|
describe('It should do unhook', () => {
|
|
270
|
379
|
const yesCandy = "OK"
|
|
271
|
380
|
const noCandy = "stolen"
|
|
|
@@ -304,12 +413,12 @@ describe('It should do unhook', () => {
|
|
304
|
413
|
function publish(): string { cb(candy); return candy },
|
|
305
|
414
|
function unsubscribe(): string { candy = noCandy; cb(candy); cb = () => { }; return candy }
|
|
306
|
415
|
]
|
|
307
|
|
- }],
|
|
308
|
|
- {
|
|
309
|
|
- connectionHandler: (socket) => { },
|
|
310
|
|
- closeHandler: (socket) => { },
|
|
311
|
|
- errorHandler: (socket, err) => { throw err }
|
|
312
|
|
- })
|
|
|
416
|
+ }],
|
|
|
417
|
+ {
|
|
|
418
|
+ connectionHandler: noop,
|
|
|
419
|
+ closeHandler: noop,
|
|
|
420
|
+ errorHandler: (socket, err) => { throw err }
|
|
|
421
|
+ })
|
|
313
|
422
|
server.listen(21010)
|
|
314
|
423
|
client = new RPCSocket(21010, "localhost")
|
|
315
|
424
|
return await client.connect()
|
|
|
@@ -321,7 +430,7 @@ describe('It should do unhook', () => {
|
|
321
|
430
|
})
|
|
322
|
431
|
|
|
323
|
432
|
it('Subscribe with param', (done) => {
|
|
324
|
|
- client['test'].subscribeWithParam("OK", c => { }).then(async (res) => {
|
|
|
433
|
+ client['test'].subscribeWithParam("OK", noop).then(async (res) => {
|
|
325
|
434
|
if (res.uuid === candy) {
|
|
326
|
435
|
done()
|
|
327
|
436
|
} else
|
|
|
@@ -363,10 +472,6 @@ type SesameTestIfc = {
|
|
363
|
472
|
subscribe: (callback: Function) => Promise<topicDTO>
|
|
364
|
473
|
manyParams: <A = string, B = number, C = boolean, D = Object>(a: A, b: B, c: C, d: D) => Promise<[A, B, C, D]>
|
|
365
|
474
|
}
|
|
366
|
|
-
|
|
367
|
|
- other: {
|
|
368
|
|
- echo: (x: any) => Promise<any>
|
|
369
|
|
- }
|
|
370
|
475
|
}
|
|
371
|
476
|
|
|
372
|
477
|
describe('Sesame should unlock the socket', () => {
|
|
|
@@ -387,17 +492,11 @@ describe('Sesame should unlock the socket', () => {
|
|
387
|
492
|
topic: 'test'
|
|
388
|
493
|
}
|
|
389
|
494
|
},
|
|
390
|
|
- onClose: (a) => { }
|
|
|
495
|
+ onDestroy: noop
|
|
391
|
496
|
},
|
|
392
|
|
- async function checkCandy() { cb(candy); cb = () => { }; return candy },
|
|
|
497
|
+ async function checkCandy() { cb(candy); cb = noop; return candy },
|
|
393
|
498
|
async function manyParams(a, b, c, d) { return [a, b, c, d] }
|
|
394
|
499
|
],
|
|
395
|
|
- }, {
|
|
396
|
|
- name: 'other',
|
|
397
|
|
- RPCs: () => [
|
|
398
|
|
- async function echo(x) { return x }
|
|
399
|
|
- ]
|
|
400
|
|
-
|
|
401
|
500
|
}], {
|
|
402
|
501
|
sesame: (_sesame) => _sesame === 'sesame!'
|
|
403
|
502
|
})
|
|
|
@@ -413,7 +512,7 @@ describe('Sesame should unlock the socket', () => {
|
|
413
|
512
|
client.close()
|
|
414
|
513
|
server.close()
|
|
415
|
514
|
})
|
|
416
|
|
-
|
|
|
515
|
+
|
|
417
|
516
|
it('should work with sesame', (done) => {
|
|
418
|
517
|
client.test.checkCandy().then(c => done())
|
|
419
|
518
|
})
|
|
|
@@ -575,7 +674,7 @@ describe("Errorhandler functionality", () => {
|
|
575
|
674
|
})
|
|
576
|
675
|
.then(r => {
|
|
577
|
676
|
if (r != null)
|
|
578
|
|
- done("UNEXPECTED RESULT " + r)
|
|
|
677
|
+ done(new Error("UNEXPECTED RESULT " + r))
|
|
579
|
678
|
})
|
|
580
|
679
|
.catch((e) => {
|
|
581
|
680
|
done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
|
|
|
@@ -614,11 +713,10 @@ describe("Errorhandler functionality", () => {
|
|
614
|
713
|
})
|
|
615
|
714
|
.then(r => {
|
|
616
|
715
|
if (r != null)
|
|
617
|
|
- done("UNEXPECTED RESULT " + r)
|
|
|
716
|
+ done(new Error("UNEXPECTED RESULT " + r))
|
|
618
|
717
|
})
|
|
619
|
718
|
.catch((e) => {
|
|
620
|
|
- done("UNEXPECTED CLIENT ERROR " + e)
|
|
621
|
|
- done(e)
|
|
|
719
|
+ done(new Error("UNEXPECTED CLIENT ERROR " + e))
|
|
622
|
720
|
})
|
|
623
|
721
|
.finally(() => {
|
|
624
|
722
|
cli.close()
|
|
|
@@ -670,7 +768,7 @@ describe("Class binding", () => {
|
|
670
|
768
|
before(done => {
|
|
671
|
769
|
exporter1 = new MyExporter()
|
|
672
|
770
|
serv = new RPCServer<myExporterIfc>(
|
|
673
|
|
- [exporter1],
|
|
|
771
|
+ [exporter1],
|
|
674
|
772
|
{
|
|
675
|
773
|
accessFilter: async (sesame, exporter) => {
|
|
676
|
774
|
if (exporter.name === 'MyExporter') {
|
|
|
@@ -772,6 +870,25 @@ describe("attaching handlers before connecting", () => {
|
|
772
|
870
|
})
|
|
773
|
871
|
})
|
|
774
|
872
|
|
|
|
873
|
+ it("fires error if call is unknown", (done) => {
|
|
|
874
|
+ const serv = new RPCServer().listen(21004)
|
|
|
875
|
+ const sock = new RPCSocket(21004, 'localhost')
|
|
|
876
|
+
|
|
|
877
|
+ sock.on('error', (err) => {
|
|
|
878
|
+ sock.close()
|
|
|
879
|
+ serv.close()
|
|
|
880
|
+ done()
|
|
|
881
|
+ })
|
|
|
882
|
+
|
|
|
883
|
+ sock.connect().then(_ => {
|
|
|
884
|
+ sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
|
|
|
885
|
+ done(new Error("unexpected return value"))
|
|
|
886
|
+ })
|
|
|
887
|
+ }).catch(e => {
|
|
|
888
|
+ done(e)
|
|
|
889
|
+ })
|
|
|
890
|
+ })
|
|
|
891
|
+
|
|
775
|
892
|
/*
|
|
776
|
893
|
* ## 1.11.0 breaking ##
|
|
777
|
894
|
*
|