Removed params from proxy's SendAsync and rename to SendCoreAsync (#1605)

This commit is contained in:
James Newton-King 2018-03-16 14:05:22 +13:00 committed by GitHub
parent d27844dfef
commit 2d6077db4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 260 additions and 49 deletions

View File

@ -9,7 +9,7 @@ namespace ChatSample
{ {
public class HubWithPresence : Hub public class HubWithPresence : Hub
{ {
private IUserTracker<HubWithPresence> _userTracker; private readonly IUserTracker<HubWithPresence> _userTracker;
public HubWithPresence(IUserTracker<HubWithPresence> userTracker) public HubWithPresence(IUserTracker<HubWithPresence> userTracker)
{ {

View File

@ -23,12 +23,12 @@ namespace ChatSample.Hubs
public override Task OnUsersJoined(UserDetails[] users) public override Task OnUsersJoined(UserDetails[] users)
{ {
return Clients.Client(Context.ConnectionId).SendAsync("UsersJoined", new[] { users }); return Clients.Client(Context.ConnectionId).SendAsync("UsersJoined", users);
} }
public override Task OnUsersLeft(UserDetails[] users) public override Task OnUsersLeft(UserDetails[] users)
{ {
return Clients.Client(Context.ConnectionId).SendAsync("UsersLeft", new[] { users }); return Clients.Client(Context.ConnectionId).SendAsync("UsersLeft", users);
} }
public async Task Send(string message) public async Task Send(string message)

View File

@ -9,7 +9,7 @@ using Microsoft.AspNetCore.SignalR.Internal.Protocol;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
public class DefaultHubLifetimeManager<THub> : HubLifetimeManager<THub> public class DefaultHubLifetimeManager<THub> : HubLifetimeManager<THub> where THub : Hub
{ {
private readonly HubConnectionList _connections = new HubConnectionList(); private readonly HubConnectionList _connections = new HubConnectionList();
private readonly HubGroupList _groups = new HubGroupList(); private readonly HubGroupList _groups = new HubGroupList();

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.SignalR
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{ {
result = _clientProxy.SendAsync(binder.Name, args); result = _clientProxy.SendCoreAsync(binder.Name, args);
return true; return true;
} }
} }

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
public class HubClients<THub> : IHubClients public class HubClients<THub> : IHubClients where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
public class HubClients<THub, T> : IHubClients<T> public class HubClients<THub, T> : IHubClients<T> where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
public abstract class HubLifetimeManager<THub> public abstract class HubLifetimeManager<THub> where THub : Hub
{ {
public abstract Task OnConnectedAsync(HubConnectionContext connection); public abstract Task OnConnectedAsync(HubConnectionContext connection);

View File

@ -7,13 +7,17 @@ namespace Microsoft.AspNetCore.SignalR
{ {
public interface IClientProxy public interface IClientProxy
{ {
// client proxy method is called SendCoreAsync instead of SendAsync so that arrays of references
// like string[], e.g. SendAsync(string, string[]), do not choose SendAsync(string, object[])
// over SendAsync(string, object) overload
/// <summary> /// <summary>
/// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance. /// Invokes a method on the connection(s) represented by the <see cref="IClientProxy"/> instance.
/// Does not wait for a response from the receiver. /// Does not wait for a response from the receiver.
/// </summary> /// </summary>
/// <param name="method">name of the method to invoke</param> /// <param name="method">Name of the method to invoke.</param>
/// <param name="args">argumetns to pass to the client</param> /// <param name="args">A collection of arguments to pass to the client.</param>
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
Task SendAsync(string method, object[] args); Task SendCoreAsync(string method, object[] args);
} }
} }

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method) public static Task SendAsync(this IClientProxy clientProxy, string method)
{ {
return clientProxy.SendAsync(method, Array.Empty<object>()); return clientProxy.SendCoreAsync(method, Array.Empty<object>());
} }
/// <summary> /// <summary>
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1)
{ {
return clientProxy.SendAsync(method, new object[] { arg1 }); return clientProxy.SendCoreAsync(method, new object[] { arg1 });
} }
/// <summary> /// <summary>
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2 });
} }
/// <summary> /// <summary>
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3 });
} }
/// <summary> /// <summary>
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4 });
} }
/// <summary> /// <summary>
@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5 });
} }
/// <summary> /// <summary>
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
} }
/// <summary> /// <summary>
@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
} }
/// <summary> /// <summary>
@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 });
} }
/// <summary> /// <summary>
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 });
} }
/// <summary> /// <summary>
@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.SignalR
/// <returns>A task that represents when the data has been sent to the client.</returns> /// <returns>A task that represents when the data has been sent to the client.</returns>
public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10) public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, object arg3, object arg4, object arg5, object arg6, object arg7, object arg8, object arg9, object arg10)
{ {
return clientProxy.SendAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 }); return clientProxy.SendCoreAsync(method, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 });
} }
} }
} }

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.SignalR namespace Microsoft.AspNetCore.SignalR
{ {
public class UserProxy<THub> : IClientProxy public class UserProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly string _userId; private readonly string _userId;
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -17,13 +17,13 @@ namespace Microsoft.AspNetCore.SignalR
_userId = userId; _userId = userId;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendUserAsync(_userId, method, args); return _lifetimeManager.SendUserAsync(_userId, method, args);
} }
} }
public class MultipleUserProxy<THub> : IClientProxy public class MultipleUserProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly IReadOnlyList<string> _userIds; private readonly IReadOnlyList<string> _userIds;
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -34,13 +34,13 @@ namespace Microsoft.AspNetCore.SignalR
_userIds = userIds; _userIds = userIds;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendUsersAsync(_userIds, method, args); return _lifetimeManager.SendUsersAsync(_userIds, method, args);
} }
} }
public class GroupProxy<THub> : IClientProxy public class GroupProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly string _groupName; private readonly string _groupName;
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -51,16 +51,16 @@ namespace Microsoft.AspNetCore.SignalR
_groupName = groupName; _groupName = groupName;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendGroupAsync(_groupName, method, args); return _lifetimeManager.SendGroupAsync(_groupName, method, args);
} }
} }
public class MultipleGroupProxy<THub> : IClientProxy public class MultipleGroupProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
private IReadOnlyList<string> _groupNames; private readonly IReadOnlyList<string> _groupNames;
public MultipleGroupProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> groupNames) public MultipleGroupProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> groupNames)
{ {
@ -68,13 +68,13 @@ namespace Microsoft.AspNetCore.SignalR
_groupNames = groupNames; _groupNames = groupNames;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendGroupsAsync(_groupNames, method, args); return _lifetimeManager.SendGroupsAsync(_groupNames, method, args);
} }
} }
public class GroupExceptProxy<THub> : IClientProxy public class GroupExceptProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly string _groupName; private readonly string _groupName;
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -87,13 +87,13 @@ namespace Microsoft.AspNetCore.SignalR
_excludedIds = excludedIds; _excludedIds = excludedIds;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedIds); return _lifetimeManager.SendGroupExceptAsync(_groupName, method, args, _excludedIds);
} }
} }
public class AllClientProxy<THub> : IClientProxy public class AllClientProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -102,16 +102,16 @@ namespace Microsoft.AspNetCore.SignalR
_lifetimeManager = lifetimeManager; _lifetimeManager = lifetimeManager;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendAllAsync(method, args); return _lifetimeManager.SendAllAsync(method, args);
} }
} }
public class AllClientsExceptProxy<THub> : IClientProxy public class AllClientsExceptProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
private IReadOnlyList<string> _excludedIds; private readonly IReadOnlyList<string> _excludedIds;
public AllClientsExceptProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> excludedIds) public AllClientsExceptProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> excludedIds)
{ {
@ -119,13 +119,13 @@ namespace Microsoft.AspNetCore.SignalR
_excludedIds = excludedIds; _excludedIds = excludedIds;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendAllExceptAsync(method, args, _excludedIds); return _lifetimeManager.SendAllExceptAsync(method, args, _excludedIds);
} }
} }
public class SingleClientProxy<THub> : IClientProxy public class SingleClientProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly string _connectionId; private readonly string _connectionId;
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
@ -136,16 +136,16 @@ namespace Microsoft.AspNetCore.SignalR
_connectionId = connectionId; _connectionId = connectionId;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendConnectionAsync(_connectionId, method, args); return _lifetimeManager.SendConnectionAsync(_connectionId, method, args);
} }
} }
public class MultipleClientProxy<THub> : IClientProxy public class MultipleClientProxy<THub> : IClientProxy where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;
private IReadOnlyList<string> _connectionIds; private readonly IReadOnlyList<string> _connectionIds;
public MultipleClientProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> connectionIds) public MultipleClientProxy(HubLifetimeManager<THub> lifetimeManager, IReadOnlyList<string> connectionIds)
{ {
@ -153,13 +153,13 @@ namespace Microsoft.AspNetCore.SignalR
_connectionIds = connectionIds; _connectionIds = connectionIds;
} }
public Task SendAsync(string method, params object[] args) public Task SendCoreAsync(string method, object[] args)
{ {
return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args); return _lifetimeManager.SendConnectionsAsync(_connectionIds, method, args);
} }
} }
public class GroupManager<THub> : IGroupManager public class GroupManager<THub> : IGroupManager where THub : Hub
{ {
private readonly HubLifetimeManager<THub> _lifetimeManager; private readonly HubLifetimeManager<THub> _lifetimeManager;

View File

@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.SignalR
var methodBuilder = type.DefineMethod(interfaceMethodInfo.Name, methodAttributes); var methodBuilder = type.DefineMethod(interfaceMethodInfo.Name, methodAttributes);
var invokeMethod = typeof(IClientProxy).GetMethod( var invokeMethod = typeof(IClientProxy).GetMethod(
"SendAsync", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, nameof(IClientProxy.SendCoreAsync), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
new Type[] { typeof(string), typeof(object[]) }, null); new Type[] { typeof(string), typeof(object[]) }, null);
methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType); methodBuilder.SetReturnType(interfaceMethodInfo.ReturnType);
@ -132,14 +132,14 @@ namespace Microsoft.AspNetCore.SignalR
var generator = methodBuilder.GetILGenerator(); var generator = methodBuilder.GetILGenerator();
// Declare local variable to store the arguments to IClientProxy.SendAsync // Declare local variable to store the arguments to IClientProxy.SendCoreAsync
generator.DeclareLocal(typeof(object[])); generator.DeclareLocal(typeof(object[]));
// Get IClientProxy // Get IClientProxy
generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, proxyField); generator.Emit(OpCodes.Ldfld, proxyField);
// The first argument to IClientProxy.SendAsync is this method's name // The first argument to IClientProxy.SendCoreAsync is this method's name
generator.Emit(OpCodes.Ldstr, interfaceMethodInfo.Name); generator.Emit(OpCodes.Ldstr, interfaceMethodInfo.Name);
// Create an new object array to hold all the parameters to this method // Create an new object array to hold all the parameters to this method
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.SignalR
generator.Emit(OpCodes.Stelem_Ref); generator.Emit(OpCodes.Stelem_Ref);
} }
// Call SendAsync // Call SendCoreAsync
generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Callvirt, invokeMethod); generator.Emit(OpCodes.Callvirt, invokeMethod);

View File

@ -18,7 +18,7 @@ using StackExchange.Redis;
namespace Microsoft.AspNetCore.SignalR.Redis namespace Microsoft.AspNetCore.SignalR.Redis
{ {
public class RedisHubLifetimeManager<THub> : HubLifetimeManager<THub>, IDisposable public class RedisHubLifetimeManager<THub> : HubLifetimeManager<THub>, IDisposable where THub : Hub
{ {
private readonly HubConnectionList _connections = new HubConnectionList(); private readonly HubConnectionList _connections = new HubConnectionList();
// TODO: Investigate "memory leak" entries never get removed // TODO: Investigate "memory leak" entries never get removed

View File

@ -0,0 +1,207 @@
// 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.
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.SignalR.Tests
{
public class ClientHubProxyTests
{
public class FakeHub : Hub
{
}
[Fact]
public async Task UserProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendUserAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<string, string, object[]>((userId, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new UserProxy<FakeHub>(o.Object, string.Empty);
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[]) Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task MultipleUserProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendUsersAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<IReadOnlyList<string>, string, object[]>((userIds, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new MultipleUserProxy<FakeHub>(o.Object, new List<string>());
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task GroupProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendGroupAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<string, string, object[]>((groupName, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new GroupProxy<FakeHub>(o.Object, string.Empty);
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task MultipleGroupProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendGroupsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<IReadOnlyList<string>, string, object[]>((groupNames, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new MultipleGroupProxy<FakeHub>(o.Object, new List<string>());
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task GroupExceptProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendGroupExceptAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>()))
.Callback<string, string, object[], IReadOnlyList<string>>((groupName, methodName, args, excludedIds) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new GroupExceptProxy<FakeHub>(o.Object, string.Empty, new List<string>());
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task AllClientProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendAllAsync(It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<string, object[]>((methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new AllClientProxy<FakeHub>(o.Object);
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task AllClientsExceptProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendAllExceptAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<IReadOnlyList<string>>()))
.Callback<string, object[], IReadOnlyList<string>>((methodName, args, excludedIds) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new AllClientsExceptProxy<FakeHub>(o.Object, new List<string>());
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task SingleClientProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendConnectionAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<string, string, object[]>((connectionId, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new SingleClientProxy<FakeHub>(o.Object, string.Empty);
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
[Fact]
public async Task MultipleClientProxy_SendAsync_ArrayArgumentNotExpanded()
{
object[] resultArgs = null;
var o = new Mock<HubLifetimeManager<FakeHub>>();
o.Setup(m => m.SendConnectionsAsync(It.IsAny<IReadOnlyList<string>>(), It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<IReadOnlyList<string>, string, object[]>((connectionIds, methodName, args) => { resultArgs = args; })
.Returns(Task.CompletedTask);
var proxy = new MultipleClientProxy<FakeHub>(o.Object, new List<string>());
var data = Encoding.UTF8.GetBytes("Hello world");
await proxy.SendAsync("Method", data);
Assert.NotNull(resultArgs);
var arg = (byte[])Assert.Single(resultArgs);
Assert.Same(data, arg);
}
}
}