diff --git a/CliFx.Tests/CliApplicationTests.cs b/CliFx.Tests/CliApplicationTests.cs index 6d7bf9b..083e44b 100644 --- a/CliFx.Tests/CliApplicationTests.cs +++ b/CliFx.Tests/CliApplicationTests.cs @@ -1,33 +1,36 @@ using System.Threading.Tasks; +using CliFx.Attributes; +using CliFx.Models; using CliFx.Services; -using CliFx.Tests.TestObjects; using NUnit.Framework; namespace CliFx.Tests { + public partial class CliApplicationTests + { + [DefaultCommand] + public class TestCommand : Command + { + public override ExitCode Execute() => new ExitCode(13); + } + } + [TestFixture] - public class CliApplicationTests + public partial class CliApplicationTests { [Test] public async Task RunAsync_Test() { // Arrange - var command = new TestCommand(); - var expectedExitCode = await command.ExecuteAsync(); - - var commandOptionParser = new CommandOptionParser(); - - var typeProvider = new TypeProvider(typeof(TestCommand)); - var commandOptionConverter = new CommandOptionConverter(); - var commandResolver = new CommandResolver(typeProvider, commandOptionConverter); - - var application = new CliApplication(commandOptionParser, commandResolver); + var application = new CliApplication( + new CommandOptionParser(), + new CommandResolver(new[] {typeof(TestCommand)}, new CommandOptionConverter())); // Act var exitCodeValue = await application.RunAsync(); // Assert - Assert.That(exitCodeValue, Is.EqualTo(expectedExitCode.Value), "Exit code"); + Assert.That(exitCodeValue, Is.EqualTo(13), "Exit code"); } } } \ No newline at end of file diff --git a/CliFx.Tests/CommandOptionConverterTests.cs b/CliFx.Tests/CommandOptionConverterTests.cs index 3d3ab09..2bd332a 100644 --- a/CliFx.Tests/CommandOptionConverterTests.cs +++ b/CliFx.Tests/CommandOptionConverterTests.cs @@ -3,13 +3,44 @@ using System.Collections; using System.Collections.Generic; using CliFx.Models; using CliFx.Services; -using CliFx.Tests.TestObjects; using NUnit.Framework; namespace CliFx.Tests { + public partial class CommandOptionConverterTests + { + public enum TestEnum + { + Value1, + Value2, + Value3 + } + + public struct TestStringConstructable + { + public string Value { get; } + + public TestStringConstructable(string value) + { + Value = value; + } + } + + public struct TestStringParseable + { + public string Value { get; } + + private TestStringParseable(string value) + { + Value = value; + } + + public static TestStringParseable Parse(string value) => new TestStringParseable(value); + } + } + [TestFixture] - public class CommandOptionConverterTests + public partial class CommandOptionConverterTests { private static IEnumerable GetTestCases_ConvertOption() { diff --git a/CliFx.Tests/CommandResolverTests.cs b/CliFx.Tests/CommandResolverTests.cs index 1be1d25..2340b78 100644 --- a/CliFx.Tests/CommandResolverTests.cs +++ b/CliFx.Tests/CommandResolverTests.cs @@ -1,14 +1,28 @@ using System.Collections.Generic; +using CliFx.Attributes; using CliFx.Exceptions; using CliFx.Models; using CliFx.Services; -using CliFx.Tests.TestObjects; using NUnit.Framework; namespace CliFx.Tests { + public partial class CommandResolverTests + { + [DefaultCommand] + public class TestCommand : Command + { + [CommandOption("int", 'i', IsRequired = true)] + public int IntOption { get; set; } = 24; + + [CommandOption("str", 's')] public string StringOption { get; set; } = "foo bar"; + + public override ExitCode Execute() => new ExitCode(IntOption, StringOption); + } + } + [TestFixture] - public class CommandResolverTests + public partial class CommandResolverTests { private static IEnumerable GetTestCases_ResolveCommand() { @@ -36,14 +50,6 @@ namespace CliFx.Tests }), new TestCommand {IntOption = 13} ); - - yield return new TestCaseData( - new CommandOptionSet("command", new[] - { - new CommandOption("int", "13") - }), - new TestCommand {IntOption = 13} - ); } [Test] @@ -51,10 +57,7 @@ namespace CliFx.Tests public void ResolveCommand_Test(CommandOptionSet commandOptionSet, TestCommand expectedCommand) { // Arrange - var typeProvider = new TypeProvider(typeof(TestCommand)); - var optionConverter = new CommandOptionConverter(); - - var resolver = new CommandResolver(typeProvider, optionConverter); + var resolver = new CommandResolver(new[] {typeof(TestCommand)}, new CommandOptionConverter()); // Act var command = resolver.ResolveCommand(commandOptionSet) as TestCommand; @@ -85,10 +88,7 @@ namespace CliFx.Tests public void ResolveCommand_IsRequired_Test(CommandOptionSet commandOptionSet) { // Arrange - var typeProvider = new TypeProvider(typeof(TestCommand)); - var optionConverter = new CommandOptionConverter(); - - var resolver = new CommandResolver(typeProvider, optionConverter); + var resolver = new CommandResolver(new[] {typeof(TestCommand)}, new CommandOptionConverter()); // Act & Assert Assert.Throws(() => resolver.ResolveCommand(commandOptionSet)); diff --git a/CliFx.Tests/TestObjects/TestCommand.cs b/CliFx.Tests/TestObjects/TestCommand.cs deleted file mode 100644 index 19a206d..0000000 --- a/CliFx.Tests/TestObjects/TestCommand.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CliFx.Attributes; -using CliFx.Models; - -namespace CliFx.Tests.TestObjects -{ - [DefaultCommand] - [Command("command")] - public class TestCommand : Command - { - [CommandOption("int", 'i', IsRequired = true)] - public int IntOption { get; set; } = 24; - - [CommandOption("str", 's')] - public string StringOption { get; set; } = "foo bar"; - - public override ExitCode Execute() => new ExitCode(IntOption, StringOption); - } -} \ No newline at end of file diff --git a/CliFx.Tests/TestObjects/TestEnum.cs b/CliFx.Tests/TestObjects/TestEnum.cs deleted file mode 100644 index 6035f37..0000000 --- a/CliFx.Tests/TestObjects/TestEnum.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CliFx.Tests.TestObjects -{ - public enum TestEnum - { - Value1, - Value2, - Value3 - } -} \ No newline at end of file diff --git a/CliFx.Tests/TestObjects/TestStringConstructable.cs b/CliFx.Tests/TestObjects/TestStringConstructable.cs deleted file mode 100644 index 1fb7abd..0000000 --- a/CliFx.Tests/TestObjects/TestStringConstructable.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace CliFx.Tests.TestObjects -{ - public struct TestStringConstructable - { - public string Value { get; } - - public TestStringConstructable(string value) - { - Value = value; - } - } -} \ No newline at end of file diff --git a/CliFx.Tests/TestObjects/TestStringParseable.cs b/CliFx.Tests/TestObjects/TestStringParseable.cs deleted file mode 100644 index b8b1dfc..0000000 --- a/CliFx.Tests/TestObjects/TestStringParseable.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace CliFx.Tests.TestObjects -{ - public partial struct TestStringParseable - { - public string Value { get; } - - private TestStringParseable(string value) - { - Value = value; - } - } - - public partial struct TestStringParseable - { - public static TestStringParseable Parse(string value) => new TestStringParseable(value); - } -} \ No newline at end of file diff --git a/CliFx/CliApplication.cs b/CliFx/CliApplication.cs index 24ce922..32cc0dd 100644 --- a/CliFx/CliApplication.cs +++ b/CliFx/CliApplication.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; -using System.Reflection; using System.Threading.Tasks; using CliFx.Services; namespace CliFx { - public partial class CliApplication : ICliApplication + public class CliApplication : ICliApplication { private readonly ICommandOptionParser _commandOptionParser; private readonly ICommandResolver _commandResolver; @@ -17,7 +16,7 @@ namespace CliFx } public CliApplication() - : this(new CommandOptionParser(), GetDefaultCommandResolver(Assembly.GetCallingAssembly())) + : this(new CommandOptionParser(), new CommandResolver(new CommandOptionConverter())) { } @@ -31,15 +30,4 @@ namespace CliFx return exitCode.Value; } } - - public partial class CliApplication - { - private static ICommandResolver GetDefaultCommandResolver(Assembly assembly) - { - var typeProvider = TypeProvider.FromAssembly(assembly); - var commandOptionConverter = new CommandOptionConverter(); - - return new CommandResolver(typeProvider, commandOptionConverter); - } - } } \ No newline at end of file diff --git a/CliFx/Extensions.cs b/CliFx/Extensions.cs index 972387e..0ca26fc 100644 --- a/CliFx/Extensions.cs +++ b/CliFx/Extensions.cs @@ -1,12 +1,9 @@ -using System; -using System.Linq; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace CliFx { public static class Extensions { - public static Task RunAsync(this ICliApplication application) => - application.RunAsync(Environment.GetCommandLineArgs().Skip(1).ToArray()); + public static Task RunAsync(this ICliApplication application) => application.RunAsync(new string[0]); } } \ No newline at end of file diff --git a/CliFx/Internal/CommandType.cs b/CliFx/Internal/CommandType.cs index d1dbaeb..602b1af 100644 --- a/CliFx/Internal/CommandType.cs +++ b/CliFx/Internal/CommandType.cs @@ -36,7 +36,7 @@ namespace CliFx.Internal // Derives from Command type.IsDerivedFrom(typeof(Command)) && // Marked with DefaultCommandAttribute or CommandAttribute - (type.IsDefined(typeof(DefaultCommandAttribute)) || type.IsDefined(typeof(CommandAttribute))); + type.IsDefined(typeof(CommandAttribute)); public static CommandType Initialize(Type type) { diff --git a/CliFx/Services/CommandResolver.cs b/CliFx/Services/CommandResolver.cs index ef9d1c1..2ec7693 100644 --- a/CliFx/Services/CommandResolver.cs +++ b/CliFx/Services/CommandResolver.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using CliFx.Attributes; using CliFx.Exceptions; using CliFx.Internal; @@ -8,18 +9,23 @@ using CliFx.Models; namespace CliFx.Services { - public class CommandResolver : ICommandResolver + public partial class CommandResolver : ICommandResolver { - private readonly ITypeProvider _typeProvider; + private readonly IReadOnlyList _availableTypes; private readonly ICommandOptionConverter _commandOptionConverter; - public CommandResolver(ITypeProvider typeProvider, ICommandOptionConverter commandOptionConverter) + public CommandResolver(IReadOnlyList availableTypes, ICommandOptionConverter commandOptionConverter) { - _typeProvider = typeProvider; + _availableTypes = availableTypes; _commandOptionConverter = commandOptionConverter; } - private IEnumerable GetCommandTypes() => CommandType.GetCommandTypes(_typeProvider.GetTypes()); + public CommandResolver(ICommandOptionConverter commandOptionConverter) + : this(GetDefaultAvailableTypes(), commandOptionConverter) + { + } + + private IEnumerable GetCommandTypes() => CommandType.GetCommandTypes(_availableTypes); private CommandType GetDefaultCommandType() { @@ -100,4 +106,9 @@ namespace CliFx.Services return command; } } + + public partial class CommandResolver + { + private static IReadOnlyList GetDefaultAvailableTypes() => Assembly.GetEntryAssembly()?.GetExportedTypes() ?? new Type[0]; + } } \ No newline at end of file diff --git a/CliFx/Services/ITypeProvider.cs b/CliFx/Services/ITypeProvider.cs deleted file mode 100644 index bc7c5da..0000000 --- a/CliFx/Services/ITypeProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace CliFx.Services -{ - public interface ITypeProvider - { - IReadOnlyList GetTypes(); - } -} \ No newline at end of file diff --git a/CliFx/Services/TypeProvider.cs b/CliFx/Services/TypeProvider.cs deleted file mode 100644 index 93c92f7..0000000 --- a/CliFx/Services/TypeProvider.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -namespace CliFx.Services -{ - public partial class TypeProvider : ITypeProvider - { - private readonly IReadOnlyList _types; - - public TypeProvider(IReadOnlyList types) - { - _types = types; - } - - public TypeProvider(params Type[] types) - : this((IReadOnlyList) types) - { - } - - public IReadOnlyList GetTypes() => _types; - } - - public partial class TypeProvider - { - public static TypeProvider FromAssembly(Assembly assembly) => new TypeProvider(assembly.GetExportedTypes()); - - public static TypeProvider FromAssemblies(IReadOnlyList assemblies) => - new TypeProvider(assemblies.SelectMany(a => a.ExportedTypes).ToArray()); - - public static TypeProvider FromAssemblies(params Assembly[] assemblies) => FromAssemblies((IReadOnlyList) assemblies); - } -} \ No newline at end of file