fix #2407 by tslinting tests before running (#2459)

This commit is contained in:
Andrew Stanton-Nurse 2018-06-11 14:19:33 -07:00 committed by GitHub
parent c7ebae47ea
commit 7317762b29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 164 additions and 161 deletions

View File

@ -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();
}

View File

@ -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";

View File

@ -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"
},

View File

@ -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";

View File

@ -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 {

View File

@ -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<void>;
private closeError?: Error;

View File

@ -45,6 +45,8 @@ export interface IStreamResult<T> {
*
* @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<T> {
/** Disconnects the {@link IStreamSubscriber} associated with this subscription from the stream. */
dispose(): void;

View File

@ -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<void> {
send(): Promise<void> {
return Promise.resolve();
},
stop(): Promise<void> {
@ -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;

View File

@ -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<any>("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();
}
});
});

View File

@ -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<HttpRequest>();
const pollCompleted = new PromiseSource<HttpResponse>();
const negotiateReceived = new PromiseSource<HttpRequest>();
const testClient = createTestClient(pollSent, pollCompleted.promise, allTransportsNegotiateResponse);
const builder = createConnectionBuilder()
.withUrl("http://example.com", HttpTransportType.WebSockets)
.withHubProtocol(protocol);

View File

@ -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<void> {
}
};
return closed.promise;
}
}

View File

@ -60,4 +60,4 @@ export class SyncPoint {
this.atSyncPoint.resolve();
return this.continueFromSyncPoint.promise;
}
}
}

View File

@ -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