Преглед на файлове

before rewrite to have callbacks as FIRST parameter

master
nitowa преди 2 години
родител
ревизия
b2ffbbfa48
променени са 6 файла, в които са добавени 182 реда и са изтрити 126 реда
  1. 16
    10
      src/Frontend.ts
  2. 2
    2
      src/Interfaces.ts
  3. 2
    1
      src/Strings.ts
  4. 50
    44
      src/Types.ts
  5. 4
    2
      src/Utils.ts
  6. 108
    67
      test/Test.ts

+ 16
- 10
src/Frontend.ts Целия файл

@@ -4,7 +4,7 @@ import { PromiseIOClient, defaultClientConfig } from './PromiseIO/Client'
4 4
 import * as T from './Types';
5 5
 import * as I from './Interfaces';
6 6
 import { stripAfterEquals, appendComma } from './Utils';
7
-import { DESTROY_PREFIX, SOCKET_NOT_CONNECTED, UNKNOWN_RPC_IDENTIFIER, USER_DEFINED_TIMEOUT } from './Strings';
7
+import { CALLBACK_NAME, DESTROY_PREFIX, SOCKET_NOT_CONNECTED, UNKNOWN_RPC_IDENTIFIER, USER_DEFINED_TIMEOUT } from './Strings';
8 8
 import { DeserializerFactory } from './Decorator';
9 9
 DeserializerFactory
10 10
 
@@ -21,12 +21,12 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
21 21
 
22 22
     private socket: I.Socket
23 23
     private handlers: {
24
-        [name in string]: T.AnyFunction[]
24
+        [name in string]: T.GenericFunction[]
25 25
     } = {
26 26
             error: [],
27 27
             close: []
28 28
         }
29
-    private hooks: { [name in string]: T.AnyFunction } = {}
29
+    private hooks: { [name in string]: T.GenericFunction } = {}
30 30
 
31 31
     /**
32 32
      * 
@@ -82,7 +82,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
82 82
      * @param type 'error' or 'close'
83 83
      * @param f The listener to attach
84 84
      */
85
-    public on(type: string, f: T.AnyFunction) {
85
+    public on(type: string, f: T.GenericFunction) {
86 86
         if (!this.socket) {
87 87
             if (!this.handlers[type])
88 88
                 this.handlers[type] = []
@@ -166,7 +166,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
166 166
             v.forEach(h => this.socket.on(k, h))
167 167
         })
168 168
 
169
-        Object.entries(this.hooks).forEach((kv: [string, T.AnyFunction]) => {
169
+        Object.entries(this.hooks).forEach((kv: [string, T.GenericFunction]) => {
170 170
             this.socket.hook(kv[0], kv[1])
171 171
         })
172 172
         const info: T.ExtendedRpcInfo[] = await this.info(sesame)
@@ -205,7 +205,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
205 205
      * @param fnName The function name
206 206
      * @param fnArgs A string-list of parameters
207 207
      */
208
-    private callGenerator(fnName: string, fnArgs: string[], sesame?: string): T.AnyFunction {
208
+    private callGenerator(fnName: string, fnArgs: string[], sesame?: string): T.GenericFunction {
209 209
         const headerArgs = fnArgs.join(",")
210 210
         const argParams = fnArgs.map(stripAfterEquals).join(",")
211 211
         sesame = appendComma(sesame)
@@ -221,7 +221,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
221 221
      * @param fnName The function name
222 222
      * @param fnArgs A string-list of parameters
223 223
      */
224
-    private frontEndHookGenerator(fnName: string, fnArgs: string[], sesame?: string): T.HookFunction {
224
+    private frontEndHookGenerator(fnName: string, fnArgs: string[], sesame?: string): T.GenericFunction {
225 225
 
226 226
         if (sesame)
227 227
             fnArgs.shift()
@@ -234,16 +234,22 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
234 234
         const destroy_prefix = DESTROY_PREFIX
235 235
 
236 236
         const frontendHookStr = `
237
-        async (${headerArgs} $__callback__$) => {
237
+        async (${headerArgs} ${CALLBACK_NAME}) => {
238 238
             const r = await this.call("${fnName}", ${sesame} ${argParams})
239 239
             try{
240 240
                 if(r){
241 241
                     if(r.uuid){
242
-                        $__callback__$['destroy'] = () => {
242
+                        ${CALLBACK_NAME}['destroy'] = () => {
243 243
                             this.socket.fire(destroy_prefix+r.uuid)
244 244
                             this.socket.unhook(r.uuid) 
245 245
                         }
246
-                        this.socket.hook(r.uuid, $__callback__$)
246
+                        ${CALLBACK_NAME} = ${CALLBACK_NAME}.bind({
247
+                            destroy: ${CALLBACK_NAME}['destroy']
248
+                        })
249
+
250
+                        this.socket.hook(r.uuid, (...args) => {
251
+                            ${CALLBACK_NAME}.apply(${CALLBACK_NAME}, args.map(deserializer.from))
252
+                        })
247 253
                     }
248 254
                     return deserializer.from(r.return)
249 255
                 }else{

+ 2
- 2
src/Interfaces.ts Целия файл

@@ -15,10 +15,10 @@ export interface Socket {
15 15
     id?: string
16 16
     bind: (name: string, listener: T.PioBindListener) => void
17 17
     hook: (rpcname: string, handler: T.PioHookListener) => void
18
-    unhook: (rpcname: string, listener?:T.AnyFunction) => void
18
+    unhook: (rpcname: string, listener?:T.GenericFunction) => void
19 19
     call: (rpcname: string, ...args: any[]) => Promise<any>
20 20
     fire: (rpcname: string, ...args: any[]) => Promise<any>
21
-    on: (type: string, f: T.AnyFunction)=>any
21
+    on: (type: string, f: T.GenericFunction)=>any
22 22
     emit: (eventName: string, ...args: any[]) => void
23 23
     close(): void
24 24
   }

+ 2
- 1
src/Strings.ts Целия файл

@@ -13,4 +13,5 @@ RPC did not provide a name.
13 13
 \n${name}
14 14
 \n>------------OFFENDING RPC`
15 15
 export const CLASSNAME_ATTRIBUTE = "$__CLASSNAME__$"
16
-export const DESTROY_PREFIX = "$__DESTROY__$_"
16
+export const DESTROY_PREFIX = "$__DESTROY__$_"
17
+export const CALLBACK_NAME = "$__CALLBACK__$"

+ 50
- 44
src/Types.ts Целия файл

@@ -1,12 +1,28 @@
1 1
 import * as I from "./Interfaces";
2 2
 import { RPCSocket } from "./Frontend";
3
-import { PromiseIO } from "./PromiseIO/Server";
4 3
 
5 4
 export type PioBindListener = (...args: any) => void
6
-export type PioHookListener = AnyFunction
5
+export type PioHookListener = GenericFunction
6
+
7
+export type GenericFunction<Parameters extends any[] = any[], Result = any> = {(...args: Parameters): Result}
8
+
9
+export type BackendHook<Func extends GenericFunction> =
10
+    GenericFunction<
11
+        [
12
+            ...Head<Parameters<Func>>,
13
+            GenericFunction<
14
+                Parameters<
15
+                    AsFunction<
16
+                        Last<Parameters<Func>>
17
+                    >
18
+                >,
19
+                void
20
+            >
21
+        ],
22
+        ReturnType<Func>
23
+    >
24
+
7 25
 
8
-export type AnyFunction = (...args: any[]) => any
9
-export type HookFunction = AnyFunction
10 26
 export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame: string | undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
11 27
 export type Visibility = "127.0.0.1" | "0.0.0.0"
12 28
 export type ConnectionHandler = (socket: I.Socket) => void
@@ -45,24 +61,23 @@ export type ErrorResponse<T = {}> = Respose<T> & { result: "Error", message?: st
45 61
 
46 62
 export type RPCType = 'Hook' | 'Unhook' | 'Call'
47 63
 
48
-export type CallRPC<Name, Func extends AnyFunction> = {
64
+export type CallRPC<Name, Func extends GenericFunction> = {
49 65
     name: Name
50 66
     call: Func
51 67
 }
52 68
 
53
-
54
-export type HookRPC<Name, Func extends AnyFunction> = {
69
+export type HookRPC<Name, Func extends GenericFunction> = {
55 70
     name: Name
56
-    hook: AnyFunction
57
-    onCallback?: AnyFunction
71
+    hook: BackendHook<Func>
72
+    onCallback?: GenericFunction
58 73
     onDestroy?: HookCloseFunction<ReturnType<Func> extends Promise<infer T> ? T : ReturnType<Func>>
59 74
 }
60 75
 
61
-export type RPC<Name, Func extends AnyFunction> = HookRPC<Name, Func> | CallRPC<Name, Func> | Func
76
+export type RPC<Name, Func extends GenericFunction> = HookRPC<Name, Func> | CallRPC<Name, Func> | Func
62 77
 
63 78
 export type RPCInterface<Impl extends RPCInterface = {}> = {
64 79
     [grp in string]: {
65
-        [rpc in string]: AnyFunction
80
+        [rpc in string]: GenericFunction
66 81
     }
67 82
 } & Impl
68 83
 
@@ -71,8 +86,8 @@ export type exportT = {
71 86
 }
72 87
 
73 88
 export type RPCDefinitions<Ifc extends RPCInterface> = {
74
-    [grp in keyof Ifc]: ({ 
75
-        [rpc in keyof Ifc[grp]]: RPC<rpc, Ifc[grp][rpc]> 
89
+    [grp in keyof Ifc]: ({
90
+        [rpc in keyof Ifc[grp]]: RPC<rpc, Ifc[grp][rpc]>
76 91
     }[keyof Ifc[grp]])[]
77 92
 }
78 93
 
@@ -89,7 +104,7 @@ export type HookInfo<SubresT = {}> = BaseInfo & {
89 104
 
90 105
 export type CallInfo = BaseInfo & {
91 106
     type: 'Call',
92
-    call: AnyFunction
107
+    call: GenericFunction
93 108
 }
94 109
 
95 110
 export type RpcInfo = HookInfo | CallInfo
@@ -99,39 +114,30 @@ export type OnFunction = <T extends "error" | "close">(type: T, f: FrontEndHandl
99 114
 export type HookCloseFunction<T> = (res: T, rpc: HookRPC<any, any>) => any
100 115
 
101 116
 
102
-export type AsyncIfc<Ifc extends RPCInterface> = { [grp in keyof Ifc]: { [rpcname in keyof Ifc[grp]]: AsyncAnyFunction<Ifc[grp][rpcname]> } }
117
+export type AsyncIfc<Ifc extends RPCInterface> = { [grp in keyof Ifc]: { [rpcname in keyof Ifc[grp]]: AsyncGenericFunction<Ifc[grp][rpcname]> } }
103 118
 
104
-export type AsyncAnyFunction<F extends AnyFunction = AnyFunction> = F extends (...args: Parameters<F>) => infer R
119
+export type AsyncGenericFunction<F extends GenericFunction = GenericFunction> = F extends (...args: Parameters<F>) => infer R
105 120
     ? ((...args: Parameters<F>) => R extends Promise<any> ? R : Promise<R>)
106 121
     : Promise<any>
107 122
 
108
-type DYN_PARAM<
109
-    A = void, 
110
-    B = void,
111
-    C = void,
112
-    D = void,
113
-    E = void,
114
-    F = void,
115
-    G = void,
116
-    H = void,
117
-> = H extends void ?
118
-     G extends void ?
119
-      F extends void ?
120
-       E extends void ?
121
-        D extends void ?
122
-         C extends void ?
123
-          B extends void ?
124
-           A extends void ?
125
-            []
126
-            : [A]
127
-          : [A,B]
128
-         :[A,B,C]
129
-        :[A,B,C,D]
130
-       :[A,B,C,D,E]
131
-      :[A,B,C,D,E,F]
132
-     :[A,B,C,D,E,F,G]
133
-    :[A,B,C,D,E,F,G,H] 
134 123
 
135 124
 type Destroyable = { destroy: () => void }
136
-export type Callback<A0 = void, A1 = void, A2 = void, A3 = void, A4 = void, A5 = void, A6 = void, A7 = void> = 
137
-    (this: Destroyable, ...args: DYN_PARAM<A0, A1, A2, A3, A4, A5, A6, A7>) => void 
125
+export type Callback<Params extends any[] = []> =
126
+    (this: Destroyable, ...args: Params) => void
127
+
128
+type AsFunction<F> = F extends GenericFunction ? F : GenericFunction
129
+
130
+type Last<Tuple extends any[]> = Tuple[ Subtract<Length<Tuple>, 1> ]
131
+type Head<T extends any[]> = T extends [ ...infer Head, any ] ? Head : any[]
132
+type Tail<T extends any[]> = T extends [any, ...infer Tail] ? Tail: []
133
+
134
+type Length<T extends any[]> = 
135
+    T extends { length: infer L } ? L : never;
136
+
137
+type BuildTuple<L extends number, T extends any[] = []> = 
138
+    T extends { length: L } ? T : BuildTuple<L, [...T, any]>;
139
+
140
+type Subtract<A extends number, B extends number> = 
141
+    BuildTuple<A> extends [...(infer U), ...BuildTuple<B>]
142
+        ? Length<U>
143
+        : never;

+ 4
- 2
src/Utils.ts Целия файл

@@ -76,7 +76,7 @@ export function rpcHooker(socket: I.Socket, exporter: I.RPCExporter<any, any>, e
76 76
  * Decorate an RPC with the error handler
77 77
  * @param rpcFunction the function to decorate
78 78
  */
79
-const callGenerator = (rpcName: string, $__socket__$: I.Socket, rpcFunction: T.AnyFunction, errorHandler: T.ErrorHandler): T.AnyFunction => {
79
+const callGenerator = (rpcName: string, $__socket__$: I.Socket, rpcFunction: T.GenericFunction, errorHandler: T.ErrorHandler): T.GenericFunction => {
80 80
     const argsArr = extractArgs(rpcFunction)
81 81
     const args = argsArr.join(',')
82 82
     const argsStr = argsArr.map(stripAfterEquals).join(',')
@@ -108,6 +108,7 @@ export function stripAfterEquals(str: string): string {
108 108
  * @returns A {@link HookFunction}
109 109
  */
110 110
 const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction, injectSocket?: boolean): T.HookInfo['generator'] => {
111
+    const deserializer = DeserializerFactory 
111 112
     let argsArr = extractArgs(rpc.hook)
112 113
     argsArr.pop() //remove callback param
113 114
 
@@ -124,6 +125,7 @@ const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, s
124 125
             const uuid = uuidv4()
125 126
             const res = await rpc.hook(${callArgs} (...cbargs) => {
126 127
                 ${rpc.onCallback ? `rpc.onCallback.apply({}, cbargs)` : ``}
128
+                cbargs = cbargs.map(deserializer.makeDeserializable)
127 129
                 $__socket__$.call.apply($__socket__$, [uuid, ...cbargs])
128 130
             })
129 131
             ${rpc.onDestroy ? `$__socket__$.bind(destroy_prefix+uuid, () => {
@@ -247,7 +249,7 @@ export const makePioSocket = (socket: any): I.Socket => {
247 249
             res(undefined)
248 250
         }),
249 251
 
250
-        unhook: (name: string, listener?: T.AnyFunction) => {
252
+        unhook: (name: string, listener?: T.GenericFunction) => {
251 253
             if (listener) {
252 254
                 socket.removeListener(name, listener)
253 255
             } else {

+ 108
- 67
test/Test.ts Целия файл

@@ -1,7 +1,7 @@
1 1
 import { describe, it } from "mocha";
2 2
 import { RPCServer, RPCSocket, Serializable } from '../Index'
3 3
 import { RPCExporter, Socket } from "../src/Interfaces";
4
-import { ConnectedSocket, Callback } from "../src/Types";
4
+import { ConnectedSocket, Callback, GenericFunction } 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';
@@ -9,11 +9,11 @@ import * as fetch from 'node-fetch';
9 9
 import { PromiseIO } from "../src/PromiseIO/Server";
10 10
 import { PromiseIOClient } from "../src/PromiseIO/Client";
11 11
 import { assert, expect } from 'chai';
12
-import { USER_DEFINED_TIMEOUT } from "../src/Strings";
12
+import { CLASSNAME_ATTRIBUTE, USER_DEFINED_TIMEOUT } from "../src/Strings";
13 13
 var should = require('chai').should();
14 14
 var chai = require("chai");
15 15
 var chaiAsPromised = require("chai-as-promised");
16
- 
16
+
17 17
 chai.use(chaiAsPromised);
18 18
 const noop = (...args) => { }
19 19
 
@@ -489,12 +489,12 @@ describe('RPCSocket', () => {
489 489
     })
490 490
 
491 491
 
492
-    it('should have rpc echo', async() => {
492
+    it('should have rpc echo', async () => {
493 493
         const x = await client['test'].echo("x")
494 494
         expect(x).to.be.equal('x')
495 495
     })
496 496
 
497
-    it('should add up to 6', async() => {
497
+    it('should add up to 6', async () => {
498 498
         const sum = await client['test'].add(1, 2, 3)
499 499
         expect(sum).to.be.equal(6)
500 500
     })
@@ -590,7 +590,7 @@ describe('It should do unhook', () => {
590 590
     let run = 0
591 591
     const expected = [yesCandy, noCandy, noCandy, noCandy]
592 592
 
593
-    it('Unhook+unsubscribe should stop callbacks', async() => {
593
+    it('Unhook+unsubscribe should stop callbacks', async () => {
594 594
         await client['test'].subscribe(function myCallback(c) {
595 595
             if (run == 1)
596 596
                 (myCallback as any).destroy()
@@ -614,7 +614,7 @@ type topicDTO = { topic: string; }
614 614
 type SesameTestIfc = {
615 615
     test: {
616 616
         checkCandy: () => Promise<string>
617
-        subscribe: (callback: Callback<string>) => Promise<topicDTO>
617
+        subscribe: (callback: Callback<[string]>) => Promise<topicDTO>
618 618
         manyParams: <A = string, B = number, C = boolean, D = Object>(a: A, b: B, c: C, d: D) => Promise<[A, B, C, D]>
619 619
     }
620 620
 }
@@ -688,7 +688,7 @@ describe('Sesame should unlock the socket', () => {
688 688
     })
689 689
 
690 690
     it('callback should work with sesame', (done) => {
691
-        client.test.subscribe(function(c){
691
+        client.test.subscribe(function (c) {
692 692
             if (c === candy) {
693 693
                 done()
694 694
             }
@@ -725,21 +725,21 @@ describe('Error handling', () => {
725 725
                 a: 'a',
726 726
                 b: 'b'
727 727
             })
728
-            .then(r => {
729
-                if (r != null)
730
-                    done(new Error("UNEXPECTED RESULT " + r))
731
-            })
732
-            .catch((e) => {
733
-                if (e.message === errtxt)
734
-                    done()
735
-                else
736
-                    done(e)
737
-            })
738
-            .finally(() => {
739
-                cli.close()
740
-                sock.close()
741
-                server.close()
742
-            })
728
+                .then(r => {
729
+                    if (r != null)
730
+                        done(new Error("UNEXPECTED RESULT " + r))
731
+                })
732
+                .catch((e) => {
733
+                    if (e.message === errtxt)
734
+                        done()
735
+                    else
736
+                        done(e)
737
+                })
738
+                .finally(() => {
739
+                    cli.close()
740
+                    sock.close()
741
+                    server.close()
742
+                })
743 743
         })
744 744
     })
745 745
 
@@ -1014,12 +1014,12 @@ describe("attaching handlers before connecting", () => {
1014 1014
 describe("class (de-)serialization", () => {
1015 1015
 
1016 1016
     @Serializable()
1017
-    class SubClass{
1017
+    class SubClass {
1018 1018
         fString = "F"
1019 1019
     }
1020 1020
 
1021 1021
     @Serializable()
1022
-    class TestClass{
1022
+    class TestClass {
1023 1023
         aString = "A"
1024 1024
         aNumber = 46
1025 1025
         aObject = {
@@ -1029,39 +1029,12 @@ describe("class (de-)serialization", () => {
1029 1029
         }
1030 1030
         aClassObject = new SubClass()
1031 1031
 
1032
-        public returnOK(){
1032
+        public returnOK() {
1033 1033
             return "OK"
1034 1034
         }
1035 1035
     }
1036 1036
 
1037
-    let myServer: RPCServer;
1038
-    let mySocket: RPCSocket;
1039
-
1040
-    before(function(done){
1041
-        myServer = new RPCServer([{
1042
-            name: "Test",
1043
-            RPCs: [
1044
-                function returnClass(){
1045
-                    return new TestClass()
1046
-                }
1047
-            ]
1048
-        }])
1049
-        myServer.listen(8084)
1050
-
1051
-        mySocket = new RPCSocket(8084, 'localhost')
1052
-        mySocket.connect().then(() => done())
1053
-    })
1054
-
1055
-    after(function(done){
1056
-        mySocket.close()
1057
-        myServer.close()
1058
-        done()
1059
-    })
1060
-
1061
-
1062
-    it("receives class in call response", async () => {
1063
-        const obj: TestClass = await mySocket['Test'].returnClass()
1064
-
1037
+    const verifyObject = (obj: any) => {
1065 1038
         expect(obj).to.be.an.instanceOf(TestClass)
1066 1039
         expect(obj.aString).to.be.a('string')
1067 1040
         expect(obj.aNumber).to.be.a('number')
@@ -1070,22 +1043,90 @@ describe("class (de-)serialization", () => {
1070 1043
         expect(obj.aObject.y).to.be.undefined
1071 1044
         expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
1072 1045
         expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
1073
-
1046
+        expect(obj).to.not.have.key(CLASSNAME_ATTRIBUTE)
1047
+        expect(obj.aObject.sub).to.not.have.key(CLASSNAME_ATTRIBUTE)
1048
+        expect(obj.aClassObject).to.not.have.key(CLASSNAME_ATTRIBUTE)
1074 1049
         expect(obj.returnOK()).to.be.equal('OK')
1075
-    })
1050
+    }
1076 1051
 
1077
-    it("receives class in hook response", async () => {
1078
-        const obj: TestClass = await mySocket['Test'].returnClass()
1052
+    describe("Responses", () => {
1053
+        type TestIfc = {
1054
+            Test: {
1055
+                returnClass: () => Promise<TestClass>
1056
+                classCallback: (callback: Callback<[TestClass]>) => Promise<TestClass>
1057
+            }
1058
+        }
1079 1059
 
1080
-        expect(obj).to.be.an.instanceOf(TestClass)
1081
-        expect(obj.aString).to.be.a('string')
1082
-        expect(obj.aNumber).to.be.a('number')
1083
-        expect(obj.aObject).to.be.a('object')
1084
-        expect(obj.aObject.x).to.be.a('string')
1085
-        expect(obj.aObject.y).to.be.undefined
1086
-        expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
1087
-        expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
1060
+        let myServer: RPCServer<TestIfc>;
1061
+        let mySocket: ConnectedSocket<TestIfc>;
1062
+
1063
+        before(function (done) {
1064
+            myServer = new RPCServer<TestIfc>([{
1065
+                name: "Test",
1066
+                RPCs: [
1067
+                    async function returnClass() {
1068
+                        return new TestClass()
1069
+                    }, {
1070
+                        name: "classCallback",
1071
+                        hook: async function (callback) {
1072
+                            setTimeout(_ => callback(new TestClass()), 250)
1073
+                            return new TestClass()
1074
+                        }
1075
+                    }
1076
+                ]
1077
+            }])
1078
+            myServer.listen(8084)
1088 1079
 
1089
-        expect(obj.returnOK()).to.be.equal('OK')
1080
+            new RPCSocket<TestIfc>(8084, 'localhost').connect().then(connsock => {
1081
+                mySocket = connsock
1082
+                done()
1083
+            })
1084
+        })
1085
+
1086
+        after(function (done) {
1087
+            mySocket.close()
1088
+            myServer.close()
1089
+            done()
1090
+        })
1091
+
1092
+
1093
+        it("receives class object in call response", async () => {
1094
+            const obj: TestClass = await mySocket['Test'].returnClass()
1095
+            verifyObject(obj)
1096
+        })
1097
+
1098
+        it("receives class object in hook response", async function () {
1099
+            const obj: TestClass = await mySocket.Test.classCallback(noop)
1100
+            verifyObject(obj)
1101
+        })
1102
+
1103
+        it("receives class object in callback", function (done) {
1104
+            mySocket.Test.classCallback(function (cbValue) {
1105
+                verifyObject(cbValue)
1106
+                done()
1107
+            }).then(verifyObject)
1108
+        })
1109
+    })
1110
+    describe("Parameters", () => {
1111
+        it("Class object in call", function(done){
1112
+            const server = new RPCServer([
1113
+                {
1114
+                    name: "Test",
1115
+                    RPCs: [
1116
+                        function callWithClass(testObj: TestClass){
1117
+                            verifyObject(testObj)
1118
+                            done()
1119
+                        }
1120
+                    ]
1121
+                }
1122
+            ]).listen(8086)
1123
+
1124
+            new RPCSocket(8086, 'localhost').connect().then(sock => {
1125
+                sock['Test'].callWithClass(new TestClass()).then(_ => {
1126
+                    sock.close()
1127
+                    server.close()
1128
+                })
1129
+            })
1130
+        })
1090 1131
     })
1091 1132
 })

Loading…
Отказ
Запис