123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945 |
- import { describe, it } from "mocha";
- import { RPCServer, RPCSocket } from '../Index'
- import { RPCExporter, Socket } from "../src/Interfaces";
- import { ConnectedSocket } from "../src/Types";
- import * as log from 'why-is-node-running';
- import * as http from 'http';
- import * as express from 'express';
- import * as fetch from 'node-fetch';
- import { PromiseIO } from "../src/PromiseIO/Server";
- import { PromiseIOClient } from "../src/PromiseIO/Client";
-
- const noop = (...args) => { }
-
- const add = (...args: number[]) => { return args.reduce((a, b) => a + b, 0) }
- function makeServer(onCallback = noop, connectionHandler = noop, hookCloseHandler = noop, closeHandler = noop, errorHandler = (socket, err) => { throw err }) {
- let subcallback
- const serv = new RPCServer([{
- name: 'test',
- RPCs: [
- {
- name: 'echo',
- call: async (s: string) => s,
- }, {
- name: 'simpleSubscribe',
- hook: async (callback) => {
- subcallback = callback
- return { topic: "test" }
- },
- onDestroy: hookCloseHandler
- }, {
- name: 'subscribe',
- hook: async (callback) => {
- subcallback = callback
- return { topic: "test" }
- },
- onDestroy: hookCloseHandler,
- onCallback: onCallback
- },
- add,
- function triggerCallback(...messages: any[]): number { return subcallback.apply({}, messages) },
- function brokenRPC(){ throw new Error("Intended error") }
- ]
- }],
- {
- connectionHandler: connectionHandler,
- closeHandler: closeHandler,
- errorHandler: errorHandler
- })
- serv.listen(21010)
- return serv
- }
-
-
- describe('PromiseIO', () => {
-
- it("bind + fire", (done) => {
- const server = new PromiseIO()
- server.attach(new http.Server())
- server.on("socket", clientSocket => {
- clientSocket.bind("test123", (p1,p2) => {
- server.close()
- if(p1 === "p1" && p2 === "p2")
- done()
- })
- });
-
- server.listen(21003)
- PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
- cli.fire("test123", "p1", "p2")
- cli.close()
- })
- })
-
- it("hook + call", (done) => {
- const server = new PromiseIO()
- server.attach(new http.Server())
- server.on("socket", clientSocket => {
- clientSocket.hook("test123", (p1,p2) => {
- if(p1 === "p1" && p2 === "p2")
- return "OK"
- })
- });
-
- server.listen(21003)
- PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
- cli.call("test123", "p1", "p2").then(resp => {
- cli.close()
- server.close()
-
- if(resp === "OK")
- done()
- })
- })
- })
-
- it("on + emit", (done) => {
- const server = new PromiseIO()
- server.attach(new http.Server())
- server.on("socket", clientSocket => {
- clientSocket.on("test123", (p1,p2) => {
- server.close()
- if(p1 === "p1" && p2 === "p2")
- done()
- })
- });
-
- server.listen(21003)
- PromiseIOClient.connect(21003, "localhost", "http").then(cli => {
- cli.emit("test123", "p1", "p2")
- cli.close()
- })
- })
- })
-
- describe('RPCServer', () => {
- let client, server
- const echo = (x) => x
-
- before(done => {
- server = new RPCServer([{
- name: 'HelloWorldRPCGroup',
- RPCs: () => [
- echo, //named function variable
- function echof(x) { return x }, //named function
- {
- name: 'echoExplicit', //describing object
- call: async (x, y, z) => [x, y, z]
- }
- ]
- }])
- server.listen(21003)
- client = new RPCSocket(21003, 'localhost')
- done()
- })
-
- after(done => {
- client.close()
- server.close()
-
- 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!')
-
-
- 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 {
- const sv = new RPCServer([{
- name: 'bad',
- RPCs: () => [
- (aaa, bbb, ccc) => { return aaa + bbb + ccc }
- ]
- }])
- sv.listen(20001)
- done(new Error("Didn't fail with bad RPC"))
- } catch (badRPCError) {
- done()
- }
- })
- })
-
- describe('RPCServer with premade http server', () => {
- const echo = (x) => x
- const RPCs = [
- echo, //named function variable
- function echof(x) { return x }, //named function
- {
- name: 'echoExplicit', //describing object
- call: async (x, y, z) => [x, y, z]
- }
- ]
-
- const RPCExporters = [
- {
- name: 'HelloWorldRPCGroup',
- RPCs: RPCs,
- }
- ]
-
- const RPCExporters2 = [
- {
- name: 'Grp2',
- RPCs: [
- function test() { return "test" }
- ],
- }
- ]
-
- let client: RPCSocket, server: RPCServer
-
- before(done => {
- const expressServer = express()
- const httpServer = new http.Server(expressServer)
-
- expressServer.get('/REST_ping', (req, res) => {
- return res
- .send('REST_pong')
- .status(200)
- })
-
- server = new RPCServer(
- RPCExporters,
- )
- server.attach(httpServer)
- httpServer.listen(8080)
-
- client = new RPCSocket(8080, 'localhost')
-
- done()
- })
-
- after(done => {
- client.close()
- server.close()
-
- done()
- })
-
- it('should serve REST', (done) => {
- fetch('http://localhost:8080/REST_ping').then(response => {
- response.text().then(text => {
- if (text === "REST_pong")
- done()
- else
- done(new Error("REST repsonse was " + text))
- })
- })
- })
-
-
- 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!')
-
-
- if (r0 === 'Hello' && r1 === 'World' && r2.join('') === 'RPC!') {
- done()
- } else {
- done(new Error("Bad response"))
- }
- })
- })
- })
-
-
- describe('Serverside Triggers', () => {
- let server, client
- const closerFunction = (done) => () => {
- client.close()
- server.close()
- done()
- }
-
- it('trigger onCallback', (done) => {
- server = makeServer(closerFunction(done))
- client = new RPCSocket(21010, "localhost")
- client.connect().then(_ => {
- client['test'].subscribe(noop).then(_ => client['test'].triggerCallback())
- })
- })
-
- it('trigger connectionHandler', (done) => {
- server = makeServer(undefined, closerFunction(done))
- client = new RPCSocket(21010, "localhost")
- client.connect()
- })
-
-
- it('trigger hook closeHandler', (done) => {
- server = makeServer(undefined, undefined, closerFunction(done))
- client = new RPCSocket(21010, "localhost")
- client.connect().then(_ => {
- client['test'].subscribe(function cb(){
- cb['destroy']()
- }).then(_ => client['test'].triggerCallback())
- })
- })
-
-
- it('trigger global closeHandler', (done) => {
- server = makeServer(undefined, undefined, undefined, () => {
- server.close()
- done()
- })
- client = new RPCSocket(21010, "localhost")
- client.connect().then(_ => {
- client['test'].subscribe(noop).then(_ => client.close())
- })
- })
-
-
- })
-
- describe('RPCSocket', () => {
- let client: RPCSocket
- let server: RPCServer
-
- before(async () => {
- server = makeServer()
-
- client = new RPCSocket(21010, "localhost")
- return await client.connect()
- })
-
- after(() => {
- client.close()
- server.close()
- })
-
-
- it('should have rpc echo', (done) => {
- client['test'].echo("x").then(x => {
- if (x === 'x')
- done()
- else
- 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)
- done()
- else
- done(new Error('add RPC response did not match'))
- })
- })
-
- it('should subscribe with success', (done) => {
- client['test'].simpleSubscribe(console.log).then(res => {
- if (res.topic === 'test') {
- done()
- } else {
- console.error(res)
- done(new Error('Subscribe did not return success'))
- }
- })
- })
-
- it('subscribe should call back', (done) => {
- client['test'].subscribe((...args: any) => {
- if (args[0] === "test" && args[1] === "callback")
- done()
- 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_")
- done()
- else
- done(new Error("Bad callback value " + args))
- }).then(async () => {
- await client['test'].triggerCallback("test_", "callback_")
- })
- })
- })
-
-
- describe('It should do unhook', () => {
- const yesCandy = "OK"
- const noCandy = "stolen"
- let candy = yesCandy
- let cb: Function
- let cb2: Function
- let client: RPCSocket
- let server: RPCServer
-
- before(async () => {
- server = new RPCServer([{
- name: "test",
- RPCs: () => [{
- name: 'subscribe',
- hook: async (callback): Promise<void> => {
- cb = <Function>callback
- return
- }
- },
- {
- name: 'subscribeWithParam',
- hook: async (param, callback): Promise<{ uuid: string }> => {
-
- if (param != "OK") {
- console.log("param was" + param);
- return {
- uuid: "no",
- }
- }
- cb2 = <Function>callback
- return {
- uuid: "OK",
- }
- }
- },
- function publish(): string { cb(candy); return candy },
- function unsubscribe(): string { candy = noCandy; cb(candy); cb = () => { }; return candy }
- ]
- }],
- {
- connectionHandler: noop,
- closeHandler: noop,
- errorHandler: (socket, err) => { throw err }
- })
- server.listen(21010)
- client = new RPCSocket(21010, "localhost")
- return await client.connect()
- })
-
- after(() => {
- client.close()
- server.close()
- })
-
- it('Subscribe with param', (done) => {
- client['test'].subscribeWithParam("OK", noop).then(async (res) => {
- if (res.uuid === candy) {
- done()
- } else
- done(new Error("Results did not match " + res.uuid))
- })
- })
-
- let run = 0
- const expected = [yesCandy, noCandy, noCandy, noCandy]
-
- 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]))
- })
- })
- })
-
- type topicDTO = { 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]>
- }
- }
-
- describe('Sesame should unlock the socket', () => {
- let candy = "OK"
- let client: ConnectedSocket<SesameTestIfc>
- let server: RPCServer<SesameTestIfc>
- let cb: Function = (...args) => { }
-
- before((done) => {
- server = new RPCServer<SesameTestIfc>([{
- name: "test",
- RPCs: () => [
- {
- name: 'subscribe',
- hook: async (callback) => {
- cb = callback
- return {
- topic: 'test'
- }
- },
- onDestroy: noop
- },
- async function checkCandy() { cb(candy); cb = noop; return candy },
- async function manyParams(a, b, c, d) { return [a, b, c, d] }
- ],
- }], {
- sesame: (_sesame) => _sesame === 'sesame!'
- })
- server.listen(21004)
- const sock = new RPCSocket<SesameTestIfc>(21004, "localhost")
- sock.connect('sesame!').then(cli => {
- client = cli
- done()
- })
- })
-
- after(() => {
- client.close()
- server.close()
- })
-
- it('should work with sesame', (done) => {
- client.test.checkCandy().then(c => done())
- })
-
- 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')
- done()
- })
- })
-
- it('should not work without sesame', (done) => {
- const sock = new RPCSocket(21004, "localhost")
- sock.connect( /* no sesame */).then(async (cli) => {
- if (!cli.test)
- done()
- else {
- done(new Error("Function supposed to be removed without sesame"))
- }
- cli.close()
- sock.close()
- })
- })
-
- it('should fail with wrong sesame', (done) => {
- const sock = new RPCSocket(21004, "localhost")
- sock.connect('abasd').then(async (cli) => {
- if (!cli.test)
- done()
- else {
- done(new Error("Function supposed to be removed without sesame"))
- }
- cli.close()
- sock.close()
- })
- })
-
- it('callback should work with sesame', (done) => {
- client.test.subscribe((c) => {
- if (c === candy) {
- done()
- }
- }).then(d => {
- if (d.topic !== 'test')
- done('unexpected invalid response')
-
- client.test.checkCandy()
- })
- })
- })
-
-
- 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([{
- name: "createUser",
- RPCs: () => [{
- name: 'createUser' as 'createUser',
- call: createUser
- }]
- }])
- server.listen(21004)
-
- let sock = new RPCSocket(21004, 'localhost')
- sock.connect().then((cli) => {
- cli["createUser"]["createUser"]({
- 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.close()
- sock.close()
- server.close()
- })
- })
- })
-
- it("RPC throws on server with handler", (done) => {
- let server = new RPCServer([{
- name: "createUser",
- RPCs: () => [{
- name: 'createUser' as 'createUser',
- call: createUser
- }]
- }], {
- errorHandler: (socket, e, rpcName, args) => {
- done()
- }
- })
- server.listen(21004)
-
- 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.close()
- sock.close()
- server.close()
- })
- })
- })
- })
-
-
- 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([{
- name: "createUser",
- RPCs: () => [{
- name: 'createUser' as 'createUser',
- call: createUser
- }]
- }], {
- errorHandler: (socket, e, rpcName, args) => {
- if (e.message === errtxt && rpcName === "createUser" && args[0]['a'] === 'a' && args[0]['b'] === 'b')
- done()
- }
- })
- server.listen(21004)
-
- let sock = new RPCSocket(21004, 'localhost')
- sock.connect().then((cli) => {
- cli["createUser"]["createUser"]({
- a: 'a',
- b: 'b'
- })
- .then(r => {
- if (r != null)
- done(new Error("UNEXPECTED RESULT " + r))
- })
- .catch((e) => {
- done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
- })
- .finally(() => {
- cli.close()
- sock.close()
- server.close()
- })
- })
- })
-
- it("handler sees sesame", (done) => {
- let sesame = "AAAAAAAAAAAAAAA"
- let server = new RPCServer([{
- name: "createUser" as "createUser",
- RPCs: () => [{
- name: 'createUser' as 'createUser',
- call: createUser
- }]
- }], {
- sesame: sesame,
- errorHandler: (socket, e, rpcName, args) => {
- if (e.message === errtxt && rpcName === "createUser" && args[0] === sesame && args[1]['a'] === 'a' && args[1]['b'] === 'b')
- done()
- }
-
- })
- server.listen(21004)
-
- let sock = new RPCSocket(21004, 'localhost')
- sock.connect(sesame).then((cli) => {
- cli["createUser"]["createUser"]({
- a: 'a',
- b: 'b'
- })
- .then(r => {
- if (r != null)
- done(new Error("UNEXPECTED RESULT " + r))
- })
- .catch((e) => {
- done(new Error("UNEXPECTED CLIENT ERROR " + e))
- })
- .finally(() => {
- cli.close()
- sock.close()
- server.close()
- })
- })
- })
- })
-
- type myExporterIfc = {
- MyExporter: {
- myRPC: () => Promise<string>
- }
- }
-
-
- describe("Class binding", () => {
-
- let exporter1: MyExporter
- let serv: RPCServer<myExporterIfc>
- let sock: RPCSocket & myExporterIfc
- let allowed = true
-
- class MyExporter implements RPCExporter<myExporterIfc>{
- name = "MyExporter" as "MyExporter"
- RPCs = () => [
- this.myRPC
- ]
-
- myRPC = async () => {
- //serv.setExporters([new MyOtherExporter])
- return "Hello World"
- }
- }
-
- class MyOtherExporter implements RPCExporter<myExporterIfc>{
- name = "MyExporter" as "MyExporter"
- RPCs = () => [
- this.myRPC
- ]
-
- myRPC = async () => {
- return "Hello Borld"
- }
-
- }
-
- before(done => {
- exporter1 = new MyExporter()
- serv = new RPCServer<myExporterIfc>(
- [exporter1],
- {
- accessFilter: async (sesame, exporter) => {
- if (exporter.name === 'MyExporter') {
- if (!allowed) return false
- allowed = false
- return sesame === 'xxx';
- } else {
- return false
- }
- },
- sesame: "xxx"
- })
- serv.listen(21004)
- done()
- })
-
- beforeEach((done) => {
- const s = new RPCSocket<myExporterIfc>(21004, 'localhost')
- s.connect("xxx").then(conn => {
- sock = conn
- done()
- })
- })
-
- afterEach((done) => {
- sock.close()
- done()
- })
-
- after(() => {
- serv.close()
- })
-
- /* 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 => {
- //job will time out because of setExporters
- allowed = true
- done()
- })
- })
-
- it("changes exporters", (done) => {
-
- sock['MyExporter'].myRPC().then((res) => {
- 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()
- else done(new Error("RPC supposed to be gone"))
- })
- })
-
-
- describe("attaching handlers before connecting", () => {
- it("fires error if server is unreachable", (done) => {
- const sock = new RPCSocket<myExporterIfc>(21004, 'localhost')
- let errorHandleCount = 0
-
- sock.on('error', (err) => {
- //attached listener fires first
- if (errorHandleCount != 0) {
- console.log("Error handler didn't fire first");
- } else {
- errorHandleCount++
- }
- })
-
- sock.connect().then(_ => {
- console.log("Unexpected successful connect")
- }).catch(e => {
- //catch clause fires second
- if (errorHandleCount != 1) {
- console.log("catch clause didn't fire second", errorHandleCount);
- } else {
- sock.close()
- done()
- }
- })
- })
-
- it("fires error if call is unknown", (done) => {
- const serv = new RPCServer().listen(21004)
- const sock = new RPCSocket(21004, 'localhost')
-
- sock.on('error', (err) => {
- sock.close()
- serv.close()
- done()
- })
-
- sock.connect().then(_ => {
- sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
- done(new Error("unexpected return value"))
- })
- }).catch(e => {
- done(e)
- })
- })
-
- /*
- * ## 1.11.0 breaking ##
- *
- * API change: Move from bsock to socketio changes underlying API for when errors are thrown.
- * socketio does not throw on unknown listener. This behaviour is considered more consistent with the design
- * goals of RPClibrary and was thus adopted
- *
-
-
- it("fires error if call is unknown", (done) => {
- const serv = new RPCServer(21004)
- const sock = new RPCSocket(21004, 'localhost')
-
- sock.on('error', (err) => {
- sock.close()
- serv.close()
- done()
- })
-
- sock.connect().then(_ => {
- sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
- console.log("X",x);
-
- })
- }).catch(e => {
- console.log("unexpected connect catch clause");
- done(e)
- })
- })
-
- it("demands catch on method invocation if call is unknown", (done) => {
- const serv = new RPCServer(21004)
- const sock = new RPCSocket(21004, 'localhost')
-
- sock.connect().then(_ => {
- sock.call("unknownRPC123", "AAAAA").catch(e => {
- sock.close()
- serv.close()
- done()
- })
- }).catch(e => {
- console.log("unexpected connect catch clause");
- done(e)
- })
- })
- */
-
- })
-
- describe('finally', () => {
- it('print open handles (Ignore `DNSCHANNEL` and `Immediate`)', () => {
- //log(console)
- })
- })
|