Skip to content

Commit

Permalink
JSkimming#226 - added test coverage for IAsyncEnumerable
Browse files Browse the repository at this point in the history
  • Loading branch information
gentledepp committed Dec 7, 2023
1 parent 3534396 commit 808fb52
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,25 @@ public Task<Guid> AsynchronousResultMethod()
_log.Add(nameof(AsynchronousResultMethod) + ":End");
return Task.FromResult(Guid.NewGuid());
}

#if NET5_0_OR_GREATER
public async IAsyncEnumerable<string> AsynchronousEnumerableMethod()
{
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
yield return "b";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield b");
}

public async IAsyncEnumerable<string> AsynchronousEnumerableExceptionMethod()
{
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
throw new InvalidOperationException(nameof(AsynchronousEnumerableExceptionMethod) + ":Exception");
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,26 @@ public async Task<Guid> AsynchronousResultMethod()
_log.Add(nameof(AsynchronousResultMethod) + ":End");
return Guid.NewGuid();
}

#if NET5_0_OR_GREATER
public async IAsyncEnumerable<string> AsynchronousEnumerableMethod()
{
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
yield return "b";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield b");
}

public async IAsyncEnumerable<string> AsynchronousEnumerableExceptionMethod()
{
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
throw new InvalidOperationException(nameof(AsynchronousEnumerableExceptionMethod) + ":Exception");
}
#endif

}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,25 @@ public async Task<Guid> AsynchronousResultExceptionMethod()
await Task.Delay(10).ConfigureAwait(false);
throw new InvalidOperationException(nameof(AsynchronousResultExceptionMethod) + ":Exception");
}

#if NET5_0_OR_GREATER
public async IAsyncEnumerable<string> AsynchronousEnumerableMethod()
{
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
yield return "b";
_log.Add(nameof(AsynchronousEnumerableMethod) + ":Yield b");
}

public async IAsyncEnumerable<string> AsynchronousEnumerableExceptionMethod()
{
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Start");
yield return "a";
_log.Add(nameof(AsynchronousEnumerableExceptionMethod) + ":Yield a");
await Task.Delay(10).ConfigureAwait(false);
throw new InvalidOperationException(nameof(AsynchronousEnumerableExceptionMethod) + ":Exception");
}
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ public interface IInterfaceToProxy
Task<Guid> AsynchronousResultMethod();

Task<Guid> AsynchronousResultExceptionMethod();

#if NET5_0_OR_GREATER
IAsyncEnumerable<string> AsynchronousEnumerableMethod();

IAsyncEnumerable<string> AsynchronousEnumerableExceptionMethod();
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Copyright (c) 2016-2023 James Skimming. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
#if NET5_0_OR_GREATER

namespace Castle.DynamicProxy;

using System;
using Castle.DynamicProxy.InterfaceProxies;
using Xunit;
using Xunit.Abstractions;

public class WhenProcessingAsynchronousEnumerableMethods
{
private const string MethodName = nameof(IInterfaceToProxy.AsynchronousEnumerableMethod);
private readonly ListLogger _log;
private readonly IInterfaceToProxy _proxy;

public WhenProcessingAsynchronousEnumerableMethods(ITestOutputHelper output)
{
_log = new ListLogger(output);
var interceptor = new TestProcessingReturnValueAsyncInterceptor(_log);
_proxy = ProxyGen.CreateProxy(_log, interceptor);
}

[Fact]
public async Task ShouldLog4Entries()
{
// Arrange
var messages = new List<string>();

// Act
await foreach (string msg in _proxy.AsynchronousEnumerableMethod().ConfigureAwait(false))
{
messages.Add(msg);
}

// Assert
Assert.Equal(2, messages.Count);
Assert.Equal("a", messages[0]);
Assert.Equal("b", messages[1]);
Assert.Equal(5, _log.Count);
}

[Fact]
public async Task ShouldAllowProcessingPriorToInvocation()
{
// Arrange
var messages = new List<string>();

// Act
await foreach (string msg in _proxy.AsynchronousEnumerableMethod().ConfigureAwait(false))
{
messages.Add(msg);
}

// Assert
Assert.Equal($"{MethodName}:StartingInvocation", _log[0]);
}

[Fact]
public async Task ShouldAllowProcessingAfterInvocation()
{
// Arrange
var messages = new List<string>();

// Act
await foreach (string msg in _proxy.AsynchronousEnumerableMethod().ConfigureAwait(false))
{
messages.Add(msg);
}

// Assert
Assert.Equal($"{MethodName}:Yield b", _log[4]);
}
}

public class WhenProcessingAsynchronousEnumerableMethodsThatThrowExceptions
{
private const string MethodName = nameof(IInterfaceToProxy.AsynchronousEnumerableExceptionMethod);
private readonly ListLogger _log;
private readonly IInterfaceToProxy _proxy;

public WhenProcessingAsynchronousEnumerableMethodsThatThrowExceptions(ITestOutputHelper output)
{
_log = new ListLogger(output);
var interceptor = new TestProcessingReturnValueAsyncInterceptor(_log);
_proxy = ProxyGen.CreateProxy(_log, interceptor);
}

[Fact]
public async Task ShouldLog4Entries()
{
// Arrange
var messages = new List<string>();
InvalidOperationException? exception = null;

// Act
try
{
await foreach (string msg in _proxy.AsynchronousEnumerableExceptionMethod().ConfigureAwait(false))
{
messages.Add(msg);
}
}
catch (InvalidOperationException ioe)
{
exception = ioe;
}

// Assert
Assert.Single(messages);
Assert.Equal("a", messages[0]);
Assert.NotNull(exception);
Assert.Equal(4, _log.Count);
}

[Fact]
public async Task ShouldAllowProcessingPriorToInvocation()
{
// Arrange
var messages = new List<string>();
InvalidOperationException? exception = null;

// Act
try
{
await foreach (string msg in _proxy.AsynchronousEnumerableExceptionMethod().ConfigureAwait(false))
{
messages.Add(msg);
}
}
catch (InvalidOperationException ioe)
{
exception = ioe;
}

// Assert
Assert.Single(messages);
Assert.Equal("a", messages[0]);
Assert.NotNull(exception);
Assert.Equal($"{MethodName}:StartingInvocation", _log[0]);
}

[Fact]
public async Task ShouldAllowProcessingAfterInvocation()
{
// Arrange
var messages = new List<string>();
InvalidOperationException? exception = null;

// Act
try
{
await foreach (string msg in _proxy.AsynchronousEnumerableExceptionMethod().ConfigureAwait(false))
{
messages.Add(msg);
}
}
catch (InvalidOperationException ioe)
{
exception = ioe;
}

// Assert
Assert.Single(messages);
Assert.Equal("a", messages[0]);
Assert.NotNull(exception);
Assert.Equal($"{MethodName}:Yield a", _log[3]);
}
}

#endif

0 comments on commit 808fb52

Please sign in to comment.