diff --git a/ReadMe.md b/ReadMe.md index def9921..3400b40 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -58,10 +58,10 @@ public void Hello( { ``` -`help` command(or no argument to pass) shows there detail. This help format is same as `dotnet` command. +`-help` option (or no argument to pass) shows there detail. This help format is same as `dotnet` command. ``` -> SampleApp.exe help +> SampleApp.exe -help Usage: SampleApp [options...] Options: @@ -69,10 +69,10 @@ Options: -r, -repeat repeat count. (Default: 3) ``` -`version` command shows `AssemblyInformationalVersion` or `AssemblylVersion`. +`-version` option shows `AssemblyInformationalVersion` or `AssemblylVersion`. ``` -> SampleApp.exe version +> SampleApp.exe -version 1.0.0 ``` diff --git a/src/ConsoleAppFramework/ConsoleAppEngineHostBuilderExtensions.cs b/src/ConsoleAppFramework/ConsoleAppEngineHostBuilderExtensions.cs index a898818..33306ee 100644 --- a/src/ConsoleAppFramework/ConsoleAppEngineHostBuilderExtensions.cs +++ b/src/ConsoleAppFramework/ConsoleAppEngineHostBuilderExtensions.cs @@ -150,26 +150,26 @@ IHostBuilder ConfigureEmptyService() else { // override default Help - args = new string[] { "help" }; + args = new string[] { "--help" }; } } } - if (!hasHelp && args.Length == 1 && TrimEquals(args[0], HelpCommand)) + if (!hasHelp && args.Length == 1 && OptionEquals(args[0], HelpCommand)) { Console.Write(new CommandHelpBuilder().BuildHelpMessage(methods, defaultMethod)); ConfigureEmptyService(); return hostBuilder; } - if (args.Length == 1 && TrimEquals(args[0], VersionCommand)) + if (args.Length == 1 && OptionEquals(args[0], VersionCommand)) { ShowVersion(); ConfigureEmptyService(); return hostBuilder; } - if (args.Length == 2 && methods.Length != 1) + if (args.Length == 2 && methods.Length > 0 && defaultMethod == null) { int methodIndex = -1; @@ -179,7 +179,7 @@ IHostBuilder ConfigureEmptyService() methodIndex = 1; } // command -help - else if (TrimEquals(args[1], HelpCommand)) + else if (OptionEquals(args[1], HelpCommand)) { methodIndex = 0; } @@ -223,6 +223,11 @@ static bool TrimEquals(string arg, string command) return arg.Trim('-').Equals(command, StringComparison.OrdinalIgnoreCase); } + static bool OptionEquals(string arg, string command) + { + return arg.StartsWith("-") && arg.Trim('-').Equals(command, StringComparison.OrdinalIgnoreCase); + } + static void ShowVersion() { var asm = Assembly.GetEntryAssembly(); diff --git a/tests/ConsoleAppFramework.Integration.Test/MultipleCommandTest.cs b/tests/ConsoleAppFramework.Integration.Test/MultipleCommandTest.cs index 48bc8d1..4acf474 100644 --- a/tests/ConsoleAppFramework.Integration.Test/MultipleCommandTest.cs +++ b/tests/ConsoleAppFramework.Integration.Test/MultipleCommandTest.cs @@ -86,15 +86,58 @@ public void OptionAndArg_Option() console.Output.Should().Contain("Hello Cysharp (-128)"); } + [Fact] + public void OptionAndArg_Help() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "hello", "help" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Hello help (18)"); + } + + [Fact] + public void OptionAndArg_HelpAndOtherArgs() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "hello", "help", "-age", "-128" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + + console.Output.Should().Contain("Hello help (-128)"); + } + [Fact] public void OptionAndArg_HelpOptionLike() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "hello", "-help" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Arguments:"); + + // NOTE: Currently, ConsoleAppFramework treats the first argument as special. If the argument is '-help', it is same as '-help' option. + //console.Output.Should().Contain("Hello -help (-128)"); + } + + [Fact] + public void OptionAndArg_HelpOptionLikeAndOtherOptions() { using var console = new CaptureConsoleOutput(); var args = new string[] { "hello", "-help", "-age", "-128" }; Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Hello -help (-128)"); } + [Fact] + public void CommandHelp_OptionAndArg() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "help", "hello" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Arguments:"); + } + public class CommandTests_Multiple_OptionAndArg : ConsoleAppBase { [Command("hello")] @@ -102,5 +145,27 @@ public class CommandTests_Multiple_OptionAndArg : ConsoleAppBase [Command("konnichiwa")] public void Konnichiwa() => Console.WriteLine("Konnichiwa"); } + + [Fact] + public void OptionHelp() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "-help" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Commands:"); + console.Output.Should().Contain("hello"); + console.Output.Should().Contain("konnichiwa"); + } + + [Fact] + public void OptionVersion() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "-version" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().MatchRegex(@"\d.\d.\d"); // NOTE: When running with unit test runner, it returns a version of the runner. + } + } } diff --git a/tests/ConsoleAppFramework.Integration.Test/NamedSingleCommandTest.cs b/tests/ConsoleAppFramework.Integration.Test/NamedSingleCommandTest.cs new file mode 100644 index 0000000..6401f75 --- /dev/null +++ b/tests/ConsoleAppFramework.Integration.Test/NamedSingleCommandTest.cs @@ -0,0 +1,83 @@ +using System; +using FluentAssertions; +using Microsoft.Extensions.Hosting; +using Xunit; + +// ReSharper disable InconsistentNaming + +namespace ConsoleAppFramework.Integration.Test +{ + public partial class NamedSingleCommandTest + { + [Fact] + public void NamedCommand_NoArgs_CommandIsNotSpecified() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Commands:"); + } + + [Fact] + public void NamedCommand_NoArgs_Invoke() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "hello" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Hello"); + } + + [Fact] + public void NamedCommand_NoArgs_CommandHelp() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "help", "hello" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain(" hello"); + } + + public class CommandTests_Single_Named_NoArgs : ConsoleAppBase + { + [Command("hello")] + public void Hello() => Console.WriteLine("Hello"); + } + + [Fact] + public void NamedCommand_OneArg_CommandIsNotSpecified() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Commands:"); + } + + [Fact] + public void NamedCommand_OneArg_Invoke() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "hello", "Cysharp" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Hello Cysharp"); + } + + [Fact] + public void NamedCommand_OneArg_CommandHelp() + { + using var console = new CaptureConsoleOutput(); + var args = new string[] { "help", "hello" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().Contain("Usage:"); + console.Output.Should().Contain("Arguments:"); + } + + public class CommandTests_Single_Named_OneArg : ConsoleAppBase + { + [Command("hello")] + public void Hello([Option(0)]string name) => Console.WriteLine($"Hello {name}"); + } + + } +} diff --git a/tests/ConsoleAppFramework.Integration.Test/SingleCommandTest.Arguments.cs b/tests/ConsoleAppFramework.Integration.Test/SingleCommandTest.Arguments.cs index f522dbc..b5f99af 100644 --- a/tests/ConsoleAppFramework.Integration.Test/SingleCommandTest.Arguments.cs +++ b/tests/ConsoleAppFramework.Integration.Test/SingleCommandTest.Arguments.cs @@ -25,8 +25,6 @@ public void NoOptions_OneRequiredArg_ArgHelp() var args = new[] { "help" }; Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); console.Output.Should().Contain("Hello help"); - // console.GetOutputText().Should().Contain("Usage:"); - // console.GetOutputText().Should().Contain("Arguments:"); } [Fact] @@ -47,6 +45,21 @@ public void NoOptions_OneRequiredArg_Help() Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); console.Output.Should().Contain("Usage:"); console.Output.Should().Contain("Arguments:"); + + // NOTE: Currently, ConsoleAppFramework treats the first argument as special. If the argument is '-help', it is same as '-help' option. + //console.Output.Should().Contain("Hello -version"); + } + + [Fact] + public void NoOptions_OneRequiredArg_Version() + { + using var console = new CaptureConsoleOutput(); + var args = new[] { "-version" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().MatchRegex(@"\d.\d.\d"); // NOTE: When running with unit test runner, it returns a version of the runner. + + // NOTE: Currently, ConsoleAppFramework treats the first argument as special. If the argument is '-help', it is same as '-help' option. + //console.Output.Should().Contain("Hello -version"); } public class CommandTests_Single_NoOptions_OneRequiredArg : ConsoleAppBase @@ -70,8 +83,6 @@ public void NoOptions_OneOptionalArg_ArgHelp() var args = new[] { "help" }; Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); console.Output.Should().Contain("Hello help"); - // console.GetOutputText().Should().Contain("Usage:"); - // console.GetOutputText().Should().Contain("Arguments:"); } [Fact] @@ -91,6 +102,21 @@ public void NoOptions_OneOptionalArg_Help() Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); console.Output.Should().Contain("Usage:"); console.Output.Should().Contain("Arguments:"); + + // NOTE: Currently, ConsoleAppFramework treats the first argument as special. If the argument is '-help', it is same as '-help' option. + //console.Output.Should().Contain("Hello -help"); + } + + [Fact] + public void NoOptions_OneOptionalArg_Version() + { + using var console = new CaptureConsoleOutput(); + var args = new[] { "-version" }; + Host.CreateDefaultBuilder().RunConsoleAppFrameworkAsync(args); + console.Output.Should().MatchRegex(@"\d.\d.\d"); // NOTE: When running with unit test runner, it returns a version of the runner. + + // NOTE: Currently, ConsoleAppFramework treats the first argument as special. If the argument is '-help', it is same as '-help' option. + //console.Output.Should().Contain("Hello -version"); } public class CommandTests_Single_NoOptions_OneOptionalArgs : ConsoleAppBase diff --git a/tests/ConsoleAppFramework.Tests/SingleContainedTest.cs b/tests/ConsoleAppFramework.Tests/SingleContainedTest.cs index 5ce1927..f87ad35 100644 --- a/tests/ConsoleAppFramework.Tests/SingleContainedTest.cs +++ b/tests/ConsoleAppFramework.Tests/SingleContainedTest.cs @@ -116,8 +116,8 @@ public async Task SimpleComplexArgsTest() public class TwoArgsWithOption : ConsoleAppBase { public void Hello( - [Option("-n", "name of this")]string name, - [Option("-r", "repeat msg")]int repeat) + [Option("n", "name of this")]string name, + [Option("r", "repeat msg")]int repeat) { Context.Logger.LogInformation($"name:{name}"); Context.Logger.LogInformation($"repeat:{repeat}");