|
@@ -1,45 +1,44 @@
|
1
|
|
-import { describe, it, Func } from "mocha";
|
2
|
|
-
|
3
|
|
-import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
|
4
|
|
-import * as uuidv4 from "uuid/v4"
|
5
|
|
-import { doesNotReject } from "assert";
|
6
|
|
-import { Socket } from "dgram";
|
|
1
|
+import { describe, it } from "mocha";
|
|
2
|
+import { RPCServer, RPCSocket } from '../Index'
|
7
|
3
|
import { RPCExporter } from "../src/Interfaces";
|
|
4
|
+import { ConnectedSocket } from "../src/Types";
|
|
5
|
+import * as log from 'why-is-node-running';
|
8
|
6
|
|
9
|
|
-const add = (...args:number[]) => {return args.reduce((a,b)=>a+b, 0)}
|
10
|
|
-function makeServer(){
|
|
7
|
+const add = (...args: number[]) => { return args.reduce((a, b) => a + b, 0) }
|
|
8
|
+function makeServer() {
|
11
|
9
|
let subcallback
|
12
|
|
- return new RPCServer<{ topic: string }>(21010, [{
|
13
|
|
- name: "test",
|
|
10
|
+ return new RPCServer(21010, [{
|
|
11
|
+ name: 'test',
|
14
|
12
|
exportRPCs: () => [
|
15
|
13
|
{
|
16
|
14
|
name: 'echo',
|
17
|
|
- call: async (s:string) => s,
|
18
|
|
- },{
|
|
15
|
+ call: async (s: string) => s,
|
|
16
|
+ }, {
|
19
|
17
|
name: 'simpleSubscribe',
|
20
|
|
- hook: async(callback) => {
|
21
|
|
- subcallback = callback
|
22
|
|
- return makeSubResponse<{topic: string}>({topic: "test"})
|
23
|
|
- }
|
24
|
|
- },{
|
|
18
|
+ hook: async (callback) => {
|
|
19
|
+ subcallback = callback
|
|
20
|
+ return { topic: "test" }
|
|
21
|
+ },
|
|
22
|
+ onClose: (res) => { }
|
|
23
|
+ }, {
|
25
|
24
|
name: 'subscribe',
|
26
|
25
|
hook: async (callback) => {
|
27
|
26
|
subcallback = callback
|
28
|
|
- return makeSubResponse<{topic: string}>({topic: "test"})
|
|
27
|
+ return { topic: "test" }
|
29
|
28
|
},
|
30
|
|
- onClose: (res, rpc) => {
|
31
|
|
- console.log("onClose", rpc.name === 'subscribe' && res?"OK":"")
|
32
|
|
- subcallback = null
|
|
29
|
+ onClose: (res, rpc) => {
|
|
30
|
+ console.log("onClose", rpc.name === 'subscribe' && res ? "OK" : "")
|
|
31
|
+ subcallback = null
|
33
|
32
|
},
|
34
|
|
- onCallback: (...args:any) => {
|
35
|
|
- console.log("onCallback", args[0] === "test" && args[1] === "callback"?"OK":"")
|
|
33
|
+ onCallback: (...args: any) => {
|
|
34
|
+ console.log("onCallback", args[0] === "test" && args[1] === "callback" ? "OK" : "")
|
36
|
35
|
}
|
37
|
36
|
},
|
38
|
37
|
add,
|
39
|
|
- function triggerCallback(...messages:any[]):number {return subcallback.apply({}, messages)},
|
|
38
|
+ function triggerCallback(...messages: any[]): number { return subcallback.apply({}, messages) },
|
40
|
39
|
]
|
41
|
|
- }],{
|
42
|
|
- connectionHandler: (socket) => { },
|
|
40
|
+ }], {
|
|
41
|
+ connectionHandler: (socket) => { },
|
43
|
42
|
closeHandler: (socket) => { },
|
44
|
43
|
errorHandler: (socket, err) => { throw err }
|
45
|
44
|
})
|
|
@@ -47,57 +46,58 @@ function makeServer(){
|
47
|
46
|
|
48
|
47
|
|
49
|
48
|
describe('RPCServer', () => {
|
50
|
|
- let server: RPCServer<{ topic: string }, any>
|
|
49
|
+ let client, server
|
|
50
|
+ const echo = (x) => x
|
51
|
51
|
|
52
|
|
- before(() => {
|
53
|
|
- server = makeServer()
|
54
|
|
- })
|
55
|
|
-
|
56
|
|
- after(() => {
|
57
|
|
- server.destroy()
|
58
|
|
- })
|
59
|
|
-
|
60
|
|
- it('should be able to use all kinds of RPC definitions', (done) => {
|
61
|
|
-
|
62
|
|
- const echo = (x) => x
|
63
|
|
-
|
64
|
|
- const server = new RPCServer(21003, [{
|
|
52
|
+ before(done => {
|
|
53
|
+ server = new RPCServer(21003, [{
|
65
|
54
|
name: 'HelloWorldRPCGroup',
|
66
|
|
- exportRPCs: () => [
|
|
55
|
+ exportRPCs: () => [
|
67
|
56
|
echo, //named function variable
|
68
|
|
- function echof(x){ return x }, //named function
|
|
57
|
+ function echof(x) { return x }, //named function
|
69
|
58
|
{
|
70
|
59
|
name: 'echoExplicit', //describing object
|
71
|
|
- call: async (x,y,z) => [x,y,z]
|
|
60
|
+ call: async (x, y, z) => [x, y, z]
|
72
|
61
|
}
|
73
|
62
|
]
|
74
|
63
|
}])
|
75
|
64
|
|
76
|
|
- const client = new RPCSocket(21003, 'localhost')
|
|
65
|
+ client = new RPCSocket(21003, 'localhost')
|
|
66
|
+ done()
|
|
67
|
+ })
|
|
68
|
+
|
|
69
|
+ after(done => {
|
|
70
|
+ client.destroy()
|
|
71
|
+ server.destroy()
|
|
72
|
+
|
|
73
|
+ done()
|
|
74
|
+ })
|
77
|
75
|
|
|
76
|
+ it('should be able to use all kinds of RPC definitions', (done) => {
|
78
|
77
|
client.connect().then(async () => {
|
79
|
78
|
const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
80
|
79
|
const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
81
|
|
- const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R','P','C!')
|
|
80
|
+ const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
|
81
|
+
|
82
|
82
|
|
83
|
|
- if(r0 === 'Hello' && r1 === 'World' && r2.join('') ==='RPC!'){
|
84
|
|
- client.destroy()
|
85
|
|
- server.destroy()
|
|
83
|
+ if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
|
86
|
84
|
done()
|
|
85
|
+ }else{
|
|
86
|
+ done(new Error("Bad response"))
|
87
|
87
|
}
|
88
|
88
|
})
|
89
|
89
|
})
|
90
|
90
|
|
91
|
91
|
it('new RPCServer() should fail on bad RPC', (done) => {
|
92
|
|
- try{
|
|
92
|
+ try {
|
93
|
93
|
new RPCServer(20001, [{
|
94
|
|
- name: "bad",
|
95
|
|
- exportRPCs: () => [
|
96
|
|
- (aaa,bbb,ccc) => { return aaa+bbb+ccc }
|
|
94
|
+ name: 'bad',
|
|
95
|
+ exportRPCs: () => [
|
|
96
|
+ (aaa, bbb, ccc) => { return aaa + bbb + ccc }
|
97
|
97
|
]
|
98
|
98
|
}])
|
99
|
99
|
done(new Error("Didn't fail with bad RPC"))
|
100
|
|
- }catch(badRPCError){
|
|
100
|
+ } catch (badRPCError) {
|
101
|
101
|
done()
|
102
|
102
|
}
|
103
|
103
|
})
|
|
@@ -106,9 +106,9 @@ describe('RPCServer', () => {
|
106
|
106
|
|
107
|
107
|
describe('RPCSocket', () => {
|
108
|
108
|
let client: RPCSocket
|
109
|
|
- let server: RPCServer<{topic: string}>
|
|
109
|
+ let server: RPCServer
|
110
|
110
|
|
111
|
|
- before(async() => {
|
|
111
|
+ before(async () => {
|
112
|
112
|
server = makeServer()
|
113
|
113
|
client = new RPCSocket(21010, "localhost")
|
114
|
114
|
return await client.connect()
|
|
@@ -122,27 +122,27 @@ describe('RPCSocket', () => {
|
122
|
122
|
|
123
|
123
|
it('should have rpc echo', (done) => {
|
124
|
124
|
client['test'].echo("x").then(x => {
|
125
|
|
- if(x === 'x')
|
|
125
|
+ if (x === 'x')
|
126
|
126
|
done()
|
127
|
127
|
else
|
128
|
|
- done(new Error('echo RPC response did not match'))
|
|
128
|
+ done(new Error('echo RPC response did not match'))
|
129
|
129
|
})
|
130
|
130
|
})
|
131
|
131
|
|
132
|
132
|
it('should add up to 6', (done) => {
|
133
|
|
- client['test'].add(1,2,3).then(x => {
|
134
|
|
- if(x === 6)
|
|
133
|
+ client['test'].add(1, 2, 3).then(x => {
|
|
134
|
+ if (x === 6)
|
135
|
135
|
done()
|
136
|
136
|
else
|
137
|
|
- done(new Error('add RPC response did not match'))
|
|
137
|
+ done(new Error('add RPC response did not match'))
|
138
|
138
|
})
|
139
|
139
|
})
|
140
|
140
|
|
141
|
141
|
it('should subscribe with success', (done) => {
|
142
|
142
|
client['test'].simpleSubscribe(console.log).then(res => {
|
143
|
|
- if(res.result === 'Success'){
|
|
143
|
+ if (res.topic === 'test') {
|
144
|
144
|
done()
|
145
|
|
- }else{
|
|
145
|
+ } else {
|
146
|
146
|
console.error(res)
|
147
|
147
|
done(new Error('Subscribe did not return success'))
|
148
|
148
|
}
|
|
@@ -151,72 +151,66 @@ describe('RPCSocket', () => {
|
151
|
151
|
|
152
|
152
|
it('subscribe should call back', (done) => {
|
153
|
153
|
client['test'].subscribe((...args: any) => {
|
154
|
|
- if(args[0] === "test" && args[1] === "callback")
|
|
154
|
+ if (args[0] === "test" && args[1] === "callback")
|
155
|
155
|
done()
|
156
|
|
- else
|
157
|
|
- done(new Error("Bad callback value "+ args))
|
158
|
|
- }).then( async () => {
|
|
156
|
+ else
|
|
157
|
+ done(new Error("Bad callback value " + args))
|
|
158
|
+ }).then(async () => {
|
159
|
159
|
await client['test'].triggerCallback("test", "callback")
|
160
|
160
|
})
|
161
|
161
|
})
|
162
|
162
|
|
163
|
163
|
it('simpleSubscribe should call back', (done) => {
|
164
|
164
|
client['test'].simpleSubscribe((...args: any) => {
|
165
|
|
- if(args[0] === "test_" && args[1] === "callback_")
|
|
165
|
+ if (args[0] === "test_" && args[1] === "callback_")
|
166
|
166
|
done()
|
167
|
|
- else
|
168
|
|
- done(new Error("Bad callback value "+ args))
|
169
|
|
- }).then( async () => {
|
|
167
|
+ else
|
|
168
|
+ done(new Error("Bad callback value " + args))
|
|
169
|
+ }).then(async () => {
|
170
|
170
|
await client['test'].triggerCallback("test_", "callback_")
|
171
|
171
|
})
|
172
|
172
|
})
|
173
|
173
|
})
|
174
|
174
|
|
175
|
175
|
describe('It should do unhook', () => {
|
176
|
|
- let candy = "OK"
|
|
176
|
+ const yesCandy = "OK"
|
|
177
|
+ const noCandy = "stolen"
|
|
178
|
+ let candy = yesCandy
|
177
|
179
|
let cb: Function
|
178
|
180
|
let cb2: Function
|
179
|
181
|
let client: RPCSocket
|
180
|
|
- let server: RPCServer<{topic: string}>
|
|
182
|
+ let server: RPCServer
|
181
|
183
|
|
182
|
|
- before(async() => {
|
183
|
|
- server = new RPCServer<{ topic: string }>(21010, [{
|
|
184
|
+ before(async () => {
|
|
185
|
+ server = new RPCServer(21010, [{
|
184
|
186
|
name: "test",
|
185
|
187
|
exportRPCs: () => [{
|
186
|
188
|
name: 'subscribe',
|
187
|
|
- hook: async(callback):Promise<SubscriptionResponse<{topic:string}>> => {
|
188
|
|
- cb = <Function> callback
|
189
|
|
- return {
|
190
|
|
- result: "Success",
|
191
|
|
- uuid: uuidv4(),
|
192
|
|
- topic: "test"
|
193
|
|
- }
|
|
189
|
+ hook: async (callback): Promise<void> => {
|
|
190
|
+ cb = <Function>callback
|
|
191
|
+ return
|
194
|
192
|
}
|
195
|
|
- },
|
|
193
|
+ },
|
196
|
194
|
{
|
197
|
195
|
name: 'subscribeWithParam',
|
198
|
|
- hook: async(param, callback):Promise<SubscriptionResponse<{topic:string}>> => {
|
199
|
|
-
|
200
|
|
- if(param != "OK"){
|
201
|
|
- console.log("param was"+ param);
|
|
196
|
+ hook: async (param, callback): Promise<{ uuid: string }> => {
|
|
197
|
+
|
|
198
|
+ if (param != "OK") {
|
|
199
|
+ console.log("param was" + param);
|
202
|
200
|
return {
|
203
|
|
- result: "Success",
|
204
|
201
|
uuid: "no",
|
205
|
|
- topic: "test"
|
206
|
202
|
}
|
207
|
203
|
}
|
208
|
|
- cb2 = <Function> callback
|
|
204
|
+ cb2 = <Function>callback
|
209
|
205
|
return {
|
210
|
|
- result: "Success",
|
211
|
206
|
uuid: "OK",
|
212
|
|
- topic: "test"
|
213
|
207
|
}
|
214
|
208
|
}
|
215
|
209
|
},
|
216
|
|
- function checkCandy():string { cb(candy); return candy },
|
217
|
|
- function stealCandy():string { candy = "_OK"; cb(candy); cb = () => {}; return candy }
|
218
|
|
- ]
|
219
|
|
- }],{
|
|
210
|
+ function publish(): string { cb(candy); return candy },
|
|
211
|
+ function unsubscribe(): string { candy = noCandy; cb(candy); cb = () => { }; return candy }
|
|
212
|
+ ]
|
|
213
|
+ }], {
|
220
|
214
|
connectionHandler: (socket) => { },
|
221
|
215
|
closeHandler: (socket) => { },
|
222
|
216
|
errorHandler: (socket, err) => { throw err }
|
|
@@ -231,69 +225,90 @@ describe('It should do unhook', () => {
|
231
|
225
|
})
|
232
|
226
|
|
233
|
227
|
it('Subscribe with param', (done) => {
|
234
|
|
- client['test'].subscribeWithParam("OK", c => {}).then( async (res: SubscriptionResponse) => {
|
235
|
|
- if(res.uuid === "OK"){
|
|
228
|
+ client['test'].subscribeWithParam("OK", c => { }).then(async (res) => {
|
|
229
|
+ if (res.uuid === candy) {
|
236
|
230
|
done()
|
237
|
|
- }else
|
238
|
|
- done(new Error("Results did not match "+res.uuid))
|
|
231
|
+ } else
|
|
232
|
+ done(new Error("Results did not match " + res.uuid))
|
239
|
233
|
})
|
240
|
234
|
})
|
241
|
235
|
|
|
236
|
+ let run = 0
|
|
237
|
+ const expected = [yesCandy, noCandy, noCandy, noCandy]
|
|
238
|
+
|
242
|
239
|
it('Unhook+unsubscribe should stop callbacks', (done) => {
|
243
|
|
- client['test'].subscribe(c => {}).then( async (res: SubscriptionResponse) => {
|
244
|
|
- const r1 = await client['test'].checkCandy()
|
245
|
|
- const r3 = await client['test'].stealCandy()
|
246
|
|
- client.unhook(res.uuid)
|
247
|
|
- const r2 = await client['test'].checkCandy()
|
248
|
|
- const r4 = await client['test'].checkCandy()
|
249
|
|
-
|
250
|
|
- if(r1 === "OK" && r3 === "_OK" && r2 === "_OK" && r4 === "_OK")
|
|
240
|
+
|
|
241
|
+ client['test'].subscribe(function myCallback(c){
|
|
242
|
+ if(run == 1)
|
|
243
|
+ (myCallback as any).destroy()
|
|
244
|
+
|
|
245
|
+ if (c !== expected[run++]) {
|
|
246
|
+ done(new Error(`Wrong candy '${c}' in iteration '${run - 1}'`))
|
|
247
|
+ }
|
|
248
|
+ }).then(async function(res){
|
|
249
|
+ const r1 = await client['test'].publish()
|
|
250
|
+ const r3 = await client['test'].unsubscribe()
|
|
251
|
+ const r2 = await client['test'].publish()
|
|
252
|
+ const r4 = await client['test'].publish()
|
|
253
|
+
|
|
254
|
+ if (r1 === yesCandy && r3 === noCandy && r2 === noCandy && r4 === noCandy)
|
251
|
255
|
done()
|
252
|
256
|
else
|
253
|
|
- done(new Error("Results did not match: "+[r1,r2,r3,r4]))
|
|
257
|
+ done(new Error("Results did not match: " + [r1, r2, r3, r4]))
|
254
|
258
|
})
|
255
|
259
|
})
|
256
|
260
|
})
|
257
|
261
|
|
|
262
|
+type topicDTO = { topic: string; }
|
258
|
263
|
|
259
|
|
-type SesameTestIfc = {
|
260
|
|
- test: {
|
261
|
|
- checkCandy: ()=>Promise<string>
|
262
|
|
- subscribe: (callback) => Promise<SubscriptionResponse<{ topic: string; }>>
|
263
|
|
- }
|
|
264
|
+type SesameTestIfc = {
|
|
265
|
+ test: {
|
|
266
|
+ checkCandy: () => Promise<string>
|
|
267
|
+ subscribe: (callback: Function) => Promise<topicDTO>
|
|
268
|
+ manyParams: <A=string,B=number,C=boolean,D=Object>(a:A, b:B, c:C, d:D) => Promise<[A, B, C, D]>
|
|
269
|
+ }
|
|
270
|
+
|
|
271
|
+ other: {
|
|
272
|
+ echo: (x:any) => Promise<any>
|
|
273
|
+ }
|
264
|
274
|
}
|
265
|
275
|
|
266
|
276
|
describe('Sesame should unlock the socket', () => {
|
267
|
277
|
let candy = "OK"
|
268
|
|
- let client: RPCSocket & SesameTestIfc
|
269
|
|
- let server: RPCServer
|
270
|
|
- let cb = (...args) => {}
|
|
278
|
+ let client: ConnectedSocket<SesameTestIfc>
|
|
279
|
+ let server: RPCServer<SesameTestIfc>
|
|
280
|
+ let cb: Function = (...args) => { }
|
271
|
281
|
|
272
|
282
|
before((done) => {
|
273
|
|
- server = new RPCServer(21004, [{
|
|
283
|
+ server = new RPCServer<SesameTestIfc>(21004, [{
|
274
|
284
|
name: "test",
|
275
|
285
|
exportRPCs: () => [
|
276
|
286
|
{
|
277
|
287
|
name: 'subscribe',
|
278
|
|
- hook: async(callback) => {
|
|
288
|
+ hook: async (callback) => {
|
279
|
289
|
cb = callback
|
280
|
|
- return <SubscriptionResponse>{
|
281
|
|
- result: "Success",
|
282
|
|
- uuid: uuidv4(),
|
|
290
|
+ return {
|
283
|
291
|
topic: 'test'
|
284
|
292
|
}
|
285
|
|
- }
|
|
293
|
+ },
|
|
294
|
+ onClose: (a) => { }
|
286
|
295
|
},
|
287
|
|
- async function checkCandy():Promise<string> { cb(candy); cb=()=>{}; return candy },
|
288
|
|
- async function manyParams(a,b,c,d) {return [a,b,c,d]}
|
289
|
|
- ]}
|
290
|
|
- ],{
|
291
|
|
- sesame: (_sesame) => _sesame === 'sesame!'
|
|
296
|
+ async function checkCandy() { cb(candy); cb = () => { }; return candy },
|
|
297
|
+ async function manyParams(a, b, c, d) { return [a, b, c, d] }
|
|
298
|
+ ],
|
|
299
|
+ },{
|
|
300
|
+ name: 'other',
|
|
301
|
+ exportRPCs: () => [
|
|
302
|
+ async function echo(x){return x}
|
|
303
|
+ ]
|
|
304
|
+
|
|
305
|
+ }], {
|
|
306
|
+ sesame: (_sesame) => _sesame === 'sesame!'
|
292
|
307
|
})
|
293
|
|
- const sock = new RPCSocket(21004, "localhost")
|
294
|
|
- sock.connect<SesameTestIfc>('sesame!').then(cli => {
|
|
308
|
+ const sock = new RPCSocket<SesameTestIfc>(21004, "localhost")
|
|
309
|
+ sock.connect('sesame!').then(cli => {
|
295
|
310
|
client = cli
|
296
|
|
- done()
|
|
311
|
+ done()
|
297
|
312
|
})
|
298
|
313
|
})
|
299
|
314
|
|
|
@@ -307,8 +322,8 @@ describe('Sesame should unlock the socket', () => {
|
307
|
322
|
})
|
308
|
323
|
|
309
|
324
|
it('should work with multiple params', (done) => {
|
310
|
|
- client.test['manyParams']('a','b','c','d').then(c => {
|
311
|
|
- if(c[0] == 'a' && c[1] === 'b' && c[2] === 'c' && c[3] === 'd')
|
|
325
|
+ client.test['manyParams']('a', 'b', 'c', 'd').then(c => {
|
|
326
|
+ if (c[0] == 'a' && c[1] === 'b' && c[2] === 'c' && c[3] === 'd')
|
312
|
327
|
done()
|
313
|
328
|
})
|
314
|
329
|
})
|
|
@@ -316,9 +331,9 @@ describe('Sesame should unlock the socket', () => {
|
316
|
331
|
it('should not work without sesame', (done) => {
|
317
|
332
|
const sock = new RPCSocket(21004, "localhost")
|
318
|
333
|
sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
|
319
|
|
- if(!cli.test)
|
|
334
|
+ if (!cli.test)
|
320
|
335
|
done()
|
321
|
|
- else{
|
|
336
|
+ else {
|
322
|
337
|
done(new Error("Function supposed to be removed without sesame"))
|
323
|
338
|
}
|
324
|
339
|
cli.destroy()
|
|
@@ -329,9 +344,9 @@ describe('Sesame should unlock the socket', () => {
|
329
|
344
|
it('should fail with wrong sesame', (done) => {
|
330
|
345
|
const sock = new RPCSocket(21004, "localhost")
|
331
|
346
|
sock.connect<SesameTestIfc>('abasd').then(async (cli) => {
|
332
|
|
- if(!cli.test)
|
|
347
|
+ if (!cli.test)
|
333
|
348
|
done()
|
334
|
|
- else{
|
|
349
|
+ else {
|
335
|
350
|
done(new Error("Function supposed to be removed without sesame"))
|
336
|
351
|
}
|
337
|
352
|
cli.destroy()
|
|
@@ -341,12 +356,12 @@ describe('Sesame should unlock the socket', () => {
|
341
|
356
|
|
342
|
357
|
it('callback should work with sesame', (done) => {
|
343
|
358
|
client.test.subscribe((c) => {
|
344
|
|
- if(c === candy){
|
|
359
|
+ if (c === candy) {
|
345
|
360
|
done()
|
346
|
361
|
}
|
347
|
362
|
}).then(d => {
|
348
|
|
- if(d.result !== 'Success')
|
349
|
|
- done('unexpected valid response')
|
|
363
|
+ if (d.topic !== 'test')
|
|
364
|
+ done('unexpected invalid response')
|
350
|
365
|
|
351
|
366
|
client.test.checkCandy()
|
352
|
367
|
})
|
|
@@ -354,51 +369,56 @@ describe('Sesame should unlock the socket', () => {
|
354
|
369
|
})
|
355
|
370
|
|
356
|
371
|
|
357
|
|
-describe('Error handling', ()=>{
|
358
|
|
-
|
359
|
|
- let createUser = async( user: {a:any,b:any}) => {
|
360
|
|
- throw new Error("BAD BAD BAD")
|
|
372
|
+describe('Error handling', () => {
|
|
373
|
+ const errtxt = "BAD BAD BAD"
|
|
374
|
+
|
|
375
|
+ let createUser = async (user: { a: any, b: any }) => {
|
|
376
|
+ throw new Error(errtxt)
|
361
|
377
|
}
|
362
|
378
|
|
363
|
|
- it("RPC throws on client without handler", (done)=>{
|
364
|
|
- let server = new RPCServer(21004, [ {
|
365
|
|
- name: 'createUser' as 'createUser',
|
|
379
|
+ it("RPC throws on client without handler", (done) => {
|
|
380
|
+ let server = new RPCServer(21004, [{
|
|
381
|
+ name: "createUser",
|
366
|
382
|
exportRPCs: () => [{
|
367
|
383
|
name: 'createUser' as 'createUser',
|
368
|
384
|
call: createUser
|
369
|
|
- }]}], {
|
|
385
|
+ }]
|
|
386
|
+ }], {
|
370
|
387
|
|
371
|
388
|
})
|
372
|
389
|
|
373
|
390
|
let sock = new RPCSocket(21004, 'localhost')
|
374
|
391
|
sock.connect().then((cli) => {
|
375
|
392
|
cli["createUser"]["createUser"]({
|
376
|
|
- a:'a',
|
377
|
|
- b:'b'
|
|
393
|
+ a: 'a',
|
|
394
|
+ b: 'b'
|
378
|
395
|
})
|
379
|
|
- .then(r => {
|
380
|
|
- if(r != null)
|
381
|
|
- done("UNEXPECTED RESULT " + r)
|
382
|
|
- })
|
383
|
|
- .catch((e) => {
|
384
|
|
- //console.log("EXPECTED CLIENT EXCEPTION", String(e));
|
385
|
|
- done()
|
386
|
|
- })
|
387
|
|
- .finally(() => {
|
388
|
|
- cli.destroy()
|
389
|
|
- sock.destroy()
|
390
|
|
- server.destroy()
|
391
|
|
- })
|
392
|
|
- })
|
393
|
|
- })
|
394
|
|
-
|
395
|
|
- it("RPC throws on server with handler", (done)=>{
|
396
|
|
- let server = new RPCServer(21004, [ {
|
397
|
|
- name: 'createUser' as 'createUser',
|
|
396
|
+ .then(r => {
|
|
397
|
+ if (r != null)
|
|
398
|
+ done(new Error("UNEXPECTED RESULT " + r))
|
|
399
|
+ })
|
|
400
|
+ .catch((e) => {
|
|
401
|
+ if (e.message === errtxt)
|
|
402
|
+ done()
|
|
403
|
+ else
|
|
404
|
+ done(e)
|
|
405
|
+ })
|
|
406
|
+ .finally(() => {
|
|
407
|
+ cli.destroy()
|
|
408
|
+ sock.destroy()
|
|
409
|
+ server.destroy()
|
|
410
|
+ })
|
|
411
|
+ })
|
|
412
|
+ })
|
|
413
|
+
|
|
414
|
+ it("RPC throws on server with handler", (done) => {
|
|
415
|
+ let server = new RPCServer(21004, [{
|
|
416
|
+ name: "createUser",
|
398
|
417
|
exportRPCs: () => [{
|
399
|
418
|
name: 'createUser' as 'createUser',
|
400
|
419
|
call: createUser
|
401
|
|
- }]}], {
|
|
420
|
+ }]
|
|
421
|
+ }], {
|
402
|
422
|
errorHandler: (socket, e, rpcName, args) => {
|
403
|
423
|
done()
|
404
|
424
|
}
|
|
@@ -407,41 +427,44 @@ describe('Error handling', ()=>{
|
407
|
427
|
let sock = new RPCSocket(21004, 'localhost')
|
408
|
428
|
sock.connect().then((cli) => {
|
409
|
429
|
cli["createUser"]["createUser"]({
|
410
|
|
- a:'a',
|
411
|
|
- b:'b'
|
412
|
|
- })
|
413
|
|
- .then(r => {
|
414
|
|
- if(r != null)
|
415
|
|
- done("UNEXPECTED RESULT " + r)
|
416
|
|
- })
|
417
|
|
- .catch((e) => {
|
418
|
|
- done("UNEXPECTED CLIENT ERROR " + e)
|
419
|
|
- done(e)
|
420
|
|
- })
|
421
|
|
- .finally(() => {
|
422
|
|
- cli.destroy()
|
423
|
|
- sock.destroy()
|
424
|
|
- server.destroy()
|
|
430
|
+ a: 'a',
|
|
431
|
+ b: 'b'
|
425
|
432
|
})
|
|
433
|
+ .then(r => {
|
|
434
|
+ if (r != null)
|
|
435
|
+ done("UNEXPECTED RESULT " + r)
|
|
436
|
+ })
|
|
437
|
+ .catch((e) => {
|
|
438
|
+ done("UNEXPECTED CLIENT ERROR " + e)
|
|
439
|
+ done(e)
|
|
440
|
+ })
|
|
441
|
+ .finally(() => {
|
|
442
|
+ cli.destroy()
|
|
443
|
+ sock.destroy()
|
|
444
|
+ server.destroy()
|
|
445
|
+ })
|
426
|
446
|
})
|
427
|
447
|
})
|
428
|
448
|
})
|
429
|
449
|
|
430
|
450
|
|
431
|
|
-describe("Errorhandler functionality", ()=>{
|
432
|
|
- let createUser = async( user: {a:any,b:any}) => {
|
433
|
|
- throw new Error("BAD BAD BAD")
|
|
451
|
+describe("Errorhandler functionality", () => {
|
|
452
|
+ const errtxt = "BAD BAD BAD"
|
|
453
|
+
|
|
454
|
+ let createUser = async (user: { a: any, b: any }) => {
|
|
455
|
+ throw new Error(errtxt)
|
434
|
456
|
}
|
435
|
457
|
|
436
|
|
- it("correct values are passed to the handler", (done)=>{
|
437
|
|
- let server = new RPCServer(21004, [ {
|
438
|
|
- name: 'createUser' as 'createUser',
|
|
458
|
+ it("correct values are passed to the handler", (done) => {
|
|
459
|
+ let server = new RPCServer(21004, [{
|
|
460
|
+ name: "createUser",
|
439
|
461
|
exportRPCs: () => [{
|
440
|
462
|
name: 'createUser' as 'createUser',
|
441
|
463
|
call: createUser
|
442
|
|
- }]}], {
|
|
464
|
+ }]
|
|
465
|
+ }], {
|
443
|
466
|
errorHandler: (socket, e, rpcName, args) => {
|
444
|
|
- if(e.message === "BAD BAD BAD" && rpcName === "createUser" && args[0]['a'] === 'a' && args[0]['b'] === 'b')
|
|
467
|
+ if (e.message === errtxt && rpcName === "createUser" && args[0]['a'] === 'a' && args[0]['b'] === 'b')
|
445
|
468
|
done()
|
446
|
469
|
}
|
447
|
470
|
})
|
|
@@ -449,97 +472,97 @@ describe("Errorhandler functionality", ()=>{
|
449
|
472
|
let sock = new RPCSocket(21004, 'localhost')
|
450
|
473
|
sock.connect().then((cli) => {
|
451
|
474
|
cli["createUser"]["createUser"]({
|
452
|
|
- a:'a',
|
453
|
|
- b:'b'
|
454
|
|
- })
|
455
|
|
- .then(r => {
|
456
|
|
- if(r != null)
|
457
|
|
- done("UNEXPECTED RESULT " + r)
|
458
|
|
- })
|
459
|
|
- .catch((e) => {
|
460
|
|
- done("UNEXPECTED CLIENT ERROR " + e)
|
461
|
|
- done(e)
|
|
475
|
+ a: 'a',
|
|
476
|
+ b: 'b'
|
462
|
477
|
})
|
463
|
|
- .finally(() => {
|
464
|
|
- cli.destroy()
|
465
|
|
- sock.destroy()
|
466
|
|
- server.destroy()
|
467
|
|
- })
|
468
|
|
- })
|
469
|
|
- })
|
470
|
|
-
|
471
|
|
- it("handler sees sesame", (done)=>{
|
|
478
|
+ .then(r => {
|
|
479
|
+ if (r != null)
|
|
480
|
+ done("UNEXPECTED RESULT " + r)
|
|
481
|
+ })
|
|
482
|
+ .catch((e) => {
|
|
483
|
+ done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
|
|
484
|
+ })
|
|
485
|
+ .finally(() => {
|
|
486
|
+ cli.destroy()
|
|
487
|
+ sock.destroy()
|
|
488
|
+ server.destroy()
|
|
489
|
+ })
|
|
490
|
+ })
|
|
491
|
+ })
|
|
492
|
+
|
|
493
|
+ it("handler sees sesame", (done) => {
|
472
|
494
|
let sesame = "AAAAAAAAAAAAAAA"
|
473
|
|
- let server = new RPCServer(21004, [ {
|
474
|
|
- name: 'createUser' as 'createUser',
|
|
495
|
+ let server = new RPCServer(21004, [{
|
|
496
|
+ name: "createUser" as "createUser",
|
475
|
497
|
exportRPCs: () => [{
|
476
|
498
|
name: 'createUser' as 'createUser',
|
477
|
499
|
call: createUser
|
478
|
|
- }]}], {
|
|
500
|
+ }]
|
|
501
|
+ }], {
|
479
|
502
|
sesame: sesame,
|
480
|
503
|
errorHandler: (socket, e, rpcName, args) => {
|
481
|
|
- if(e.message === "BAD BAD BAD" && rpcName === "createUser" && args[0] === sesame && args[1]['a'] === 'a' && args[1]['b'] === 'b')
|
|
504
|
+ if (e.message === errtxt && rpcName === "createUser" && args[0] === sesame && args[1]['a'] === 'a' && args[1]['b'] === 'b')
|
482
|
505
|
done()
|
483
|
506
|
}
|
484
|
|
-
|
|
507
|
+
|
485
|
508
|
})
|
486
|
509
|
|
487
|
510
|
let sock = new RPCSocket(21004, 'localhost')
|
488
|
511
|
sock.connect(sesame).then((cli) => {
|
489
|
512
|
cli["createUser"]["createUser"]({
|
490
|
|
- a:'a',
|
491
|
|
- b:'b'
|
492
|
|
- })
|
493
|
|
- .then(r => {
|
494
|
|
- if(r != null)
|
495
|
|
- done("UNEXPECTED RESULT " + r)
|
496
|
|
- })
|
497
|
|
- .catch((e) => {
|
498
|
|
- done("UNEXPECTED CLIENT ERROR " + e)
|
499
|
|
- done(e)
|
500
|
|
- })
|
501
|
|
- .finally(() => {
|
502
|
|
- cli.destroy()
|
503
|
|
- sock.destroy()
|
504
|
|
- server.destroy()
|
|
513
|
+ a: 'a',
|
|
514
|
+ b: 'b'
|
505
|
515
|
})
|
|
516
|
+ .then(r => {
|
|
517
|
+ if (r != null)
|
|
518
|
+ done("UNEXPECTED RESULT " + r)
|
|
519
|
+ })
|
|
520
|
+ .catch((e) => {
|
|
521
|
+ done("UNEXPECTED CLIENT ERROR " + e)
|
|
522
|
+ done(e)
|
|
523
|
+ })
|
|
524
|
+ .finally(() => {
|
|
525
|
+ cli.destroy()
|
|
526
|
+ sock.destroy()
|
|
527
|
+ server.destroy()
|
|
528
|
+ })
|
506
|
529
|
})
|
507
|
530
|
})
|
508
|
531
|
})
|
509
|
532
|
|
510
|
533
|
type myExporterIfc = {
|
511
|
534
|
MyExporter: {
|
512
|
|
- myRPC: ()=>Promise<string>
|
|
535
|
+ myRPC: () => Promise<string>
|
513
|
536
|
}
|
514
|
537
|
}
|
515
|
538
|
|
516
|
539
|
|
517
|
|
-describe("Class binding", ()=>{
|
|
540
|
+describe("Class binding", () => {
|
518
|
541
|
|
519
|
|
- let exporter1 : MyExporter
|
520
|
|
- let serv : RPCServer<{}, myExporterIfc>
|
|
542
|
+ let exporter1: MyExporter
|
|
543
|
+ let serv: RPCServer<myExporterIfc>
|
521
|
544
|
let sock: RPCSocket & myExporterIfc
|
522
|
545
|
let allowed = true
|
523
|
546
|
|
524
|
547
|
class MyExporter implements RPCExporter<myExporterIfc>{
|
525
|
|
- name = "MyExporter" as "MyExporter";
|
|
548
|
+ name = "MyExporter" as "MyExporter"
|
526
|
549
|
exportRPCs = () => [
|
527
|
550
|
this.myRPC
|
528
|
551
|
]
|
529
|
552
|
|
530
|
553
|
myRPC = async () => {
|
531
|
|
- serv.setExporters([new MyOtherExporter])
|
|
554
|
+ //serv.setExporters([new MyOtherExporter])
|
532
|
555
|
return "Hello World"
|
533
|
556
|
}
|
534
|
557
|
}
|
535
|
558
|
|
536
|
559
|
class MyOtherExporter implements RPCExporter<myExporterIfc>{
|
537
|
|
- name = "MyExporter" as "MyExporter";
|
|
560
|
+ name = "MyExporter" as "MyExporter"
|
538
|
561
|
exportRPCs = () => [
|
539
|
562
|
this.myRPC
|
540
|
563
|
]
|
541
|
564
|
|
542
|
|
- myRPC = async () => {
|
|
565
|
+ myRPC = async () => {
|
543
|
566
|
return "Hello Borld"
|
544
|
567
|
}
|
545
|
568
|
|
|
@@ -547,24 +570,22 @@ describe("Class binding", ()=>{
|
547
|
570
|
|
548
|
571
|
before(done => {
|
549
|
572
|
exporter1 = new MyExporter()
|
550
|
|
- serv = new RPCServer<{}, myExporterIfc>(21004, [exporter1], {
|
551
|
|
- accessFilter: async (sesame,exporter) => {
|
552
|
|
- switch(exporter.name){
|
553
|
|
- case "MyExporter":
|
554
|
|
- if(!allowed) return false
|
555
|
|
- allowed = false
|
556
|
|
- return sesame==='xxx';
|
557
|
|
- default:
|
558
|
|
- return false
|
|
573
|
+ serv = new RPCServer<myExporterIfc>(21004, [exporter1], {
|
|
574
|
+ accessFilter: async (sesame, exporter) => {
|
|
575
|
+ if(exporter.name === 'MyExporter'){
|
|
576
|
+ if (!allowed) return false
|
|
577
|
+ allowed = false
|
|
578
|
+ return sesame === 'xxx';
|
|
579
|
+ }else{
|
|
580
|
+ return false
|
559
|
581
|
}
|
560
|
582
|
},
|
561
|
583
|
sesame: "xxx"
|
562
|
584
|
})
|
563
|
585
|
done()
|
564
|
586
|
})
|
565
|
|
-
|
566
|
|
- beforeEach((done)=>{
|
567
|
|
-
|
|
587
|
+
|
|
588
|
+ beforeEach((done) => {
|
568
|
589
|
const s = new RPCSocket(21004, 'localhost')
|
569
|
590
|
s.connect<myExporterIfc>("xxx").then(conn => {
|
570
|
591
|
sock = conn
|
|
@@ -572,7 +593,7 @@ describe("Class binding", ()=>{
|
572
|
593
|
})
|
573
|
594
|
})
|
574
|
595
|
|
575
|
|
- afterEach(done => {
|
|
596
|
+ afterEach((done) => {
|
576
|
597
|
sock.destroy()
|
577
|
598
|
done()
|
578
|
599
|
})
|
|
@@ -581,7 +602,11 @@ describe("Class binding", ()=>{
|
581
|
602
|
serv.destroy()
|
582
|
603
|
})
|
583
|
604
|
|
584
|
|
- it("binds correctly", (done)=>{
|
|
605
|
+ /* The server-side socket will enter a 30s timeout if destroyed by a RPC.
|
|
606
|
+ to mitigate the impact on testing time these are not run.
|
|
607
|
+
|
|
608
|
+ it("binds correctly", function(done){
|
|
609
|
+ this.timeout(1000)
|
585
|
610
|
sock['MyExporter'].myRPC().then((res) => {
|
586
|
611
|
done(new Error(res))
|
587
|
612
|
}).catch(e => {
|
|
@@ -592,31 +617,42 @@ describe("Class binding", ()=>{
|
592
|
617
|
})
|
593
|
618
|
|
594
|
619
|
it("changes exporters", (done) => {
|
|
620
|
+
|
595
|
621
|
sock['MyExporter'].myRPC().then((res) => {
|
596
|
|
- if(res === "Hello Borld")
|
|
622
|
+ if (res === "Hello Borld")
|
597
|
623
|
done()
|
598
|
624
|
else
|
599
|
625
|
done(new Error(res))
|
600
|
626
|
})
|
601
|
627
|
})
|
|
628
|
+ */
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+ it("use sesameFilter for available", (done) => {
|
|
632
|
+ if (sock['MyExporter']){
|
|
633
|
+ allowed = false
|
|
634
|
+ done()
|
|
635
|
+ }
|
|
636
|
+ else done(new Error("RPC supposed to be here"))
|
|
637
|
+ })
|
602
|
638
|
|
603
|
639
|
it("use sesameFilter", (done) => {
|
604
|
|
- if(!sock['MyExporter']) done()
|
|
640
|
+ if (!sock['MyExporter']) done()
|
605
|
641
|
else done(new Error("RPC supposed to be gone"))
|
606
|
642
|
})
|
607
|
643
|
})
|
608
|
644
|
|
609
|
645
|
|
610
|
|
-describe("attaching handlers before connecting", ()=>{
|
611
|
|
- it("fires error if server is unreachable", (done)=>{
|
|
646
|
+describe("attaching handlers before connecting", () => {
|
|
647
|
+ it("fires error if server is unreachable", (done) => {
|
612
|
648
|
const sock = new RPCSocket(21004, 'localhost')
|
613
|
649
|
let errorHandleCount = 0
|
614
|
650
|
|
615
|
651
|
sock.on('error', (err) => {
|
616
|
652
|
//attached listener fires first
|
617
|
|
- if(errorHandleCount != 0){
|
|
653
|
+ if (errorHandleCount != 0) {
|
618
|
654
|
console.log("Error handler didn't fire first");
|
619
|
|
- }else{
|
|
655
|
+ } else {
|
620
|
656
|
errorHandleCount++
|
621
|
657
|
}
|
622
|
658
|
})
|
|
@@ -625,16 +661,16 @@ describe("attaching handlers before connecting", ()=>{
|
625
|
661
|
console.log("Unexpected successful connect")
|
626
|
662
|
}).catch(e => {
|
627
|
663
|
//catch clause fires second
|
628
|
|
- if(errorHandleCount != 1){
|
|
664
|
+ if (errorHandleCount != 1) {
|
629
|
665
|
console.log("catch clause didn't fire second");
|
630
|
|
- }else{
|
|
666
|
+ } else {
|
631
|
667
|
sock.destroy()
|
632
|
668
|
done()
|
633
|
669
|
}
|
634
|
670
|
})
|
635
|
671
|
})
|
636
|
672
|
|
637
|
|
- it("fires error if call is unknown", (done)=>{
|
|
673
|
+ it("fires error if call is unknown", (done) => {
|
638
|
674
|
const serv = new RPCServer(21004)
|
639
|
675
|
const sock = new RPCSocket(21004, 'localhost')
|
640
|
676
|
|
|
@@ -645,14 +681,14 @@ describe("attaching handlers before connecting", ()=>{
|
645
|
681
|
})
|
646
|
682
|
|
647
|
683
|
sock.connect().then(_ => {
|
648
|
|
- sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */})
|
|
684
|
+ sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */ })
|
649
|
685
|
}).catch(e => {
|
650
|
686
|
console.log("unexpected connect catch clause");
|
651
|
687
|
done(e)
|
652
|
688
|
})
|
653
|
689
|
})
|
654
|
690
|
|
655
|
|
- it("demands catch on method invocation if call is unknown", (done)=>{
|
|
691
|
+ it("demands catch on method invocation if call is unknown", (done) => {
|
656
|
692
|
const serv = new RPCServer(21004)
|
657
|
693
|
const sock = new RPCSocket(21004, 'localhost')
|
658
|
694
|
|
|
@@ -667,4 +703,11 @@ describe("attaching handlers before connecting", ()=>{
|
667
|
703
|
done(e)
|
668
|
704
|
})
|
669
|
705
|
})
|
|
706
|
+
|
|
707
|
+})
|
|
708
|
+
|
|
709
|
+describe('finally', () => {
|
|
710
|
+ it('print open handles (Ignore `DNSCHANNEL` and `Immediate`)', () => {
|
|
711
|
+ log()
|
|
712
|
+ })
|
670
|
713
|
})
|