Skip to content

Commit

Permalink
Replaces sync API with async API
Browse files Browse the repository at this point in the history
  • Loading branch information
joncloud committed Aug 9, 2020
1 parent 7ec3695 commit 0a306c8
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 42 deletions.
4 changes: 2 additions & 2 deletions src/ThorNet.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public void Hello(string name)
if (verbose) { Console.WriteLine("> done saying hello"); }
}

public static int Main(string[] args)
public static Task<int> Main(string[] args)
{
return Start<Program>(args);
return StartAsync<Program>(args);
}
}
}
17 changes: 9 additions & 8 deletions src/ThorNet/Thor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ThorNet
{
Expand Down Expand Up @@ -116,8 +117,8 @@ int HandleException(Exception ex)
/// </summary>
/// <param name="commandName">The name of the command to invoke.</param>
/// <param name="args">The arguments to provide to the command.</param>
/// <returns>The exit code to return to the command prompt.</returns>
internal int Invoke(string commandName, string[] args)
/// <returns>A task that represents the asynchronous operation. The task result contains the exit code to return to the command prompt.</returns>
internal async Task<int> InvokeAsync(string commandName, string[] args)
{
// Show warnings for any public methods that don't have examples defined.
foreach (string invalid in Commands.Where(p => string.IsNullOrEmpty(p.Value.Example))
Expand All @@ -129,7 +130,7 @@ internal int Invoke(string commandName, string[] args)
ThorCommand command;
if (Commands.TryGetValue(commandName, out command))
{
try { return command.Invoke(args); }
try { return await command.InvokeAsync(args); }
catch (TargetInvocationException ex)
{
return HandleException(ex.InnerException);
Expand All @@ -145,7 +146,7 @@ internal int Invoke(string commandName, string[] args)
if (TryGetSubcommand(commandName, out subcommand))
{
commandName = PrepareInvocationArguments(ref args);
return subcommand.Invoke(commandName, args);
return await subcommand.InvokeAsync(commandName, args);
}

else
Expand Down Expand Up @@ -260,7 +261,7 @@ protected IEnumerable<T> Options<T>(string name, Func<string, T> convert = null,
}

/// <summary>
/// Prepares the input arguments to invoke <see cref="Thor.Invoke(string, string[])"/>
/// Prepares the input arguments to invoke <see cref="Thor.InvokeAsync(string, string[])"/>
/// </summary>
/// <param name="args">The array of arguments provided. This is modified to remove the first argument if present.</param>
/// <returns>The name of the command to invoke. If no arguments are provided, this defaults to <see cref="Help(string, string[])"/>.</returns>
Expand Down Expand Up @@ -490,14 +491,14 @@ void PrintSummaryHelp()
/// Starts the thor program.
/// </summary>
/// <param name="args">The arguments given from the command line.</param>
/// <returns>The exit code to return to the command prompt.</returns>
public static int Start<T>(string[] args)
/// <returns>A task that represents the asynchronous operation. The task result contains the exit code to return to the command prompt.</returns>
public static async Task<int> StartAsync<T>(string[] args)
where T : Thor, new()
{
string commandName = PrepareInvocationArguments(ref args);

T thor = new T();
return thor.Invoke(commandName, args);
return await thor.InvokeAsync(commandName, args);
}

/// <summary>
Expand Down
10 changes: 4 additions & 6 deletions src/ThorNet/ThorCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private Dictionary<string, Option> GetOptions()
.ToDictionary(x => x.Key, x => x.Option);
}

public int Invoke(string[] args)
public async Task<int> InvokeAsync(string[] args)
{
try
{
Expand All @@ -96,13 +96,11 @@ public int Invoke(string[] args)
object result = _command.Invoke(_host, arguments);

// If the result is a task, then make sure to wait for it to complete.
if (typeof(Task).GetTypeInfo().IsAssignableFrom(_command.ReturnType))
if (result is Task task)
{
Task task = (Task)result;
task.Wait();
await task;

var intTask = task as Task<int>;
if (intTask != null)
if (task is Task<int> intTask)
{
return intTask.Result;
}
Expand Down
21 changes: 11 additions & 10 deletions tests/ThorNet.UnitTests/AliasTests.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace ThorNet.UnitTests
{
public class AliasTests
{
[Fact]
public void Invoke_ShouldCallCommand_GivenAlias()
public async Task Invoke_ShouldCallCommand_GivenAlias()
{
var message = Guid.NewGuid().ToString();

var thor = new T();
thor.Invoke("handle", new[] { message });
await thor.InvokeAsync("handle", new[] { message });

Assert.Equal(message, thor.Message);
}

[Fact]
public void Invoke_ShouldCallCommand_GivenMethodName()
public async Task Invoke_ShouldCallCommand_GivenMethodName()
{
var message = Guid.NewGuid().ToString();

var thor = new T();
thor.Invoke(nameof(T.Handle), new[] { message });
await thor.InvokeAsync(nameof(T.Handle), new[] { message });

Assert.Equal(message, thor.Message);
}

[Fact]
public void Help_ShouldPrintAlias_GivenAlias()
public async Task Help_ShouldPrintAlias_GivenAlias()
{
var lines = GetHelp();
var lines = await GetHelpAsync();

var actual = Assert.Single(
lines.Where(
Expand All @@ -44,9 +45,9 @@ public void Help_ShouldPrintAlias_GivenAlias()
}

[Fact]
public void Help_ShouldPrintMethodName_GivenNoAlias()
public async Task Help_ShouldPrintMethodName_GivenNoAlias()
{
var lines = GetHelp();
var lines = await GetHelpAsync();

var actual = Assert.Single(
lines.Where(
Expand All @@ -57,13 +58,13 @@ public void Help_ShouldPrintMethodName_GivenNoAlias()
Assert.Equal(expected, actual);
}

static IEnumerable<string> GetHelp()
static async Task<IEnumerable<string>> GetHelpAsync()
{
var terminal = new MockTerminal(100);

var commandName = nameof(Thor.Help);
var args = new string[0];
new T(terminal).Invoke(commandName, args);
await new T(terminal).InvokeAsync(commandName, args);

return terminal.GetLines();
}
Expand Down
9 changes: 5 additions & 4 deletions tests/ThorNet.UnitTests/ExceptionHandlingTests.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace ThorNet.UnitTests
{
public class ExceptionHandlingTests
{
[Fact]
public void Invoke_ShouldUnwrapTargetInvocationException_GivenThrownException()
public async Task Invoke_ShouldUnwrapTargetInvocationException_GivenThrownException()
{
var message = Guid.NewGuid().ToString();
var terminal = new MockTerminal(100);
new E(terminal).Invoke(nameof(E.Throw), new[] { message });
await new T(terminal).InvokeAsync(nameof(T.Throw), new[] { message });

var actual = Assert.Single(
terminal.GetLines().Where(line => line.StartsWith("[ERROR]"))
Expand All @@ -21,9 +22,9 @@ public void Invoke_ShouldUnwrapTargetInvocationException_GivenThrownException()
Assert.Equal(expected, actual);
}

public class E : Thor
public class T : Thor
{
public E(ITerminal terminal)
public T(ITerminal terminal)
: base(terminal)
{
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ThorNet.UnitTests/ExitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ public class ExitTests
[InlineData("SubTarget,Invalid", 1)]
[InlineData("SubTarget,Throws", 1)]
[Theory]
public void Test(string argsList, int exitCode)
public async Task Test(string argsList, int exitCode)
{
string[] args = Utility.ToArray(argsList);

int actual = Thor.Start<Target>(args);
int actual = await Thor.StartAsync<Target>(args);
Assert.Equal(exitCode, actual);
}

Expand Down
17 changes: 9 additions & 8 deletions tests/ThorNet.UnitTests/OptionTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace ThorNet.UnitTests
Expand All @@ -10,10 +11,10 @@ public class OptionTests
[InlineData("Test,--class=A,--classDefault=B,--method=C,--methodDefault=D", "A,B,C,D")]
[InlineData("Test,-cA,-dB,-mC,-nD", "A,B,C,D")]
[Theory]
public void Option_Tests(string args, string values)
public async Task Option_Tests(string args, string values)
{
Target.OptionValues = new Options();
Thor.Start<Target>(Utility.ToArray(args));
await Thor.StartAsync<Target>(Utility.ToArray(args));

var valuesList = Utility.ToArray(values);

Expand All @@ -24,9 +25,9 @@ public void Option_Tests(string args, string values)
}

[Fact]
public void Help_ShouldIncludeHyphen_GivenAliasWithoutHyphen()
public async Task Help_ShouldIncludeHyphen_GivenAliasWithoutHyphen()
{
var lines = GetHelp();
var lines = await GetHelpAsync();

var actual = Assert.Single(
lines.Where(line => line.Trim().StartsWith("-c"))
Expand All @@ -37,9 +38,9 @@ public void Help_ShouldIncludeHyphen_GivenAliasWithoutHyphen()
}

[Fact]
public void Help_ShouldIncludeHyphen_GivenAliasWithHyphen()
public async Task Help_ShouldIncludeHyphen_GivenAliasWithHyphen()
{
var lines = GetHelp();
var lines = await GetHelpAsync();

var actual = Assert.Single(
lines.Where(line => line.Trim().StartsWith("-n"))
Expand All @@ -49,7 +50,7 @@ public void Help_ShouldIncludeHyphen_GivenAliasWithHyphen()
Assert.Equal(expected, actual);
}

static IEnumerable<string> GetHelp()
static async Task<IEnumerable<string>> GetHelpAsync()
{
var terminal = new MockTerminal(100);

Expand All @@ -58,7 +59,7 @@ static IEnumerable<string> GetHelp()
{
nameof(Target.Test)
};
new Target(terminal).Invoke(commandName, args);
await new Target(terminal).InvokeAsync(commandName, args);

return terminal.GetLines();
}
Expand Down
5 changes: 3 additions & 2 deletions tests/ThorNet.UnitTests/SubcommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Xunit;

namespace ThorNet.UnitTests
Expand Down Expand Up @@ -32,10 +33,10 @@ public class Duplicate : Thor
}

[Fact]
public void Subcommand_IsTriggered()
public async Task Subcommand_IsTriggered()
{
Assert.Equal(0, Trigger.Counter);
Thor.Start<TriggerTarget>(new[] { nameof(Trigger), nameof(Trigger.Increment) });
await Thor.StartAsync<TriggerTarget>(new[] { nameof(Trigger), nameof(Trigger.Increment) });
Assert.Equal(1, Trigger.Counter);
}

Expand Down

0 comments on commit 0a306c8

Please sign in to comment.