mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Refactor
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Threading.Tasks;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using CliFx.Services;
|
using CliFx.Services;
|
||||||
using CliFx.Tests.TestObjects;
|
using CliFx.Tests.TestObjects;
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace CliFx.Tests
|
namespace CliFx.Tests
|
||||||
@@ -17,11 +15,13 @@ namespace CliFx.Tests
|
|||||||
var command = new TestCommand();
|
var command = new TestCommand();
|
||||||
var expectedExitCode = await command.ExecuteAsync();
|
var expectedExitCode = await command.ExecuteAsync();
|
||||||
|
|
||||||
var commandResolverMock = new Mock<ICommandResolver>();
|
var commandOptionParser = new CommandOptionParser();
|
||||||
commandResolverMock.Setup(m => m.ResolveCommand(It.IsAny<IReadOnlyList<string>>())).Returns(command);
|
|
||||||
var commandResolver = commandResolverMock.Object;
|
|
||||||
|
|
||||||
var application = new CliApplication(commandResolver);
|
var typeProvider = new TypeProvider(typeof(TestCommand));
|
||||||
|
var commandOptionConverter = new CommandOptionConverter();
|
||||||
|
var commandResolver = new CommandResolver(typeProvider, commandOptionConverter);
|
||||||
|
|
||||||
|
var application = new CliApplication(commandOptionParser, commandResolver);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var exitCodeValue = await application.RunAsync();
|
var exitCodeValue = await application.RunAsync();
|
||||||
|
|||||||
@@ -8,10 +8,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Include="Moq" Version="4.11.0" />
|
|
||||||
<PackageReference Include="CliWrap" Version="2.3.0" />
|
<PackageReference Include="CliWrap" Version="2.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace CliFx.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CommandOptionConverterTests
|
public class CommandOptionConverterTests
|
||||||
{
|
{
|
||||||
private static IEnumerable<TestCaseData> GetData_ConvertOption()
|
private static IEnumerable<TestCaseData> GetTestCases_ConvertOption()
|
||||||
{
|
{
|
||||||
yield return new TestCaseData(
|
yield return new TestCaseData(
|
||||||
new CommandOption("option", "value"),
|
new CommandOption("option", "value"),
|
||||||
@@ -171,7 +171,7 @@ namespace CliFx.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[TestCaseSource(nameof(GetData_ConvertOption))]
|
[TestCaseSource(nameof(GetTestCases_ConvertOption))]
|
||||||
public void ConvertOption_Test(CommandOption option, Type targetType, object expectedConvertedValue)
|
public void ConvertOption_Test(CommandOption option, Type targetType, object expectedConvertedValue)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -181,10 +181,13 @@ namespace CliFx.Tests
|
|||||||
var convertedValue = converter.ConvertOption(option, targetType);
|
var convertedValue = converter.ConvertOption(option, targetType);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
Assert.That(convertedValue, Is.EqualTo(expectedConvertedValue));
|
Assert.That(convertedValue, Is.EqualTo(expectedConvertedValue));
|
||||||
|
|
||||||
if (convertedValue != null)
|
if (convertedValue != null)
|
||||||
Assert.That(convertedValue, Is.AssignableTo(targetType));
|
Assert.That(convertedValue, Is.AssignableTo(targetType));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ namespace CliFx.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CommandOptionParserTests
|
public class CommandOptionParserTests
|
||||||
{
|
{
|
||||||
private static IEnumerable<TestCaseData> GetData_ParseOptions()
|
private static IEnumerable<TestCaseData> GetTestCases_ParseOptions()
|
||||||
{
|
{
|
||||||
yield return new TestCaseData(new string[0], CommandOptionSet.Empty);
|
yield return new TestCaseData(new string[0], CommandOptionSet.Empty);
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ namespace CliFx.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[TestCaseSource(nameof(GetData_ParseOptions))]
|
[TestCaseSource(nameof(GetTestCases_ParseOptions))]
|
||||||
public void ParseOptions_Test(IReadOnlyList<string> commandLineArguments, CommandOptionSet expectedCommandOptionSet)
|
public void ParseOptions_Test(IReadOnlyList<string> commandLineArguments, CommandOptionSet expectedCommandOptionSet)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -164,6 +164,8 @@ namespace CliFx.Tests
|
|||||||
var optionSet = parser.ParseOptions(commandLineArguments);
|
var optionSet = parser.ParseOptions(commandLineArguments);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
Assert.That(optionSet.CommandName, Is.EqualTo(expectedCommandOptionSet.CommandName), "Command name");
|
Assert.That(optionSet.CommandName, Is.EqualTo(expectedCommandOptionSet.CommandName), "Command name");
|
||||||
Assert.That(optionSet.Options.Count, Is.EqualTo(expectedCommandOptionSet.Options.Count), "Option count");
|
Assert.That(optionSet.Options.Count, Is.EqualTo(expectedCommandOptionSet.Options.Count), "Option count");
|
||||||
|
|
||||||
@@ -175,6 +177,7 @@ namespace CliFx.Tests
|
|||||||
Assert.That(optionSet.Options[i].Values, Is.EqualTo(expectedCommandOptionSet.Options[i].Values),
|
Assert.That(optionSet.Options[i].Values, Is.EqualTo(expectedCommandOptionSet.Options[i].Values),
|
||||||
$"Option[{i}] values");
|
$"Option[{i}] values");
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ using CliFx.Exceptions;
|
|||||||
using CliFx.Models;
|
using CliFx.Models;
|
||||||
using CliFx.Services;
|
using CliFx.Services;
|
||||||
using CliFx.Tests.TestObjects;
|
using CliFx.Tests.TestObjects;
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace CliFx.Tests
|
namespace CliFx.Tests
|
||||||
@@ -11,7 +10,7 @@ namespace CliFx.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class CommandResolverTests
|
public class CommandResolverTests
|
||||||
{
|
{
|
||||||
private static IEnumerable<TestCaseData> GetData_ResolveCommand()
|
private static IEnumerable<TestCaseData> GetTestCases_ResolveCommand()
|
||||||
{
|
{
|
||||||
yield return new TestCaseData(
|
yield return new TestCaseData(
|
||||||
new CommandOptionSet(new[]
|
new CommandOptionSet(new[]
|
||||||
@@ -48,34 +47,28 @@ namespace CliFx.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[TestCaseSource(nameof(GetData_ResolveCommand))]
|
[TestCaseSource(nameof(GetTestCases_ResolveCommand))]
|
||||||
public void ResolveCommand_Test(CommandOptionSet commandOptionSet, TestCommand expectedCommand)
|
public void ResolveCommand_Test(CommandOptionSet commandOptionSet, TestCommand expectedCommand)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var commandTypes = new[] {typeof(TestCommand)};
|
var typeProvider = new TypeProvider(typeof(TestCommand));
|
||||||
|
|
||||||
var typeProviderMock = new Mock<ITypeProvider>();
|
|
||||||
typeProviderMock.Setup(m => m.GetTypes()).Returns(commandTypes);
|
|
||||||
var typeProvider = typeProviderMock.Object;
|
|
||||||
|
|
||||||
var optionParserMock = new Mock<ICommandOptionParser>();
|
|
||||||
optionParserMock.Setup(m => m.ParseOptions(It.IsAny<IReadOnlyList<string>>())).Returns(commandOptionSet);
|
|
||||||
var optionParser = optionParserMock.Object;
|
|
||||||
|
|
||||||
var optionConverter = new CommandOptionConverter();
|
var optionConverter = new CommandOptionConverter();
|
||||||
|
|
||||||
var resolver = new CommandResolver(typeProvider, optionParser, optionConverter);
|
var resolver = new CommandResolver(typeProvider, optionConverter);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var command = resolver.ResolveCommand() as TestCommand;
|
var command = resolver.ResolveCommand(commandOptionSet) as TestCommand;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
Assert.That(command, Is.Not.Null);
|
Assert.That(command, Is.Not.Null);
|
||||||
Assert.That(command.StringOption, Is.EqualTo(expectedCommand.StringOption), nameof(command.StringOption));
|
Assert.That(command.StringOption, Is.EqualTo(expectedCommand.StringOption), nameof(command.StringOption));
|
||||||
Assert.That(command.IntOption, Is.EqualTo(expectedCommand.IntOption), nameof(command.IntOption));
|
Assert.That(command.IntOption, Is.EqualTo(expectedCommand.IntOption), nameof(command.IntOption));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<TestCaseData> GetData_ResolveCommand_IsRequired()
|
private static IEnumerable<TestCaseData> GetTestCases_ResolveCommand_IsRequired()
|
||||||
{
|
{
|
||||||
yield return new TestCaseData(CommandOptionSet.Empty);
|
yield return new TestCaseData(CommandOptionSet.Empty);
|
||||||
|
|
||||||
@@ -88,26 +81,17 @@ namespace CliFx.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[TestCaseSource(nameof(GetData_ResolveCommand_IsRequired))]
|
[TestCaseSource(nameof(GetTestCases_ResolveCommand_IsRequired))]
|
||||||
public void ResolveCommand_IsRequired_Test(CommandOptionSet commandOptionSet)
|
public void ResolveCommand_IsRequired_Test(CommandOptionSet commandOptionSet)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var commandTypes = new[] {typeof(TestCommand)};
|
var typeProvider = new TypeProvider(typeof(TestCommand));
|
||||||
|
|
||||||
var typeProviderMock = new Mock<ITypeProvider>();
|
|
||||||
typeProviderMock.Setup(m => m.GetTypes()).Returns(commandTypes);
|
|
||||||
var typeProvider = typeProviderMock.Object;
|
|
||||||
|
|
||||||
var optionParserMock = new Mock<ICommandOptionParser>();
|
|
||||||
optionParserMock.Setup(m => m.ParseOptions(It.IsAny<IReadOnlyList<string>>())).Returns(commandOptionSet);
|
|
||||||
var optionParser = optionParserMock.Object;
|
|
||||||
|
|
||||||
var optionConverter = new CommandOptionConverter();
|
var optionConverter = new CommandOptionConverter();
|
||||||
|
|
||||||
var resolver = new CommandResolver(typeProvider, optionParser, optionConverter);
|
var resolver = new CommandResolver(typeProvider, optionConverter);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.Throws<CommandResolveException>(() => resolver.ResolveCommand());
|
Assert.Throws<CommandResolveException>(() => resolver.ResolveCommand(commandOptionSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,25 +7,26 @@ namespace CliFx
|
|||||||
{
|
{
|
||||||
public partial class CliApplication : ICliApplication
|
public partial class CliApplication : ICliApplication
|
||||||
{
|
{
|
||||||
|
private readonly ICommandOptionParser _commandOptionParser;
|
||||||
private readonly ICommandResolver _commandResolver;
|
private readonly ICommandResolver _commandResolver;
|
||||||
|
|
||||||
public CliApplication(ICommandResolver commandResolver)
|
public CliApplication(ICommandOptionParser commandOptionParser, ICommandResolver commandResolver)
|
||||||
{
|
{
|
||||||
|
_commandOptionParser = commandOptionParser;
|
||||||
_commandResolver = commandResolver;
|
_commandResolver = commandResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CliApplication()
|
public CliApplication()
|
||||||
: this(GetDefaultCommandResolver(Assembly.GetCallingAssembly()))
|
: this(new CommandOptionParser(), GetDefaultCommandResolver(Assembly.GetCallingAssembly()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> RunAsync(IReadOnlyList<string> commandLineArguments)
|
public async Task<int> RunAsync(IReadOnlyList<string> commandLineArguments)
|
||||||
{
|
{
|
||||||
// Resolve and execute command
|
var optionSet = _commandOptionParser.ParseOptions(commandLineArguments);
|
||||||
var command = _commandResolver.ResolveCommand(commandLineArguments);
|
var command = _commandResolver.ResolveCommand(optionSet);
|
||||||
var exitCode = await command.ExecuteAsync();
|
|
||||||
|
|
||||||
// TODO: print message if error?
|
var exitCode = await command.ExecuteAsync();
|
||||||
|
|
||||||
return exitCode.Value;
|
return exitCode.Value;
|
||||||
}
|
}
|
||||||
@@ -36,10 +37,9 @@ namespace CliFx
|
|||||||
private static ICommandResolver GetDefaultCommandResolver(Assembly assembly)
|
private static ICommandResolver GetDefaultCommandResolver(Assembly assembly)
|
||||||
{
|
{
|
||||||
var typeProvider = TypeProvider.FromAssembly(assembly);
|
var typeProvider = TypeProvider.FromAssembly(assembly);
|
||||||
var commandOptionParser = new CommandOptionParser();
|
|
||||||
var commandOptionConverter = new CommandOptionConverter();
|
var commandOptionConverter = new CommandOptionConverter();
|
||||||
|
|
||||||
return new CommandResolver(typeProvider, commandOptionParser, commandOptionConverter);
|
return new CommandResolver(typeProvider, commandOptionConverter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,14 +11,11 @@ namespace CliFx.Services
|
|||||||
public class CommandResolver : ICommandResolver
|
public class CommandResolver : ICommandResolver
|
||||||
{
|
{
|
||||||
private readonly ITypeProvider _typeProvider;
|
private readonly ITypeProvider _typeProvider;
|
||||||
private readonly ICommandOptionParser _commandOptionParser;
|
|
||||||
private readonly ICommandOptionConverter _commandOptionConverter;
|
private readonly ICommandOptionConverter _commandOptionConverter;
|
||||||
|
|
||||||
public CommandResolver(ITypeProvider typeProvider,
|
public CommandResolver(ITypeProvider typeProvider, ICommandOptionConverter commandOptionConverter)
|
||||||
ICommandOptionParser commandOptionParser, ICommandOptionConverter commandOptionConverter)
|
|
||||||
{
|
{
|
||||||
_typeProvider = typeProvider;
|
_typeProvider = typeProvider;
|
||||||
_commandOptionParser = commandOptionParser;
|
|
||||||
_commandOptionConverter = commandOptionConverter;
|
_commandOptionConverter = commandOptionConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +68,8 @@ namespace CliFx.Services
|
|||||||
$"Apply {nameof(CommandAttribute)} to give command a name.");
|
$"Apply {nameof(CommandAttribute)} to give command a name.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Command ResolveCommand(IReadOnlyList<string> commandLineArguments)
|
public Command ResolveCommand(CommandOptionSet optionSet)
|
||||||
{
|
{
|
||||||
var optionSet = _commandOptionParser.ParseOptions(commandLineArguments);
|
|
||||||
|
|
||||||
// Get command type
|
// Get command type
|
||||||
var commandType = !optionSet.CommandName.IsNullOrWhiteSpace()
|
var commandType = !optionSet.CommandName.IsNullOrWhiteSpace()
|
||||||
? GetCommandType(optionSet.CommandName)
|
? GetCommandType(optionSet.CommandName)
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace CliFx.Services
|
|
||||||
{
|
|
||||||
public static class Extensions
|
|
||||||
{
|
|
||||||
public static Command ResolveCommand(this ICommandResolver commandResolver) => commandResolver.ResolveCommand(new string[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using CliFx.Models;
|
||||||
|
|
||||||
namespace CliFx.Services
|
namespace CliFx.Services
|
||||||
{
|
{
|
||||||
public interface ICommandResolver
|
public interface ICommandResolver
|
||||||
{
|
{
|
||||||
Command ResolveCommand(IReadOnlyList<string> commandLineArguments);
|
Command ResolveCommand(CommandOptionSet optionSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user