clean up type system, remove subres
This commit is contained in:
+301
-258
@@ -1,45 +1,44 @@
|
||||
import { describe, it, Func } from "mocha";
|
||||
|
||||
import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
|
||||
import * as uuidv4 from "uuid/v4"
|
||||
import { doesNotReject } from "assert";
|
||||
import { Socket } from "dgram";
|
||||
import { describe, it } from "mocha";
|
||||
import { RPCServer, RPCSocket } from '../Index'
|
||||
import { RPCExporter } from "../src/Interfaces";
|
||||
import { ConnectedSocket } from "../src/Types";
|
||||
import * as log from 'why-is-node-running';
|
||||
|
||||
const add = (...args:number[]) => {return args.reduce((a,b)=>a+b, 0)}
|
||||
function makeServer(){
|
||||
const add = (...args: number[]) => { return args.reduce((a, b) => a + b, 0) }
|
||||
function makeServer() {
|
||||
let subcallback
|
||||
return new RPCServer<{ topic: string }>(21010, [{
|
||||
name: "test",
|
||||
return new RPCServer(21010, [{
|
||||
name: 'test',
|
||||
exportRPCs: () => [
|
||||
{
|
||||
name: 'echo',
|
||||
call: async (s:string) => s,
|
||||
},{
|
||||
call: async (s: string) => s,
|
||||
}, {
|
||||
name: 'simpleSubscribe',
|
||||
hook: async(callback) => {
|
||||
subcallback = callback
|
||||
return makeSubResponse<{topic: string}>({topic: "test"})
|
||||
}
|
||||
},{
|
||||
hook: async (callback) => {
|
||||
subcallback = callback
|
||||
return { topic: "test" }
|
||||
},
|
||||
onClose: (res) => { }
|
||||
}, {
|
||||
name: 'subscribe',
|
||||
hook: async (callback) => {
|
||||
subcallback = callback
|
||||
return makeSubResponse<{topic: string}>({topic: "test"})
|
||||
return { topic: "test" }
|
||||
},
|
||||
onClose: (res, rpc) => {
|
||||
console.log("onClose", rpc.name === 'subscribe' && res?"OK":"")
|
||||
subcallback = null
|
||||
onClose: (res, rpc) => {
|
||||
console.log("onClose", rpc.name === 'subscribe' && res ? "OK" : "")
|
||||
subcallback = null
|
||||
},
|
||||
onCallback: (...args:any) => {
|
||||
console.log("onCallback", args[0] === "test" && args[1] === "callback"?"OK":"")
|
||||
onCallback: (...args: any) => {
|
||||
console.log("onCallback", args[0] === "test" && args[1] === "callback" ? "OK" : "")
|
||||
}
|
||||
},
|
||||
add,
|
||||
function triggerCallback(...messages:any[]):number {return subcallback.apply({}, messages)},
|
||||
function triggerCallback(...messages: any[]): number { return subcallback.apply({}, messages) },
|
||||
]
|
||||
}],{
|
||||
connectionHandler: (socket) => { },
|
||||
}], {
|
||||
connectionHandler: (socket) => { },
|
||||
closeHandler: (socket) => { },
|
||||
errorHandler: (socket, err) => { throw err }
|
||||
})
|
||||
@@ -47,57 +46,58 @@ function makeServer(){
|
||||
|
||||
|
||||
describe('RPCServer', () => {
|
||||
let server: RPCServer<{ topic: string }, any>
|
||||
let client, server
|
||||
const echo = (x) => x
|
||||
|
||||
before(() => {
|
||||
server = makeServer()
|
||||
})
|
||||
|
||||
after(() => {
|
||||
server.destroy()
|
||||
})
|
||||
|
||||
it('should be able to use all kinds of RPC definitions', (done) => {
|
||||
|
||||
const echo = (x) => x
|
||||
|
||||
const server = new RPCServer(21003, [{
|
||||
before(done => {
|
||||
server = new RPCServer(21003, [{
|
||||
name: 'HelloWorldRPCGroup',
|
||||
exportRPCs: () => [
|
||||
exportRPCs: () => [
|
||||
echo, //named function variable
|
||||
function echof(x){ return x }, //named function
|
||||
function echof(x) { return x }, //named function
|
||||
{
|
||||
name: 'echoExplicit', //describing object
|
||||
call: async (x,y,z) => [x,y,z]
|
||||
call: async (x, y, z) => [x, y, z]
|
||||
}
|
||||
]
|
||||
}])
|
||||
|
||||
const client = new RPCSocket(21003, 'localhost')
|
||||
client = new RPCSocket(21003, 'localhost')
|
||||
done()
|
||||
})
|
||||
|
||||
after(done => {
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
it('should be able to use all kinds of RPC definitions', (done) => {
|
||||
client.connect().then(async () => {
|
||||
const r0 = await client['HelloWorldRPCGroup'].echo('Hello')
|
||||
const r1 = await client['HelloWorldRPCGroup'].echof('World')
|
||||
const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R','P','C!')
|
||||
const r2 = await client['HelloWorldRPCGroup'].echoExplicit('R', 'P', 'C!')
|
||||
|
||||
if(r0 === 'Hello' && r1 === 'World' && r2.join('') ==='RPC!'){
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
|
||||
if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
|
||||
done()
|
||||
}else{
|
||||
done(new Error("Bad response"))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('new RPCServer() should fail on bad RPC', (done) => {
|
||||
try{
|
||||
try {
|
||||
new RPCServer(20001, [{
|
||||
name: "bad",
|
||||
exportRPCs: () => [
|
||||
(aaa,bbb,ccc) => { return aaa+bbb+ccc }
|
||||
name: 'bad',
|
||||
exportRPCs: () => [
|
||||
(aaa, bbb, ccc) => { return aaa + bbb + ccc }
|
||||
]
|
||||
}])
|
||||
done(new Error("Didn't fail with bad RPC"))
|
||||
}catch(badRPCError){
|
||||
} catch (badRPCError) {
|
||||
done()
|
||||
}
|
||||
})
|
||||
@@ -106,9 +106,9 @@ describe('RPCServer', () => {
|
||||
|
||||
describe('RPCSocket', () => {
|
||||
let client: RPCSocket
|
||||
let server: RPCServer<{topic: string}>
|
||||
let server: RPCServer
|
||||
|
||||
before(async() => {
|
||||
before(async () => {
|
||||
server = makeServer()
|
||||
client = new RPCSocket(21010, "localhost")
|
||||
return await client.connect()
|
||||
@@ -122,27 +122,27 @@ describe('RPCSocket', () => {
|
||||
|
||||
it('should have rpc echo', (done) => {
|
||||
client['test'].echo("x").then(x => {
|
||||
if(x === 'x')
|
||||
if (x === 'x')
|
||||
done()
|
||||
else
|
||||
done(new Error('echo RPC response did not match'))
|
||||
done(new Error('echo RPC response did not match'))
|
||||
})
|
||||
})
|
||||
|
||||
it('should add up to 6', (done) => {
|
||||
client['test'].add(1,2,3).then(x => {
|
||||
if(x === 6)
|
||||
client['test'].add(1, 2, 3).then(x => {
|
||||
if (x === 6)
|
||||
done()
|
||||
else
|
||||
done(new Error('add RPC response did not match'))
|
||||
done(new Error('add RPC response did not match'))
|
||||
})
|
||||
})
|
||||
|
||||
it('should subscribe with success', (done) => {
|
||||
client['test'].simpleSubscribe(console.log).then(res => {
|
||||
if(res.result === 'Success'){
|
||||
if (res.topic === 'test') {
|
||||
done()
|
||||
}else{
|
||||
} else {
|
||||
console.error(res)
|
||||
done(new Error('Subscribe did not return success'))
|
||||
}
|
||||
@@ -151,72 +151,66 @@ describe('RPCSocket', () => {
|
||||
|
||||
it('subscribe should call back', (done) => {
|
||||
client['test'].subscribe((...args: any) => {
|
||||
if(args[0] === "test" && args[1] === "callback")
|
||||
if (args[0] === "test" && args[1] === "callback")
|
||||
done()
|
||||
else
|
||||
done(new Error("Bad callback value "+ args))
|
||||
}).then( async () => {
|
||||
else
|
||||
done(new Error("Bad callback value " + args))
|
||||
}).then(async () => {
|
||||
await client['test'].triggerCallback("test", "callback")
|
||||
})
|
||||
})
|
||||
|
||||
it('simpleSubscribe should call back', (done) => {
|
||||
client['test'].simpleSubscribe((...args: any) => {
|
||||
if(args[0] === "test_" && args[1] === "callback_")
|
||||
if (args[0] === "test_" && args[1] === "callback_")
|
||||
done()
|
||||
else
|
||||
done(new Error("Bad callback value "+ args))
|
||||
}).then( async () => {
|
||||
else
|
||||
done(new Error("Bad callback value " + args))
|
||||
}).then(async () => {
|
||||
await client['test'].triggerCallback("test_", "callback_")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('It should do unhook', () => {
|
||||
let candy = "OK"
|
||||
const yesCandy = "OK"
|
||||
const noCandy = "stolen"
|
||||
let candy = yesCandy
|
||||
let cb: Function
|
||||
let cb2: Function
|
||||
let client: RPCSocket
|
||||
let server: RPCServer<{topic: string}>
|
||||
let server: RPCServer
|
||||
|
||||
before(async() => {
|
||||
server = new RPCServer<{ topic: string }>(21010, [{
|
||||
before(async () => {
|
||||
server = new RPCServer(21010, [{
|
||||
name: "test",
|
||||
exportRPCs: () => [{
|
||||
name: 'subscribe',
|
||||
hook: async(callback):Promise<SubscriptionResponse<{topic:string}>> => {
|
||||
cb = <Function> callback
|
||||
return {
|
||||
result: "Success",
|
||||
uuid: uuidv4(),
|
||||
topic: "test"
|
||||
}
|
||||
hook: async (callback): Promise<void> => {
|
||||
cb = <Function>callback
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'subscribeWithParam',
|
||||
hook: async(param, callback):Promise<SubscriptionResponse<{topic:string}>> => {
|
||||
|
||||
if(param != "OK"){
|
||||
console.log("param was"+ param);
|
||||
hook: async (param, callback): Promise<{ uuid: string }> => {
|
||||
|
||||
if (param != "OK") {
|
||||
console.log("param was" + param);
|
||||
return {
|
||||
result: "Success",
|
||||
uuid: "no",
|
||||
topic: "test"
|
||||
}
|
||||
}
|
||||
cb2 = <Function> callback
|
||||
cb2 = <Function>callback
|
||||
return {
|
||||
result: "Success",
|
||||
uuid: "OK",
|
||||
topic: "test"
|
||||
}
|
||||
}
|
||||
},
|
||||
function checkCandy():string { cb(candy); return candy },
|
||||
function stealCandy():string { candy = "_OK"; cb(candy); cb = () => {}; return candy }
|
||||
]
|
||||
}],{
|
||||
function publish(): string { cb(candy); return candy },
|
||||
function unsubscribe(): string { candy = noCandy; cb(candy); cb = () => { }; return candy }
|
||||
]
|
||||
}], {
|
||||
connectionHandler: (socket) => { },
|
||||
closeHandler: (socket) => { },
|
||||
errorHandler: (socket, err) => { throw err }
|
||||
@@ -231,69 +225,90 @@ describe('It should do unhook', () => {
|
||||
})
|
||||
|
||||
it('Subscribe with param', (done) => {
|
||||
client['test'].subscribeWithParam("OK", c => {}).then( async (res: SubscriptionResponse) => {
|
||||
if(res.uuid === "OK"){
|
||||
client['test'].subscribeWithParam("OK", c => { }).then(async (res) => {
|
||||
if (res.uuid === candy) {
|
||||
done()
|
||||
}else
|
||||
done(new Error("Results did not match "+res.uuid))
|
||||
} else
|
||||
done(new Error("Results did not match " + res.uuid))
|
||||
})
|
||||
})
|
||||
|
||||
it('Unhook+unsubscribe should stop callbacks', (done) => {
|
||||
client['test'].subscribe(c => {}).then( async (res: SubscriptionResponse) => {
|
||||
const r1 = await client['test'].checkCandy()
|
||||
const r3 = await client['test'].stealCandy()
|
||||
client.unhook(res.uuid)
|
||||
const r2 = await client['test'].checkCandy()
|
||||
const r4 = await client['test'].checkCandy()
|
||||
let run = 0
|
||||
const expected = [yesCandy, noCandy, noCandy, noCandy]
|
||||
|
||||
if(r1 === "OK" && r3 === "_OK" && r2 === "_OK" && r4 === "_OK")
|
||||
it('Unhook+unsubscribe should stop callbacks', (done) => {
|
||||
|
||||
client['test'].subscribe(function myCallback(c){
|
||||
if(run == 1)
|
||||
(myCallback as any).destroy()
|
||||
|
||||
if (c !== expected[run++]) {
|
||||
done(new Error(`Wrong candy '${c}' in iteration '${run - 1}'`))
|
||||
}
|
||||
}).then(async function(res){
|
||||
const r1 = await client['test'].publish()
|
||||
const r3 = await client['test'].unsubscribe()
|
||||
const r2 = await client['test'].publish()
|
||||
const r4 = await client['test'].publish()
|
||||
|
||||
if (r1 === yesCandy && r3 === noCandy && r2 === noCandy && r4 === noCandy)
|
||||
done()
|
||||
else
|
||||
done(new Error("Results did not match: "+[r1,r2,r3,r4]))
|
||||
done(new Error("Results did not match: " + [r1, r2, r3, r4]))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
type topicDTO = { topic: string; }
|
||||
|
||||
type SesameTestIfc = {
|
||||
test: {
|
||||
checkCandy: ()=>Promise<string>
|
||||
subscribe: (callback) => Promise<SubscriptionResponse<{ topic: string; }>>
|
||||
}
|
||||
type SesameTestIfc = {
|
||||
test: {
|
||||
checkCandy: () => Promise<string>
|
||||
subscribe: (callback: Function) => Promise<topicDTO>
|
||||
manyParams: <A=string,B=number,C=boolean,D=Object>(a:A, b:B, c:C, d:D) => Promise<[A, B, C, D]>
|
||||
}
|
||||
|
||||
other: {
|
||||
echo: (x:any) => Promise<any>
|
||||
}
|
||||
}
|
||||
|
||||
describe('Sesame should unlock the socket', () => {
|
||||
let candy = "OK"
|
||||
let client: RPCSocket & SesameTestIfc
|
||||
let server: RPCServer
|
||||
let cb = (...args) => {}
|
||||
let client: ConnectedSocket<SesameTestIfc>
|
||||
let server: RPCServer<SesameTestIfc>
|
||||
let cb: Function = (...args) => { }
|
||||
|
||||
before((done) => {
|
||||
server = new RPCServer(21004, [{
|
||||
server = new RPCServer<SesameTestIfc>(21004, [{
|
||||
name: "test",
|
||||
exportRPCs: () => [
|
||||
{
|
||||
name: 'subscribe',
|
||||
hook: async(callback) => {
|
||||
hook: async (callback) => {
|
||||
cb = callback
|
||||
return <SubscriptionResponse>{
|
||||
result: "Success",
|
||||
uuid: uuidv4(),
|
||||
return {
|
||||
topic: 'test'
|
||||
}
|
||||
}
|
||||
},
|
||||
onClose: (a) => { }
|
||||
},
|
||||
async function checkCandy():Promise<string> { cb(candy); cb=()=>{}; return candy },
|
||||
async function manyParams(a,b,c,d) {return [a,b,c,d]}
|
||||
]}
|
||||
],{
|
||||
sesame: (_sesame) => _sesame === 'sesame!'
|
||||
async function checkCandy() { cb(candy); cb = () => { }; return candy },
|
||||
async function manyParams(a, b, c, d) { return [a, b, c, d] }
|
||||
],
|
||||
},{
|
||||
name: 'other',
|
||||
exportRPCs: () => [
|
||||
async function echo(x){return x}
|
||||
]
|
||||
|
||||
}], {
|
||||
sesame: (_sesame) => _sesame === 'sesame!'
|
||||
})
|
||||
const sock = new RPCSocket(21004, "localhost")
|
||||
sock.connect<SesameTestIfc>('sesame!').then(cli => {
|
||||
const sock = new RPCSocket<SesameTestIfc>(21004, "localhost")
|
||||
sock.connect('sesame!').then(cli => {
|
||||
client = cli
|
||||
done()
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -307,8 +322,8 @@ describe('Sesame should unlock the socket', () => {
|
||||
})
|
||||
|
||||
it('should work with multiple params', (done) => {
|
||||
client.test['manyParams']('a','b','c','d').then(c => {
|
||||
if(c[0] == 'a' && c[1] === 'b' && c[2] === 'c' && c[3] === 'd')
|
||||
client.test['manyParams']('a', 'b', 'c', 'd').then(c => {
|
||||
if (c[0] == 'a' && c[1] === 'b' && c[2] === 'c' && c[3] === 'd')
|
||||
done()
|
||||
})
|
||||
})
|
||||
@@ -316,9 +331,9 @@ describe('Sesame should unlock the socket', () => {
|
||||
it('should not work without sesame', (done) => {
|
||||
const sock = new RPCSocket(21004, "localhost")
|
||||
sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
|
||||
if(!cli.test)
|
||||
if (!cli.test)
|
||||
done()
|
||||
else{
|
||||
else {
|
||||
done(new Error("Function supposed to be removed without sesame"))
|
||||
}
|
||||
cli.destroy()
|
||||
@@ -329,9 +344,9 @@ describe('Sesame should unlock the socket', () => {
|
||||
it('should fail with wrong sesame', (done) => {
|
||||
const sock = new RPCSocket(21004, "localhost")
|
||||
sock.connect<SesameTestIfc>('abasd').then(async (cli) => {
|
||||
if(!cli.test)
|
||||
if (!cli.test)
|
||||
done()
|
||||
else{
|
||||
else {
|
||||
done(new Error("Function supposed to be removed without sesame"))
|
||||
}
|
||||
cli.destroy()
|
||||
@@ -341,12 +356,12 @@ describe('Sesame should unlock the socket', () => {
|
||||
|
||||
it('callback should work with sesame', (done) => {
|
||||
client.test.subscribe((c) => {
|
||||
if(c === candy){
|
||||
if (c === candy) {
|
||||
done()
|
||||
}
|
||||
}).then(d => {
|
||||
if(d.result !== 'Success')
|
||||
done('unexpected valid response')
|
||||
if (d.topic !== 'test')
|
||||
done('unexpected invalid response')
|
||||
|
||||
client.test.checkCandy()
|
||||
})
|
||||
@@ -354,51 +369,56 @@ describe('Sesame should unlock the socket', () => {
|
||||
})
|
||||
|
||||
|
||||
describe('Error handling', ()=>{
|
||||
|
||||
let createUser = async( user: {a:any,b:any}) => {
|
||||
throw new Error("BAD BAD BAD")
|
||||
describe('Error handling', () => {
|
||||
const errtxt = "BAD BAD BAD"
|
||||
|
||||
let createUser = async (user: { a: any, b: any }) => {
|
||||
throw new Error(errtxt)
|
||||
}
|
||||
|
||||
it("RPC throws on client without handler", (done)=>{
|
||||
let server = new RPCServer(21004, [ {
|
||||
name: 'createUser' as 'createUser',
|
||||
it("RPC throws on client without handler", (done) => {
|
||||
let server = new RPCServer(21004, [{
|
||||
name: "createUser",
|
||||
exportRPCs: () => [{
|
||||
name: 'createUser' as 'createUser',
|
||||
call: createUser
|
||||
}]}], {
|
||||
}]
|
||||
}], {
|
||||
|
||||
})
|
||||
|
||||
let sock = new RPCSocket(21004, 'localhost')
|
||||
sock.connect().then((cli) => {
|
||||
cli["createUser"]["createUser"]({
|
||||
a:'a',
|
||||
b:'b'
|
||||
})
|
||||
.then(r => {
|
||||
if(r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
//console.log("EXPECTED CLIENT EXCEPTION", String(e));
|
||||
done()
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
a: 'a',
|
||||
b: 'b'
|
||||
})
|
||||
.then(r => {
|
||||
if (r != null)
|
||||
done(new Error("UNEXPECTED RESULT " + r))
|
||||
})
|
||||
.catch((e) => {
|
||||
if (e.message === errtxt)
|
||||
done()
|
||||
else
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("RPC throws on server with handler", (done)=>{
|
||||
let server = new RPCServer(21004, [ {
|
||||
name: 'createUser' as 'createUser',
|
||||
it("RPC throws on server with handler", (done) => {
|
||||
let server = new RPCServer(21004, [{
|
||||
name: "createUser",
|
||||
exportRPCs: () => [{
|
||||
name: 'createUser' as 'createUser',
|
||||
call: createUser
|
||||
}]}], {
|
||||
}]
|
||||
}], {
|
||||
errorHandler: (socket, e, rpcName, args) => {
|
||||
done()
|
||||
}
|
||||
@@ -407,41 +427,44 @@ describe('Error handling', ()=>{
|
||||
let sock = new RPCSocket(21004, 'localhost')
|
||||
sock.connect().then((cli) => {
|
||||
cli["createUser"]["createUser"]({
|
||||
a:'a',
|
||||
b:'b'
|
||||
})
|
||||
.then(r => {
|
||||
if(r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done("UNEXPECTED CLIENT ERROR " + e)
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
a: 'a',
|
||||
b: 'b'
|
||||
})
|
||||
.then(r => {
|
||||
if (r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done("UNEXPECTED CLIENT ERROR " + e)
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe("Errorhandler functionality", ()=>{
|
||||
let createUser = async( user: {a:any,b:any}) => {
|
||||
throw new Error("BAD BAD BAD")
|
||||
describe("Errorhandler functionality", () => {
|
||||
const errtxt = "BAD BAD BAD"
|
||||
|
||||
let createUser = async (user: { a: any, b: any }) => {
|
||||
throw new Error(errtxt)
|
||||
}
|
||||
|
||||
it("correct values are passed to the handler", (done)=>{
|
||||
let server = new RPCServer(21004, [ {
|
||||
name: 'createUser' as 'createUser',
|
||||
it("correct values are passed to the handler", (done) => {
|
||||
let server = new RPCServer(21004, [{
|
||||
name: "createUser",
|
||||
exportRPCs: () => [{
|
||||
name: 'createUser' as 'createUser',
|
||||
call: createUser
|
||||
}]}], {
|
||||
}]
|
||||
}], {
|
||||
errorHandler: (socket, e, rpcName, args) => {
|
||||
if(e.message === "BAD BAD BAD" && rpcName === "createUser" && args[0]['a'] === 'a' && args[0]['b'] === 'b')
|
||||
if (e.message === errtxt && rpcName === "createUser" && args[0]['a'] === 'a' && args[0]['b'] === 'b')
|
||||
done()
|
||||
}
|
||||
})
|
||||
@@ -449,97 +472,97 @@ describe("Errorhandler functionality", ()=>{
|
||||
let sock = new RPCSocket(21004, 'localhost')
|
||||
sock.connect().then((cli) => {
|
||||
cli["createUser"]["createUser"]({
|
||||
a:'a',
|
||||
b:'b'
|
||||
})
|
||||
.then(r => {
|
||||
if(r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done("UNEXPECTED CLIENT ERROR " + e)
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
a: 'a',
|
||||
b: 'b'
|
||||
})
|
||||
.then(r => {
|
||||
if (r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("handler sees sesame", (done)=>{
|
||||
it("handler sees sesame", (done) => {
|
||||
let sesame = "AAAAAAAAAAAAAAA"
|
||||
let server = new RPCServer(21004, [ {
|
||||
name: 'createUser' as 'createUser',
|
||||
let server = new RPCServer(21004, [{
|
||||
name: "createUser" as "createUser",
|
||||
exportRPCs: () => [{
|
||||
name: 'createUser' as 'createUser',
|
||||
call: createUser
|
||||
}]}], {
|
||||
}]
|
||||
}], {
|
||||
sesame: sesame,
|
||||
errorHandler: (socket, e, rpcName, args) => {
|
||||
if(e.message === "BAD BAD BAD" && rpcName === "createUser" && args[0] === sesame && args[1]['a'] === 'a' && args[1]['b'] === 'b')
|
||||
if (e.message === errtxt && rpcName === "createUser" && args[0] === sesame && args[1]['a'] === 'a' && args[1]['b'] === 'b')
|
||||
done()
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
let sock = new RPCSocket(21004, 'localhost')
|
||||
sock.connect(sesame).then((cli) => {
|
||||
cli["createUser"]["createUser"]({
|
||||
a:'a',
|
||||
b:'b'
|
||||
})
|
||||
.then(r => {
|
||||
if(r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done("UNEXPECTED CLIENT ERROR " + e)
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
a: 'a',
|
||||
b: 'b'
|
||||
})
|
||||
.then(r => {
|
||||
if (r != null)
|
||||
done("UNEXPECTED RESULT " + r)
|
||||
})
|
||||
.catch((e) => {
|
||||
done("UNEXPECTED CLIENT ERROR " + e)
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
type myExporterIfc = {
|
||||
MyExporter: {
|
||||
myRPC: ()=>Promise<string>
|
||||
myRPC: () => Promise<string>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
describe("Class binding", ()=>{
|
||||
describe("Class binding", () => {
|
||||
|
||||
let exporter1 : MyExporter
|
||||
let serv : RPCServer<{}, myExporterIfc>
|
||||
let exporter1: MyExporter
|
||||
let serv: RPCServer<myExporterIfc>
|
||||
let sock: RPCSocket & myExporterIfc
|
||||
let allowed = true
|
||||
|
||||
class MyExporter implements RPCExporter<myExporterIfc>{
|
||||
name = "MyExporter" as "MyExporter";
|
||||
name = "MyExporter" as "MyExporter"
|
||||
exportRPCs = () => [
|
||||
this.myRPC
|
||||
]
|
||||
|
||||
myRPC = async () => {
|
||||
serv.setExporters([new MyOtherExporter])
|
||||
//serv.setExporters([new MyOtherExporter])
|
||||
return "Hello World"
|
||||
}
|
||||
}
|
||||
|
||||
class MyOtherExporter implements RPCExporter<myExporterIfc>{
|
||||
name = "MyExporter" as "MyExporter";
|
||||
name = "MyExporter" as "MyExporter"
|
||||
exportRPCs = () => [
|
||||
this.myRPC
|
||||
]
|
||||
|
||||
myRPC = async () => {
|
||||
myRPC = async () => {
|
||||
return "Hello Borld"
|
||||
}
|
||||
|
||||
@@ -547,24 +570,22 @@ describe("Class binding", ()=>{
|
||||
|
||||
before(done => {
|
||||
exporter1 = new MyExporter()
|
||||
serv = new RPCServer<{}, myExporterIfc>(21004, [exporter1], {
|
||||
accessFilter: async (sesame,exporter) => {
|
||||
switch(exporter.name){
|
||||
case "MyExporter":
|
||||
if(!allowed) return false
|
||||
allowed = false
|
||||
return sesame==='xxx';
|
||||
default:
|
||||
return false
|
||||
serv = new RPCServer<myExporterIfc>(21004, [exporter1], {
|
||||
accessFilter: async (sesame, exporter) => {
|
||||
if(exporter.name === 'MyExporter'){
|
||||
if (!allowed) return false
|
||||
allowed = false
|
||||
return sesame === 'xxx';
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
},
|
||||
sesame: "xxx"
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
beforeEach((done)=>{
|
||||
|
||||
|
||||
beforeEach((done) => {
|
||||
const s = new RPCSocket(21004, 'localhost')
|
||||
s.connect<myExporterIfc>("xxx").then(conn => {
|
||||
sock = conn
|
||||
@@ -572,7 +593,7 @@ describe("Class binding", ()=>{
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(done => {
|
||||
afterEach((done) => {
|
||||
sock.destroy()
|
||||
done()
|
||||
})
|
||||
@@ -581,7 +602,11 @@ describe("Class binding", ()=>{
|
||||
serv.destroy()
|
||||
})
|
||||
|
||||
it("binds correctly", (done)=>{
|
||||
/* The server-side socket will enter a 30s timeout if destroyed by a RPC.
|
||||
to mitigate the impact on testing time these are not run.
|
||||
|
||||
it("binds correctly", function(done){
|
||||
this.timeout(1000)
|
||||
sock['MyExporter'].myRPC().then((res) => {
|
||||
done(new Error(res))
|
||||
}).catch(e => {
|
||||
@@ -592,31 +617,42 @@ describe("Class binding", ()=>{
|
||||
})
|
||||
|
||||
it("changes exporters", (done) => {
|
||||
|
||||
sock['MyExporter'].myRPC().then((res) => {
|
||||
if(res === "Hello Borld")
|
||||
if (res === "Hello Borld")
|
||||
done()
|
||||
else
|
||||
done(new Error(res))
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
|
||||
it("use sesameFilter for available", (done) => {
|
||||
if (sock['MyExporter']){
|
||||
allowed = false
|
||||
done()
|
||||
}
|
||||
else done(new Error("RPC supposed to be here"))
|
||||
})
|
||||
|
||||
it("use sesameFilter", (done) => {
|
||||
if(!sock['MyExporter']) done()
|
||||
if (!sock['MyExporter']) done()
|
||||
else done(new Error("RPC supposed to be gone"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe("attaching handlers before connecting", ()=>{
|
||||
it("fires error if server is unreachable", (done)=>{
|
||||
describe("attaching handlers before connecting", () => {
|
||||
it("fires error if server is unreachable", (done) => {
|
||||
const sock = new RPCSocket(21004, 'localhost')
|
||||
let errorHandleCount = 0
|
||||
|
||||
sock.on('error', (err) => {
|
||||
//attached listener fires first
|
||||
if(errorHandleCount != 0){
|
||||
if (errorHandleCount != 0) {
|
||||
console.log("Error handler didn't fire first");
|
||||
}else{
|
||||
} else {
|
||||
errorHandleCount++
|
||||
}
|
||||
})
|
||||
@@ -625,16 +661,16 @@ describe("attaching handlers before connecting", ()=>{
|
||||
console.log("Unexpected successful connect")
|
||||
}).catch(e => {
|
||||
//catch clause fires second
|
||||
if(errorHandleCount != 1){
|
||||
if (errorHandleCount != 1) {
|
||||
console.log("catch clause didn't fire second");
|
||||
}else{
|
||||
} else {
|
||||
sock.destroy()
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it("fires error if call is unknown", (done)=>{
|
||||
it("fires error if call is unknown", (done) => {
|
||||
const serv = new RPCServer(21004)
|
||||
const sock = new RPCSocket(21004, 'localhost')
|
||||
|
||||
@@ -645,14 +681,14 @@ describe("attaching handlers before connecting", ()=>{
|
||||
})
|
||||
|
||||
sock.connect().then(_ => {
|
||||
sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */})
|
||||
sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */ })
|
||||
}).catch(e => {
|
||||
console.log("unexpected connect catch clause");
|
||||
done(e)
|
||||
})
|
||||
})
|
||||
|
||||
it("demands catch on method invocation if call is unknown", (done)=>{
|
||||
it("demands catch on method invocation if call is unknown", (done) => {
|
||||
const serv = new RPCServer(21004)
|
||||
const sock = new RPCSocket(21004, 'localhost')
|
||||
|
||||
@@ -667,4 +703,11 @@ describe("attaching handlers before connecting", ()=>{
|
||||
done(e)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('finally', () => {
|
||||
it('print open handles (Ignore `DNSCHANNEL` and `Immediate`)', () => {
|
||||
log()
|
||||
})
|
||||
})
|
||||
@@ -1,73 +0,0 @@
|
||||
import { RPCServer } from "../src/Backend";
|
||||
import { SubscriptionResponse, RPCInterface } from "../src/Types";
|
||||
import { RPCSocket } from "../src/Frontend";
|
||||
import { makeSubResponse } from "../src/Utils";
|
||||
|
||||
type SubresExtension = {a:string}
|
||||
|
||||
type MyInterface = {
|
||||
Group1: {
|
||||
triggerCallbacks: (...args:any[]) => Promise<void>,
|
||||
subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<SubresExtension>>,
|
||||
unsubscribe: (uuid:string) => Promise<void>
|
||||
},
|
||||
Group2: {
|
||||
echo: (x:string) => Promise<string>
|
||||
}
|
||||
}
|
||||
|
||||
new RPCServer<SubresExtension, MyInterface>(20000,
|
||||
[{
|
||||
name: 'Group1',
|
||||
exportRPCs: () => [{
|
||||
name: 'triggerCallbacks',
|
||||
call: async () => { /*...*/ }
|
||||
},{
|
||||
name: 'subscribe',
|
||||
hook: async (param, callback) => { return makeSubResponse<SubresExtension>({a: "test"}) }
|
||||
},{
|
||||
name: 'unsubscribe',
|
||||
call: async(uuid) => { }
|
||||
}
|
||||
]
|
||||
},{
|
||||
name: 'Group2',
|
||||
exportRPCs: () => [{
|
||||
name: 'echo',
|
||||
call: async (x) => "..."
|
||||
}]
|
||||
}]
|
||||
)
|
||||
|
||||
RPCSocket.makeSocket<MyInterface>(20000, 'localhost').then((async (client) => {
|
||||
console.log(client)
|
||||
const res = await client.Group1.subscribe('test', async (...args:any) => {
|
||||
console.log.apply(console, args)
|
||||
|
||||
/* close the callbacks once you're done */
|
||||
await client.Group1.unsubscribe(res.uuid)
|
||||
client.unhook(res.uuid)
|
||||
})
|
||||
|
||||
await client.Group1.triggerCallbacks("Hello", "World", "Callbacks")
|
||||
}))
|
||||
|
||||
const srv = new RPCServer(30000, [{
|
||||
name: 'Group2',
|
||||
exportRPCs: () => [{
|
||||
name: 'echo',
|
||||
call: async (x) => x
|
||||
}]
|
||||
}], {
|
||||
sesame: 'open'
|
||||
})
|
||||
|
||||
const s = new RPCSocket(30000, 'localhost')
|
||||
s.connect("open").then(async() => {
|
||||
s['Group2']['echo']('open', 'dfgfg').then(console.log)
|
||||
s['Group2']['echo']('dfgfg').then(console.log)
|
||||
|
||||
s['Group2']['echo']('dfgfg').then(console.log)
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user