|
@@ -8,6 +8,8 @@ import * as express from 'express';
|
8
|
8
|
import * as fetch from 'node-fetch';
|
9
|
9
|
import { PromiseIO } from "../src/PromiseIO/Server";
|
10
|
10
|
import { PromiseIOClient } from "../src/PromiseIO/Client";
|
|
11
|
+import { assert, expect } from 'chai';
|
|
12
|
+var should = require('chai').should();
|
11
|
13
|
|
12
|
14
|
const noop = (...args) => { }
|
13
|
15
|
|
|
@@ -20,6 +22,11 @@ function makeServer(onCallback = noop, connectionHandler = noop, hookCloseHandle
|
20
|
22
|
{
|
21
|
23
|
name: 'echo',
|
22
|
24
|
call: async (s: string) => s,
|
|
25
|
+ }, {
|
|
26
|
+ name: 'complexSignature',
|
|
27
|
+ call: async ([a, b]) => {
|
|
28
|
+ return [b, a]
|
|
29
|
+ }
|
23
|
30
|
}, {
|
24
|
31
|
name: 'simpleSubscribe',
|
25
|
32
|
hook: async (callback) => {
|
|
@@ -140,34 +147,26 @@ describe('RPCServer', () => {
|
140
|
147
|
done()
|
141
|
148
|
})
|
142
|
149
|
|
143
|
|
- it('should be able to use all kinds of RPC definitions', (done) => {
|
144
|
|
- client.connect().then(async () => {
|
145
|
|
- const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
146
|
|
- const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
147
|
|
- const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
148
|
|
-
|
|
150
|
+ it('should be able to use all kinds of RPC definitions', async () => {
|
|
151
|
+ await client.connect()
|
|
152
|
+ const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
|
153
|
+ const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
|
154
|
+ const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
149
|
155
|
|
150
|
|
- if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
|
151
|
|
- done()
|
152
|
|
- } else {
|
153
|
|
- done(new Error("Bad response"))
|
154
|
|
- }
|
155
|
|
- })
|
|
156
|
+ expect(r0).to.be.equal('Hello')
|
|
157
|
+ expect(r1).to.be.equal('World')
|
|
158
|
+ expect(r2.join('')).to.be.equal('RPC!')
|
156
|
159
|
})
|
157
|
160
|
|
158
|
|
- it('new RPCServer() should fail on bad RPC', (done) => {
|
159
|
|
- try {
|
|
161
|
+ it('new RPCServer() should fail on unnamed RPC', async () => {
|
|
162
|
+ expect(() => {
|
160
|
163
|
const sv = new RPCServer([{
|
161
|
164
|
name: 'bad',
|
162
|
165
|
RPCs: () => [
|
163
|
166
|
(aaa, bbb, ccc) => { return aaa + bbb + ccc }
|
164
|
167
|
]
|
165
|
168
|
}])
|
166
|
|
- sv.listen(20001)
|
167
|
|
- done(new Error("Didn't fail with bad RPC"))
|
168
|
|
- } catch (badRPCError) {
|
169
|
|
- done()
|
170
|
|
- }
|
|
169
|
+ }).to.throw()
|
171
|
170
|
})
|
172
|
171
|
})
|
173
|
172
|
|
|
@@ -228,31 +227,21 @@ describe('RPCServer with premade http server', () => {
|
228
|
227
|
done()
|
229
|
228
|
})
|
230
|
229
|
|
231
|
|
- it('should serve REST', (done) => {
|
232
|
|
- fetch('http://localhost:8080/REST_ping').then(response => {
|
233
|
|
- response.text().then(text => {
|
234
|
|
- if (text === "REST_pong")
|
235
|
|
- done()
|
236
|
|
- else
|
237
|
|
- done(new Error("REST repsonse was " + text))
|
238
|
|
- })
|
239
|
|
- })
|
|
230
|
+ it('should serve REST', async () => {
|
|
231
|
+ const response = await fetch('http://localhost:8080/REST_ping')
|
|
232
|
+ const text = await response.text()
|
|
233
|
+ expect(text).to.be.equal("REST_pong")
|
240
|
234
|
})
|
241
|
235
|
|
242
|
236
|
|
243
|
|
- it('should be able to use all kinds of RPC definitions', (done) => {
|
244
|
|
- client.connect().then(async () => {
|
245
|
|
- const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
246
|
|
- const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
247
|
|
- const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
248
|
|
-
|
249
|
|
-
|
250
|
|
- if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
|
251
|
|
- done()
|
252
|
|
- } else {
|
253
|
|
- done(new Error("Bad response"))
|
254
|
|
- }
|
255
|
|
- })
|
|
237
|
+ it('should be able to use all kinds of RPC definitions', async () => {
|
|
238
|
+ await client.connect()
|
|
239
|
+ const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
|
240
|
+ const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
|
241
|
+ const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
|
242
|
+ expect(r0).to.be.equal('Hello')
|
|
243
|
+ expect(r1).to.be.equal('World')
|
|
244
|
+ expect(r2.join('')).to.be.equal('RPC!')
|
256
|
245
|
})
|
257
|
246
|
})
|
258
|
247
|
|
|
@@ -272,8 +261,8 @@ describe('should be able to attach to non-standard path', () => {
|
272
|
261
|
}
|
273
|
262
|
]
|
274
|
263
|
}])
|
275
|
|
- server.listen(21003, {path: '/test'})
|
276
|
|
- client = new RPCSocket(21003, 'localhost', {path: '/test'})
|
|
264
|
+ server.listen(21003, { path: '/test' })
|
|
265
|
+ client = new RPCSocket(21003, 'localhost', { path: '/test' })
|
277
|
266
|
done()
|
278
|
267
|
})
|
279
|
268
|
|
|
@@ -284,19 +273,14 @@ describe('should be able to attach to non-standard path', () => {
|
284
|
273
|
done()
|
285
|
274
|
})
|
286
|
275
|
|
287
|
|
- it('should be able to use all kinds of RPC definitions', (done) => {
|
288
|
|
- client.connect().then(async () => {
|
289
|
|
- const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
290
|
|
- const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
291
|
|
- const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
292
|
|
-
|
293
|
|
-
|
294
|
|
- if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
|
295
|
|
- done()
|
296
|
|
- } else {
|
297
|
|
- done(new Error("Bad response"))
|
298
|
|
- }
|
299
|
|
- })
|
|
276
|
+ it('should be able to use all kinds of RPC definitions', async () => {
|
|
277
|
+ await client.connect()
|
|
278
|
+ const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
|
279
|
+ const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
|
280
|
+ const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
|
281
|
+ expect(r0).to.be.equal('Hello')
|
|
282
|
+ expect(r1).to.be.equal('World')
|
|
283
|
+ expect(r2.join('')).to.be.equal('RPC!')
|
300
|
284
|
})
|
301
|
285
|
})
|
302
|
286
|
|
|
@@ -366,22 +350,12 @@ describe('can attach multiple RPCServers to same http server', () => {
|
366
|
350
|
done()
|
367
|
351
|
})
|
368
|
352
|
|
369
|
|
- it('both servers should answer', (done) => {
|
370
|
|
- client['HelloWorldRPCGroup'].echo("test").then(res => {
|
371
|
|
- if(res != "test"){
|
372
|
|
- done(new Error("response was "+res))
|
373
|
|
- }else{
|
374
|
|
- client2['Grp2'].test().then(res => {
|
375
|
|
- if(res != "/test"){
|
376
|
|
- done(new Error("response2 was "+res))
|
377
|
|
- }else{
|
378
|
|
- done()
|
379
|
|
- }
|
380
|
|
- })
|
381
|
|
- }
|
382
|
|
- })
|
|
353
|
+ it('both servers should answer', async () => {
|
|
354
|
+ const res = await client['HelloWorldRPCGroup'].echo("test")
|
|
355
|
+ expect(res).to.equal('test')
|
|
356
|
+ const res2 = await client2['Grp2'].test()
|
|
357
|
+ expect(res2).to.equal('/test')
|
383
|
358
|
})
|
384
|
|
-
|
385
|
359
|
})
|
386
|
360
|
|
387
|
361
|
describe("can attach second RPCServer if first is already running", () => {
|
|
@@ -390,7 +364,7 @@ describe("can attach second RPCServer if first is already running", () => {
|
390
|
364
|
{
|
391
|
365
|
name: 'HelloWorldRPCGroup',
|
392
|
366
|
RPCs: [
|
393
|
|
- function echo (x) { return x}, //named function variable
|
|
367
|
+ function echo(x) { return x }, //named function variable
|
394
|
368
|
function echof(x) { return x }, //named function
|
395
|
369
|
{
|
396
|
370
|
name: 'echoExplicit', //describing object
|
|
@@ -409,7 +383,7 @@ describe("can attach second RPCServer if first is already running", () => {
|
409
|
383
|
}
|
410
|
384
|
]
|
411
|
385
|
|
412
|
|
- it("attaches correctly", done => {
|
|
386
|
+ it("attaches correctly", async () => {
|
413
|
387
|
const expressServer = express()
|
414
|
388
|
const httpServer = new http.Server(expressServer)
|
415
|
389
|
|
|
@@ -427,21 +401,15 @@ describe("can attach second RPCServer if first is already running", () => {
|
427
|
401
|
path: "test"
|
428
|
402
|
})
|
429
|
403
|
|
430
|
|
- new RPCSocket(8080, 'localhost').connect().then(sock => {
|
431
|
|
- new RPCSocket(8080, 'localhost', { path: "test" }).connect().then(sock2 => {
|
432
|
|
- sock2.Grp2.test().then(resp => {
|
433
|
|
- if(resp === "/test")
|
434
|
|
- done()
|
435
|
|
- else
|
436
|
|
- done(new Error("response did not match"))
|
|
404
|
+ const sock = await new RPCSocket(8080, 'localhost').connect()
|
|
405
|
+ const sock2 = await new RPCSocket(8080, 'localhost', { path: "test" }).connect()
|
|
406
|
+ const resp = await sock2.Grp2.test()
|
|
407
|
+ expect(resp).to.be.equal("/test")
|
437
|
408
|
|
438
|
|
- server.close()
|
439
|
|
- server2.close()
|
440
|
|
- sock.close()
|
441
|
|
- sock2.close()
|
442
|
|
- })
|
443
|
|
- })
|
444
|
|
- })
|
|
409
|
+ server.close()
|
|
410
|
+ server2.close()
|
|
411
|
+ sock.close()
|
|
412
|
+ sock2.close()
|
445
|
413
|
})
|
446
|
414
|
})
|
447
|
415
|
|
|
@@ -509,33 +477,19 @@ describe('RPCSocket', () => {
|
509
|
477
|
})
|
510
|
478
|
|
511
|
479
|
|
512
|
|
- it('should have rpc echo', (done) => {
|
513
|
|
- client['test'].echo("x").then(x => {
|
514
|
|
- if (x === 'x')
|
515
|
|
- done()
|
516
|
|
- else
|
517
|
|
- done(new Error('echo RPC response did not match'))
|
518
|
|
- })
|
|
480
|
+ it('should have rpc echo', async() => {
|
|
481
|
+ const x = await client['test'].echo("x")
|
|
482
|
+ expect(x).to.be.equal('x')
|
519
|
483
|
})
|
520
|
484
|
|
521
|
|
- it('should add up to 6', (done) => {
|
522
|
|
- client['test'].add(1, 2, 3).then(x => {
|
523
|
|
- if (x === 6)
|
524
|
|
- done()
|
525
|
|
- else
|
526
|
|
- done(new Error('add RPC response did not match'))
|
527
|
|
- })
|
|
485
|
+ it('should add up to 6', async() => {
|
|
486
|
+ const sum = await client['test'].add(1, 2, 3)
|
|
487
|
+ expect(sum).to.be.equal(6)
|
528
|
488
|
})
|
529
|
489
|
|
530
|
|
- it('should subscribe with success', (done) => {
|
531
|
|
- client['test'].simpleSubscribe(console.log).then(res => {
|
532
|
|
- if (res.topic === 'test') {
|
533
|
|
- done()
|
534
|
|
- } else {
|
535
|
|
- console.error(res)
|
536
|
|
- done(new Error('Subscribe did not return success'))
|
537
|
|
- }
|
538
|
|
- })
|
|
490
|
+ it('should subscribe with success', async () => {
|
|
491
|
+ const res = await client['test'].simpleSubscribe(noop)
|
|
492
|
+ expect(res.topic).to.be.equal('test')
|
539
|
493
|
})
|
540
|
494
|
|
541
|
495
|
it('subscribe should call back', (done) => {
|
|
@@ -616,38 +570,30 @@ describe('It should do unhook', () => {
|
616
|
570
|
server.close()
|
617
|
571
|
})
|
618
|
572
|
|
619
|
|
- it('Subscribe with param', (done) => {
|
620
|
|
- client['test'].subscribeWithParam("OK", noop).then(async (res) => {
|
621
|
|
- if (res.uuid === candy) {
|
622
|
|
- done()
|
623
|
|
- } else
|
624
|
|
- done(new Error("Results did not match " + res.uuid))
|
625
|
|
- })
|
|
573
|
+ it('Subscribe with param', async () => {
|
|
574
|
+ const res = await client['test'].subscribeWithParam("OK", noop)
|
|
575
|
+ expect(res.uuid).to.be.equal(candy)
|
626
|
576
|
})
|
627
|
577
|
|
628
|
578
|
let run = 0
|
629
|
579
|
const expected = [yesCandy, noCandy, noCandy, noCandy]
|
630
|
580
|
|
631
|
|
- it('Unhook+unsubscribe should stop callbacks', (done) => {
|
632
|
|
-
|
633
|
|
- client['test'].subscribe(function myCallback(c) {
|
|
581
|
+ it('Unhook+unsubscribe should stop callbacks', async() => {
|
|
582
|
+ await client['test'].subscribe(function myCallback(c) {
|
634
|
583
|
if (run == 1)
|
635
|
584
|
(myCallback as any).destroy()
|
|
585
|
+ expect(c).to.equal(expected[run++])
|
|
586
|
+ })
|
636
|
587
|
|
637
|
|
- if (c !== expected[run++]) {
|
638
|
|
- done(new Error(`Wrong candy '${c}' in iteration '${run - 1}'`))
|
639
|
|
- }
|
640
|
|
- }).then(async function (res) {
|
641
|
|
- const r1 = await client['test'].publish()
|
642
|
|
- const r3 = await client['test'].unsubscribe()
|
643
|
|
- const r2 = await client['test'].publish()
|
644
|
|
- const r4 = await client['test'].publish()
|
|
588
|
+ const r1 = await client['test'].publish()
|
|
589
|
+ const r3 = await client['test'].unsubscribe()
|
|
590
|
+ const r2 = await client['test'].publish()
|
|
591
|
+ const r4 = await client['test'].publish()
|
645
|
592
|
|
646
|
|
- if (r1 === yesCandy && r3 === noCandy && r2 === noCandy && r4 === noCandy)
|
647
|
|
- done()
|
648
|
|
- else
|
649
|
|
- done(new Error("Results did not match: " + [r1, r2, r3, r4]))
|
650
|
|
- })
|
|
593
|
+ expect(r1).to.be.equal(yesCandy)
|
|
594
|
+ expect(r2).to.be.equal(noCandy)
|
|
595
|
+ expect(r3).to.be.equal(noCandy)
|
|
596
|
+ expect(r4).to.be.equal(noCandy)
|
651
|
597
|
})
|
652
|
598
|
})
|
653
|
599
|
|
|
@@ -700,41 +646,33 @@ describe('Sesame should unlock the socket', () => {
|
700
|
646
|
server.close()
|
701
|
647
|
})
|
702
|
648
|
|
703
|
|
- it('should work with sesame', (done) => {
|
704
|
|
- client.test.checkCandy().then(c => done())
|
|
649
|
+ it('should work with sesame', async () => {
|
|
650
|
+ const c = client.test.checkCandy()
|
|
651
|
+ expect(c).to.exist
|
705
|
652
|
})
|
706
|
653
|
|
707
|
|
- it('should work with multiple params', (done) => {
|
708
|
|
- client.test['manyParams']('a', 'b', 'c', 'd').then(c => {
|
709
|
|
- if (c[0] == 'a' && c[1] === 'b' && c[2] === 'c' && c[3] === 'd')
|
710
|
|
- done()
|
711
|
|
- })
|
|
654
|
+ it('should work with multiple params', async () => {
|
|
655
|
+ const c = await client.test['manyParams']('a', 'b', 'c', 'd')
|
|
656
|
+ expect(c[0]).to.be.equal('a')
|
|
657
|
+ expect(c[1]).to.be.equal('b')
|
|
658
|
+ expect(c[2]).to.be.equal('c')
|
|
659
|
+ expect(c[3]).to.be.equal('d')
|
712
|
660
|
})
|
713
|
661
|
|
714
|
|
- it('should not work without sesame', (done) => {
|
|
662
|
+ it('should not work without sesame', async () => {
|
715
|
663
|
const sock = new RPCSocket(21004, "localhost")
|
716
|
|
- sock.connect().then(async (cli) => {
|
717
|
|
- if (!cli.test)
|
718
|
|
- done()
|
719
|
|
- else {
|
720
|
|
- done(new Error("Function supposed to be removed without sesame"))
|
721
|
|
- }
|
722
|
|
- cli.close()
|
723
|
|
- sock.close()
|
724
|
|
- })
|
|
664
|
+ const cli = await sock.connect()
|
|
665
|
+ expect(cli.test).to.not.exist
|
|
666
|
+ cli.close()
|
|
667
|
+ sock.close()
|
725
|
668
|
})
|
726
|
669
|
|
727
|
|
- it('should fail with wrong sesame', (done) => {
|
|
670
|
+ it('should fail with wrong sesame', async () => {
|
728
|
671
|
const sock = new RPCSocket(21004, "localhost")
|
729
|
|
- sock.connect('abasd').then(async (cli) => {
|
730
|
|
- if (!cli.test)
|
731
|
|
- done()
|
732
|
|
- else {
|
733
|
|
- done(new Error("Function supposed to be removed without sesame"))
|
734
|
|
- }
|
735
|
|
- cli.close()
|
736
|
|
- sock.close()
|
737
|
|
- })
|
|
672
|
+ const cli = await sock.connect('iamwrong')
|
|
673
|
+ expect(cli.test).to.not.exist
|
|
674
|
+ cli.close()
|
|
675
|
+ sock.close()
|
738
|
676
|
})
|
739
|
677
|
|
740
|
678
|
it('callback should work with sesame', (done) => {
|
|
@@ -775,21 +713,21 @@ describe('Error handling', () => {
|
775
|
713
|
a: 'a',
|
776
|
714
|
b: 'b'
|
777
|
715
|
})
|
778
|
|
- .then(r => {
|
779
|
|
- if (r != null)
|
780
|
|
- done(new Error("UNEXPECTED RESULT " + r))
|
781
|
|
- })
|
782
|
|
- .catch((e) => {
|
783
|
|
- if (e.message === errtxt)
|
784
|
|
- done()
|
785
|
|
- else
|
786
|
|
- done(e)
|
787
|
|
- })
|
788
|
|
- .finally(() => {
|
789
|
|
- cli.close()
|
790
|
|
- sock.close()
|
791
|
|
- server.close()
|
792
|
|
- })
|
|
716
|
+ .then(r => {
|
|
717
|
+ if (r != null)
|
|
718
|
+ done(new Error("UNEXPECTED RESULT " + r))
|
|
719
|
+ })
|
|
720
|
+ .catch((e) => {
|
|
721
|
+ if (e.message === errtxt)
|
|
722
|
+ done()
|
|
723
|
+ else
|
|
724
|
+ done(e)
|
|
725
|
+ })
|
|
726
|
+ .finally(() => {
|
|
727
|
+ cli.close()
|
|
728
|
+ sock.close()
|
|
729
|
+ server.close()
|
|
730
|
+ })
|
793
|
731
|
})
|
794
|
732
|
})
|
795
|
733
|
|
|
@@ -926,6 +864,7 @@ describe("Class binding", () => {
|
926
|
864
|
let serv: RPCServer<myExporterIfc>
|
927
|
865
|
let sock: RPCSocket & myExporterIfc
|
928
|
866
|
let allowed = true
|
|
867
|
+ const SESAME = 'xyz'
|
929
|
868
|
|
930
|
869
|
class MyExporter implements RPCExporter<myExporterIfc>{
|
931
|
870
|
name = "MyExporter" as "MyExporter"
|
|
@@ -960,12 +899,12 @@ describe("Class binding", () => {
|
960
|
899
|
if (exporter.name === 'MyExporter') {
|
961
|
900
|
if (!allowed) return false
|
962
|
901
|
allowed = false
|
963
|
|
- return sesame === 'xxx';
|
|
902
|
+ return sesame === SESAME;
|
964
|
903
|
} else {
|
965
|
904
|
return false
|
966
|
905
|
}
|
967
|
906
|
},
|
968
|
|
- sesame: "xxx"
|
|
907
|
+ sesame: SESAME
|
969
|
908
|
})
|
970
|
909
|
serv.listen(21004)
|
971
|
910
|
done()
|
|
@@ -973,7 +912,7 @@ describe("Class binding", () => {
|
973
|
912
|
|
974
|
913
|
beforeEach((done) => {
|
975
|
914
|
const s = new RPCSocket<myExporterIfc>(21004, 'localhost')
|
976
|
|
- s.connect("xxx").then(conn => {
|
|
915
|
+ s.connect(SESAME).then(conn => {
|
977
|
916
|
sock = conn
|
978
|
917
|
done()
|
979
|
918
|
})
|
|
@@ -1049,9 +988,9 @@ describe("attaching handlers before connecting", () => {
|
1049
|
988
|
})
|
1050
|
989
|
|
1051
|
990
|
sock.connect().then(_ => {
|
1052
|
|
- sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
|
1053
|
|
- console.log("X",x);
|
1054
|
|
-
|
|
991
|
+ sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
|
|
992
|
+ console.log("X", x);
|
|
993
|
+
|
1055
|
994
|
})
|
1056
|
995
|
}).catch(e => {
|
1057
|
996
|
console.log("unexpected connect catch clause");
|