Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nullable annotation and extraction of RaisesAsync from modified Assert class to new MyAssert class. #249

Merged
merged 1 commit into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TwitchLib.Client.Test/CommandInfoTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class CommandInfoTest
[InlineData("! command")]
public void ParsingFailAndReturnNull(string s)
{
Assert.False(CommandInfo.TryParse(s, out CommandInfo commandInfo));
Assert.False(CommandInfo.TryParse(s, out var commandInfo));
Assert.Null(commandInfo);
}
}
31 changes: 15 additions & 16 deletions TwitchLib.Client.Test/MockIClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using TwitchLib.Communication.Events;
using TwitchLib.Communication.Interfaces;
using TwitchLib.Communication.Models;

namespace TwitchLib.Client.Test
{
Expand All @@ -12,17 +13,17 @@ public class MockIClient : IClient
public int SendQueueLength => throw new NotImplementedException();

public bool IsConnected { get; private set; }
public IClientOptions Options { get; set; }
public IClientOptions Options { get; set; } = new ClientOptions();

public int WhisperQueueLength => throw new NotImplementedException();

public event AsyncEventHandler<OnConnectedEventArgs> OnConnected;
public event AsyncEventHandler<OnDisconnectedEventArgs> OnDisconnected;
public event AsyncEventHandler<OnErrorEventArgs> OnError;
public event AsyncEventHandler<OnFatalErrorEventArgs> OnFatality;
public event AsyncEventHandler<OnMessageEventArgs> OnMessage;
public event AsyncEventHandler<OnSendFailedEventArgs> OnSendFailed;
public event AsyncEventHandler<OnConnectedEventArgs> OnReconnected;
public event AsyncEventHandler<OnConnectedEventArgs>? OnConnected;
public event AsyncEventHandler<OnDisconnectedEventArgs>? OnDisconnected;
public event AsyncEventHandler<OnErrorEventArgs>? OnError;
public event AsyncEventHandler<OnFatalErrorEventArgs>? OnFatality;
public event AsyncEventHandler<OnMessageEventArgs>? OnMessage;
public event AsyncEventHandler<OnSendFailedEventArgs>? OnSendFailed;
public event AsyncEventHandler<OnConnectedEventArgs>? OnReconnected;

public Task CloseAsync()
{
Expand All @@ -34,20 +35,19 @@ public Task CloseAsync()
public void Dispose()
{ }

public void Dispose(bool waitForSendsToComplete)
{ }

public async Task<bool> OpenAsync()
{
IsConnected = true;
await OnConnected?.Invoke(this, new OnConnectedEventArgs());
if (OnConnected is not null)
await OnConnected.Invoke(this, new OnConnectedEventArgs());
return true;
}

public async Task<bool> ReconnectAsync()
{
IsConnected = true;
await OnReconnected?.Invoke(this, new OnConnectedEventArgs());
if (OnReconnected is not null)
await OnReconnected.Invoke(this, new OnConnectedEventArgs());
return true;
}

Expand All @@ -68,9 +68,8 @@ public Task<bool> SendAsync(string data)

public async Task ReceiveMessage(string message)
{

await OnMessage?.Invoke(this, new OnMessageEventArgs(message));

if (OnMessage is not null)
await OnMessage.Invoke(this, new OnMessageEventArgs(message));
}

public bool SendWhisper(string data)
Expand Down
99 changes: 99 additions & 0 deletions TwitchLib.Client.Test/MyAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using Xunit;
using TwitchLib.Communication.Events;
using System.Threading.Tasks;
using Xunit.Sdk;

namespace TwitchLib.Client.Test;

//TL;DR: XUNIT with modification to accept async event Handler
public partial class MyAssert
{
/// <summary>
/// Verifies that a event with the exact event args (and not a derived type) is raised.
/// </summary>
/// <typeparam name="T">The type of the event arguments to expect</typeparam>
/// <param name="attach">Code to attach the event handler</param>
/// <param name="detach">Code to detach the event handler</param>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <returns>The event sender and arguments wrapped in an object</returns>
/// <exception cref="RaisesException">Thrown when the expected event was not raised.</exception>
public static async Task<RaisedEvent<T>> RaisesAsync<T>(Action<AsyncEventHandler<T>> attach, Action<AsyncEventHandler<T>> detach, Func<Task> testCode)
{
var raisedEvent = await RaisesAsyncInternal(attach, detach, testCode);

if (raisedEvent == null)
throw new RaisesException(typeof(T));

if (raisedEvent.Arguments != null && !raisedEvent.Arguments.GetType().Equals(typeof(T)))
throw new RaisesException(typeof(T), raisedEvent.Arguments.GetType());

return raisedEvent;
}

/// <summary>
/// Verifies that an event with the exact or a derived event args is raised.
/// </summary>
/// <typeparam name="T">The type of the event arguments to expect</typeparam>
/// <param name="attach">Code to attach the event handler</param>
/// <param name="detach">Code to detach the event handler</param>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <returns>The event sender and arguments wrapped in an object</returns>
/// <exception cref="RaisesException">Thrown when the expected event was not raised.</exception>
public static async Task<RaisedEvent<T>> RaisesAnyAsync<T>(Action<AsyncEventHandler<T>> attach, Action<AsyncEventHandler<T>> detach, Func<Task> testCode)
{
var raisedEvent = await RaisesAsyncInternal(attach, detach, testCode);

if (raisedEvent == null)
throw new RaisesException(typeof(T));

return raisedEvent;
}

static async Task<RaisedEvent<T>?> RaisesAsyncInternal<T>(Action<AsyncEventHandler<T>> attach, Action<AsyncEventHandler<T>> detach, Func<Task> testCode)
{
Assert.NotNull(attach);
Assert.NotNull(detach);
Assert.NotNull(testCode);

RaisedEvent<T>? raisedEvent = null;
AsyncEventHandler<T> value = (object? s, T args) =>
{
raisedEvent = new RaisedEvent<T>(s, args);
return Task.CompletedTask;
};
AsyncEventHandler<T> handler = value;
attach(handler);
await testCode();
detach(handler);
return raisedEvent;
}

/// <summary>
/// Represents a raised event after the fact.
/// </summary>
/// <typeparam name="T">The type of the event arguments.</typeparam>
public class RaisedEvent<T>
{
/// <summary>
/// The sender of the event.
/// </summary>
public object? Sender { get; }

/// <summary>
/// The event arguments.
/// </summary>
public T Arguments { get; }

/// <summary>
/// Creates a new instance of the <see cref="RaisedEvent{T}" /> class.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="args">The event arguments</param>
public RaisedEvent(object? sender, T args)
{
Sender = sender;
Arguments = args;
}
}
}
2 changes: 1 addition & 1 deletion TwitchLib.Client.Test/ThrottlingServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void EnqueueMessageTests(bool isConnected, uint queueCapacity, bool withM
.Returns(isConnected);
var client = clientMock.Object;
var throttlerService = new ThrottlingService(client, sendOptions);
OutboundChatMessage message = null;
OutboundChatMessage? message = null;

if (withMessage)
{
Expand Down
Loading