Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit e9660f4

Browse files
committed
some test simplification to prepare for adding ts client tests for streaming
1 parent a3bcaf5 commit e9660f4

File tree

5 files changed

+71
-132
lines changed

5 files changed

+71
-132
lines changed

client-ts/Microsoft.AspNetCore.SignalR.Client.TS.Tests/HubConnection.spec.ts

Lines changed: 45 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -3,149 +3,84 @@ import { HubConnection } from "../Microsoft.AspNetCore.SignalR.Client.TS/HubConn
33
import { DataReceived, ConnectionClosed } from "../Microsoft.AspNetCore.SignalR.Client.TS/Common"
44
import { TransportType, ITransport } from "../Microsoft.AspNetCore.SignalR.Client.TS/Transports"
55

6+
import { asyncit as it, captureException } from './JasmineUtils';
7+
68
describe("HubConnection", () => {
7-
it("completes pending invocations when stopped", async done => {
8-
let connection: IConnection = {
9-
start(transportType: TransportType | ITransport): Promise<void> {
10-
return Promise.resolve();
11-
},
12-
13-
send(data: any): Promise<void> {
14-
return Promise.resolve();
15-
},
16-
17-
stop(): void {
18-
if (this.onClosed) {
19-
this.onClosed();
20-
}
21-
},
22-
23-
onDataReceived: null,
24-
onClosed: null
25-
};
9+
it("completes pending invocations when stopped", async () => {
10+
let connection = new TestConnection();
2611

2712
let hubConnection = new HubConnection(connection);
2813
var invokePromise = hubConnection.invoke("testMethod");
2914
hubConnection.stop();
3015

31-
try {
32-
await invokePromise;
33-
fail();
34-
}
35-
catch (e) {
36-
expect(e.message).toBe("Invocation cancelled due to connection being closed.");
37-
}
38-
done();
16+
let ex = await captureException(async () => await invokePromise);
17+
expect(ex.message).toBe("Invocation cancelled due to connection being closed.");
3918
});
4019

41-
it("completes pending invocations when connection is lost", async done => {
42-
let connection: IConnection = {
43-
start(transportType: TransportType | ITransport): Promise<void> {
44-
return Promise.resolve();
45-
},
46-
47-
send(data: any): Promise<void> {
48-
return Promise.resolve();
49-
},
50-
51-
stop(): void {
52-
if (this.onClosed) {
53-
this.onClosed();
54-
}
55-
},
56-
57-
onDataReceived: null,
58-
onClosed: null
59-
};
20+
it("completes pending invocations when connection is lost", async () => {
21+
let connection = new TestConnection();
6022

6123
let hubConnection = new HubConnection(connection);
6224
var invokePromise = hubConnection.invoke("testMethod");
6325
// Typically this would be called by the transport
6426
connection.onClosed(new Error("Connection lost"));
6527

66-
try {
67-
await invokePromise;
68-
fail();
69-
}
70-
catch (e) {
71-
expect(e.message).toBe("Connection lost");
72-
}
73-
done();
28+
let ex = await captureException(async () => await invokePromise);
29+
expect(ex.message).toBe("Connection lost");
7430
});
7531

76-
it("sends invocations as nonblocking", async done => {
77-
let dataSent: string;
78-
let connection: IConnection = {
79-
start(transportType: TransportType): Promise<void> {
80-
return Promise.resolve();
81-
},
82-
83-
send(data: any): Promise<void> {
84-
dataSent = data;
85-
return Promise.resolve();
86-
},
87-
88-
stop(): void {
89-
if (this.onClosed) {
90-
this.onClosed();
91-
}
92-
},
93-
94-
onDataReceived: null,
95-
onClosed: null
96-
};
32+
it("sends invocations as nonblocking", async () => {
33+
let connection = new TestConnection();
9734

9835
let hubConnection = new HubConnection(connection);
9936
let invokePromise = hubConnection.invoke("testMethod");
10037

101-
expect(JSON.parse(dataSent).nonblocking).toBe(false);
38+
expect(connection.sentData.length).toBe(1);
39+
expect(JSON.parse(connection.sentData[0]).nonblocking).toBe(false);
10240

10341
// will clean pending promises
10442
connection.onClosed();
10543

106-
try {
107-
await invokePromise;
108-
fail(); // exception is expected because the call has not completed
109-
}
110-
catch (e) {
111-
}
112-
done();
44+
let ex = await captureException(async () => await invokePromise);
45+
// Don't care about the exception
11346
});
11447

115-
it("rejects streaming responses made using 'invoke'", async done => {
116-
let connection: IConnection = {
117-
start(transportType: TransportType): Promise<void> {
118-
return Promise.resolve();
119-
},
120-
121-
send(data: any): Promise<void> {
122-
return Promise.resolve();
123-
},
124-
125-
stop(): void {
126-
if (this.onClosed) {
127-
this.onClosed();
128-
}
129-
},
130-
131-
onDataReceived: null,
132-
onClosed: null
133-
};
48+
it("rejects streaming responses made using 'invoke'", async () => {
49+
let connection = new TestConnection();
13450

13551
let hubConnection = new HubConnection(connection);
13652
let invokePromise = hubConnection.invoke("testMethod");
13753

13854
connection.onDataReceived("{ \"type\": 2, \"invocationId\": \"0\", \"result\": null }");
13955
connection.onClosed();
14056

141-
try {
142-
await invokePromise;
143-
fail();
57+
let ex = await captureException(async () => await invokePromise);
58+
expect(ex.message).toBe("Streaming methods must be invoked using HubConnection.stream");
59+
});
60+
});
61+
62+
class TestConnection implements IConnection {
63+
start(transportType: TransportType | ITransport): Promise<void> {
64+
return Promise.resolve();
65+
};
66+
67+
send(data: any): Promise<void> {
68+
if (this.sentData) {
69+
this.sentData.push(data);
14470
}
145-
catch (e) {
146-
expect(e.message).toBe("Streaming methods must be invoked using HubConnection.stream");
71+
else {
72+
this.sentData = [data];
14773
}
74+
return Promise.resolve();
75+
};
14876

149-
done();
150-
});
151-
});
77+
stop(): void {
78+
if (this.onClosed) {
79+
this.onClosed();
80+
}
81+
};
82+
83+
onDataReceived: DataReceived;
84+
onClosed: ConnectionClosed;
85+
sentData: [any];
86+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export function asyncit(expectation: string, assertion?: () => Promise<any>, timeout?: number): void {
2+
let testFunction: (done: DoneFn) => void;
3+
if (assertion) {
4+
testFunction = done => {
5+
assertion()
6+
.then(() => done())
7+
.catch(() => fail());
8+
};
9+
}
10+
11+
it(expectation, testFunction, timeout);
12+
}
13+
14+
export async function captureException(fn: () => Promise<any>): Promise<Error> {
15+
try {
16+
await fn();
17+
return null;
18+
} catch (e) {
19+
return e;
20+
}
21+
}

samples/SocketsSample/Hubs/Streaming.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ namespace SocketsSample.Hubs
99
{
1010
public class Streaming : Hub
1111
{
12-
[return: Streaming]
1312
public IObservable<int> ObservableCounter(int count, int delay)
1413
{
1514
return new CounterObservable(count, delay);
1615
}
1716

18-
[return: Streaming]
1917
public ReadableChannel<int> ChannelCounter(int count, int delay)
2018
{
2119
var channel = Channel.CreateUnbounded<int>();

src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,12 @@ private async Task Invoke(HubMethodDescriptor descriptor, Connection connection,
283283

284284
if (hasResult && IsStreamed(methodExecutor, result, out var channel))
285285
{
286+
_logger.LogTrace("[{connectionId}/{invocationId}] Streaming result of type {resultType}", connection.ConnectionId, invocationMessage.InvocationId, result.GetType().FullName);
286287
await StreamResultsAsync(invocationMessage.InvocationId, connection, protocol, channel);
287288
}
288289
else
289290
{
291+
_logger.LogTrace("[{connectionId}/{invocationId}] Sending result of type {resultType}", connection.ConnectionId, invocationMessage.InvocationId, result.GetType().FullName);
290292
await SendMessageAsync(connection, protocol, CompletionMessage.WithResult(invocationMessage.InvocationId, result));
291293
}
292294
}
@@ -343,14 +345,6 @@ private async Task StreamResultsAsync(string invocationId, Connection connection
343345

344346
private bool IsStreamed(ObjectMethodExecutor methodExecutor, object result, out IAsyncEnumerator<object> enumerator)
345347
{
346-
// TODO: Cache attributes the OME?
347-
var streamingAttribute = methodExecutor.MethodInfo.ReturnParameter.GetCustomAttribute<StreamingAttribute>();
348-
if (streamingAttribute == null)
349-
{
350-
enumerator = null;
351-
return false;
352-
}
353-
354348
var observableInterface = result.GetType().GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IObservable<>));
355349
if (observableInterface != null)
356350
{
@@ -364,8 +358,9 @@ private bool IsStreamed(ObjectMethodExecutor methodExecutor, object result, out
364358
}
365359
else
366360
{
367-
// This type cannot be streamed
368-
throw new NotSupportedException($"Cannot stream results of type: {result.GetType().FullName}");
361+
// Not streamed
362+
enumerator = null;
363+
return false;
369364
}
370365
}
371366

src/Microsoft.AspNetCore.SignalR/StreamingAttribute.cs

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)