From 7317762b29979b6dde7e38cc91e07561a44184ad Mon Sep 17 00:00:00 2001 From: Andrew Stanton-Nurse Date: Mon, 11 Jun 2018 14:19:33 -0700 Subject: [PATCH] fix #2407 by tslinting tests before running (#2459) --- .../ts/FunctionalTests/ts/ConnectionTests.ts | 6 +- .../FunctionalTests/ts/HubConnectionTests.ts | 2 +- clients/ts/package.json | 1 + clients/ts/signalr/src/HttpConnection.ts | 1 - clients/ts/signalr/src/HubConnection.ts | 17 ++- .../ts/signalr/src/LongPollingTransport.ts | 1 - clients/ts/signalr/src/Stream.ts | 2 + .../ts/signalr/tests/HttpConnection.test.ts | 130 +++++++++--------- .../ts/signalr/tests/HubConnection.test.ts | 114 +++++++-------- .../tests/HubConnectionBuilder.test.ts | 14 -- .../tests/LongPollingTransport.test.ts | 33 +++-- clients/ts/signalr/tests/Utils.ts | 2 +- clients/ts/tslint.json | 2 + 13 files changed, 164 insertions(+), 161 deletions(-) diff --git a/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/clients/ts/FunctionalTests/ts/ConnectionTests.ts index 636d7e6998..6308aba1bb 100644 --- a/clients/ts/FunctionalTests/ts/ConnectionTests.ts +++ b/clients/ts/FunctionalTests/ts/ConnectionTests.ts @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -import { HttpTransportType, IHttpConnectionOptions, LogLevel, TransferFormat } from "@aspnet/signalr"; +import { HttpTransportType, IHttpConnectionOptions, TransferFormat } from "@aspnet/signalr"; import { eachTransport, ECHOENDPOINT_URL } from "./Common"; import { TestLogger } from "./TestLogger"; @@ -23,9 +23,7 @@ describe("connection", () => { ...commonOptions, }); - let received = ""; connection.onreceive = (data) => { - received += data; if (data === message) { connection.stop(); } @@ -55,9 +53,7 @@ describe("connection", () => { transport: transportType, }); - let received = ""; connection.onreceive = (data) => { - received += data; if (data === message) { connection.stop(); } diff --git a/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/clients/ts/FunctionalTests/ts/HubConnectionTests.ts index b3d1af3e9e..c7e6ca310b 100644 --- a/clients/ts/FunctionalTests/ts/HubConnectionTests.ts +++ b/clients/ts/FunctionalTests/ts/HubConnectionTests.ts @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, HttpTransportType, HubConnection, HubConnectionBuilder, IHttpConnectionOptions, IStreamSubscriber, JsonHubProtocol, LogLevel } from "@aspnet/signalr"; +import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, HttpTransportType, HubConnectionBuilder, IHttpConnectionOptions, JsonHubProtocol } from "@aspnet/signalr"; import { MessagePackHubProtocol } from "@aspnet/signalr-protocol-msgpack"; import { eachTransport, eachTransportAndProtocol, ENDPOINT_BASE_URL } from "./Common"; diff --git a/clients/ts/package.json b/clients/ts/package.json index a75758112e..0305660af4 100644 --- a/clients/ts/package.json +++ b/clients/ts/package.json @@ -5,6 +5,7 @@ "main": "index.js", "scripts": { "build": "cd ./signalr && npm run build && cd ../signalr-protocol-msgpack && npm run build", + "pretest": "tslint -c ./tslint.json -p ./signalr/tests/tsconfig.json && tslint -c ./tslint.json -p ./signalr-protocol-msgpack/tests/tsconfig.json", "test": "jest", "coverage": "jest --coverage" }, diff --git a/clients/ts/signalr/src/HttpConnection.ts b/clients/ts/signalr/src/HttpConnection.ts index 76d02bca09..becb08e5e6 100644 --- a/clients/ts/signalr/src/HttpConnection.ts +++ b/clients/ts/signalr/src/HttpConnection.ts @@ -7,7 +7,6 @@ import { IHttpConnectionOptions } from "./IHttpConnectionOptions"; import { ILogger, LogLevel } from "./ILogger"; import { HttpTransportType, ITransport, TransferFormat } from "./ITransport"; import { LongPollingTransport } from "./LongPollingTransport"; -import { EventSourceConstructor, WebSocketConstructor } from "./Polyfills"; import { ServerSentEventsTransport } from "./ServerSentEventsTransport"; import { Arg, createLogger } from "./Utils"; import { WebSocketTransport } from "./WebSocketTransport"; diff --git a/clients/ts/signalr/src/HubConnection.ts b/clients/ts/signalr/src/HubConnection.ts index d91556e375..d148dd3eb7 100644 --- a/clients/ts/signalr/src/HubConnection.ts +++ b/clients/ts/signalr/src/HubConnection.ts @@ -6,7 +6,6 @@ import { IConnection } from "./IConnection"; import { CancelInvocationMessage, CompletionMessage, IHubProtocol, InvocationMessage, MessageType, StreamInvocationMessage, StreamItemMessage } from "./IHubProtocol"; import { ILogger, LogLevel } from "./ILogger"; import { IStreamResult } from "./Stream"; -import { TextMessageFormat } from "./TextMessageFormat"; import { Arg, Subject } from "./Utils"; const DEFAULT_TIMEOUT_IN_MS: number = 30 * 1000; @@ -354,7 +353,11 @@ export class HubConnection { break; case MessageType.Close: this.logger.log(LogLevel.Information, "Close message received from server."); + + // We don't want to wait on the stop itself. + // tslint:disable-next-line:no-floating-promises this.connection.stop(message.error ? new Error("Server returned an error on close: " + message.error) : undefined); + break; default: this.logger.log(LogLevel.Warning, "Invalid message type: " + message.type); @@ -377,12 +380,18 @@ export class HubConnection { this.logger.log(LogLevel.Error, message); const error = new Error(message); + + // We don't want to wait on the stop itself. + // tslint:disable-next-line:no-floating-promises this.connection.stop(error); throw error; } if (responseMessage.error) { const message = "Server returned handshake error: " + responseMessage.error; this.logger.log(LogLevel.Error, message); + + // We don't want to wait on the stop itself. + // tslint:disable-next-line:no-floating-promises this.connection.stop(new Error(message)); } else { this.logger.log(LogLevel.Debug, "Server handshake complete."); @@ -405,7 +414,8 @@ export class HubConnection { private serverTimeout() { // The server hasn't talked to us in a while. It doesn't like us anymore ... :( - // Terminate the connection + // Terminate the connection, but we don't need to wait on the promise. + // tslint:disable-next-line:no-floating-promises this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server.")); } @@ -417,6 +427,9 @@ export class HubConnection { // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response. const message = "Server requested a response, which is not supported in this version of the client."; this.logger.log(LogLevel.Error, message); + + // We don't need to wait on this Promise. + // tslint:disable-next-line:no-floating-promises this.connection.stop(new Error(message)); } } else { diff --git a/clients/ts/signalr/src/LongPollingTransport.ts b/clients/ts/signalr/src/LongPollingTransport.ts index 6ec083214e..ff75fa91fa 100644 --- a/clients/ts/signalr/src/LongPollingTransport.ts +++ b/clients/ts/signalr/src/LongPollingTransport.ts @@ -17,7 +17,6 @@ export class LongPollingTransport implements ITransport { private readonly pollAbort: AbortController; private url?: string; - private pollXhr?: XMLHttpRequest; private running: boolean; private receiving?: Promise; private closeError?: Error; diff --git a/clients/ts/signalr/src/Stream.ts b/clients/ts/signalr/src/Stream.ts index 8dca2fb526..28e44c773f 100644 --- a/clients/ts/signalr/src/Stream.ts +++ b/clients/ts/signalr/src/Stream.ts @@ -45,6 +45,8 @@ export interface IStreamResult { * * @typeparam T The type of the items being sent by the server. */ +// We can't remove this, it's a breaking change, but it's not used. +// tslint:disable-next-line:no-unused-variable export interface ISubscription { /** Disconnects the {@link IStreamSubscriber} associated with this subscription from the stream. */ dispose(): void; diff --git a/clients/ts/signalr/tests/HttpConnection.test.ts b/clients/ts/signalr/tests/HttpConnection.test.ts index c3641c2712..dcce611d87 100644 --- a/clients/ts/signalr/tests/HttpConnection.test.ts +++ b/clients/ts/signalr/tests/HttpConnection.test.ts @@ -7,15 +7,15 @@ import { IHttpConnectionOptions } from "../src/IHttpConnectionOptions"; import { HttpTransportType, ITransport, TransferFormat } from "../src/ITransport"; import { HttpError } from "../src/Errors"; -import { LogLevel } from "../src/ILogger"; -import { EventSourceConstructor, WebSocketConstructor } from "../src/Polyfills"; -import { TextMessageFormat } from "../src/TextMessageFormat"; -import { WebSocketTransport } from "../src/WebSocketTransport"; +import { NullLogger } from "../src/Loggers"; +import { EventSourceConstructor } from "../src/Polyfills"; + import { eachEndpointUrl, eachTransport } from "./Common"; import { TestHttpClient } from "./TestHttpClient"; import { PromiseSource } from "./Utils"; const commonOptions: IHttpConnectionOptions = { + logger: NullLogger.instance, }; const defaultConnectionId = "abc123"; @@ -45,13 +45,13 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => Promise.reject("error")) - .on("GET", (r) => ""), + .on("POST", () => Promise.reject("error")) + .on("GET", () => ""), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); - expect(connection.start(TransferFormat.Text)) + await expect(connection.start(TransferFormat.Text)) .rejects .toThrow("error"); }); @@ -61,15 +61,15 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => { + .on("POST", () => { negotiating.resolve(); return defaultNegotiateResponse; }), transport: { - connect(url: string, transferFormat: TransferFormat) { + connect() { return Promise.resolve(); }, - send(data: any) { + send() { return Promise.resolve(); }, stop() { @@ -93,15 +93,13 @@ describe("HttpConnection", () => { }); it("can start a stopped connection", async () => { - let negotiateCalls = 0; const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => { - negotiateCalls += 1; + .on("POST", () => { return Promise.reject("reached negotiate"); }) - .on("GET", (r) => ""), + .on("GET", () => ""), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); @@ -119,12 +117,12 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => { - connection.stop(); + .on("POST", async () => { + await connection.stop(); return "{}"; }) - .on("GET", (r) => { - connection.stop(); + .on("GET", async () => { + await connection.stop(); return ""; }), } as IHttpConnectionOptions; @@ -143,8 +141,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [] })) - .on("GET", (r) => { throw new Error("fail"); }), + .on("POST", () => ({ connectionId: "42", availableTransports: [] })) + .on("GET", () => { throw new Error("fail"); }), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org?q=myData", options); @@ -161,7 +159,7 @@ describe("HttpConnection", () => { connectUrl.resolve(url); return Promise.resolve(); }, - send(data: any): Promise { + send(): Promise { return Promise.resolve(); }, stop(): Promise { @@ -174,8 +172,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => "{ \"connectionId\": \"42\" }") - .on("GET", (r) => ""), + .on("POST", () => "{ \"connectionId\": \"42\" }") + .on("GET", () => ""), transport: fakeTransport, } as IHttpConnectionOptions; @@ -201,10 +199,10 @@ describe("HttpConnection", () => { negotiateUrl.resolve(r.url); throw new HttpError("We don't care how this turns out", 500); }) - .on("GET", (r) => { + .on("GET", () => { return new HttpResponse(204); }) - .on("DELETE", (r) => new HttpResponse(202)), + .on("DELETE", () => new HttpResponse(202)), } as IHttpConnectionOptions; const connection = new HttpConnection(givenUrl, options); @@ -232,8 +230,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => negotiateResponse) - .on("GET", (r) => new HttpResponse(204)), + .on("POST", () => negotiateResponse) + .on("GET", () => new HttpResponse(204)), transport: requestedTransport, } as IHttpConnectionOptions; @@ -248,9 +246,9 @@ describe("HttpConnection", () => { it(`can be started using ${HttpTransportType[requestedTransport]} transport when transport mask is ${name}`, async () => { const negotiateResponse = { availableTransports: [ - { transport: "WebSockets", transferFormats: [ "Text", "Binary" ] }, - { transport: "ServerSentEvents", transferFormats: [ "Text" ] }, - { transport: "LongPolling", transferFormats: [ "Text", "Binary" ] }, + { transport: "WebSockets", transferFormats: ["Text", "Binary"] }, + { transport: "ServerSentEvents", transferFormats: ["Text"] }, + { transport: "LongPolling", transferFormats: ["Text", "Binary"] }, ], connectionId: "abc123", }; @@ -258,8 +256,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => negotiateResponse) - .on("GET", (r) => new HttpResponse(204)), + .on("POST", () => negotiateResponse) + .on("GET", () => new HttpResponse(204)), transport: val, } as IHttpConnectionOptions; @@ -272,9 +270,9 @@ describe("HttpConnection", () => { it(`cannot be started if server's only transport (${HttpTransportType[requestedTransport]}) is masked out by the transport option`, async () => { const negotiateResponse = { availableTransports: [ - { transport: "WebSockets", transferFormats: [ "Text", "Binary" ] }, - { transport: "ServerSentEvents", transferFormats: [ "Text" ] }, - { transport: "LongPolling", transferFormats: [ "Text", "Binary" ] }, + { transport: "WebSockets", transferFormats: ["Text", "Binary"] }, + { transport: "ServerSentEvents", transferFormats: ["Text"] }, + { transport: "LongPolling", transferFormats: ["Text", "Binary"] }, ], connectionId: "abc123", }; @@ -289,8 +287,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => negotiateResponse) - .on("GET", (r) => new HttpResponse(204)), + .on("POST", () => negotiateResponse) + .on("GET", () => new HttpResponse(204)), transport: transportMask, } as IHttpConnectionOptions; @@ -309,8 +307,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [] })) - .on("GET", (r) => ""), + .on("POST", () => ({ connectionId: "42", availableTransports: [] })) + .on("GET", () => ""), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); @@ -351,7 +349,7 @@ describe("HttpConnection", () => { let firstNegotiate = true; let firstPoll = true; const httpClient = new TestHttpClient() - .on("POST", /negotiate$/, (r) => { + .on("POST", /negotiate$/, () => { if (firstNegotiate) { firstNegotiate = false; return { url: "https://another.domain.url/chat" }; @@ -361,14 +359,14 @@ describe("HttpConnection", () => { connectionId: "0rge0d00-0040-0030-0r00-000q00r00e00", }; }) - .on("GET", (r) => { + .on("GET", () => { if (firstPoll) { firstPoll = false; return ""; } return new HttpResponse(204, "No Content", ""); }) - .on("DELETE", (r) => new HttpResponse(202)); + .on("DELETE", () => new HttpResponse(202)); const options: IHttpConnectionOptions = { ...commonOptions, @@ -392,7 +390,7 @@ describe("HttpConnection", () => { it("fails to start if negotiate redirects more than 100 times", async () => { const httpClient = new TestHttpClient() - .on("POST", /negotiate$/, (r) => ({ url: "https://another.domain.url/chat" })); + .on("POST", /negotiate$/, () => ({ url: "https://another.domain.url/chat" })); const options: IHttpConnectionOptions = { ...commonOptions, @@ -441,7 +439,7 @@ describe("HttpConnection", () => { } return new HttpResponse(204, "No Content", ""); }) - .on("DELETE", (r) => new HttpResponse(202)); + .on("DELETE", () => new HttpResponse(202)); const options: IHttpConnectionOptions = { ...commonOptions, @@ -481,7 +479,7 @@ describe("HttpConnection", () => { } }, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [availableTransport] })) + .on("POST", () => ({ connectionId: "42", availableTransports: [availableTransport] })) .on("GET", (r) => { httpClientGetCount++; // tslint:disable-next-line:no-string-literal @@ -500,7 +498,7 @@ describe("HttpConnection", () => { throw new Error("fail"); } }) - .on("DELETE", (r) => new HttpResponse(202)), + .on("DELETE", () => new HttpResponse(202)), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); @@ -521,8 +519,8 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [availableTransport] })) - .on("GET", (r) => { + .on("POST", () => ({ connectionId: "42", availableTransports: [availableTransport] })) + .on("GET", () => { httpClientGetCount++; if (httpClientGetCount === 1) { // First long polling request must succeed so start completes @@ -531,7 +529,7 @@ describe("HttpConnection", () => { throw new Error("fail"); } }) - .on("DELETE", (r) => new HttpResponse(202)), + .on("DELETE", () => new HttpResponse(202)), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); @@ -549,7 +547,7 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [serverSentEventsTransport] })), + .on("POST", () => ({ connectionId: "42", availableTransports: [serverSentEventsTransport] })), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); @@ -565,12 +563,12 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, httpClient: new TestHttpClient() - .on("POST", (r) => ({ connectionId: "42", availableTransports: [webSocketsTransport] })), + .on("POST", () => ({ connectionId: "42", availableTransports: [webSocketsTransport] })), } as IHttpConnectionOptions; const connection = new HttpConnection("http://tempuri.org", options); - expect(connection.start(TransferFormat.Text)) + await expect(connection.start(TransferFormat.Text)) .rejects .toThrow("Unable to initialize any of the available transports."); }); @@ -584,7 +582,7 @@ describe("HttpConnection", () => { it("uses global WebSocket if defined", async () => { // tslint:disable-next-line:no-string-literal global["WebSocket"] = class WebSocket { - constructor(url: string, protocols?: string | string[]) { + constructor() { throw new Error("WebSocket constructor called."); } }; @@ -609,7 +607,7 @@ describe("HttpConnection", () => { let eventSourceConstructorCalled: boolean = false; // tslint:disable-next-line:no-string-literal global["EventSource"] = class EventSource { - constructor(url: string, eventSourceInitDict?: EventSourceInit) { + constructor() { eventSourceConstructorCalled = true; throw new Error("EventSource constructor called."); } @@ -617,7 +615,7 @@ describe("HttpConnection", () => { const options: IHttpConnectionOptions = { ...commonOptions, - httpClient: new TestHttpClient().on("POST", (r) => { + httpClient: new TestHttpClient().on("POST", () => { return { availableTransports: [ { transport: "ServerSentEvents", transferFormats: ["Text"] }, @@ -643,17 +641,19 @@ describe("HttpConnection", () => { it("uses EventSource constructor from options if provided", async () => { let eventSourceConstructorCalled: boolean = false; - const customEventSourceType = class EventSource { - constructor(url: string, eventSourceInitDict?: EventSourceInit) { + class TestEventSource { + // The "_" prefix tell TypeScript not to worry about unused parameter, but tslint doesn't like it. + // tslint:disable-next-line:variable-name + constructor(_url: string, _eventSourceInitDict: EventSourceInit) { eventSourceConstructorCalled = true; throw new Error("EventSource constructor called."); } - }; + } const options: IHttpConnectionOptions = { ...commonOptions, - EventSource: customEventSourceType as EventSourceConstructor, - httpClient: new TestHttpClient().on("POST", (r) => { + EventSource: TestEventSource as EventSourceConstructor, + httpClient: new TestHttpClient().on("POST", () => { return { availableTransports: [ { transport: "ServerSentEvents", transferFormats: ["Text"] }, @@ -674,15 +674,17 @@ describe("HttpConnection", () => { }); it("uses WebSocket constructor from options if provided", async () => { - const customWebSocketType = class WebSocket { - constructor(url: string, protocols?: string | string[]) { + class TestWebSocket { + // The "_" prefix tell TypeScript not to worry about unused parameter, but tslint doesn't like it. + // tslint:disable-next-line:variable-name + constructor(_url: string, _protocols?: string | string[]) { throw new Error("WebSocket constructor called."); } - }; + } const options: IHttpConnectionOptions = { ...commonOptions, - WebSocket: customWebSocketType as WebSocketConstructor, + WebSocket: TestWebSocket, skipNegotiation: true, transport: HttpTransportType.WebSockets, } as IHttpConnectionOptions; diff --git a/clients/ts/signalr/tests/HubConnection.test.ts b/clients/ts/signalr/tests/HubConnection.test.ts index a33aee6586..6c55cb8177 100644 --- a/clients/ts/signalr/tests/HubConnection.test.ts +++ b/clients/ts/signalr/tests/HubConnection.test.ts @@ -88,7 +88,9 @@ describe("HubConnection", () => { const hubConnection = createHubConnection(connection); try { - const invokePromise = hubConnection.send("testMethod", "arg", 42) + // We don't actually care to wait for the send. + // tslint:disable-next-line:no-floating-promises + hubConnection.send("testMethod", "arg", 42) .catch((_) => { }); // Suppress exception and unhandled promise rejection warning. // Verify the message is sent @@ -103,7 +105,7 @@ describe("HubConnection", () => { }); } finally { // Close the connection - hubConnection.stop(); + await hubConnection.stop(); } }); }); @@ -114,7 +116,9 @@ describe("HubConnection", () => { const hubConnection = createHubConnection(connection); try { - const invokePromise = hubConnection.invoke("testMethod", "arg", 42) + // We don't actually care to wait for the send. + // tslint:disable-next-line:no-floating-promises + hubConnection.invoke("testMethod", "arg", 42) .catch((_) => { }); // Suppress exception and unhandled promise rejection warning. // Verify the message is sent @@ -131,7 +135,7 @@ describe("HubConnection", () => { } finally { // Close the connection - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -153,7 +157,7 @@ describe("HubConnection", () => { // message only contained handshake response expect(protocolCalled).toEqual(false); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -176,7 +180,7 @@ describe("HubConnection", () => { // message only contained handshake response expect(protocolCalled).toEqual(false); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -204,7 +208,7 @@ describe("HubConnection", () => { // left over data is the message pack message expect(receivedProcotolData!.byteLength).toEqual(102); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -223,7 +227,7 @@ describe("HubConnection", () => { expect(receivedProcotolData).toEqual("{\"type\":6}" + TextMessageFormat.RecordSeparator); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -239,7 +243,7 @@ describe("HubConnection", () => { await expect(invokePromise).rejects.toThrow("foo"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -255,7 +259,7 @@ describe("HubConnection", () => { expect(await invokePromise).toBe("foo"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -267,9 +271,9 @@ describe("HubConnection", () => { connection.receiveHandshakeResponse(); const invokePromise = hubConnection.invoke("testMethod"); - hubConnection.stop(); + await hubConnection.stop(); - expect(invokePromise).rejects.toThrow("Invocation canceled due to connection being closed."); + await expect(invokePromise).rejects.toThrow("Invocation canceled due to connection being closed."); }); it("completes pending invocations when connection is lost", async () => { @@ -283,9 +287,9 @@ describe("HubConnection", () => { // Typically this would be called by the transport connection.onclose!(new Error("Connection lost")); - expect(invokePromise).rejects.toThrow("Connection lost"); + await expect(invokePromise).rejects.toThrow("Connection lost"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); }); @@ -314,7 +318,7 @@ describe("HubConnection", () => { expect(warnings).toEqual(["No client method with the name 'message' found."]); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -346,7 +350,7 @@ describe("HubConnection", () => { expect(warnings).toEqual(["No client method with the name 'message' found."]); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -382,7 +386,7 @@ describe("HubConnection", () => { expect(count).toBe(2); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -418,7 +422,7 @@ describe("HubConnection", () => { expect(count).toBe(3); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -443,7 +447,7 @@ describe("HubConnection", () => { expect(count).toBe(1); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -466,7 +470,7 @@ describe("HubConnection", () => { expect(value).toBe("test"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -481,7 +485,7 @@ describe("HubConnection", () => { expect(closeError!.message).toEqual("Server returned handshake error: Error!"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -505,7 +509,7 @@ describe("HubConnection", () => { expect(isClosed).toEqual(true); expect(closeError).toBeUndefined(); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -530,7 +534,7 @@ describe("HubConnection", () => { expect(isClosed).toEqual(true); expect(closeError!.message).toEqual("Server returned an error on close: Error!"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -556,7 +560,7 @@ describe("HubConnection", () => { expect(numInvocations1).toBe(1); expect(numInvocations2).toBe(1); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -590,7 +594,7 @@ describe("HubConnection", () => { expect(numInvocations).toBe(1); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -602,7 +606,7 @@ describe("HubConnection", () => { hubConnection.on("message", (t) => { }); hubConnection.on("message", () => { }); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -647,7 +651,7 @@ describe("HubConnection", () => { hubConnection.off(null!, () => { }); hubConnection.off(undefined!, () => { }); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); }); @@ -658,7 +662,7 @@ describe("HubConnection", () => { const hubConnection = createHubConnection(connection); try { - const invokePromise = hubConnection.stream("testStream", "arg", 42); + hubConnection.stream("testStream", "arg", 42); // Verify the message is sent expect(connection.sentData.length).toBe(1); @@ -673,9 +677,9 @@ describe("HubConnection", () => { }); // Close the connection - hubConnection.stop(); + await hubConnection.stop(); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -691,9 +695,9 @@ describe("HubConnection", () => { connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId, error: "foo" }); - expect(observer.completed).rejects.toThrow("Error: foo"); + await expect(observer.completed).rejects.toThrow("Error: foo"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -711,7 +715,7 @@ describe("HubConnection", () => { expect(await observer.completed).toEqual([]); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -723,11 +727,11 @@ describe("HubConnection", () => { const observer = new TestObserver(); hubConnection.stream("testMethod") .subscribe(observer); - hubConnection.stop(); + await hubConnection.stop(); - expect(observer.completed).rejects.toThrow("Error: Invocation canceled due to connection being closed."); + await expect(observer.completed).rejects.toThrow("Error: Invocation canceled due to connection being closed."); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -743,9 +747,9 @@ describe("HubConnection", () => { // Typically this would be called by the transport connection.onclose!(new Error("Connection lost")); - expect(observer.completed).rejects.toThrow("Error: Connection lost"); + await expect(observer.completed).rejects.toThrow("Error: Connection lost"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -771,7 +775,7 @@ describe("HubConnection", () => { connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId }); expect(await observer.completed).toEqual([1, 2, 3]); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -780,13 +784,13 @@ describe("HubConnection", () => { const hubConnection = createHubConnection(connection); try { - const observer = hubConnection.stream("testMethod").subscribe(NullSubscriber.instance); + hubConnection.stream("testMethod").subscribe(NullSubscriber.instance); // Typically this would be called by the transport // triggers observer.error() connection.onclose!(new Error("Connection lost")); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -795,17 +799,17 @@ describe("HubConnection", () => { const hubConnection = createHubConnection(connection); try { - const observer = hubConnection.stream("testMethod").subscribe(NullSubscriber.instance); + hubConnection.stream("testMethod").subscribe(NullSubscriber.instance); // Send completion to trigger observer.complete() // Expectation is connection.receive will not to throw connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId }); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); - it("can be canceled", () => { + it("can be canceled", async () => { const connection = new TestConnection(); const hubConnection = createHubConnection(connection); try { @@ -831,7 +835,7 @@ describe("HubConnection", () => { type: MessageType.CancelInvocation, }); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); }); @@ -848,7 +852,7 @@ describe("HubConnection", () => { connection.onclose!(); expect(invocations).toBe(2); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -863,7 +867,7 @@ describe("HubConnection", () => { connection.onclose!(new Error("Test error.")); expect(error!.message).toBe("Test error."); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -877,7 +881,7 @@ describe("HubConnection", () => { connection.onclose!(); // expect no errors } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -892,7 +896,7 @@ describe("HubConnection", () => { expect(state).toBe(HubConnectionState.Disconnected); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); }); @@ -911,7 +915,7 @@ describe("HubConnection", () => { expect(await invokePromise).toBe("foo"); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -930,13 +934,13 @@ describe("HubConnection", () => { await pingAndWait(connection); } - connection.stop(); + await connection.stop(); const error = await p.promise; expect(error).toBeUndefined(); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -959,13 +963,13 @@ describe("HubConnection", () => { await pingAndWait(connection); } - connection.stop(); + await connection.stop(); const error = await p.promise; expect(error).toBeUndefined(); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); @@ -984,7 +988,7 @@ describe("HubConnection", () => { expect(error).toEqual(new Error("Server timeout elapsed without receiving a message from the server.")); } finally { - hubConnection.stop(); + await hubConnection.stop(); } }); }); diff --git a/clients/ts/signalr/tests/HubConnectionBuilder.test.ts b/clients/ts/signalr/tests/HubConnectionBuilder.test.ts index cb29ac4e3e..8c76e36a7c 100644 --- a/clients/ts/signalr/tests/HubConnectionBuilder.test.ts +++ b/clients/ts/signalr/tests/HubConnectionBuilder.test.ts @@ -13,15 +13,6 @@ import { NullLogger } from "../src/Loggers"; import { TestHttpClient } from "./TestHttpClient"; import { PromiseSource } from "./Utils"; -const allTransportsNegotiateResponse = { - availableTransports: [ - { transport: "WebSockets", transferFormats: ["Text", "Binary"] }, - { transport: "ServerSentEvents", transferFormats: ["Text"] }, - { transport: "LongPolling", transferFormats: ["Text", "Binary"] }, - ], - connectionId: "abc123", -}; - const longPollingNegotiateResponse = { availableTransports: [ { transport: "LongPolling", transferFormats: ["Text", "Binary"] }, @@ -80,11 +71,6 @@ describe("HubConnectionBuilder", () => { it("can configure transport type", async () => { const protocol = new TestProtocol(); - const pollSent = new PromiseSource(); - const pollCompleted = new PromiseSource(); - const negotiateReceived = new PromiseSource(); - const testClient = createTestClient(pollSent, pollCompleted.promise, allTransportsNegotiateResponse); - const builder = createConnectionBuilder() .withUrl("http://example.com", HttpTransportType.WebSockets) .withHubProtocol(protocol); diff --git a/clients/ts/signalr/tests/LongPollingTransport.test.ts b/clients/ts/signalr/tests/LongPollingTransport.test.ts index f0b050aa3f..66d3715c86 100644 --- a/clients/ts/signalr/tests/LongPollingTransport.test.ts +++ b/clients/ts/signalr/tests/LongPollingTransport.test.ts @@ -1,13 +1,13 @@ -import { HttpError, TimeoutError } from "../src/Errors"; +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + import { HttpResponse } from "../src/HttpClient"; -import { LogLevel } from "../src/ILogger"; import { TransferFormat } from "../src/ITransport"; import { NullLogger } from "../src/Loggers"; import { LongPollingTransport } from "../src/LongPollingTransport"; -import { ConsoleLogger } from "../src/Utils"; import { TestHttpClient } from "./TestHttpClient"; -import { delay, PromiseSource, SyncPoint } from "./Utils"; +import { PromiseSource, SyncPoint } from "./Utils"; describe("LongPollingTransport", () => { it("shuts down polling by aborting in-progress request", async () => { @@ -29,7 +29,7 @@ describe("LongPollingTransport", () => { return new HttpResponse(200); } }) - .on("DELETE", (r) => new HttpResponse(202)); + .on("DELETE", () => new HttpResponse(202)); const transport = new LongPollingTransport(client, undefined, NullLogger.instance, false); await transport.connect("http://example.com", TransferFormat.Text); @@ -42,17 +42,16 @@ describe("LongPollingTransport", () => { it("204 server response stops polling and raises onClose", async () => { let firstPoll = true; - let onCloseCalled = false; const client = new TestHttpClient() - .on("GET", async (r) => { - if (firstPoll) { - firstPoll = false; - return new HttpResponse(200); - } else { - // A 204 response will stop the long polling transport - return new HttpResponse(204); - } - }); + .on("GET", async () => { + if (firstPoll) { + firstPoll = false; + return new HttpResponse(200); + } else { + // A 204 response will stop the long polling transport + return new HttpResponse(204); + } + }); const transport = new LongPollingTransport(client, undefined, NullLogger.instance, false); const stopPromise = makeClosedPromise(transport); @@ -83,7 +82,7 @@ describe("LongPollingTransport", () => { await deleteSyncPoint.waitToContinue(); return new HttpResponse(202); }); - + const transport = new LongPollingTransport(httpClient, undefined, NullLogger.instance, false); await transport.connect("http://tempuri.org", TransferFormat.Text); @@ -119,4 +118,4 @@ function makeClosedPromise(transport: LongPollingTransport): Promise { } }; return closed.promise; -} \ No newline at end of file +} diff --git a/clients/ts/signalr/tests/Utils.ts b/clients/ts/signalr/tests/Utils.ts index 6be03892ee..df132a74e3 100644 --- a/clients/ts/signalr/tests/Utils.ts +++ b/clients/ts/signalr/tests/Utils.ts @@ -60,4 +60,4 @@ export class SyncPoint { this.atSyncPoint.resolve(); return this.continueFromSyncPoint.promise; } -} \ No newline at end of file +} diff --git a/clients/ts/tslint.json b/clients/ts/tslint.json index 9dc31ff068..19d791f379 100644 --- a/clients/ts/tslint.json +++ b/clients/ts/tslint.json @@ -6,6 +6,8 @@ "interface-name": false, "unified-signatures": false, "max-classes-per-file": false, + "no-floating-promises": true, + "no-unused-variable": [true, {"ignore-pattern": "^_"}], "no-empty": false, "no-bitwise": false, "no-console": false