Переглянути джерело

tempalte strings & bugfixes

master
peter 4 роки тому
джерело
коміт
d36f2053c3
3 змінених файлів з 67 додано та 67 видалено
  1. 18
    25
      src/Frontend.ts
  2. 24
    27
      src/Utils.ts
  3. 25
    15
      test/Test.ts

+ 18
- 25
src/Frontend.ts Переглянути файл

@@ -4,7 +4,7 @@ import bsock = require('bsock');
4 4
 
5 5
 import * as T from './Types'; 
6 6
 import * as I from './Interfaces';
7
-import { stripAfterEquals } from './Utils';
7
+import { stripAfterEquals, appendComma } from './Utils';
8 8
 
9 9
 
10 10
 
@@ -127,10 +127,9 @@ export class RPCSocket implements I.Socket{
127 127
     private callGenerator(fnName: string, fnArgs:string[], sesame?:string): T.AnyFunction{
128 128
         const headerArgs = fnArgs.join(",")
129 129
         const argParams = fnArgs.map(stripAfterEquals).join(",")
130
-        if(!sesame)
131
-            return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
132
-        else 
133
-            return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", "'+sesame+'", '+argParams+')} )()' )
130
+        sesame = appendComma(sesame)
131
+
132
+        return eval(`async (${headerArgs}) => { return await this.socket.call("${fnName}", ${sesame} ${argParams})}`)
134 133
     }
135 134
 
136 135
     /**
@@ -140,25 +139,19 @@ export class RPCSocket implements I.Socket{
140 139
      */
141 140
     private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
142 141
         fnArgs.pop()
143
-        const headerArgs = fnArgs.join(",")
142
+        let headerArgs = fnArgs.join(",")
144 143
         const argParams = fnArgs.map(stripAfterEquals).join(",")
145
-
146
-        if(!sesame){
147
-            return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
148
-                const r = await this.socket.call("`+fnName+`", `+argParams+`)
149
-                if(r && r.result === 'Success'){
150
-                    this.socket.hook(r.uuid, callback)
151
-                }
152
-                return r
153
-            } )()` )
154
-        }else{
155
-            return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
156
-                const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
157
-                if(r && r.result === 'Success'){
158
-                    this.socket.hook(r.uuid, callback)
159
-                }
160
-                return r
161
-            } )()` )
162
-        }
144
+        sesame = appendComma(sesame)
145
+        headerArgs = appendComma(headerArgs) 
146
+
147
+        return eval( `
148
+        async (${headerArgs} callback) => {
149
+            const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
150
+            if(r && r.result === 'Success'){
151
+                this.socket.hook(r.uuid, callback)
152
+                this.socket.on('error', e => this.socket.unhook(r.uuid))
153
+            }
154
+            return r
155
+        }`)
163 156
     }
164
-}
157
+}

+ 24
- 27
src/Utils.ts Переглянути файл

@@ -10,7 +10,7 @@ import { SubscriptionResponse } from "./Types";
10 10
  * @param owner The owning RPC group's name
11 11
  * @throws Error on RPC without name property
12 12
  */
13
-export const rpcToRpcinfo = <SubResT = {}>(rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
13
+export const rpcToRpcinfo = <SubResT = {}>(socket: I.Socket, rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
14 14
     switch (typeof rpc){
15 15
         case  "object":
16 16
             if(rpc['call']){
@@ -19,7 +19,7 @@ export const rpcToRpcinfo = <SubResT = {}>(rpc : T.RPC<any, any, SubResT>, owner
19 19
                     argNames: extractArgs(rpc['call']),
20 20
                     type: "Call",
21 21
                     name: rpc.name,
22
-                    call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); throw makeError(rpc.name)}:rpc['call'], // check & remove sesame 
22
+                    call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); socket.destroy()}:rpc['call'], // check & remove sesame 
23 23
                 }
24 24
             }else{
25 25
                 const generator = hookGenerator(<T.HookRPC<any, any, any>>rpc, errorHandler, sesame)
@@ -37,7 +37,7 @@ RPC did not provide a name.
37 37
 \nUse 'funtion name(..){ .. }' syntax instead.
38 38
 \n
39 39
 \n<------------OFFENDING RPC:
40
-\n`+rpc.toString()+`
40
+\n${rpc.toString()}
41 41
 \n>------------OFFENDING RPC`)
42 42
             return {
43 43
                 owner : owner,
@@ -61,7 +61,7 @@ export function rpcHooker<SubResT = {}>(socket: I.Socket, exporter:I.RPCExporter
61 61
     const RPCs = [...exporter.exportRPCs()]
62 62
 
63 63
 
64
-    return RPCs.map(rpc => rpcToRpcinfo(rpc, owner, errorHandler, sesame))
64
+    return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
65 65
     .map(info => {
66 66
         const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
67 67
         const ret:any = info
@@ -111,41 +111,33 @@ export function stripAfterEquals(str:string):string{
111 111
  * @returns A {@link HookFunction}
112 112
  */
113 113
 const hookGenerator = (rpc:T.HookRPC<any, any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { 
114
-    const argsArr = extractArgs(rpc.hook)
114
+    let argsArr = extractArgs(rpc.hook)
115 115
     argsArr.pop() //remove 'callback' from the end
116
-    const argsStr = argsArr.join(',')
117
-
118
-    if(sesameFn){
119
-        const args = ['sesame', ...argsArr].join(',')
120
-        return eval(`(socket) => async (`+args+`) => {
121
-            try{
122
-                if(!sesameFn(sesame)) return
123
-                const res = await rpc.hook(`+argsStr+(argsStr.length!==0?',':'')+` (...cbargs) => {
124
-                    if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
125
-                    socket.call.apply(socket, [res.uuid, ...cbargs])
126
-                })
127
-                return res
128
-            }catch(e){
129
-                errorHandler(socket)(e, rpc.name, [`+args+`])
130
-            }
131
-        }`)
132
-    }
133
-    const args = argsArr.join(',')
134
-    return eval(`(socket) => async (`+args+`) => {
116
+    let callArgs = argsArr.join(',')
117
+
118
+    const args = sesameFn?(['sesame', ...argsArr].join(','))
119
+                         :callArgs
120
+
121
+    callArgs = appendComma(callArgs)
122
+
123
+    //note rpc.hook is the associated RPC, not a socket.hook
124
+    return eval(`
125
+    (socket) => async (${args}) => {
135 126
         try{
136
-            const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => {
127
+            if(sesameFn && !sesameFn(sesame)) return
128
+            const res = await rpc.hook(${callArgs} (...cbargs) => {
137 129
                 if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
138 130
                 socket.call.apply(socket, [res.uuid, ...cbargs])
139 131
             })
140 132
             return res
141 133
         }catch(e){
142
-            errorHandler(socket)(e, rpc.name, [`+args+`])
134
+            errorHandler(socket)(e, ${rpc.name}, [${args}])
143 135
         }
144 136
     }`)
145 137
 }
146 138
 
147 139
 const makeError = (callName: string) => {
148
-    return new Error("Unhandled Promise rejection: Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
140
+    return new Error("Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
149 141
 }
150 142
 
151 143
 /**
@@ -179,3 +171,8 @@ export function makeSesameFunction (sesame : T.SesameFunction | string) : T.Sesa
179 171
         return testSesame === sesame 
180 172
     }
181 173
 }
174
+
175
+
176
+export function appendComma(s?:string):string{
177
+    return s?`'${s}',`:"" 
178
+}

+ 25
- 15
test/Test.ts Переглянути файл

@@ -48,13 +48,12 @@ function makeServer(){
48 48
 describe('RPCServer', () => {
49 49
     let server: RPCServer<{ topic: string }, any>
50 50
 
51
-    before((done) => {
51
+    before(() => {
52 52
         server = makeServer()
53
-        done()
54 53
     })
55 54
     
56
-    after(async() => {
57
-        await server.destroy()
55
+    after(() => {
56
+        server.destroy()
58 57
     })
59 58
 
60 59
     it('should be able to use all kinds of RPC definitions', (done) => {
@@ -239,7 +238,7 @@ describe('Sesame should unlock the socket', () => {
239 238
     let server: RPCServer 
240 239
     let cb = (...args) => {}
241 240
 
242
-    before(async() => {
241
+    before((done) => {
243 242
         server = new RPCServer(21004, [{
244 243
             name: "test",
245 244
             exportRPCs: () => [
@@ -261,7 +260,10 @@ describe('Sesame should unlock the socket', () => {
261 260
             sesame: (_sesame) => _sesame === 'sesame!' 
262 261
         })
263 262
         const sock = new RPCSocket(21004, "localhost")
264
-        client = await sock.connect<SesameTestIfc>('sesame!')
263
+        sock.connect<SesameTestIfc>('sesame!').then(cli => {
264
+            client = cli
265
+            done() 
266
+        })
265 267
     })
266 268
 
267 269
     after(() => {
@@ -282,13 +284,14 @@ describe('Sesame should unlock the socket', () => {
282 284
 
283 285
     it('should not work without sesame', (done) => {
284 286
         const sock = new RPCSocket(21004, "localhost")
285
-        sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
286
-            c.test.checkCandy().then(d => {
287
-                done()
287
+        sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
288
+            cli.test.checkCandy().then(d => {
289
+                done(d)
288 290
             }).catch(e => {
289 291
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
290 292
                 done()
291 293
             }).finally(() => {
294
+                cli.destroy()
292 295
                 sock.destroy()
293 296
             })
294 297
         })
@@ -296,14 +299,15 @@ describe('Sesame should unlock the socket', () => {
296 299
 
297 300
     it('should fail with wrong sesame', (done) => {
298 301
         const sock = new RPCSocket(21004, "localhost")
299
-        sock.connect<SesameTestIfc>('abasd').then(async (c) => {
300
-            c.test.checkCandy().then(d => {
302
+        sock.connect<SesameTestIfc>('abasd').then(async (cli) => {
303
+            cli.test.checkCandy().then(d => {
301 304
                 done("should not be able to get candy")
302 305
             }).catch(e => {
303 306
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
304 307
                 done()
305 308
             }).finally(() => {
306 309
                 sock.destroy()
310
+                cli.destroy()
307 311
             })
308 312
         })
309 313
     })
@@ -323,8 +327,8 @@ describe('Sesame should unlock the socket', () => {
323 327
 
324 328
     it('callback should not work without sesame', (done) => {
325 329
         const sock = new RPCSocket(21004, "localhost")
326
-        sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
327
-            c.test.subscribe((c) => {
330
+        sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
331
+            cli.test.subscribe((c) => {
328 332
                 console.log("CALLBACK TRIGGERED UNEXPECTED");
329 333
                 
330 334
                 if(c === candy)
@@ -333,16 +337,17 @@ describe('Sesame should unlock the socket', () => {
333 337
                 await client.test.checkCandy()
334 338
                 if(d == null){
335 339
                     done()
340
+
336 341
                 }else
337 342
                     done('unexpected valid response '+(d) )
338
-                c.destroy()
343
+            }).finally(() => {
344
+                sock.destroy()
339 345
             })
340 346
         })
341 347
     })
342 348
 })
343 349
 
344 350
 
345
-
346 351
 describe('Error handling', ()=>{
347 352
     
348 353
     let createUser = async( user: {a:any,b:any}) => {
@@ -374,6 +379,7 @@ describe('Error handling', ()=>{
374 379
                 done()
375 380
             })
376 381
             .finally(() => {
382
+                cli.destroy()
377 383
                 sock.destroy()
378 384
                 server.destroy()
379 385
             })
@@ -407,6 +413,7 @@ describe('Error handling', ()=>{
407 413
                 done(e)
408 414
             })
409 415
             .finally(() => {
416
+                cli.destroy()
410 417
                 sock.destroy()
411 418
                 server.destroy()
412 419
             })
@@ -414,6 +421,7 @@ describe('Error handling', ()=>{
414 421
     })
415 422
 })
416 423
 
424
+
417 425
 describe("Errorhandler functionality", ()=>{
418 426
     let createUser = async( user: {a:any,b:any}) => {
419 427
         throw new Error("BAD BAD BAD")
@@ -447,6 +455,7 @@ describe("Errorhandler functionality", ()=>{
447 455
                 done(e)
448 456
             })
449 457
             .finally(() => {
458
+                cli.destroy()
450 459
                 sock.destroy()
451 460
                 server.destroy()
452 461
             })
@@ -484,6 +493,7 @@ describe("Errorhandler functionality", ()=>{
484 493
                 done(e)
485 494
             })
486 495
             .finally(() => {
496
+                cli.destroy()
487 497
                 sock.destroy()
488 498
                 server.destroy()
489 499
             })

Завантаження…
Відмінити
Зберегти