diff --git a/.github/workflows/buildAndPublish.yml b/.github/workflows/buildAndPublish.yml index dbdd022..054a9f0 100644 --- a/.github/workflows/buildAndPublish.yml +++ b/.github/workflows/buildAndPublish.yml @@ -42,10 +42,10 @@ jobs: run: dotnet build -c Release -p:Version=${{ steps.version.outputs.version}} - name: Run tests - run: dotnet test -c Release --no-build + run: dotnet test -c Release --no-build -l trx --results-directory TestResults - name: Upload dotnet test results - uses: dorny/test-reporter@v1.8.0 + uses: dorny/test-reporter@v1.9.0 if: ${{ !cancelled() }} with: name: .NET Tests diff --git a/.github/workflows/generateDocs.yml b/.github/workflows/generateDocs.yml index d25c1f3..0509d4b 100644 --- a/.github/workflows/generateDocs.yml +++ b/.github/workflows/generateDocs.yml @@ -10,7 +10,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Build documenation site - uses: nunit/docfx-action@v3.1.0 + uses: nunit/docfx-action@v3.2.0 with: args: docs/docfx.json - name: Upload documentation archive diff --git a/Directory.Build.props b/Directory.Build.props index c542c0f..2789807 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,33 +1,34 @@  - - MGR.CommandLineParser - netstandard2.0 - bin\$(Configuration)\netstandard2.0\$(MSBuildProjectName).xml - latest - true - false - false - - portable - true - true + + MGR.CommandLineParser + netstandard2.0 + bin\$(Configuration)\netstandard2.0\$(MSBuildProjectName).xml + latest + enable + true + false + false + + portable + true + true - Matthias GROSPERRIN - - https://github.com/mgrosperrin/commandlineparser - https://github.com/mgrosperrin/commandlineparser - MGR.CommandLineParser is a multi-command line parser. It uses System.ComponentModel.DataAnnotations to declare the commands. - git - Copyright © Matthias GROSPERRIN - en-US - false - MIT - trx%3bLogFileName=$(MSBuildProjectName).trx - $(MSBuildThisFileDirectory)/TestResults/$(TargetFramework) - + Matthias GROSPERRIN + + https://github.com/mgrosperrin/commandlineparser + https://github.com/mgrosperrin/commandlineparser + MGR.CommandLineParser is a multi-command line parser. It uses System.ComponentModel.DataAnnotations to declare the commands. + git + Copyright © Matthias GROSPERRIN + en-US + false + MIT + trx%3bLogFileName=$(MSBuildProjectName).trx + $(MSBuildThisFileDirectory)/TestResults/$(TargetFramework) + - - true - + + true + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 2e1e315..f560a85 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,27 +2,25 @@ true false - 8.0.0 - 8.0.0 - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/MGR.CommandLineParser.sln b/MGR.CommandLineParser.sln index cdcb309..f9e2242 100644 --- a/MGR.CommandLineParser.sln +++ b/MGR.CommandLineParser.sln @@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser", "src\MGR.CommandLineParser\MGR.CommandLineParser.csproj", "{EF6019C2-2C4D-4874-BBBF-D76CA30F7E8D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{569ED12A-DA23-4457-B304-6B00C0CB335E}" + ProjectSection(SolutionItems) = preProject + tests\Directory.Build.props = tests\Directory.Build.props + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser.UnitTests", "tests\MGR.CommandLineParser.UnitTests\MGR.CommandLineParser.UnitTests.csproj", "{22F60D05-F6DB-4410-80AD-E558EF1BDF6F}" EndProject @@ -41,6 +44,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser.Hosti EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj", "{405858FA-1E78-48C7-9915-B558D0F15CAE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{AF37E9B0-D41E-4CC2-8641-61FA6B28362B}" + ProjectSection(SolutionItems) = preProject + .github\dependabot.yml = .github\dependabot.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BCD738AE-36C9-4CD9-B0F5-EAB942B193DC}" + ProjectSection(SolutionItems) = preProject + .github\workflows\buildAndPublish.yml = .github\workflows\buildAndPublish.yml + .github\workflows\ci.yml = .github\workflows\ci.yml + .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml + .github\workflows\generateDocs.yml = .github\workflows\generateDocs.yml + .github\workflows\release.yml = .github\workflows\release.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -92,6 +109,8 @@ Global {9F5A0142-E0A1-45A2-961E-55611B4440AD} = {FB795A12-C939-492F-9377-4C468D01EF3C} {40EAA8E2-7AFE-4ED1-A961-35BD7E424985} = {FB795A12-C939-492F-9377-4C468D01EF3C} {405858FA-1E78-48C7-9915-B558D0F15CAE} = {172E24C2-BF99-4DA9-A7DF-8C0BB44C138D} + {AF37E9B0-D41E-4CC2-8641-61FA6B28362B} = {EF849FD3-293F-4CC8-B227-9680CF929A66} + {BCD738AE-36C9-4CD9-B0F5-EAB942B193DC} = {AF37E9B0-D41E-4CC2-8641-61FA6B28362B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {827031C5-AE76-4B4C-9503-E13F15B497E9} diff --git a/docs/class-based/create-class-based-command.md b/docs/class-based/create-class-based-command.md index 17096aa..5be4d1d 100644 --- a/docs/class-based/create-class-based-command.md +++ b/docs/class-based/create-class-based-command.md @@ -1,24 +1,36 @@ # Create a class-based command -## Implement `ICommand` +To create a class-based command, you have to create two classes: +1. one that defines the data associated with the command, +2. one that implements the logic of the command. -To create a class-based command, you have to create a class that implements the interface `MGR.CommandLineParser.Command.ICommand` (or [inherit `CommandBase`](#inherit-from-commandbase)). -The interface provides two members: +Depending on what basic features you need for your command, you can choose to implement the logic of the command by inheriting from the abstract class `CommandBase` or by implementing the interface `ICommandHandler`. -1. a property `Arguments` (of type `IList`) that will receive all arguments not mapped to an option, -2. a method `ExecuteAsync` (that take no parameters and return a `Task`) that is called to execute the command. The returned value is the status code that should be returned as exit code. +## Inherit from `CommandBase` +The abstract class `CommandBase` provides implementation for : -## Inherit from `CommandBase` -You can inherit from `MGR.CommandLineParser.Command.CommandBase`. -This abstract class provides: +- an `--help` option, +- access to the current `IServiceProvider` via the property `ServiceProvider`, +- access to the current [IConsole](../extensibility/console.md) via the property `Console`. -- implementation of an `--help` option, -- access to the current `IServiceProvider`, -- access to the current [IConsole](../extensibility/console.md) -- access to the [ICommandType](/api/MGR.CommandLineParser.Extensibility.Command.ICommandType.html) (which describes the current command) +When deriving from this class, you have to implement the `ExecuteCommandAsync` that is called when the value of the `--help` option is `false`. +You also have to make your command data class inherit from `MGR.CommandLineParser.Command.HelpedCommandData` to have the help option implemented. +It will also give you access to the [ICommandType](/api/MGR.CommandLineParser.Extensibility.Command.ICommandType.html) which describes the current command. -When deriving from this class, you have to implement the `ExecuteCommandAsync` that is called when the value of the `--help` option is ```false```. +## Implement `ICommandHandler` and `CommandData` + +If you don't need these features, you can implement the interface `ICommandHandler`. + +The interface defines a method `ExecuteAsync` to implement which is called to execute the command. +It takes two parameters: +1. The data of the command, of type of the generic type argument `TCommandData`, +2. A `CancellationToken` used to stop the execution of the command. + +The method returns a `Task` that represent the status code of the execution of the command (usually the exit code of the program). + +The "data" class must inherit `CommandData`, that provides a property `Arguments` (of type `IList`) that will receive all arguments not mapped to an option. +To define your own opptions, you have to add properties to this class. ## Customize your command @@ -26,7 +38,7 @@ When deriving from this class, you have to implement the `ExecuteCommandAsync` t ## Add options to you command -You can add options to your command by simply adding properties to your class. +You can add options to your command by simply adding properties to your "command data" class. The properties can have any type, you just have to be sure there is a [converter](../extensibility/converter.md) for this type (see the [list of built-in converters](../extensibility/built-in-converters.md)). You can customize the behavior of the options with some annotations (the parser supports the annotations from [System.ComponentModel.DataAnnotations](https://docs.microsoft.com/dotnet/api/system.componentmodel.dataannotations)): diff --git a/docs/index.md b/docs/index.md index 51f57a7..6c959db 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ It provides an extensible mechanism to provide define commands and is able to automatically generate help/usage output for all commands. Built-in providers lets you define command by: -- [creating a class](class-based/create-class-based-command.md) that implements `MGR.CommandLineParser.Command.ICommand` or inherits `MGR.CommandLineParser.Command.CommandBase` (provides some basic behavior for commands like support of `--help` option) +- [creating classes](class-based/create-class-based-command.md) that implements `MGR.CommandLineParser.Command.ICommandHandler` for the logic of your command and `MGR.CommandLineParser.Command.CommandData` for the data associated to the command, or inherits `MGR.CommandLineParser.Command.CommandBase` (provides some basic behavior for commands like support of `--help` option) - [dynamically defining a command that uses a lambda](lambda/create-a-lambda-based-command.md) as execution (via the package `MGR.CommandLineParser.Command.Lambda) The general syntax on the command line is: @@ -19,7 +19,6 @@ by a space (` `) or a colon (`:`). Arguments is a list of non-option string that is passed to the command. - There is also some ways to customize others parts of the parser: - how to display information to the user: the [`IConsole` interface](extensibility/console.md) diff --git a/generate_docs.ps1 b/generate_docs.ps1 deleted file mode 100644 index e2b0e70..0000000 --- a/generate_docs.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -Param( - [switch]$Serve -) -$REPO_DIR = Join-Path $PSScriptRoot ".." -$ARTIFACTS_DIR = Join-Path $REPO_DIR "artifacts" -$TOOLS_DIR = Join-Path $ARTIFACTS_DIR "tools" -$docfxRoot = Join-Path $TOOLS_DIR "docfx.console" -$docfx = Join-Path (Join-Path $docfxRoot "tools") "docfx.exe" -if (-not (Test-Path $docfx)) { - mkdir -p $docfxRoot -ErrorAction Ignore | Out-Null - $temp = (New-TemporaryFile).FullName + ".zip" - Invoke-WebRequest "https://www.nuget.org/api/v2/package/docfx.console/2.52.0" -O $temp - Expand-Archive $temp -DestinationPath $docfxRoot - Remove-Item $temp -} -[string[]] $arguments = @() -if ($Serve) { - $arguments += '--serve' -} -$DocFxJsonPath = Join-Path (Join-Path $REPO_DIR "docs") "docfx.json" -& $docfx $DocFxJsonPath @arguments diff --git a/samples/SimpleApp/HostBuilderCalls.cs b/samples/SimpleApp/HostBuilderCalls.cs index a7e3ef9..5fe7e07 100644 --- a/samples/SimpleApp/HostBuilderCalls.cs +++ b/samples/SimpleApp/HostBuilderCalls.cs @@ -6,32 +6,31 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace SimpleApp +namespace SimpleApp; + +internal static class HostBuilderCalls { - internal static class HostBuilderCalls + internal static async Task CreateAndCallDefaultParserBuilderAsync() { - internal static async Task CreateAndCallDefaultParserBuilderAsync() - { - var arguments = new[] { "run", "--opt", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); + var arguments = new[] { "run", "--opt", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - var hostBuilder = new HostBuilder(); - hostBuilder.ConfigureParser(builder => - { - builder.AddCommand("run", - commandBuilder => - { - commandBuilder.AddOption("opt", "o", - o => o.Required()); - }, - context => - { - var opt = context.GetOptionValue("opt"); - return Task.FromResult(opt); - }); - }); - var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(arguments, CancellationToken.None); - Console.WriteLine("Execution result: {0}", parsingResult); - } + var hostBuilder = new HostBuilder(); + hostBuilder.ConfigureParser(builder => + { + builder.AddCommand("run", + commandBuilder => + { + commandBuilder.AddOption("opt", "o", + o => o.Required()); + }, + (context, cancellationToken) => + { + var opt = context.GetOptionValue("opt"); + return Task.FromResult(opt); + }); + }); + var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(arguments, CancellationToken.None); + Console.WriteLine("Execution result: {0}", parsingResult); } } diff --git a/samples/SimpleApp/ParserBuilderCalls.cs b/samples/SimpleApp/ParserBuilderCalls.cs index 5d1d529..3425f02 100644 --- a/samples/SimpleApp/ParserBuilderCalls.cs +++ b/samples/SimpleApp/ParserBuilderCalls.cs @@ -7,93 +7,92 @@ using MGR.CommandLineParser.Tests.Commands; using Microsoft.Extensions.DependencyInjection; -namespace SimpleApp +namespace SimpleApp; + +internal static class ParserBuilderCalls { - internal static class ParserBuilderCalls + internal static async Task CreateAndCallDefaultParserBuilderAsync() { - internal static async Task CreateAndCallDefaultParserBuilderAsync() - { - Console.WriteLine("ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync"); - var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); + Console.WriteLine("ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync"); + var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - var parserBuild = new ParserBuilder(new ParserOptions()) - .AddCommands(builder => builder.AddCommands()); - var parser = parserBuild.BuildParser(); - var commandResult = await parser.Parse(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var parserBuild = new ParserBuilder(new ParserOptions()) + .AddCommands(builder => builder.AddCommands()); + var parser = parserBuild.BuildParser(); + var commandResult = await parser.Parse(arguments); + if (commandResult.IsValid) + { + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); } - internal static async Task CreateAndCallCustomizedParserBuilderAsync() + else { - Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync"); - var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); + Console.WriteLine("Invalid parsing"); + } + } + internal static async Task CreateAndCallCustomizedParserBuilderAsync() + { + Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync"); + var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - var serviceCollection = new ServiceCollection(); - var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection) - .AddCommands(builder => builder.AddCommands()); - var parser = parserBuild.BuildParser(); - var commandResult = await parser.Parse(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var serviceCollection = new ServiceCollection(); + var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection) + .AddCommands(builder => builder.AddCommands()); + var parser = parserBuild.BuildParser(); + var commandResult = await parser.Parse(arguments); + if (commandResult.IsValid) + { + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); } - internal static async Task CreateAndCallCustomizedWithCommandsParserBuilderAsync() + else { - Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync"); - var arguments = new[] { "test", "--longName:3", "hello" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); + Console.WriteLine("Invalid parsing"); + } + } + internal static async Task CreateAndCallCustomizedWithCommandsParserBuilderAsync() + { + Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync"); + var arguments = new[] { "test", "--longName:3", "hello" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - var serviceCollection = new ServiceCollection(); - serviceCollection.AddCommandLineParser() - .AddCommand( - "test", - commandBuilder => - { - commandBuilder - .WithDescription("Description of command") - .AddOption( - "longName", - "shortName", - optionBuilder => { - optionBuilder.Required() - .AddValidation(new RangeAttribute(2, 7)); - }); - }, - context => - { - var year = context.GetOptionValue("longName"); - var arg = context.Arguments; - return Task.FromResult(year + arg.Count()); - }); + var serviceCollection = new ServiceCollection(); + serviceCollection.AddCommandLineParser() + .AddCommand( + "test", + commandBuilder => + { + commandBuilder + .WithDescription("Description of command") + .AddOption( + "longName", + "shortName", + optionBuilder => { + optionBuilder.Required() + .AddValidation(new RangeAttribute(2, 7)); + }); + }, + (context, cancellationToken) => + { + var year = context.GetOptionValue("longName"); + var arg = context.Arguments; + return Task.FromResult(year + arg.Count()); + }); - var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection) - .AddCommands(builder => builder.AddCommands()); - var parser = parserBuild.BuildParser(); - var commandResult = await parser.Parse(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection) + .AddCommands(builder => builder.AddCommands()); + var parser = parserBuild.BuildParser(); + var commandResult = await parser.Parse(arguments); + if (commandResult.IsValid) + { + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); + } + else + { + Console.WriteLine("Invalid parsing"); } } } diff --git a/samples/SimpleApp/ParserFactoryCalls.cs b/samples/SimpleApp/ParserFactoryCalls.cs index d4e5635..d6d1b9d 100644 --- a/samples/SimpleApp/ParserFactoryCalls.cs +++ b/samples/SimpleApp/ParserFactoryCalls.cs @@ -4,143 +4,142 @@ using MGR.CommandLineParser.Tests.Commands; using Microsoft.Extensions.DependencyInjection; -namespace SimpleApp +namespace SimpleApp; + +internal static class ParserFactoryCalls { - internal static class ParserFactoryCalls + internal static async Task ConfigureParserAndGetParserFactoryAsync() { - internal static async Task ConfigureParserAndGetParserFactoryAsync() + Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync"); + // In Startup class + void Configure(IServiceCollection services) { - Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync"); - // In Startup class - void Configure(IServiceCollection services) - { - services.AddCommandLineParser( - options => - { - options.Logo = "Parser via IParserFactory"; - options.CommandLineName = ""; - } - ).AddCommands(); - } + services.AddCommandLineParser( + options => + { + options.Logo = "Parser via IParserFactory"; + options.CommandLineName = ""; + } + ).AddCommands(); + } + + var serviceCollection = new ServiceCollection(); + Configure(serviceCollection); + var serviceProvider = serviceCollection.BuildServiceProvider(); + using (var serviceScope = serviceProvider.CreateScope()) + { + var scopedServiceProvider = serviceScope.ServiceProvider; - var serviceCollection = new ServiceCollection(); - Configure(serviceCollection); - var serviceProvider = serviceCollection.BuildServiceProvider(); - using (var serviceScope = serviceProvider.CreateScope()) + async Task ActionInController(IParserFactory factory) { - var scopedServiceProvider = serviceScope.ServiceProvider; + var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - async Task ActionInController(IParserFactory factory) + var parser = factory.CreateParser(); + var commandResult = await parser.Parse(arguments); + if (commandResult.IsValid) { - var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - - var parser = factory.CreateParser(); - var commandResult = await parser.Parse(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); + } + else + { + Console.WriteLine("Invalid parsing"); } - - var parserFactory = scopedServiceProvider.GetRequiredService(); - await ActionInController(parserFactory); } + + var parserFactory = scopedServiceProvider.GetRequiredService(); + await ActionInController(parserFactory); } + } - internal static async Task ConfigureParserAndGetParserFactoryWithSpecificCommandAsync() + internal static async Task ConfigureParserAndGetParserFactoryWithSpecificCommandAsync() + { + Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync"); + // In Startup class + void Configure(IServiceCollection services) { - Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync"); - // In Startup class - void Configure(IServiceCollection services) - { - services.AddCommandLineParser( - options => - { - options.Logo = "Parser via IParserFactory"; - options.CommandLineName = ""; - } - ).AddCommands(); - } + services.AddCommandLineParser( + options => + { + options.Logo = "Parser via IParserFactory"; + options.CommandLineName = ""; + } + ).AddCommands(); + } - var serviceCollection = new ServiceCollection(); - Configure(serviceCollection); - var serviceProvider = serviceCollection.BuildServiceProvider(); - using (var serviceScope = serviceProvider.CreateScope()) + var serviceCollection = new ServiceCollection(); + Configure(serviceCollection); + var serviceProvider = serviceCollection.BuildServiceProvider(); + using (var serviceScope = serviceProvider.CreateScope()) + { + var scopedServiceProvider = serviceScope.ServiceProvider; + + async Task ActionInController(IParserFactory factory) { - var scopedServiceProvider = serviceScope.ServiceProvider; + var arguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - async Task ActionInController(IParserFactory factory) + var parser = factory.CreateParser(); + var commandResult = await parser.Parse(arguments); + if (commandResult.IsValid) { - var arguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - - var parser = factory.CreateParser(); - var commandResult = await parser.Parse(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); + } + else + { + Console.WriteLine("Invalid parsing"); } - - var parserFactory = scopedServiceProvider.GetRequiredService(); - await ActionInController(parserFactory); } + + var parserFactory = scopedServiceProvider.GetRequiredService(); + await ActionInController(parserFactory); } + } - internal static async Task ConfigureParserAndGetParserFactoryWithDefaultCommandAsync() + internal static async Task ConfigureParserAndGetParserFactoryWithDefaultCommandAsync() + { + Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync"); + // In Startup class + void Configure(IServiceCollection services) { - Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync"); - // In Startup class - void Configure(IServiceCollection services) - { - services.AddCommandLineParser( - options => - { - options.Logo = "Parser via IParserFactory"; - options.CommandLineName = ""; - } - ).AddCommands(); - } + services.AddCommandLineParser( + options => + { + options.Logo = "Parser via IParserFactory"; + options.CommandLineName = ""; + } + ).AddCommands(); + } + + var serviceCollection = new ServiceCollection(); + Configure(serviceCollection); + var serviceProvider = serviceCollection.BuildServiceProvider(); + using (var serviceScope = serviceProvider.CreateScope()) + { + var scopedServiceProvider = serviceScope.ServiceProvider; - var serviceCollection = new ServiceCollection(); - Configure(serviceCollection); - var serviceProvider = serviceCollection.BuildServiceProvider(); - using (var serviceScope = serviceProvider.CreateScope()) + async Task ActionInController(IParserFactory factory) { - var scopedServiceProvider = serviceScope.ServiceProvider; + var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - async Task ActionInController(IParserFactory factory) + var parser = factory.CreateParser(); + var commandResult = await parser.ParseWithDefaultCommand(arguments); + if (commandResult.IsValid) { - var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - - var parser = factory.CreateParser(); - var commandResult = await parser.ParseWithDefaultCommand(arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); + } + else + { + Console.WriteLine("Invalid parsing"); } - - var parserFactory = scopedServiceProvider.GetRequiredService(); - await ActionInController(parserFactory); } + + var parserFactory = scopedServiceProvider.GetRequiredService(); + await ActionInController(parserFactory); } } } diff --git a/samples/SimpleApp/Program.cs b/samples/SimpleApp/Program.cs index d53ed78..72b7274 100644 --- a/samples/SimpleApp/Program.cs +++ b/samples/SimpleApp/Program.cs @@ -6,55 +6,54 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace SimpleApp +namespace SimpleApp; + +internal class Program { - internal class Program + private static async Task Main(string[] args) { - private static async Task Main(string[] args) - { - await ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync(); - WriteSeparator(); - await ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync(); - WriteSeparator(); - await ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync(); - WriteSeparator(); - - await ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync(); - WriteSeparator(); - await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync(); - WriteSeparator(); - await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync(); - WriteSeparator(); + await ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync(); + WriteSeparator(); + await ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync(); + WriteSeparator(); + await ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync(); + WriteSeparator(); - await HostBuilderCalls.CreateAndCallDefaultParserBuilderAsync(); - WriteSeparator(); + await ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync(); + WriteSeparator(); + await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync(); + WriteSeparator(); + await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync(); + WriteSeparator(); - //await Tester.RunSampleTests(); + await HostBuilderCalls.CreateAndCallDefaultParserBuilderAsync(); + WriteSeparator(); - var hostBuilder = new HostBuilder(); - hostBuilder.ConfigureParser(builder => - { - builder.AddCommand("run", - commandBuilder => - { - commandBuilder.AddOption("opt", "o", - o => o.Required()); - }, - context => - { - var opt = context.GetOptionValue("opt"); - return Task.FromResult(opt); - }); - }); - var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(args, CancellationToken.None); - return parsingResult; - } + //await Tester.RunSampleTests(); - static void WriteSeparator() + var hostBuilder = new HostBuilder(); + hostBuilder.ConfigureParser(builder => { - Console.WriteLine(); - Console.WriteLine("-------------"); - Console.WriteLine(); - } + builder.AddCommand("run", + commandBuilder => + { + commandBuilder.AddOption("opt", "o", + o => o.Required()); + }, + (context, cancellationToken) => + { + var opt = context.GetOptionValue("opt"); + return Task.FromResult(opt); + }); + }); + var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(args, CancellationToken.None); + return parsingResult; + } + + static void WriteSeparator() + { + Console.WriteLine(); + Console.WriteLine("-------------"); + Console.WriteLine(); } } \ No newline at end of file diff --git a/samples/SimpleApp/Tester.cs b/samples/SimpleApp/Tester.cs index f5f5e71..d10eef8 100644 --- a/samples/SimpleApp/Tester.cs +++ b/samples/SimpleApp/Tester.cs @@ -10,82 +10,82 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace SimpleApp +namespace SimpleApp; + +internal static class Tester { - internal static class Tester + public static async Task RunSampleTests() { - public static async Task RunSampleTests() - { - //Console.ReadLine(); - var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - var defaultPackArguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; - var defaultDeleteArguments = new[] { "delete", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--no-prompt", "--source", "source1" }; - var helpArguments = new[] { "help" }; - var serviceCollection = new ServiceCollection(); - serviceCollection.AddCommandLineParser() - .AddClassBasedCommands() - .AddCommand( - "test", - commandBuilder => - { - commandBuilder - .WithDescription("Description of command") - .AddOption( - "longName", - "shortName", - optionBuilder => { - optionBuilder.Required() - .AddValidation(new RangeAttribute(2, 7)); - }); - }, - context => - { - var year = context.GetOptionValue("longName"); - var arg = context.Arguments; - return Task.FromResult(year + arg.Count()); - }); - serviceCollection.AddLogging(builder => builder - .SetMinimumLevel(LogLevel.Trace) - .AddSeq() - //.AddConsole(options => options.IncludeScopes = true) - ); - var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection); - var parser = parserBuild.BuildParser(); - await ParseAndExecute(parser, helpArguments); + //Console.ReadLine(); + var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + var defaultPackArguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" }; + var defaultDeleteArguments = new[] { "delete", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--no-prompt", "--source", "source1" }; + var helpArguments = new[] { "help" }; + var serviceCollection = new ServiceCollection(); + serviceCollection.AddCommandLineParser() + .AddClassBasedCommands() + .AddCommand( + "test", + commandBuilder => + { + commandBuilder + .WithDescription("Description of command") + .AddOption( + "longName", + "shortName", + optionBuilder => { + optionBuilder.Required() + .AddValidation(new RangeAttribute(2, 7)); + }); + }, + (context, cancellationToken) => + { + var year = context.GetOptionValue("longName"); + var arg = context.Arguments; + return Task.FromResult(year + arg.Count()); + }); + serviceCollection.AddLogging(builder => builder + .SetMinimumLevel(LogLevel.Trace) + .AddSeq() + //.AddConsole(options => options.IncludeScopes = true) + ); + var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection); + var parser = parserBuild.BuildParser(); + await ParseAndExecute(parser, helpArguments); - await ParseAndExecute(parser, new[] { "test", "--longName:3", "hello" }); + await ParseAndExecute(parser, new[] { "test", "--longName:3", "hello" }); - await ParseWithDefaultAndExecute(parser, arguments); - await ParseWithDefaultAndExecute(parser, defaultPackArguments); - await ParseWithDefaultAndExecute(parser, defaultDeleteArguments); + await ParseWithDefaultAndExecute(parser, arguments); + await ParseWithDefaultAndExecute(parser, defaultPackArguments); + await ParseWithDefaultAndExecute(parser, defaultDeleteArguments); - await Task.Delay(TimeSpan.FromSeconds(1)); - } + await Task.Delay(TimeSpan.FromSeconds(1)); + } - static async Task ParseWithDefaultAndExecute(IParser parser, string[] arguments) - where TCommand : class, ICommand - { - await ParseFuncAndExecute(parser, arguments, - (p, args) => p.ParseWithDefaultCommand(args)); - } - static async Task ParseAndExecute(IParser parser, string[] arguments) + static async Task ParseWithDefaultAndExecute(IParser parser, string[] arguments) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + await ParseFuncAndExecute(parser, arguments, + (p, args) => p.ParseWithDefaultCommand(args)); + } + static async Task ParseAndExecute(IParser parser, string[] arguments) + { + await ParseFuncAndExecute(parser, arguments, + (p, args) => p.Parse(args)); + } + static async Task ParseFuncAndExecute(IParser parser, string[] arguments, Func, Task> parseFunc) + { + Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); + var commandResult = await parseFunc(parser, arguments); + if (commandResult.IsValid) { - await ParseFuncAndExecute(parser, arguments, - (p, args) => p.Parse(args)); + var executionResult = await commandResult.CommandObject!.ExecuteAsync(default); + Console.WriteLine("Execution result: {0}", executionResult); } - static async Task ParseFuncAndExecute(IParser parser, string[] arguments, Func, Task> parseFunc) + else { - Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments)); - var commandResult = await parseFunc(parser, arguments); - if (commandResult.IsValid) - { - var executionResult = await commandResult.CommandObject.ExecuteAsync(); - Console.WriteLine("Execution result: {0}", executionResult); - } - else - { - Console.WriteLine("Invalid parsing"); - } + Console.WriteLine("Invalid parsing"); } } } diff --git a/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs b/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs index 21e002b..a8597de 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs @@ -1,96 +1,96 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +/// +/// Represents the object used to build a lambda-based command. +/// +public class CommandBuilder { + private readonly string _commandName; + private string _description = string.Empty; + private string _usage = string.Empty; + private readonly List _samples = []; + private bool _hideFromHelpListing; + private readonly Func> _executeCommand; + private readonly List _optionsBuilders = []; + + internal CommandBuilder(string commandName, Func> executeCommand) + { + _commandName = commandName; + _executeCommand = executeCommand; + } + /// - /// Represents the object used to build a lambda-based command. + /// Defines the description of the command. /// - public class CommandBuilder + /// The description of the command. + /// The to chain calls. + public CommandBuilder WithDescription(string description) { - private readonly string _commandName; - private string _description; - private string _usage; - private readonly List _samples = new List(); - private bool _hideFromHelpListing; - private readonly Func> _executeCommand; - private readonly List _optionsBuilders = new List(); - - internal CommandBuilder(string commandName, Func> executeCommand) - { - _commandName = commandName; - _executeCommand = executeCommand; - } - - /// - /// Defines the description of the command. - /// - /// The description of the command. - /// The to chain calls. - public CommandBuilder WithDescription(string description) - { - _description = description; - return this; - } + _description = description; + return this; + } - /// - /// Defines the usage of the command. - /// - /// The usage of the command. - /// The to chain calls. - public CommandBuilder WithUsage(string usage) - { - _usage = usage; - return this; - } + /// + /// Defines the usage of the command. + /// + /// The usage of the command. + /// The to chain calls. + public CommandBuilder WithUsage(string usage) + { + _usage = usage; + return this; + } - /// - /// Add a sample to demonstrate the command usage. - /// - /// A sample. - /// The to chain calls. - public CommandBuilder AddSample(string sample) - { - _samples.Add(sample); - return this; - } + /// + /// Add a sample to demonstrate the command usage. + /// + /// A sample. + /// The to chain calls. + public CommandBuilder AddSample(string sample) + { + _samples.Add(sample); + return this; + } - /// - /// Hide the command from the help listing. - /// - /// This cannot be undone. - /// The to chain calls. - public CommandBuilder HideFromHelpListing() - { - _hideFromHelpListing = true; - return this; - } + /// + /// Hide the command from the help listing. + /// + /// This cannot be undone. + /// The to chain calls. + public CommandBuilder HideFromHelpListing() + { + _hideFromHelpListing = true; + return this; + } - /// - /// Add an option to the command. - /// - /// The type of the option. - /// The name of the option. - /// The short name of the options. - /// An action to define command - /// The to chain calls. - public CommandBuilder AddOption(string optionName, string shortOptionName, - Action defineOption) - { - var optionBuilder = new OptionBuilder(optionName, shortOptionName, typeof(T)); - (defineOption ?? (_ => { }))(optionBuilder); - _optionsBuilders.Add(optionBuilder); - return this; - } + /// + /// Add an option to the command. + /// + /// The type of the option. + /// The name of the option. + /// The short name of the options. + /// An action to define command + /// The to chain calls. + public CommandBuilder AddOption(string optionName, string shortOptionName, + Action defineOption) + { + var optionBuilder = new OptionBuilder(optionName, shortOptionName, typeof(T)); + (defineOption ?? (_ => { }))(optionBuilder); + _optionsBuilders.Add(optionBuilder); + return this; + } - internal LambdaBasedCommandType BuildCommandType(IServiceProvider serviceProvider) - { - var commandType = new LambdaBasedCommandType( - new LambdaBasedCommandMetadata(_commandName, _description, _usage, _samples.ToArray(), _hideFromHelpListing), - _optionsBuilders.Select(builder => builder.ToCommandOption(serviceProvider)).ToList(), _executeCommand); - return commandType; - } + internal LambdaBasedCommandType BuildCommandType(IServiceProvider serviceProvider) + { + var commandType = new LambdaBasedCommandType( + new LambdaBasedCommandMetadata(_commandName, _description, _usage, _samples.ToArray(), _hideFromHelpListing), + _optionsBuilders.Select(builder => builder.ToCommandOption(serviceProvider)).ToList(), _executeCommand); + return commandType; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs b/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs index 8f55b18..a1c9ecc 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs @@ -2,60 +2,59 @@ using System.Collections.Generic; using System.Linq; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +/// +/// Represents the context of execution of a lambda-based command. +/// +public class CommandExecutionContext { + private readonly IEnumerable _commandOptions; + + internal CommandExecutionContext(IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider) + { + _commandOptions = commandOptions; + Arguments = arguments; + ServiceProvider = serviceProvider; + } + /// - /// Represents the context of execution of a lambda-based command. + /// Gets the arguments of the command. /// - public class CommandExecutionContext + public IEnumerable Arguments { get; } + + /// + /// Gets the value of an option. + /// + /// The type of the option. + /// The name of the option. + /// The value of the option. + /// If no options are found. + /// If the type of the option do not match the specified type. + public T? GetOptionValue(string name) { - private readonly IEnumerable _commandOptions; + var option = _commandOptions.FirstOrDefault(o => o.Metadata.DisplayInfo.Name == name); + if (option == null) + { + throw new ArgumentOutOfRangeException(nameof(name)); + } - internal CommandExecutionContext(IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider) + if (!typeof(T).IsAssignableFrom(option.OptionType)) { - _commandOptions = commandOptions; - Arguments = arguments; - ServiceProvider = serviceProvider; + throw new InvalidOperationException($"The type of the option ({option.OptionType}) do not match the specified type ({typeof(T)})"); } - /// - /// Gets the arguments of the command. - /// - public IEnumerable Arguments { get; } - - /// - /// Gets the value of an option. - /// - /// The type of the option. - /// The name of the option. - /// The value of the option. - /// If no options are found. - /// If the type of the option do not match the specified type. - public T GetOptionValue(string name) + var rawValue = option.ValueAssigner.GetValue(); + if (rawValue == null) { - var option = _commandOptions.FirstOrDefault(o => o.Metadata.DisplayInfo.Name == name); - if (option == null) - { - throw new ArgumentOutOfRangeException(nameof(name)); - } - - if (!typeof(T).IsAssignableFrom(option.OptionType)) - { - throw new InvalidOperationException($"The type of the option ({option.OptionType}) do not match the specified type ({typeof(T)})"); - } - - var rawValue = option.ValueAssigner.GetValue(); - if (rawValue == null) - { - return default; - } - - return (T)rawValue; + return default; } - /// - /// Gets the current . - /// - public IServiceProvider ServiceProvider { get; } + return (T)rawValue; } + + /// + /// Gets the current . + /// + public IServiceProvider ServiceProvider { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs b/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs index d35558d..c52d754 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs @@ -1,35 +1,34 @@ using System; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command.Lambda; using MGR.CommandLineParser.Extensibility.Command; -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.DependencyInjection +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods for . +/// +public static class CommandLineParserBuilderLambdaExtensions { /// - /// Extension methods for . + /// Add a lambda-based command. /// - public static class CommandLineParserBuilderLambdaExtensions + /// The to configure. + /// The name of the command. + /// An action to define the command. + /// A function that represent the execution of the command. + /// The so that additional calls can be chained. + public static CommandLineParserBuilder AddCommand(this CommandLineParserBuilder builder, + string commandName, + Action defineCommand, + Func> executeCommand) { - /// - /// Add a lambda-based command. - /// - /// The to configure. - /// The name of the command. - /// An action to define the command. - /// A function that represent the execution of the command. - /// The so that additional calls can be chained. - public static CommandLineParserBuilder AddCommand(this CommandLineParserBuilder builder, - string commandName, - Action defineCommand, - Func> executeCommand) - { - var commandBuilder = new CommandBuilder(commandName, executeCommand); - (defineCommand ?? (_ => {}))(commandBuilder); + var commandBuilder = new CommandBuilder(commandName, executeCommand); + (defineCommand ?? (_ => {}))(commandBuilder); - builder.Services.AddScoped(serviceProvider => new LambdaBasedCommandTypeProvider(commandBuilder.BuildCommandType(serviceProvider))); + builder.Services.AddScoped(serviceProvider => new LambdaBasedCommandTypeProvider(commandBuilder.BuildCommandType(serviceProvider))); - return builder; - } + return builder; } } diff --git a/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs index 17af3de..2d38619 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs @@ -1,8 +1,7 @@ -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal interface ILambdaBasedCommandOptionValueAssigner { - internal interface ILambdaBasedCommandOptionValueAssigner - { - object GetValue(); - void AssignValue(object value); - } + object? GetValue(); + void AssignValue(object value); } diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs index 536c770..3774481 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs @@ -1,22 +1,21 @@ using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandMetadata : ICommandMetadata { - internal class LambdaBasedCommandMetadata : ICommandMetadata + internal LambdaBasedCommandMetadata(string commandName, string description, string usage, string[] samples, bool hideFromHelpListing) { - internal LambdaBasedCommandMetadata(string commandName, string description, string usage, string[] samples, bool hideFromHelpListing) - { - Name = commandName; - Description = description; - Usage = usage; - Samples = samples; - HideFromHelpListing = hideFromHelpListing; - } - - public string Name { get; } - public string Description { get; } - public string Usage { get; } - public string[] Samples { get; } - public bool HideFromHelpListing { get; } + Name = commandName; + Description = description; + Usage = usage; + Samples = samples; + HideFromHelpListing = hideFromHelpListing; } + + public string Name { get; } + public string Description { get; } + public string Usage { get; } + public string[] Samples { get; } + public bool HideFromHelpListing { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs index c3455d8..2cc1b97 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs @@ -1,28 +1,28 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandObject: ICommandObject { - internal class LambdaBasedCommandObject: ICommandObject - { - private readonly Func> _executeCommand; - private readonly IEnumerable _commandOptions; - private readonly List _arguments; - private readonly IServiceProvider _serviceProvider; + private readonly Func> _executeCommand; + private readonly IEnumerable _commandOptions; + private readonly List _arguments; + private readonly IServiceProvider _serviceProvider; - internal LambdaBasedCommandObject(Func> executeCommand, IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider) - { - _executeCommand = executeCommand; - _commandOptions = commandOptions; - _arguments = arguments; - _serviceProvider = serviceProvider; - } + internal LambdaBasedCommandObject(Func> executeCommand, IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider) + { + _executeCommand = executeCommand; + _commandOptions = commandOptions; + _arguments = arguments; + _serviceProvider = serviceProvider; + } - public Task ExecuteAsync() - { - var commandContext = new CommandExecutionContext(_commandOptions, _arguments, _serviceProvider); - return _executeCommand(commandContext); - } + public Task ExecuteAsync(CancellationToken cancellationToken) + { + var commandContext = new CommandExecutionContext(_commandOptions, _arguments, _serviceProvider); + return _executeCommand(commandContext, cancellationToken); } } diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs index 7a6159d..f1b4289 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs @@ -1,47 +1,47 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandObjectBuilder : CommandObjectBuilderBase { - internal class LambdaBasedCommandObjectBuilder : CommandObjectBuilderBase - { - private readonly List _arguments = new List(); - private readonly Func> _executeCommand; - private readonly IServiceProvider _serviceProvider; + private readonly List _arguments = []; + private readonly Func> _executeCommand; + private readonly IServiceProvider _serviceProvider; - internal LambdaBasedCommandObjectBuilder(ICommandMetadata commandMetadata, - IEnumerable commandOptions, IServiceProvider serviceProvider, - Func> executeCommand) - : base(commandMetadata, commandOptions) - { - _serviceProvider = serviceProvider; - _executeCommand = executeCommand; - } + internal LambdaBasedCommandObjectBuilder(ICommandMetadata commandMetadata, + IEnumerable commandOptions, IServiceProvider serviceProvider, + Func> executeCommand) + : base(commandMetadata, commandOptions) + { + _serviceProvider = serviceProvider; + _executeCommand = executeCommand; + } - public override void AddArguments(string argument) => _arguments.Add(argument); + public override void AddArguments(string argument) => _arguments.Add(argument); - public override ICommandObject GenerateCommandObject() - { - var commandObject = new LambdaBasedCommandObject(_executeCommand, CommandOptions, _arguments, _serviceProvider); - return commandObject; - } + public override ICommandObject GenerateCommandObject() + { + var commandObject = new LambdaBasedCommandObject(_executeCommand, CommandOptions, _arguments, _serviceProvider); + return commandObject; + } - protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider) + protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider) + { + var isValueValid = true; + var instance = new object(); + foreach (var commandOption in CommandOptions) { - var isValueValid = true; - var instance = new object(); - foreach (var commandOption in CommandOptions) - { - var value = commandOption.ValueAssigner.GetValue(); - var validationContext = new ValidationContext(instance, serviceProvider, null) { - MemberName = commandOption.Metadata.DisplayInfo.Name - }; - isValueValid &= Validator.TryValidateValue(value, validationContext, validationResults, commandOption.ValidationAttributes); - } - return isValueValid; + var value = commandOption.ValueAssigner.GetValue(); + var validationContext = new ValidationContext(instance, serviceProvider, null) { + MemberName = commandOption.Metadata.DisplayInfo.Name + }; + isValueValid &= Validator.TryValidateValue(value, validationContext, validationResults, commandOption.ValidationAttributes); } + return isValueValid; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs index 6238506..e0722b3 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs @@ -5,55 +5,52 @@ using MGR.CommandLineParser.Extensibility.Command; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +[DebuggerDisplay("LambdaOption:{Metadata.DisplayInfo.Name}")] +internal class LambdaBasedCommandOption : ICommandOption { - [DebuggerDisplay("LambdaOption:{Metadata.DisplayInfo.Name}")] - internal class LambdaBasedCommandOption : ICommandOption - { - private readonly IConverter _converter; + private readonly IConverter _converter; - internal LambdaBasedCommandOption(LambdaBasedCommandOptionMetadata commandOptionMetadata, Type optionType, IConverter converter, - IEnumerable validationAttributes) + internal LambdaBasedCommandOption(LambdaBasedCommandOptionMetadata commandOptionMetadata, Type optionType, IConverter converter, + IEnumerable validationAttributes) + { + OptionType = optionType; + _converter = converter; + Metadata = commandOptionMetadata; + ValidationAttributes = validationAttributes; + var collectionType = Metadata.CollectionType; + switch (collectionType) { - OptionType = optionType; - _converter = converter; - Metadata = commandOptionMetadata; - ValidationAttributes = validationAttributes; - var collectionType = Metadata.CollectionType; - switch (collectionType) - { - case CommandOptionCollectionType.None: - ValueAssigner = new LambdaBasedCommandOptionSimpleValueAssigner(); - break; - case CommandOptionCollectionType.Collection: - ValueAssigner = new LambdaBasedCommandOptionCollectionValueAssigner(); - break; - case CommandOptionCollectionType.Dictionary: - ValueAssigner = new LambdaBasedCommandOptionDictionaryValueAssigner(); - break; - default: -#pragma warning disable S3928 // Parameter names used into ArgumentException constructors should match an existing one - throw new ArgumentOutOfRangeException(nameof(collectionType)); -#pragma warning restore S3928 // Parameter names used into ArgumentException constructors should match an existing one - } + case CommandOptionCollectionType.None: + ValueAssigner = new LambdaBasedCommandOptionSimpleValueAssigner(); + break; + case CommandOptionCollectionType.Collection: + ValueAssigner = new LambdaBasedCommandOptionCollectionValueAssigner(); + break; + case CommandOptionCollectionType.Dictionary: + ValueAssigner = new LambdaBasedCommandOptionDictionaryValueAssigner(); + break; + default: + throw new ArgumentOutOfRangeException(nameof(collectionType)); + } - if (!string.IsNullOrEmpty(Metadata.DefaultValue)) - { - AssignValue(Metadata.DefaultValue); - } + if (!string.IsNullOrEmpty(Metadata.DefaultValue)) + { + AssignValue(Metadata.DefaultValue); } + } - internal Type OptionType { get; } - internal ILambdaBasedCommandOptionValueAssigner ValueAssigner { get; } - internal IEnumerable ValidationAttributes { get; } + internal Type OptionType { get; } + internal ILambdaBasedCommandOptionValueAssigner ValueAssigner { get; } + internal IEnumerable ValidationAttributes { get; } - public bool ShouldProvideValue => OptionType != typeof(bool); - public ICommandOptionMetadata Metadata { get; } + public bool ShouldProvideValue => OptionType != typeof(bool); + public ICommandOptionMetadata Metadata { get; } - public void AssignValue(string optionValue) - { - var value = _converter.Convert(optionValue, OptionType); - ValueAssigner.AssignValue(value); - } + public void AssignValue(string optionValue) + { + var value = _converter.Convert(optionValue, OptionType); + ValueAssigner.AssignValue(value); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs index 992a68c..1e7dc82 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs @@ -2,14 +2,13 @@ using System.Diagnostics; using System.Linq; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +[DebuggerDisplay("Collection value assigner (currently {Values.Count} values)")] +internal class LambdaBasedCommandOptionCollectionValueAssigner : ILambdaBasedCommandOptionValueAssigner { - [DebuggerDisplay("Collection value assigner (currently {Values.Count} values)")] - internal class LambdaBasedCommandOptionCollectionValueAssigner : ILambdaBasedCommandOptionValueAssigner - { - internal List Values { get; } = new List(); - public object GetValue() => Values.AsEnumerable(); + internal List Values { get; } = new List(); + public object GetValue() => Values.AsEnumerable(); - public void AssignValue(object value) => Values.Add(value); - } + public void AssignValue(object value) => Values.Add(value); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionDictionaryValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionDictionaryValueAssigner.cs index 84c77d0..3c589ca 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionDictionaryValueAssigner.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionDictionaryValueAssigner.cs @@ -1,18 +1,17 @@ using System.Collections.Generic; using System.Diagnostics; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +[DebuggerDisplay("Dictionary value assigner (currently {Values.Count} values)")] +internal class LambdaBasedCommandOptionDictionaryValueAssigner : ILambdaBasedCommandOptionValueAssigner { - [DebuggerDisplay("Dictionary value assigner (currently {Values.Count} values)")] - internal class LambdaBasedCommandOptionDictionaryValueAssigner : ILambdaBasedCommandOptionValueAssigner - { - internal Dictionary Values { get; } = new Dictionary(); - public object GetValue() => Values; + internal Dictionary Values { get; } = new Dictionary(); + public object GetValue() => Values; - public void AssignValue(object value) - { - var kvp = (KeyValuePair) value; - Values.Add(kvp.Key, kvp.Value); - } + public void AssignValue(object value) + { + var kvp = (KeyValuePair) value; + Values.Add(kvp.Key, kvp.Value); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionMetadata.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionMetadata.cs index 11e5e61..4d8a337 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionMetadata.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionMetadata.cs @@ -1,12 +1,11 @@ using System; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandOptionMetadata : CommandOptionMetadataBase { - internal class LambdaBasedCommandOptionMetadata : CommandOptionMetadataBase - { - public LambdaBasedCommandOptionMetadata(LambdaBasedOptionDisplayInfo optionDisplayInfo, string defaultValue, bool isRequired, Type optionType) - : base(isRequired, GetMultiValueIndicator(optionType), optionDisplayInfo, defaultValue) - { } - } + public LambdaBasedCommandOptionMetadata(LambdaBasedOptionDisplayInfo optionDisplayInfo, string defaultValue, bool isRequired, Type optionType) + : base(isRequired, GetMultiValueIndicator(optionType), optionDisplayInfo, defaultValue) + { } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionSimpleValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionSimpleValueAssigner.cs index 56f589e..b25bb98 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionSimpleValueAssigner.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionSimpleValueAssigner.cs @@ -1,13 +1,12 @@ using System.Diagnostics; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +[DebuggerDisplay("Simple value assigner (current value:{Value})")] +internal class LambdaBasedCommandOptionSimpleValueAssigner : ILambdaBasedCommandOptionValueAssigner { - [DebuggerDisplay("Simple value assigner (current value:{Value})")] - internal class LambdaBasedCommandOptionSimpleValueAssigner : ILambdaBasedCommandOptionValueAssigner - { - internal object Value { get; private set; } - public object GetValue() => Value; + internal object? Value { get; private set; } + public object? GetValue() => Value; - public void AssignValue(object value) => Value = value; - } + public void AssignValue(object value) => Value = value; } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandType.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandType.cs index 83ab7b7..bd52d08 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandType.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandType.cs @@ -1,27 +1,27 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandType : ICommandType { - internal class LambdaBasedCommandType : ICommandType - { - private readonly IEnumerable _options; - private readonly Func> _executeCommand; + private readonly IEnumerable _options; + private readonly Func> _executeCommand; - internal LambdaBasedCommandType(LambdaBasedCommandMetadata commandMetadata, IEnumerable options, Func> executeCommand) - { - _options = options; - _executeCommand = executeCommand; - Metadata = commandMetadata; - } + internal LambdaBasedCommandType(LambdaBasedCommandMetadata commandMetadata, IEnumerable options, Func> executeCommand) + { + _options = options; + _executeCommand = executeCommand; + Metadata = commandMetadata; + } - public ICommandMetadata Metadata { get; } + public ICommandMetadata Metadata { get; } - public IEnumerable Options => _options.Select(option => option.Metadata); + public IEnumerable Options => _options.Select(option => option.Metadata); - public ICommandObjectBuilder CreateCommandObjectBuilder(IServiceProvider serviceProvider) => new LambdaBasedCommandObjectBuilder(Metadata, _options, serviceProvider, _executeCommand); - } + public ICommandObjectBuilder CreateCommandObjectBuilder(IServiceProvider serviceProvider) => new LambdaBasedCommandObjectBuilder(Metadata, _options, serviceProvider, _executeCommand); } diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandTypeProvider.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandTypeProvider.cs index 1120396..873855d 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandTypeProvider.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandTypeProvider.cs @@ -2,27 +2,26 @@ using System.Threading.Tasks; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +internal class LambdaBasedCommandTypeProvider : ICommandTypeProvider { - internal class LambdaBasedCommandTypeProvider : ICommandTypeProvider - { - private readonly ICommandType _commandType; - private readonly IEnumerable _commandTypeEnumerable; + private readonly ICommandType _commandType; + private readonly IEnumerable _commandTypeEnumerable; - internal LambdaBasedCommandTypeProvider(LambdaBasedCommandType commandType) - { - _commandType = commandType; - _commandTypeEnumerable = new[] {commandType}; - } + internal LambdaBasedCommandTypeProvider(LambdaBasedCommandType commandType) + { + _commandType = commandType; + _commandTypeEnumerable = new[] {commandType}; + } - public Task> GetAllCommandTypes() - { - return Task.FromResult(_commandTypeEnumerable); - } + public Task> GetAllCommandTypes() + { + return Task.FromResult(_commandTypeEnumerable); + } - public Task GetCommandType(string commandName) - { - return Task.FromResult(commandName == _commandType.Metadata.Name ? _commandType : null); - } + public Task GetCommandType(string commandName) + { + return Task.FromResult(commandName == _commandType.Metadata.Name ? _commandType : null); } } diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedOptionDisplayInfo.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedOptionDisplayInfo.cs index 067c116..351d083 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedOptionDisplayInfo.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedOptionDisplayInfo.cs @@ -3,22 +3,21 @@ using System.Linq; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +[DebuggerDisplay("LambdaBased:Name={Name};ShortName={ShortName}")] +internal class LambdaBasedOptionDisplayInfo : IOptionDisplayInfo { - [DebuggerDisplay("LambdaBased:Name={Name};ShortName={ShortName}")] - internal class LambdaBasedOptionDisplayInfo : IOptionDisplayInfo + internal LambdaBasedOptionDisplayInfo(string name, IEnumerable alternateNames, string shortName, string description) { - internal LambdaBasedOptionDisplayInfo(string name, IEnumerable alternateNames, string shortName, string description) - { - Name = name; - AlternateNames = alternateNames ?? Enumerable.Empty(); - ShortName = shortName; - Description = description ?? string.Empty; - } - - public string Name { get; } - public IEnumerable AlternateNames { get; } - public string ShortName { get; } - public string Description { get; } + Name = name; + AlternateNames = alternateNames ?? Enumerable.Empty(); + ShortName = shortName; + Description = description ?? string.Empty; } + + public string Name { get; } + public IEnumerable AlternateNames { get; } + public string ShortName { get; } + public string Description { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/MGR.CommandLineParser.Command.Lambda.csproj b/src/MGR.CommandLineParser.Command.Lambda/MGR.CommandLineParser.Command.Lambda.csproj index a2d1705..39770d1 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/MGR.CommandLineParser.Command.Lambda.csproj +++ b/src/MGR.CommandLineParser.Command.Lambda/MGR.CommandLineParser.Command.Lambda.csproj @@ -1,7 +1,7 @@  - - - + + + diff --git a/src/MGR.CommandLineParser.Command.Lambda/OptionBuilder.cs b/src/MGR.CommandLineParser.Command.Lambda/OptionBuilder.cs index 03299a4..01035bf 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/OptionBuilder.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/OptionBuilder.cs @@ -5,89 +5,88 @@ using MGR.CommandLineParser.Extensibility.Converters; using Microsoft.Extensions.DependencyInjection; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +/// +/// Represents the object used to build an option of a lambda-based command. +/// +public class OptionBuilder { + private readonly string _optionName; + private readonly string _shortOptionName; + private readonly List _alternateNames = new List(); + private string _description = string.Empty; + private readonly Type _optionType; + private string _defaultValue = string.Empty; + private readonly List _validationAttributes = new List(); + + internal OptionBuilder(string optionName, string shortOptionName, Type optionType) + { + _optionName = optionName; + _shortOptionName = shortOptionName; + _optionType = optionType; + } + /// - /// Represents the object used to build an option of a lambda-based command. + /// Add an alternate name for the option. /// - public class OptionBuilder + /// The alternate name. + /// The to chain calls. + public OptionBuilder AddAlternateName(string alternateName) { - private readonly string _optionName; - private readonly string _shortOptionName; - private readonly List _alternateNames = new List(); - private string _description; - private readonly Type _optionType; - private string _defaultValue; - private readonly List _validationAttributes = new List(); - - internal OptionBuilder(string optionName, string shortOptionName, Type optionType) - { - _optionName = optionName; - _shortOptionName = shortOptionName; - _optionType = optionType; - } - - /// - /// Add an alternate name for the option. - /// - /// The alternate name. - /// The to chain calls. - public OptionBuilder AddAlternateName(string alternateName) - { - _alternateNames.Add(alternateName); - return this; - } + _alternateNames.Add(alternateName); + return this; + } - /// - /// Defines the description of the option. - /// - /// The description of the option. - /// The to chain calls. - public OptionBuilder WithDescription(string description) - { - _description = description; - return this; - } + /// + /// Defines the description of the option. + /// + /// The description of the option. + /// The to chain calls. + public OptionBuilder WithDescription(string description) + { + _description = description; + return this; + } - /// - /// Defines the default value of the option. - /// - /// The default value of the option. - /// The to chain calls. - public OptionBuilder WithDefaultValue(string defaultValue) - { - _defaultValue = defaultValue; - return this; - } + /// + /// Defines the default value of the option. + /// + /// The default value of the option. + /// The to chain calls. + public OptionBuilder WithDefaultValue(string defaultValue) + { + _defaultValue = defaultValue; + return this; + } - /// - /// Add a validation to the option. - /// - /// A validation. - /// The to chain calls. - public OptionBuilder AddValidation(ValidationAttribute validationAttribute) - { - _validationAttributes.Add(validationAttribute); - return this; - } + /// + /// Add a validation to the option. + /// + /// A validation. + /// The to chain calls. + public OptionBuilder AddValidation(ValidationAttribute validationAttribute) + { + _validationAttributes.Add(validationAttribute); + return this; + } - internal LambdaBasedCommandOption ToCommandOption(IServiceProvider serviceProvider) - { - var converters = serviceProvider.GetServices(); - var converter = converters.FirstOrDefault(c => c.CanConvertTo(_optionType)); + internal LambdaBasedCommandOption ToCommandOption(IServiceProvider serviceProvider) + { + var converters = serviceProvider.GetServices(); + var converter = converters.FirstOrDefault(c => c.CanConvertTo(_optionType)); - var commandOption = new LambdaBasedCommandOption( - new LambdaBasedCommandOptionMetadata( - new LambdaBasedOptionDisplayInfo(_optionName, _alternateNames, _shortOptionName, _description), - _defaultValue, - _validationAttributes.OfType().Any(), - _optionType - ), - _optionType, - converter, - _validationAttributes - ); - return commandOption; - } + var commandOption = new LambdaBasedCommandOption( + new LambdaBasedCommandOptionMetadata( + new LambdaBasedOptionDisplayInfo(_optionName, _alternateNames, _shortOptionName, _description), + _defaultValue, + _validationAttributes.OfType().Any(), + _optionType + ), + _optionType, + converter, + _validationAttributes + ); + return commandOption; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Command.Lambda/OptionBuilderExtensions.cs b/src/MGR.CommandLineParser.Command.Lambda/OptionBuilderExtensions.cs index c6b85db..a240ac6 100644 --- a/src/MGR.CommandLineParser.Command.Lambda/OptionBuilderExtensions.cs +++ b/src/MGR.CommandLineParser.Command.Lambda/OptionBuilderExtensions.cs @@ -1,33 +1,32 @@ using System.ComponentModel.DataAnnotations; -namespace MGR.CommandLineParser.Command.Lambda +namespace MGR.CommandLineParser.Command.Lambda; + +/// +/// Extension methods for the . +/// +public static class OptionBuilderExtensions { /// - /// Extension methods for the . + /// Add a validation to the option. /// - public static class OptionBuilderExtensions + /// The type of the validation attribute. + /// The . + /// The to chain calls. + public static OptionBuilder AddValidation(this OptionBuilder optionBuilder) + where TValidation : ValidationAttribute, new() { - /// - /// Add a validation to the option. - /// - /// The type of the validation attribute. - /// The . - /// The to chain calls. - public static OptionBuilder AddValidation(this OptionBuilder optionBuilder) - where TValidation : ValidationAttribute, new() - { - optionBuilder.AddValidation(new TValidation()); - return optionBuilder; - } + optionBuilder.AddValidation(new TValidation()); + return optionBuilder; + } - /// - /// Add the required validation to the option. - /// - /// The . - /// The to chain calls. - public static OptionBuilder Required(this OptionBuilder optionBuilder) - { - return optionBuilder.AddValidation(); - } + /// + /// Add the required validation to the option. + /// + /// The . + /// The to chain calls. + public static OptionBuilder Required(this OptionBuilder optionBuilder) + { + return optionBuilder.AddValidation(); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Hosting/CompilerTypes.cs b/src/MGR.CommandLineParser.Hosting/CompilerTypes.cs new file mode 100644 index 0000000..da0d507 --- /dev/null +++ b/src/MGR.CommandLineParser.Hosting/CompilerTypes.cs @@ -0,0 +1,7 @@ +namespace System.Runtime.CompilerServices; + +internal class RequiredMemberAttribute : Attribute { } +internal class CompilerFeatureRequiredAttribute : Attribute +{ + public CompilerFeatureRequiredAttribute(string name) { } +} \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Hosting/Extensions/HostBuilderExtensions.cs b/src/MGR.CommandLineParser.Hosting/Extensions/HostBuilderExtensions.cs index 19a0c78..beb29fa 100644 --- a/src/MGR.CommandLineParser.Hosting/Extensions/HostBuilderExtensions.cs +++ b/src/MGR.CommandLineParser.Hosting/Extensions/HostBuilderExtensions.cs @@ -5,87 +5,89 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace MGR.CommandLineParser.Hosting.Extensions +namespace MGR.CommandLineParser.Hosting.Extensions; + +/// +/// Extension's methods for . +/// +public static class HostBuilderExtensions { /// - /// Extension's methods for . + /// Configures the to run the parser. + /// + /// The to configure. + /// An action to configure the . + /// The configured . + public static IHostBuilder ConfigureParser(this IHostBuilder hostBuilder, Action configureParser) + { + hostBuilder.ConfigureParser(configureParser, _ => { }); + return hostBuilder; + } + /// + /// Configures the to run the parser. /// - public static class HostBuilderExtensions + /// The to configure. + /// An action to configure the . + /// An action to configure the of the parser. + /// The configured . + public static IHostBuilder ConfigureParser(this IHostBuilder hostBuilder, Action configureParser, Action configureParserOptions) { - /// - /// Configures the to run the parser. - /// - /// The to configure. - /// An action to configure the . - /// The configured . - public static IHostBuilder ConfigureParser(this IHostBuilder hostBuilder, Action configureParser) - { - hostBuilder.ConfigureParser(configureParser, _ => { }); - return hostBuilder; - } - /// - /// Configures the to run the parser. - /// - /// The to configure. - /// An action to configure the . - /// An action to configure the of the parser. - /// The configured . - public static IHostBuilder ConfigureParser(this IHostBuilder hostBuilder, Action configureParser, Action configureParserOptions) - { - hostBuilder.ConfigureServices( - (context, services) => - { - services.AddScoped(); - services.AddHostedService(); - var builder = services.AddCommandLineParser(configureParserOptions); - configureParser(builder); - } - ); - return hostBuilder; - } + hostBuilder.ConfigureServices( + (context, services) => + { + services.AddHostedService(); + var builder = services.AddCommandLineParser(configureParserOptions); + configureParser(builder); + } + ); + return hostBuilder; + } - /// - /// Parse the command line and execute the command if it is valid. - /// - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) - { - var host = hostBuilder.Build(); - var executionResult = await host.ParseCommandLineAndExecuteAsync(args, cancellationToken); - return executionResult; - } - /// - /// Parse the command line for a specific command and execute the command if it is valid. The name of the command should not be in the arguments list. - /// - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// The type of the command. - /// This method can only be used with class-based command. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) where TCommand : class, ICommand - { - var host = hostBuilder.Build(); - var executionResult = await host.ParseCommandLineAndExecuteAsync(args, cancellationToken); - return executionResult; - } - /// - /// Parse the command line and execute the command if it is valid. If the name of the command is not the first argument, fallback to the specified command. - /// - /// The type of the default command. - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// This method can only be used with class-based command. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineWithDefaultCommandAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) where TCommand : class, ICommand - { + /// + /// Parse the command line and execute the command if it is valid. + /// + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) + { + var host = hostBuilder.Build(); + var executionResult = await host.ParseCommandLineAndExecuteAsync(args, cancellationToken); + return executionResult; + } + /// + /// Parse the command line for a specific command and execute the command if it is valid. The name of the command should not be in the arguments list. + /// + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// The type of the command. + /// The type of the command. + /// This method can only be used with class-based command. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { var host = hostBuilder.Build(); - var executionResult = await host.ParseCommandLineWithDefaultCommandAndExecuteAsync(args, cancellationToken); + var executionResult = await host.ParseCommandLineAndExecuteAsync(args, cancellationToken); return executionResult; - } + } + /// + /// Parse the command line and execute the command if it is valid. If the name of the command is not the first argument, fallback to the specified command. + /// + /// The type of the default command. + /// The type of the default command. + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// This method can only be used with class-based command. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineWithDefaultCommandAndExecuteAsync(this IHostBuilder hostBuilder, string[] args, CancellationToken cancellationToken = default) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var host = hostBuilder.Build(); + var executionResult = await host.ParseCommandLineWithDefaultCommandAndExecuteAsync(args, cancellationToken); + return executionResult; } } diff --git a/src/MGR.CommandLineParser.Hosting/Extensions/HostExtensions.cs b/src/MGR.CommandLineParser.Hosting/Extensions/HostExtensions.cs index 913a5fd..9d74bd4 100644 --- a/src/MGR.CommandLineParser.Hosting/Extensions/HostExtensions.cs +++ b/src/MGR.CommandLineParser.Hosting/Extensions/HostExtensions.cs @@ -6,52 +6,56 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace MGR.CommandLineParser.Hosting.Extensions +namespace MGR.CommandLineParser.Hosting.Extensions; + +/// +/// Extension's methods for . +/// +public static class HostExtensions { /// - /// Extension's methods for . + /// Parse the command line and execute the command if it is valid. /// - public static class HostExtensions - { - /// - /// Parse the command line and execute the command if it is valid. - /// - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.Parse(arguments), cancellationToken); + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.Parse(arguments), cancellationToken); - /// - /// Parse the command line for a specific command and execute the command if it is valid. The name of the command should not be in the arguments list. - /// - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// The type of the command. - /// This method can only be used with class-based command. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) where TCommand : class, ICommand => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.Parse(arguments), cancellationToken); + /// + /// Parse the command line for a specific command and execute the command if it is valid. The name of the command should not be in the arguments list. + /// + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// The type of the command. + /// The type of the command. + /// This method can only be used with class-based command. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.Parse(arguments), cancellationToken); - /// - /// Parse the command line and execute the command if it is valid. If the name of the command is not the first argument, fallback to the specified command. - /// - /// The type of the default command. - /// The configured . - /// The arguments to parse. - /// The token to trigger shutdown. - /// This method can only be used with class-based command. - /// A code that represents the result of the parsing and the execution of the command. - public static async Task ParseCommandLineWithDefaultCommandAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) where TCommand : class, ICommand => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.ParseWithDefaultCommand(arguments), cancellationToken); + /// + /// Parse the command line and execute the command if it is valid. If the name of the command is not the first argument, fallback to the specified command. + /// + /// The type of the default command. + /// The type of the default command. + /// The configured . + /// The arguments to parse. + /// The token to trigger shutdown. + /// This method can only be used with class-based command. + /// A code that represents the result of the parsing and the execution of the command. + public static async Task ParseCommandLineWithDefaultCommandAndExecuteAsync(this IHost host, string[] args, CancellationToken cancellationToken = default) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() => await ParseCommandLineAndExecuteAsync(host, args, (parser, arguments) => parser.ParseWithDefaultCommand(arguments), cancellationToken); - private static async Task ParseCommandLineAndExecuteAsync(IHost host, string[] args, Func, Task> parseArguments, CancellationToken cancellationToken) - { - var parserContext = host.Services.GetRequiredService(); - parserContext.ParseArguments = parseArguments; - parserContext.Arguments = args; - await host.RunAsync(cancellationToken); - var parsingAndExecutionResult = parserContext.ParsingAndExecutionResult; - return parsingAndExecutionResult; - } + private static async Task ParseCommandLineAndExecuteAsync(IHost host, string[] args, Func, Task> parseArguments, CancellationToken cancellationToken) + { + var parserContext = new ParserContext { + ParseArguments = parseArguments, + Arguments = args + }; + await host.RunAsync(cancellationToken); + var parsingAndExecutionResult = parserContext.ParsingAndExecutionResult; + return parsingAndExecutionResult; } } diff --git a/src/MGR.CommandLineParser.Hosting/ParserContext.cs b/src/MGR.CommandLineParser.Hosting/ParserContext.cs index 8fd5707..aa4ae72 100644 --- a/src/MGR.CommandLineParser.Hosting/ParserContext.cs +++ b/src/MGR.CommandLineParser.Hosting/ParserContext.cs @@ -2,12 +2,11 @@ using System.Collections.Generic; using System.Threading.Tasks; -namespace MGR.CommandLineParser.Hosting +namespace MGR.CommandLineParser.Hosting; + +internal class ParserContext { - internal class ParserContext - { - internal IEnumerable Arguments { get; set; } - internal int ParsingAndExecutionResult { get; set; } - public Func, Task> ParseArguments { get; set; } - } + internal required IEnumerable Arguments { get; set; } + internal int ParsingAndExecutionResult { get; set; } + public required Func, Task> ParseArguments { get; set; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser.Hosting/ParserHostedService.cs b/src/MGR.CommandLineParser.Hosting/ParserHostedService.cs index 475225c..b03d0a2 100644 --- a/src/MGR.CommandLineParser.Hosting/ParserHostedService.cs +++ b/src/MGR.CommandLineParser.Hosting/ParserHostedService.cs @@ -2,37 +2,36 @@ using System.Threading.Tasks; using Microsoft.Extensions.Hosting; -namespace MGR.CommandLineParser.Hosting +namespace MGR.CommandLineParser.Hosting; + +internal sealed class ParserHostedService : IHostedService { - internal sealed class ParserHostedService : IHostedService - { - private readonly IParser _parser; - private readonly ParserContext _parserContext; - private readonly IHostApplicationLifetime _hostApplicationLifetime; + private readonly IParser _parser; + private readonly ParserContext _parserContext; + private readonly IHostApplicationLifetime _hostApplicationLifetime; - public ParserHostedService(IParser parser, ParserContext parserContext, IHostApplicationLifetime hostApplicationLifetime) - { - _parser = parser; - _parserContext = parserContext; - _hostApplicationLifetime = hostApplicationLifetime; - } - public async Task StartAsync(CancellationToken cancellationToken) - { - var parsingAndExecutionResult = await ParseAndExecuteAsync(); - _parserContext.ParsingAndExecutionResult = parsingAndExecutionResult; - _hostApplicationLifetime.StopApplication(); - } + public ParserHostedService(IParser parser, ParserContext parserContext, IHostApplicationLifetime hostApplicationLifetime) + { + _parser = parser; + _parserContext = parserContext; + _hostApplicationLifetime = hostApplicationLifetime; + } + public async Task StartAsync(CancellationToken cancellationToken) + { + var parsingAndExecutionResult = await ParseAndExecuteAsync(cancellationToken); + _parserContext.ParsingAndExecutionResult = parsingAndExecutionResult; + _hostApplicationLifetime.StopApplication(); + } - private async Task ParseAndExecuteAsync() + private async Task ParseAndExecuteAsync(CancellationToken cancellationToken) + { + var parsingResult = await _parserContext.ParseArguments(_parser, _parserContext.Arguments); + if (parsingResult.IsValid) { - var parsingResult = await _parserContext.ParseArguments(_parser, _parserContext.Arguments); - if (parsingResult.IsValid) - { - return await parsingResult.ExecuteAsync(); - } - return (int)parsingResult.ParsingResultCode; + return await parsingResult.ExecuteAsync(cancellationToken); } - - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + return (int)parsingResult.ParsingResultCode; } + + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } diff --git a/src/MGR.CommandLineParser/Command/CommandAttribute.cs b/src/MGR.CommandLineParser/Command/CommandAttribute.cs index beb7e19..b6ad2f0 100644 --- a/src/MGR.CommandLineParser/Command/CommandAttribute.cs +++ b/src/MGR.CommandLineParser/Command/CommandAttribute.cs @@ -1,84 +1,81 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Runtime; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +/// +/// Attribute to defines metadata for the command. +/// +[AttributeUsage(AttributeTargets.Class)] +public sealed class CommandAttribute : Attribute { + private readonly LocalizableString _description = new LocalizableString(nameof(Description)); + private readonly LocalizableString _usage = new LocalizableString(nameof(Usage)); + private Type? _resourceType; + /// - /// Defines attributes for the command. + /// Gets or sets the samples for the command. /// - [AttributeUsage(AttributeTargets.Class)] - public sealed class CommandAttribute : Attribute - { - private readonly LocalizableString _description = new LocalizableString(nameof(Description)); - private readonly LocalizableString _usage = new LocalizableString(nameof(Usage)); - private Type _resourceType; + public string[] Samples { get; set; } = []; - /// - /// Gets or sets the samples for the command. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] Samples { get; set; } - - /// - /// Gets or sets the description of the command. - /// - /// - /// If the property is not null, this is the name of the resource used to - /// determine the description. - /// - public string Description + /// + /// Gets or sets the description of the command. + /// + /// + /// If the property is not null, this is the name of the resource used to + /// determine the description. + /// + public string Description + { + get { return _description.Value; } + set { - get { return _description.Value; } - set - { - if (_description.Value != value) - _description.Value = value; - } + if (_description.Value != value) + _description.Value = value; } + } - /// - /// Gets or sets the usage of the command. - /// - /// - /// If the property is not null, this is the name of the resource used to - /// determine the usage. - /// - public string Usage + /// + /// Gets or sets the usage of the command. + /// + /// + /// If the property is not null, this is the name of the resource used to + /// determine the usage. + /// + public string Usage + { + get { return _usage.Value; } + set { - get { return _usage.Value; } - set - { - if (_usage.Value != value) - _usage.Value = value; - } + if (_usage.Value != value) + _usage.Value = value; } + } - /// - /// The type of the resource used to determine the values. - /// - public Type ResourceType + /// + /// The type of the resource used to determine the values. + /// + public Type? ResourceType + { + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + get { return _resourceType; } + set { - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - get { return _resourceType; } - set + if (_resourceType != value) { - if (_resourceType != value) - { - _resourceType = value; - _description.ResourceType = value; - _usage.ResourceType = value; - } + _resourceType = value; + _description.ResourceType = value; + _usage.ResourceType = value; } } + } - /// - /// Determine if the command should be hidden from the help listing. - /// - public bool HideFromHelpListing { get; set; } + /// + /// Determine if the command should be hidden from the help listing. + /// + public bool HideFromHelpListing { get; set; } - internal string GetLocalizedDescription() => _description.GetLocalizableValue(); + internal string GetLocalizedDescription() => _description.GetLocalizableValue(); - internal string GetLocalizedUsage() => _usage.GetLocalizableValue(); - } + internal string GetLocalizedUsage() => _usage.GetLocalizableValue(); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/CommandBase.cs b/src/MGR.CommandLineParser/Command/CommandBase.cs deleted file mode 100644 index 189f44a..0000000 --- a/src/MGR.CommandLineParser/Command/CommandBase.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Threading.Tasks; -using JetBrains.Annotations; -using MGR.CommandLineParser.Extensibility; -using MGR.CommandLineParser.Extensibility.Command; -using MGR.CommandLineParser.Properties; -using Microsoft.Extensions.DependencyInjection; - -namespace MGR.CommandLineParser.Command -{ - /// - /// Defines an base abstraction for the commands. It adds the implementation of the - /// property, and a - /// - /// option. - /// - public abstract class CommandBase : ICommand - { - /// - /// Initializes a new instance of a . - /// - protected CommandBase(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - Arguments = new List(); - } - - /// - /// Gets the console used by the parser (if the command needs to writes something). - /// - protected IConsole Console => ServiceProvider.GetRequiredService(); - - /// - /// Gets the of the parsing operation. - /// - protected IServiceProvider ServiceProvider { get; private set; } - - /// - /// Gets the of the command. - /// - protected ICommandType CommandType { get; private set; } - - /// - /// Gets or sets the indicator for showing the help of the command. - /// - [Display(ShortName = "Command_HelpOption_ShortNameMessage", - Description = "Command_HelpOption_DescriptionMessage", ResourceType = typeof (Strings))] - [PublicAPI] - public bool Help { get; set; } - - /// - /// The list of arguments of the command. - /// - public IList Arguments { get; } - - /// - /// Executes the command. - /// - /// Return 0 is everything was right, an negative error code otherwise. - public virtual Task ExecuteAsync() - { - if (Help) - { - var helpWriter = ServiceProvider.GetRequiredService(); - helpWriter.WriteHelpForCommand(CommandType); - return Task.FromResult(0); - } - return ExecuteCommandAsync(); - } - - /// - /// Configure the command with the representing the command. - /// - /// The of the command. - public virtual void Configure(ICommandType commandType) - { - CommandType = commandType; - } - - /// - /// Executes the command. - /// - /// Return 0 is everything was right, an negative error code otherwise. - protected abstract Task ExecuteCommandAsync(); - } -} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/CommandBase`1.cs b/src/MGR.CommandLineParser/Command/CommandBase`1.cs new file mode 100644 index 0000000..55f2236 --- /dev/null +++ b/src/MGR.CommandLineParser/Command/CommandBase`1.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MGR.CommandLineParser.Extensibility; +using Microsoft.Extensions.DependencyInjection; + +namespace MGR.CommandLineParser.Command; + +/// +/// Defines an base abstraction for the commands. It adds the implementation of the +/// property, and a +/// +/// option. +/// +/// The type of the command data. +public abstract class CommandBase : ICommandHandler + where TCommandData : HelpedCommandData, new() +{ + /// + /// Initializes a new instance of a . + /// + /// The of the parsing operation. + protected CommandBase(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + /// + /// Gets the console used by the parser (if the command needs to writes something). + /// + protected IConsole Console => ServiceProvider.GetRequiredService(); + + /// + /// Gets the of the parsing operation. + /// + protected IServiceProvider ServiceProvider { get; private set; } + + /// + public virtual Task ExecuteAsync(TCommandData commandData, CancellationToken cancellationToken) + { + if (commandData.Help) + { + if (commandData.CommandType == null) + { + throw new InvalidOperationException("CommandType has not been initialized."); + } + var helpWriter = ServiceProvider.GetRequiredService(); + helpWriter.WriteHelpForCommand(commandData.CommandType); + return Task.FromResult(0); + } + return ExecuteCommandAsync(commandData, cancellationToken); + } + + /// + /// Executes the command. This method is called if the property is false. + /// + /// The command data. + /// A cancellation token to stop processing the command. + /// Return 0 is everything was right, an negative error code otherwise. + protected abstract Task ExecuteCommandAsync(TCommandData commandData, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/CommandData.cs b/src/MGR.CommandLineParser/Command/CommandData.cs new file mode 100644 index 0000000..deb90f1 --- /dev/null +++ b/src/MGR.CommandLineParser/Command/CommandData.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using MGR.CommandLineParser.Extensibility.Command; + +namespace MGR.CommandLineParser.Command; +/// +/// Defines the base class for the command data. +/// +public class CommandData +{ + /// + /// The list of arguments of the command. + /// + public IList Arguments { get; } = []; + /// + /// Gets the of the command. + /// + internal ICommandType? CommandType { get; private set; } + + /// + /// Configure the command with the representing the command. + /// + /// The of the command. + internal void Configure(ICommandType commandType) + { + CommandType = commandType; + } +} diff --git a/src/MGR.CommandLineParser/Command/ConverterAttribute.cs b/src/MGR.CommandLineParser/Command/ConverterAttribute.cs index 1e149c0..d7e10a3 100644 --- a/src/MGR.CommandLineParser/Command/ConverterAttribute.cs +++ b/src/MGR.CommandLineParser/Command/ConverterAttribute.cs @@ -1,33 +1,32 @@ using System; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +/// +/// Defines the converter type for a property. +/// +[AttributeUsage(AttributeTargets.Property)] +[Obsolete("Use the generic version of the MGR.CommandLineParser.Command.ConverterAttribute if you use C#11+. This attribute will be removed in a future version.")] +public sealed class ConverterAttribute : Attribute { /// - /// Defines the converter type for a property. + /// Initializes a new instance of a with the converter type. /// - [AttributeUsage(AttributeTargets.Property)] - [Obsolete("Use the generic version of the MGR.CommandLineParser.Command.ConverterAttribute if you use C#11+. This attribute will be removed in a future version.")] - public sealed class ConverterAttribute : Attribute + /// + public ConverterAttribute(Type converterType) { - /// - /// Initializes a new instance of a with the converter type. - /// - /// - public ConverterAttribute(Type converterType) - { - Guard.NotNull(converterType, nameof(converterType)); + Guard.NotNull(converterType, nameof(converterType)); - if (!converterType.IsType()) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ConverterAttributeTypeMustBeIConverter); - } - ConverterType = converterType; + if (!converterType.IsType()) + { + throw new CommandLineParserException(Constants.ExceptionMessages.ConverterAttributeTypeMustBeIConverter); } - - /// - /// Gets the type of the converter. - /// - public Type ConverterType { get; } + ConverterType = converterType; } + + /// + /// Gets the type of the converter. + /// + public Type ConverterType { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/ConverterKeyValueAttribute.cs b/src/MGR.CommandLineParser/Command/ConverterKeyValueAttribute.cs index d0cbfb4..332a70c 100644 --- a/src/MGR.CommandLineParser/Command/ConverterKeyValueAttribute.cs +++ b/src/MGR.CommandLineParser/Command/ConverterKeyValueAttribute.cs @@ -1,46 +1,45 @@ using System; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +/// +/// Defines the key and the value converter types for a dictionary property. +/// +[AttributeUsage(AttributeTargets.Property)] +[Obsolete("Use the generic version of the MGR.CommandLineParser.Command.ConverterKeyValueAttribute if you use C#11+. This attribute will be removed in a future version.")] +public sealed class ConverterKeyValueAttribute : Attribute { /// - /// Defines the key and the value converter types for a dictionary property. + /// Initializes a new instance of a with the value converter type. + /// + /// The type of the value converter. + /// The key's converter is supposed to be the . + public ConverterKeyValueAttribute(Type valueConverterType) : this(valueConverterType, typeof(StringConverter)) + { + } + /// + /// Initializes a new instance of a with the value and the key converter types. /// - [AttributeUsage(AttributeTargets.Property)] - [Obsolete("Use the generic version of the MGR.CommandLineParser.Command.ConverterKeyValueAttribute if you use C#11+. This attribute will be removed in a future version.")] - public sealed class ConverterKeyValueAttribute : Attribute + /// The type of the value converter. + /// The type of the key converter. + //[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IConverter"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandLineParser")] + public ConverterKeyValueAttribute(Type valueConverterType, Type keyConverterType) { - /// - /// Initializes a new instance of a with the value converter type. - /// - /// The type of the value converter. - /// The key's converter is supposed to be the . - public ConverterKeyValueAttribute(Type valueConverterType) : this(valueConverterType, typeof(StringConverter)) - { - } - /// - /// Initializes a new instance of a with the value and the key converter types. - /// - /// The type of the value converter. - /// The type of the key converter. - //[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IConverter"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "CommandLineParser")] - public ConverterKeyValueAttribute(Type valueConverterType, Type keyConverterType) - { - Guard.NotNull(keyConverterType, nameof(keyConverterType)); - Guard.NotNull(valueConverterType, nameof(valueConverterType)); - Guard.IsIConverter(keyConverterType, Constants.ExceptionMessages.ConverterKeyConverterTypeMustBeIConverter); - Guard.IsIConverter(valueConverterType, Constants.ExceptionMessages.ConverterValueConverterTypeMustBeIConverter); + Guard.NotNull(keyConverterType, nameof(keyConverterType)); + Guard.NotNull(valueConverterType, nameof(valueConverterType)); + Guard.IsIConverter(keyConverterType, Constants.ExceptionMessages.ConverterKeyConverterTypeMustBeIConverter); + Guard.IsIConverter(valueConverterType, Constants.ExceptionMessages.ConverterValueConverterTypeMustBeIConverter); - KeyConverterType = keyConverterType; - ValueConverterType = valueConverterType; - } - /// - /// Gets the type of the key converter. - /// - public Type KeyConverterType { get; } - /// - /// Gets the type of the value converter. - /// - public Type ValueConverterType { get; } + KeyConverterType = keyConverterType; + ValueConverterType = valueConverterType; } + /// + /// Gets the type of the key converter. + /// + public Type KeyConverterType { get; } + /// + /// Gets the type of the value converter. + /// + public Type ValueConverterType { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/HelpCommand.cs b/src/MGR.CommandLineParser/Command/HelpCommand.cs index aa40ddf..0f6dc28 100644 --- a/src/MGR.CommandLineParser/Command/HelpCommand.cs +++ b/src/MGR.CommandLineParser/Command/HelpCommand.cs @@ -1,70 +1,61 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using MGR.CommandLineParser.Extensibility; using MGR.CommandLineParser.Extensibility.Command; using Microsoft.Extensions.DependencyInjection; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +/// +/// Defines the default implementation of the . +/// +public sealed class HelpCommand : CommandBase { /// - /// Defines the default implementation of the . + /// Name of the help command. /// - [PublicAPI] - public sealed class HelpCommand : CommandBase - { - /// - /// Name of the help command. - /// - public const string Name = "help"; + public const string Name = "help"; - /// - /// Creates a new instance of . - /// - /// A used to resolve services. - public HelpCommand(IServiceProvider serviceProvider) : base(serviceProvider) + /// + /// Creates a new instance of . + /// + /// A used to resolve services. + public HelpCommand(IServiceProvider serviceProvider) + : base(serviceProvider) + { } + + + /// + protected override async Task ExecuteCommandAsync(HelpCommandData commandData, CancellationToken cancellationToken) + { + var commandTypeProviders = ServiceProvider.GetServices().ToList(); + var helpWriter = ServiceProvider.GetRequiredService(); + var commandType = await commandTypeProviders.GetCommandType(commandData.Arguments.FirstOrDefault() ?? string.Empty); + if (commandType == null) { + await WriteHelpWhenNoCommandAreSpecified(commandTypeProviders, helpWriter, commandData); + } + else + { + helpWriter.WriteHelpForCommand(commandType); } - /// - /// Show detailed help for all commands. - /// - public bool All { get; set; } + return 0; + } - /// - /// Executes the command. - /// - /// Return 0 is everything was right, an negative error code otherwise. - protected override async Task ExecuteCommandAsync() + private async Task WriteHelpWhenNoCommandAreSpecified(IEnumerable commandTypeProviders, IHelpWriter helpWriter, HelpCommandData commandData) + { + if (commandData.All) { - var commandTypeProviders = ServiceProvider.GetServices().ToList(); - var helpWriter = ServiceProvider.GetRequiredService(); - var commandType = await commandTypeProviders.GetCommandType(Arguments.FirstOrDefault() ?? string.Empty); - if (commandType == null) - { - await WriteHelpWhenNoCommandAreSpecified(commandTypeProviders, helpWriter); - } - else - { - helpWriter.WriteHelpForCommand(commandType); - } - - return 0; + var commands = await commandTypeProviders.GetAllVisibleCommandsTypes(); + helpWriter.WriteHelpForCommand(commands.ToArray()); } - - private async Task WriteHelpWhenNoCommandAreSpecified(IEnumerable commandTypeProviders, IHelpWriter helpWriter) + else { - if (All) - { - var commands = await commandTypeProviders.GetAllVisibleCommandsTypes(); - helpWriter.WriteHelpForCommand(commands.ToArray()); - } - else - { - await helpWriter.WriteCommandListing(); - } + await helpWriter.WriteCommandListing(); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/HelpCommandData.cs b/src/MGR.CommandLineParser/Command/HelpCommandData.cs new file mode 100644 index 0000000..5406b2a --- /dev/null +++ b/src/MGR.CommandLineParser/Command/HelpCommandData.cs @@ -0,0 +1,11 @@ +namespace MGR.CommandLineParser.Command; +/// +/// Represents the data for the help command. +/// +public class HelpCommandData : HelpedCommandData +{ + /// + /// Show detailed help for all commands. + /// + public bool All { get; set; } +} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/HelpedCommandData.cs b/src/MGR.CommandLineParser/Command/HelpedCommandData.cs new file mode 100644 index 0000000..581e21a --- /dev/null +++ b/src/MGR.CommandLineParser/Command/HelpedCommandData.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using MGR.CommandLineParser.Properties; + +namespace MGR.CommandLineParser.Command; +/// +/// Base class for command data with help support. +/// +public abstract class HelpedCommandData : CommandData +{ + /// + /// Gets or sets the indicator for showing the help of the command. + /// + [Display(ShortName = "Command_HelpOption_ShortNameMessage", + Description = "Command_HelpOption_DescriptionMessage", ResourceType = typeof(Strings))] + public bool Help { get; set; } +} diff --git a/src/MGR.CommandLineParser/Command/ICommand.cs b/src/MGR.CommandLineParser/Command/ICommand.cs deleted file mode 100644 index 2af2439..0000000 --- a/src/MGR.CommandLineParser/Command/ICommand.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MGR.CommandLineParser.Command -{ - /// - /// Defines a command. - /// - public interface ICommand - { - /// - /// Executes the command. - /// - /// Return 0 is everything was right, an negative error code otherwise. - Task ExecuteAsync(); - /// - /// The list of arguments of the command. - /// - IList Arguments { get; } - } -} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/ICommandHandler.cs b/src/MGR.CommandLineParser/Command/ICommandHandler.cs new file mode 100644 index 0000000..223b715 --- /dev/null +++ b/src/MGR.CommandLineParser/Command/ICommandHandler.cs @@ -0,0 +1,20 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace MGR.CommandLineParser.Command; + +/// +/// Defines the contract for the command handler. +/// +/// The type of data the command handles. +public interface ICommandHandler + where TCommandData : CommandData, new() +{ + /// + /// Executes the command. + /// + /// The data provided to the command via the parsing. + /// A cancellation token to stop processing the command. + /// Return 0 is everything was right, an negative error code otherwise. + Task ExecuteAsync(TCommandData commandData, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/IgnoreOptionPropertyAttribute.cs b/src/MGR.CommandLineParser/Command/IgnoreOptionPropertyAttribute.cs index ce3516c..86ca147 100644 --- a/src/MGR.CommandLineParser/Command/IgnoreOptionPropertyAttribute.cs +++ b/src/MGR.CommandLineParser/Command/IgnoreOptionPropertyAttribute.cs @@ -1,12 +1,11 @@ using System; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +/// +/// Ignore the property as option. +/// +[AttributeUsage(AttributeTargets.Property)] +public sealed class IgnoreOptionPropertyAttribute : Attribute { - /// - /// Ignore the property as option. - /// - [AttributeUsage(AttributeTargets.Property)] - public sealed class IgnoreOptionPropertyAttribute : Attribute - { - } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Command/LocalizableString.cs b/src/MGR.CommandLineParser/Command/LocalizableString.cs index 28b9cc9..0af0173 100644 --- a/src/MGR.CommandLineParser/Command/LocalizableString.cs +++ b/src/MGR.CommandLineParser/Command/LocalizableString.cs @@ -1,89 +1,88 @@ using System; using System.Runtime; -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +internal sealed class LocalizableString { - internal sealed class LocalizableString - { - private Func _cachedResult; - private readonly string _propertyName; - private string _propertyValue; - private Type _resourceType; + private Func? _cachedResult; + private readonly string _propertyName; + private string? _propertyValue; + private Type? _resourceType; - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - internal LocalizableString(string propertyName) - { - _propertyName = propertyName; - } + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + internal LocalizableString(string propertyName) + { + _propertyName = propertyName; + } - private void ClearCache() - { - _cachedResult = null; - } + private void ClearCache() + { + _cachedResult = null; + } - internal string GetLocalizableValue() + internal string GetLocalizableValue() + { + if (_cachedResult == null) { - if (_cachedResult == null) + if (_propertyValue == null || _resourceType == null) + { + _cachedResult = () => _propertyValue; + } + else { - if (_propertyValue == null || _resourceType == null) + var property = _resourceType.GetProperty(_propertyValue); + var flag = false; + if (!_resourceType.IsVisible || property == null || property.PropertyType != typeof (string)) { - _cachedResult = () => _propertyValue; + flag = true; } else { - var property = _resourceType.GetProperty(_propertyValue); - var flag = false; - if (!_resourceType.IsVisible || property == null || property.PropertyType != typeof (string)) + var getMethod = property.GetGetMethod(); + if (getMethod == null || !getMethod.IsPublic || !getMethod.IsStatic) { flag = true; } - else - { - var getMethod = property.GetGetMethod(); - if (getMethod == null || !getMethod.IsPublic || !getMethod.IsStatic) - { - flag = true; - } - } - if (flag) - { - var exceptionMessage = Constants.ExceptionMessages.LocalizableNoPropertyFound(_propertyName, _resourceType, _propertyValue); - _cachedResult = delegate { throw new InvalidOperationException(exceptionMessage); }; - } - else - { - _cachedResult = () => (string)property.GetValue(null, null); - } + } + if (flag) + { + var exceptionMessage = Constants.ExceptionMessages.LocalizableNoPropertyFound(_propertyName, _resourceType, _propertyValue); + _cachedResult = delegate { throw new InvalidOperationException(exceptionMessage); }; + } + else + { + _cachedResult = () => (string)property!.GetValue(null, null); } } - return _cachedResult?.Invoke(); } + return _cachedResult?.Invoke() ?? string.Empty; + } - internal Type ResourceType + internal Type? ResourceType + { + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + get { return _resourceType; } + set { - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - get { return _resourceType; } - set + if (_resourceType != value) { - if (_resourceType != value) - { - ClearCache(); - _resourceType = value; - } + ClearCache(); + _resourceType = value; } } + } - internal string Value + internal string Value + { + [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] + get { return _propertyValue ?? string.Empty; } + set { - [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] - get { return _propertyValue; } - set + if (_propertyValue != value) { - if (_propertyValue != value) - { - ClearCache(); - _propertyValue = value; - } + ClearCache(); + _propertyValue = value; } } } diff --git a/src/MGR.CommandLineParser/CommandLineParserException.cs b/src/MGR.CommandLineParser/CommandLineParserException.cs index 7c88671..b98e80a 100644 --- a/src/MGR.CommandLineParser/CommandLineParserException.cs +++ b/src/MGR.CommandLineParser/CommandLineParserException.cs @@ -1,43 +1,42 @@ using System; using System.Runtime.Serialization; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Exception thrown by the parser if a technical errors occurs. +/// +[Serializable] +public class CommandLineParserException : Exception { /// - /// Exception thrown by the parser if a technical errors occurs. + /// Initializes a new instance of the class. + /// + public CommandLineParserException() + { } + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// The error message that explains the reason for the exception. + public CommandLineParserException(string message) + : base(message) + { } + /// + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public CommandLineParserException(string message, Exception innerException) + : base(message, innerException) + { } + /// + /// Initializes a new instance of the class with serialized data. /// - [Serializable] - public class CommandLineParserException : Exception - { - /// - /// Initializes a new instance of the class. - /// - public CommandLineParserException() - { } - /// - /// Initializes a new instance of the class with a specified error message. - /// - /// The error message that explains the reason for the exception. - public CommandLineParserException(string message) - : base(message) - { } - /// - /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public CommandLineParserException(string message, Exception innerException) - : base(message, innerException) - { } - /// - /// Initializes a new instance of the class with serialized data. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The info parameter is null. - /// The class name is null or System.Exception.HResult is zero (0). - protected CommandLineParserException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } - } + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The info parameter is null. + /// The class name is null or System.Exception.HResult is zero (0). + protected CommandLineParserException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/CommandParsingResultCode.cs b/src/MGR.CommandLineParser/CommandParsingResultCode.cs index 98b3831..b155782 100644 --- a/src/MGR.CommandLineParser/CommandParsingResultCode.cs +++ b/src/MGR.CommandLineParser/CommandParsingResultCode.cs @@ -1,29 +1,28 @@ -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Built-in list of result code. +/// +public enum CommandParsingResultCode { /// - /// Built-in list of result code. + /// The parsing and the option's validation was fine. /// - public enum CommandParsingResultCode - { - /// - /// The parsing and the option's validation was fine. - /// - Success = 0, - /// - /// The args parameter of the Parse command is null. - /// - NoArgumentsProvided = -100, - /// - /// There is no command name in the command-line. - /// - NoCommandNameProvided = -200, - /// - /// The requested command was not found. - /// - NoCommandFound = -300, - /// - /// The specified parameter for the options of the command are not valid. - /// - CommandParametersNotValid = -400 - } + Success = 0, + /// + /// The args parameter of the Parse command is null. + /// + NoArgumentsProvided = -100, + /// + /// There is no command name in the command-line. + /// + NoCommandNameProvided = -200, + /// + /// The requested command was not found. + /// + NoCommandFound = -300, + /// + /// The specified parameter for the options of the command are not valid. + /// + CommandParametersNotValid = -400 } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Constants.cs b/src/MGR.CommandLineParser/Constants.cs index 8636329..f674b2f 100644 --- a/src/MGR.CommandLineParser/Constants.cs +++ b/src/MGR.CommandLineParser/Constants.cs @@ -2,83 +2,81 @@ using System.Globalization; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +internal static class Constants { - internal static class Constants + internal static readonly string LongNameOptionStarter = "--"; + internal static readonly string ShortNameOptionStarter = "-"; + internal static readonly string[] OptionStarter = { LongNameOptionStarter, ShortNameOptionStarter }; + internal static readonly char[] OptionSplitter = {':'}; + internal static readonly string EndOfOptions = "--"; + internal const string CommandSuffix = nameof(Command); + + internal static class ExceptionMessages { - internal static readonly string LongNameOptionStarter = "--"; - internal static readonly string ShortNameOptionStarter = "-"; - internal static readonly string[] OptionStarter = { LongNameOptionStarter, ShortNameOptionStarter }; - internal static readonly char[] OptionSplitter = {':'}; - internal static readonly string EndOfOptions = "--"; - internal const string CommandSuffix = nameof(Command); - - internal static class ExceptionMessages - { - internal static readonly Func FormatConverterUnableConvert = (o, t) => string.Format(CultureInfo.InvariantCulture, "Unable to parse '{0}' to type '{1}'.", o, t.Name); - - internal static readonly Func FormatParserOptionNotFoundForCommand = - (commandName, optionName) => string.Format(CultureInfo.InvariantCulture, "There is no option '{1}' for the command '{0}'.", commandName, optionName); - - internal static readonly Func FormatParserOptionValueRequired = - (commandName, optionName) => string.Format(CultureInfo.InvariantCulture, "You should specified a value for the option '{1}' of the command '{0}'.", commandName, optionName); - - internal static readonly string NoValidCommand = "The command is not in a valid state."; - // ReSharper disable once InconsistentNaming - internal static readonly string IConverterTypeName = typeof (IConverter).FullName; - internal static readonly string ConverterKeyConverterTypeMustBeIConverter = "The key converter type must implement " + IConverterTypeName; - internal static readonly string ConverterValueConverterTypeMustBeIConverter = "The value converter type must implement " + IConverterTypeName; - internal static readonly string ConverterAttributeTypeMustBeIConverter = "The converter type must implement " + IConverterTypeName; - - internal static readonly Func ParserExtractMetadataPropertyShouldBeWritableOrICollection = - (propertyName, commandName) => - string.Format(CultureInfo.CurrentUICulture, "The option '{0}' of the command '{1}' must be writable or implements ICollection.", propertyName, commandName); - - internal static readonly Func ParserExtractConverterKeyValueConverterIsForIDictionaryProperty = - (propertyName, commandName) => - string.Format(CultureInfo.CurrentUICulture, "The option '{0}' of the command '{1}' defines a Key/Value converter but its type is not System.Generic.IDictionary.", - propertyName, commandName); - - internal static readonly Func ParserExtractKeyConverterIsNotValid = - (propertyName, commandName, keyPropertyType, keyConverterTargetType) => string.Format(CultureInfo.CurrentUICulture, - "The specified KeyValueConverter for the option '{0}' of the command '{1}' is not valid : key property type : {2}, key converter target type : {3}.", propertyName, commandName, - keyPropertyType.FullName, keyConverterTargetType.FullName); - - internal static readonly Func ParserExtractValueConverterIsNotValid = - (propertyName, commandName, valuePropertyType, valueConverterTargetType) => string.Format(CultureInfo.CurrentUICulture, - "The specified KeyValueConverter for the option '{0}' of the command '{1}' is not valid : value property type : {2}, value converter target type : {3}.", propertyName, commandName, - valuePropertyType.FullName, valueConverterTargetType.FullName); - - internal static readonly Func ParserNoKeyConverterFound = (propertyName, commandName, keyType) => - string.Format(CultureInfo.CurrentUICulture, "No converter found for the key type ('{2}') of the option '{0}' of the command '{1}'.", propertyName, commandName, keyType.FullName); - - internal static readonly Func ParserNoValueConverterFound = (propertyName, commandName, valueType) => - string.Format(CultureInfo.CurrentUICulture, "No converter found for the value type ('{2}') of the option '{0}' of the command '{1}'.", propertyName, commandName, valueType.FullName); - - internal static readonly Func ParserNoConverterFound = (propertyName, commandName, propertyType) => - string.Format(CultureInfo.CurrentUICulture, "No converter found for the option '{0}' of the command '{1}' of type '{2}'.", propertyName, commandName, propertyType.FullName); - - internal static readonly Func ParserSpecifiedConverterNotValidToAssignValue = - (optionType, targetType) => string.Format(CultureInfo.CurrentUICulture, "The specified converter is not valid : target type is '{1}' and option type is '{0}'.", optionType, targetType); - - internal static readonly Func ParserSpecifiedConverterNotValid = - (optionName, commandName, optionType, targetType) => - string.Format(CultureInfo.CurrentUICulture, "The specified converter for the option '{0}' of the command '{1}' is not valid : property type : {2}, converter target type : {3}.", - optionName, commandName, optionType.FullName, targetType.FullName); - - internal static readonly Func LocalizableNoPropertyFound = - (propertyName, resourceType, propertyValue) => - string.Format(CultureInfo.CurrentCulture, - "Cannot retrieve property '{0}' because localization failed. Type '{1}' is not public or does not contain a public static string property with the name '{2}'", propertyName, - resourceType.FullName, propertyValue); - - internal static readonly Func ParserMultiValueOptionIsNullAndHasNoSetter = (optionName, commandName) => string.Format(CultureInfo.CurrentUICulture, "The multi-valued option '{0}' of the command '{1}' returns null and have no setter.", optionName, commandName); - - internal static readonly Func EnumConverterConcreteTargetTypeIsNotAnEnum = - concreteTargetType => string.Format(CultureInfo.CurrentCulture, "The specified concrete target type ({0}) is not an enum type.", concreteTargetType.FullName); - - internal static readonly Func EnumConverterParsedValueIsNotOfConcreteType = - (value, concreteTargetType) => string.Format(CultureInfo.CurrentCulture, "The specified value '{0}' is not correct the type '{1}'.", value, concreteTargetType); - } + internal static readonly Func FormatConverterUnableConvert = (o, t) => string.Format(CultureInfo.InvariantCulture, "Unable to parse '{0}' to type '{1}'.", o, t.Name); + + internal static readonly Func FormatParserOptionNotFoundForCommand = + (commandName, optionName) => string.Format(CultureInfo.InvariantCulture, "There is no option '{1}' for the command '{0}'.", commandName, optionName); + + internal static readonly Func FormatParserOptionValueRequired = + (commandName, optionName) => string.Format(CultureInfo.InvariantCulture, "You should specified a value for the option '{1}' of the command '{0}'.", commandName, optionName); + + internal static readonly string NoValidCommand = "The command is not in a valid state."; + internal static readonly string IConverterTypeName = typeof (IConverter).FullName; + internal static readonly string ConverterKeyConverterTypeMustBeIConverter = "The key converter type must implement " + IConverterTypeName; + internal static readonly string ConverterValueConverterTypeMustBeIConverter = "The value converter type must implement " + IConverterTypeName; + internal static readonly string ConverterAttributeTypeMustBeIConverter = "The converter type must implement " + IConverterTypeName; + + internal static readonly Func ParserExtractMetadataPropertyShouldBeWritableOrICollection = + (propertyName, commandName) => + string.Format(CultureInfo.CurrentUICulture, "The option '{0}' of the command '{1}' must be writable or implements ICollection.", propertyName, commandName); + + internal static readonly Func ParserExtractConverterKeyValueConverterIsForIDictionaryProperty = + (propertyName, commandName) => + string.Format(CultureInfo.CurrentUICulture, "The option '{0}' of the command '{1}' defines a Key/Value converter but its type is not System.Generic.IDictionary.", + propertyName, commandName); + + internal static readonly Func ParserExtractKeyConverterIsNotValid = + (propertyName, commandName, keyPropertyType, keyConverterTargetType) => string.Format(CultureInfo.CurrentUICulture, + "The specified KeyValueConverter for the option '{0}' of the command '{1}' is not valid : key property type : {2}, key converter target type : {3}.", propertyName, commandName, + keyPropertyType.FullName, keyConverterTargetType.FullName); + + internal static readonly Func ParserExtractValueConverterIsNotValid = + (propertyName, commandName, valuePropertyType, valueConverterTargetType) => string.Format(CultureInfo.CurrentUICulture, + "The specified KeyValueConverter for the option '{0}' of the command '{1}' is not valid : value property type : {2}, value converter target type : {3}.", propertyName, commandName, + valuePropertyType.FullName, valueConverterTargetType.FullName); + + internal static readonly Func ParserNoKeyConverterFound = (propertyName, commandName, keyType) => + string.Format(CultureInfo.CurrentUICulture, "No converter found for the key type ('{2}') of the option '{0}' of the command '{1}'.", propertyName, commandName, keyType.FullName); + + internal static readonly Func ParserNoValueConverterFound = (propertyName, commandName, valueType) => + string.Format(CultureInfo.CurrentUICulture, "No converter found for the value type ('{2}') of the option '{0}' of the command '{1}'.", propertyName, commandName, valueType.FullName); + + internal static readonly Func ParserNoConverterFound = (propertyName, commandName, propertyType) => + string.Format(CultureInfo.CurrentUICulture, "No converter found for the option '{0}' of the command '{1}' of type '{2}'.", propertyName, commandName, propertyType.FullName); + + internal static readonly Func ParserSpecifiedConverterNotValidToAssignValue = + (optionType, targetType) => string.Format(CultureInfo.CurrentUICulture, "The specified converter is not valid : target type is '{1}' and option type is '{0}'.", optionType, targetType); + + internal static readonly Func ParserSpecifiedConverterNotValid = + (optionName, commandName, optionType, targetType) => + string.Format(CultureInfo.CurrentUICulture, "The specified converter for the option '{0}' of the command '{1}' is not valid : property type : {2}, converter target type : {3}.", + optionName, commandName, optionType.FullName, targetType.FullName); + + internal static readonly Func LocalizableNoPropertyFound = + (propertyName, resourceType, propertyValue) => + string.Format(CultureInfo.CurrentCulture, + "Cannot retrieve property '{0}' because localization failed. Type '{1}' is not public or does not contain a public static string property with the name '{2}'", propertyName, + resourceType.FullName, propertyValue); + + internal static readonly Func ParserMultiValueOptionIsNullAndHasNoSetter = (optionName, commandName) => string.Format(CultureInfo.CurrentUICulture, "The multi-valued option '{0}' of the command '{1}' returns null and have no setter.", optionName, commandName); + + internal static readonly Func EnumConverterConcreteTargetTypeIsNotAnEnum = + concreteTargetType => string.Format(CultureInfo.CurrentCulture, "The specified concrete target type ({0}) is not an enum type.", concreteTargetType.FullName); + + internal static readonly Func EnumConverterParsedValueIsNotOfConcreteType = + (value, concreteTargetType) => string.Format(CultureInfo.CurrentCulture, "The specified value '{0}' is not correct the type '{1}'.", value, concreteTargetType); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/DefaultParserFactory.cs b/src/MGR.CommandLineParser/DefaultParserFactory.cs index d30615f..474353a 100644 --- a/src/MGR.CommandLineParser/DefaultParserFactory.cs +++ b/src/MGR.CommandLineParser/DefaultParserFactory.cs @@ -1,24 +1,23 @@ using System; using Microsoft.Extensions.Options; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +internal sealed class DefaultParserFactory : IParserFactory { - internal sealed class DefaultParserFactory : IParserFactory - { - private readonly IOptions _optionsMonitor; - private readonly IServiceProvider _serviceProvider; + private readonly IOptions _optionsMonitor; + private readonly IServiceProvider _serviceProvider; - public DefaultParserFactory(IOptions optionsMonitor, IServiceProvider serviceProvider) - { - _optionsMonitor = optionsMonitor; - _serviceProvider = serviceProvider; - } + public DefaultParserFactory(IOptions optionsMonitor, IServiceProvider serviceProvider) + { + _optionsMonitor = optionsMonitor; + _serviceProvider = serviceProvider; + } - public IParser CreateParser() - { - var options = _optionsMonitor.Value; - var parser = new Parser(options, _serviceProvider); - return parser; - } + public IParser CreateParser() + { + var options = _optionsMonitor.Value; + var parser = new Parser(options, _serviceProvider); + return parser; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Diagnostics/LoggerCategory.cs b/src/MGR.CommandLineParser/Diagnostics/LoggerCategory.cs index 3a1ab4f..aff0b26 100644 --- a/src/MGR.CommandLineParser/Diagnostics/LoggerCategory.cs +++ b/src/MGR.CommandLineParser/Diagnostics/LoggerCategory.cs @@ -1,10 +1,8 @@ - -namespace MGR.CommandLineParser.Diagnostics +namespace MGR.CommandLineParser.Diagnostics; + +internal static class LoggerCategory { - internal static class LoggerCategory + public class Parser : LoggerCategory { - public class Parser : LoggerCategory - { - } } } diff --git a/src/MGR.CommandLineParser/Diagnostics/LoggerCategory`1.cs b/src/MGR.CommandLineParser/Diagnostics/LoggerCategory`1.cs index 434d9f9..36043dd 100644 --- a/src/MGR.CommandLineParser/Diagnostics/LoggerCategory`1.cs +++ b/src/MGR.CommandLineParser/Diagnostics/LoggerCategory`1.cs @@ -1,28 +1,26 @@ using System; -using JetBrains.Annotations; -namespace MGR.CommandLineParser.Diagnostics -{ - internal abstract class LoggerCategory - { - public static string Name { get; } = ToName(typeof(T)); +namespace MGR.CommandLineParser.Diagnostics; - public override string ToString() => Name; +internal abstract class LoggerCategory +{ + public static string Name { get; } = ToName(typeof(T)); - public static implicit operator string([NotNull] LoggerCategory loggerCategory) => loggerCategory.ToString(); + public override string ToString() => Name; - private static string ToName([NotNull] Type loggerCategoryType) - { - const string outerClassName = "." + nameof(LoggerCategory); + public static implicit operator string(LoggerCategory loggerCategory) => loggerCategory.ToString(); - var name = (loggerCategoryType.FullName ?? string.Empty).Replace('+', '.'); - var index = name.IndexOf(outerClassName, StringComparison.Ordinal); - if (index >= 0) - { - name = name.Substring(0, index) + name.Substring(index + outerClassName.Length); - } + private static string ToName(Type loggerCategoryType) + { + const string outerClassName = "." + nameof(LoggerCategory); - return name; + var name = (loggerCategoryType.FullName ?? string.Empty).Replace('+', '.'); + var index = name.IndexOf(outerClassName, StringComparison.Ordinal); + if (index >= 0) + { + name = name.Substring(0, index) + name.Substring(index + outerClassName.Length); } + + return name; } } diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyBrowsingClassBasedCommandTypeProvider.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyBrowsingClassBasedCommandTypeProvider.cs index 968c0a5..47ea680 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyBrowsingClassBasedCommandTypeProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyBrowsingClassBasedCommandTypeProvider.cs @@ -7,48 +7,47 @@ using MGR.CommandLineParser.Extensibility.Command; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class AssemblyBrowsingClassBasedCommandTypeProvider : ICommandTypeProvider { - internal sealed class AssemblyBrowsingClassBasedCommandTypeProvider : ICommandTypeProvider - { - private readonly IEnumerable _assemblyProviders; - private readonly Lazy> _commands; + private readonly IEnumerable _assemblyProviders; + private readonly Lazy> _commands; - private readonly IEnumerable _converters; - private readonly IEnumerable _optionAlternateNameGenerators; + private readonly IEnumerable _converters; + private readonly IEnumerable _optionAlternateNameGenerators; - public AssemblyBrowsingClassBasedCommandTypeProvider(IEnumerable assemblyProviders, IEnumerable converters, IEnumerable optionAlternateNameGenerators) - { - _assemblyProviders = assemblyProviders; - _converters = converters; - _optionAlternateNameGenerators = optionAlternateNameGenerators; - _commands = new Lazy>(SearchAllCommandTypes); - } + public AssemblyBrowsingClassBasedCommandTypeProvider(IEnumerable assemblyProviders, IEnumerable converters, IEnumerable optionAlternateNameGenerators) + { + _assemblyProviders = assemblyProviders; + _converters = converters; + _optionAlternateNameGenerators = optionAlternateNameGenerators; + _commands = new Lazy>(SearchAllCommandTypes); + } - public Task> GetAllCommandTypes() - { - var commandTypes = _commands.Value; - return Task.FromResult>(commandTypes.Values); - } + public Task> GetAllCommandTypes() + { + var commandTypes = _commands.Value; + return Task.FromResult>(commandTypes.Values); + } - public Task GetCommandType(string commandName) + public Task GetCommandType(string commandName) + { + var commandTypes = _commands.Value; + if (commandTypes.ContainsKey(commandName)) { - var commandTypes = _commands.Value; - if (commandTypes.ContainsKey(commandName)) - { - return Task.FromResult(commandTypes[commandName]); - } - return Task.FromResult(null); + return Task.FromResult(commandTypes[commandName]); } + return Task.FromResult(null); + } - private Dictionary SearchAllCommandTypes() - { - var assemblies = _assemblyProviders.SelectMany(assemblyProvider => assemblyProvider.GetAssembliesToBrowse()).ToList(); - var types = assemblies.GetTypes(type => type.IsType()).ToList(); + private Dictionary SearchAllCommandTypes() + { + var assemblies = _assemblyProviders.SelectMany(assemblyProvider => assemblyProvider.GetAssembliesToBrowse()).ToList(); + var types = assemblies.GetTypes(type => type.IsType(typeof(ICommandHandler<>)) && !type.IsAbstract).ToList(); - var commandTypes = types.Select(commandType => new ClassBasedCommandType(commandType, _converters, _optionAlternateNameGenerators)).ToList(); - var commandTypesByName = commandTypes.ToDictionary(commandType => commandType.Metadata.Name, _ => _, StringComparer.OrdinalIgnoreCase); - return commandTypesByName; - } + var commandTypes = types.Select(commandType => new ClassBasedCommandType(commandType, _converters, _optionAlternateNameGenerators)).ToList(); + var commandTypesByName = commandTypes.ToDictionary(commandType => commandType.Metadata.Name, _ => _, StringComparer.OrdinalIgnoreCase); + return commandTypesByName; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyProviderBase.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyProviderBase.cs index c5e203f..f7243dd 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyProviderBase.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/AssemblyProviderBase.cs @@ -1,69 +1,62 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyModel; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Base class for providing all files (*.dll and *.exe) in the current folder (recursive or not). +/// +public abstract class AssemblyProviderBase : IAssemblyProvider { /// - /// Base class for providing all files (*.dll and *.exe) in the current folder (recursive or not). + /// Gets the recursively options for browsing the current folder. /// - public abstract class AssemblyProviderBase : IAssemblyProvider + protected abstract SearchOption SearchOption { get; } + + private IEnumerable GetFilesToLoad() { - /// - /// Gets the recursively options for browsing the current folder. - /// - protected abstract SearchOption SearchOption { get; } - [ItemNotNull] - private IEnumerable GetFilesToLoad() + var thisDirectory = Environment.CurrentDirectory; + foreach (var item in Directory.EnumerateFiles(thisDirectory, "*.exe", SearchOption)) { - var thisDirectory = Environment.CurrentDirectory; - foreach (var item in Directory.EnumerateFiles(thisDirectory, "*.exe", SearchOption)) - { - yield return new FileInfo(item).FullName; - } - foreach (var item in Directory.EnumerateFiles(thisDirectory, "*.dll", SearchOption)) - { - yield return new FileInfo(item).FullName; - } + yield return new FileInfo(item).FullName; + } + foreach (var item in Directory.EnumerateFiles(thisDirectory, "*.dll", SearchOption)) + { + yield return new FileInfo(item).FullName; } + } - /// - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] - public IEnumerable GetAssembliesToBrowse() + /// + public IEnumerable GetAssembliesToBrowse() + { + if(DependencyContext.Default == null) { - var alreadyLoadedLibraries = DependencyContext.Default.RuntimeLibraries; - foreach (var assemblyFile in GetFilesToLoad()) + return []; + } + var alreadyLoadedLibraries = DependencyContext.Default.RuntimeLibraries; + foreach (var assemblyFile in GetFilesToLoad()) + { + var assemblyNameFromFile = Path.GetFileNameWithoutExtension(assemblyFile); + if (alreadyLoadedLibraries.Any(runtimeLibrary => runtimeLibrary.Name.Equals(assemblyNameFromFile, StringComparison.OrdinalIgnoreCase))) { - var assemblyNameFromFile = Path.GetFileNameWithoutExtension(assemblyFile); - if (alreadyLoadedLibraries.Any(runtimeLibrary => runtimeLibrary.Name.Equals(assemblyNameFromFile, StringComparison.OrdinalIgnoreCase))) - { - continue; - } - - try - { - Assembly.LoadFile(assemblyFile); - } - - // ReSharper disable once EmptyGeneralCatchClause -#pragma warning disable CC0004 // Catch block cannot be empty -#pragma warning disable S2486 // Generic exceptions should not be ignored - catch -#pragma warning disable S108 // Nested blocks of code should not be left empty - { - } -#pragma warning restore S108 // Nested blocks of code should not be left empty -#pragma warning restore CC0004 // Catch block cannot be empty -#pragma warning restore S2486 // Generic exceptions should not be ignored + continue; } - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - return assemblies; + try + { + Assembly.LoadFile(assemblyFile); + } + catch + { + // ignored + } } + + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + return assemblies; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedBasicCommandActivator.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedBasicCommandActivator.cs index 2349300..a8f1a2f 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedBasicCommandActivator.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedBasicCommandActivator.cs @@ -1,23 +1,24 @@ using System; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Basic command activator that uses Activator.CreateInstance to instantiate commands. +/// +public sealed class ClassBasedBasicCommandActivator : IClassBasedCommandActivator { /// - /// Basic command activator that uses Activator.CreateInstance to instantiate commands. + /// Gets the singleton instance of . /// - public sealed class ClassBasedBasicCommandActivator : IClassBasedCommandActivator - { - /// - /// Gets the singleton instance of . - /// - public static readonly IClassBasedCommandActivator Instance = new ClassBasedBasicCommandActivator(); - - private ClassBasedBasicCommandActivator() - { - } + public static readonly IClassBasedCommandActivator Instance = new ClassBasedBasicCommandActivator(); - /// - public ICommand ActivateCommand(Type commandType) => Activator.CreateInstance(commandType) as ICommand; + private ClassBasedBasicCommandActivator() + { } + + /// + public TCommandHandler ActivateCommand() + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() => Activator.CreateInstance(); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandMetadata.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandMetadata.cs index 287b831..02887ab 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandMetadata.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandMetadata.cs @@ -1,34 +1,34 @@ using System; -using System.Diagnostics.CodeAnalysis; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class ClassBasedCommandMetadata : ICommandMetadata + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() { - internal sealed class ClassBasedCommandMetadata : ICommandMetadata + internal ClassBasedCommandMetadata() { - internal ClassBasedCommandMetadata(Type commandType) + var commandHandlerType = typeof(TCommandHandler); + Name = commandHandlerType.GetFullCommandName(); + var commandAttribute = commandHandlerType.GetAttribute(); + if (commandAttribute != null) { - Name = commandType.GetFullCommandName(); - var commandAttribute = commandType.GetAttribute(); - if (commandAttribute != null) - { - Description = commandAttribute.GetLocalizedDescription(); - Usage = commandAttribute.GetLocalizedUsage(); - Samples = commandAttribute.Samples ?? new string[0]; - HideFromHelpListing = commandAttribute.HideFromHelpListing; - } + Description = commandAttribute.GetLocalizedDescription(); + Usage = commandAttribute.GetLocalizedUsage(); + Samples = commandAttribute.Samples ?? new string[0]; + HideFromHelpListing = commandAttribute.HideFromHelpListing; } + } - public string Name { get; } + public string Name { get; } - public string Description { get; } = string.Empty; + public string Description { get; } = string.Empty; - public string Usage { get; } = string.Empty; + public string Usage { get; } = string.Empty; - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] Samples { get; } = new string[0]; + public string[] Samples { get; } = []; - public bool HideFromHelpListing { get; } - } + public bool HideFromHelpListing { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObject.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObject.cs index 7bff3ce..7b835af 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObject.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObject.cs @@ -1,16 +1,20 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal class ClassBasedCommandObject : ICommandObject, IClassBasedCommandObject + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() { - internal class ClassBasedCommandObject: ICommandObject, IClassBasedCommandObject + internal ClassBasedCommandObject(TCommandHandler commandHandler, TCommandData commandData) { - internal ClassBasedCommandObject(ICommand command) - { - Command = command; - } - public Task ExecuteAsync() => Command.ExecuteAsync(); - - public ICommand Command { get; } + Command = commandHandler; + CommandData = commandData; } + public Task ExecuteAsync(CancellationToken cancellationToken) => Command.ExecuteAsync(CommandData, cancellationToken); + + public TCommandHandler Command { get; } + public TCommandData CommandData { get; } } diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObjectBuilder.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObjectBuilder.cs index 48231ca..9ee782f 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObjectBuilder.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandObjectBuilder.cs @@ -5,36 +5,39 @@ using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal class ClassBasedCommandObjectBuilder : CommandObjectBuilderBase + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() { - internal class ClassBasedCommandObjectBuilder : CommandObjectBuilderBase - { - private readonly ICommand _command; + private readonly TCommandData _commandData; + private readonly TCommandHandler _commandHandler; - internal ClassBasedCommandObjectBuilder(ICommandMetadata commandMetadata, IEnumerable commandOptionMetadatas, ICommand command) - :base(commandMetadata, commandOptionMetadatas.Select(metadata => - new ClassBasedCommandOption(metadata, command)).ToList()) - { - _command = command; - } + internal ClassBasedCommandObjectBuilder(ICommandMetadata commandMetadata, IEnumerable commandOptionMetadatas, TCommandHandler commandHandler, TCommandData commandData) + :base(commandMetadata, commandOptionMetadatas.Select(metadata => + new ClassBasedCommandOption(metadata, commandData)).ToList()) + { + _commandHandler = commandHandler; + _commandData = commandData; + } - public override void AddArguments(string argument) - { - _command.Arguments.Add(argument); - } + public override void AddArguments(string argument) + { + _commandData.Arguments.Add(argument); + } - public override ICommandObject GenerateCommandObject() => new ClassBasedCommandObject(_command); + public override ICommandObject GenerateCommandObject() => new ClassBasedCommandObject(_commandHandler, _commandData); - protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider) + protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider) + { + if(_commandData is HelpedCommandData commandBase && commandBase.Help) { - if(_command is CommandBase commandBase && commandBase.Help) - { - return true; - } - var validationContext = new ValidationContext(_command, null, null); - var isValid = Validator.TryValidateObject(_command, validationContext, validationResults, true); - return isValid; + return true; } - + var validationContext = new ValidationContext(_commandData, null, null); + var isValid = Validator.TryValidateObject(_commandData, validationContext, validationResults, true); + return isValid; } + } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOption.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOption.cs index ad3ff41..652c4aa 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOption.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOption.cs @@ -4,91 +4,93 @@ using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class ClassBasedCommandOption : ICommandOption { - internal sealed class ClassBasedCommandOption : ICommandOption - { - private readonly MethodInfo _miAddMethod; - private readonly ClassBasedCommandOptionMetadata _commandOptionMetadata; - private readonly ICommand _command; + private readonly MethodInfo _miAddMethod; + private readonly ClassBasedCommandOptionMetadata _commandOptionMetadata; + private readonly CommandData _commandData; - internal ClassBasedCommandOption(ClassBasedCommandOptionMetadata commandOptionMetadata, ICommand command) + internal ClassBasedCommandOption(ClassBasedCommandOptionMetadata commandOptionMetadata, CommandData commandData) + { + _commandOptionMetadata = commandOptionMetadata; + _commandData = commandData; + _miAddMethod = _commandOptionMetadata.PropertyOption.PropertyType.GetMethod("Add"); + if (!string.IsNullOrEmpty(Metadata.DefaultValue)) { - _commandOptionMetadata = commandOptionMetadata; - _command = command; - _miAddMethod = _commandOptionMetadata.PropertyOption.PropertyType.GetMethod("Add"); - if (!string.IsNullOrEmpty(Metadata.DefaultValue)) - { - AssignValue(Metadata.DefaultValue); - } + AssignValue(Metadata.DefaultValue); } + } - public ICommandOptionMetadata Metadata => _commandOptionMetadata; + public ICommandOptionMetadata Metadata => _commandOptionMetadata; - private Type OptionType => _commandOptionMetadata.OptionType; + private Type OptionType => _commandOptionMetadata.OptionType; - private object ConvertValue(object value) + private object? ConvertValue(object value) + { + if (value != null && !value.GetType().IsType(OptionType)) { - if (value != null && !value.GetType().IsType(OptionType)) - { - var convertedDefaultValue = _commandOptionMetadata.Converter.Convert(value.ToString(), OptionType); - return convertedDefaultValue; - } - return value; + var convertedDefaultValue = _commandOptionMetadata.Converter.Convert(value.ToString(), OptionType); + return convertedDefaultValue; } + return value; + } - public bool ShouldProvideValue => OptionType != typeof(bool); + public bool ShouldProvideValue => OptionType != typeof(bool); - public void AssignValue(string optionValue) + public void AssignValue(string optionValue) + { + if (!OptionType.IsType(_commandOptionMetadata.Converter.TargetType)) { - if (!OptionType.IsType(_commandOptionMetadata.Converter.TargetType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValidToAssignValue(OptionType, _commandOptionMetadata.Converter.TargetType)); - } + throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValidToAssignValue(OptionType, _commandOptionMetadata.Converter.TargetType)); + } - if (OptionType == typeof(bool) && optionValue == null) - { - optionValue = true.ToString(); - } - var convertedValue = ConvertValue(optionValue); + if (OptionType == typeof(bool) && optionValue == null) + { + optionValue = true.ToString(); + } + var convertedValue = ConvertValue(optionValue); + if (convertedValue != null) + { AssignValueInternal(convertedValue); } + } - private void AssignValueInternal(object convertedValue) + private void AssignValueInternal(object convertedValue) + { + if (!_commandOptionMetadata.PropertyOption.PropertyType.IsMultiValuedType()) { - if (!_commandOptionMetadata.PropertyOption.PropertyType.IsMultiValuedType()) + _commandOptionMetadata.PropertyOption.SetValue(_commandData, convertedValue, null); + } + else + { + if (_miAddMethod == null) { - _commandOptionMetadata.PropertyOption.SetValue(_command, convertedValue, null); + throw new InvalidOperationException(); } - else + var optionValue = _commandOptionMetadata.PropertyOption.GetValue(_commandData, null); + if (optionValue == null) { - if (_miAddMethod == null) - { - throw new InvalidOperationException(); - } - var optionValue = _commandOptionMetadata.PropertyOption.GetValue(_command, null); - if (optionValue == null) - { - if (_commandOptionMetadata.PropertyOption.CanWrite) - { - optionValue = Activator.CreateInstance(_commandOptionMetadata.PropertyOption.PropertyType); - _commandOptionMetadata.PropertyOption.SetValue(_command, optionValue, null); - } - else - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserMultiValueOptionIsNullAndHasNoSetter(_commandOptionMetadata.DisplayInfo.Name, _commandOptionMetadata.CommandMetadata.Name)); - } - } - if (_commandOptionMetadata.PropertyOption.PropertyType.IsCollectionType()) + if (_commandOptionMetadata.PropertyOption.CanWrite) { - _miAddMethod.Invoke(optionValue, new[] { convertedValue }); + optionValue = Activator.CreateInstance(_commandOptionMetadata.PropertyOption.PropertyType); + _commandOptionMetadata.PropertyOption.SetValue(_commandData, optionValue, null); } else { - var targetTupleValue = (KeyValuePair)convertedValue; - _miAddMethod.Invoke(_commandOptionMetadata.PropertyOption.GetValue(_command, null), new[] { targetTupleValue.Key, targetTupleValue.Value }); + throw new CommandLineParserException(Constants.ExceptionMessages.ParserMultiValueOptionIsNullAndHasNoSetter(_commandOptionMetadata.DisplayInfo.Name, _commandOptionMetadata.CommandMetadata.Name)); } } + if (_commandOptionMetadata.PropertyOption.PropertyType.IsCollectionType()) + { + _miAddMethod.Invoke(optionValue, new[] { convertedValue }); + } + else + { + var targetTupleValue = (KeyValuePair)convertedValue; + _miAddMethod.Invoke(_commandOptionMetadata.PropertyOption.GetValue(_commandData, null), new[] { targetTupleValue.Key, targetTupleValue.Value }); + } } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOptionMetadata.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOptionMetadata.cs index 05721a3..569d998 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOptionMetadata.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandOptionMetadata.cs @@ -4,57 +4,56 @@ using MGR.CommandLineParser.Extensibility.Command; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class ClassBasedCommandOptionMetadata : CommandOptionMetadataBase { - internal sealed class ClassBasedCommandOptionMetadata : CommandOptionMetadataBase + private ClassBasedCommandOptionMetadata(PropertyInfo propertyInfo, ICommandMetadata commandMetadata, List converters, IEnumerable optionAlternateNameGenerators) + :base(propertyInfo.ExtractIsRequiredMetadata(), + GetMultiValueIndicator(propertyInfo.PropertyType), + propertyInfo.ExtractOptionDisplayInfoMetadata(optionAlternateNameGenerators), + propertyInfo.ExtractDefaultValue()) { - private ClassBasedCommandOptionMetadata(PropertyInfo propertyInfo, ICommandMetadata commandMetadata, List converters, IEnumerable optionAlternateNameGenerators) - :base(propertyInfo.ExtractIsRequiredMetadata(), - GetMultiValueIndicator(propertyInfo.PropertyType), - propertyInfo.ExtractOptionDisplayInfoMetadata(optionAlternateNameGenerators), - propertyInfo.ExtractDefaultValue()) - { - PropertyOption = propertyInfo; - CommandMetadata = commandMetadata; - Converter = propertyInfo.ExtractConverter(converters, DisplayInfo.Name, CommandMetadata.Name); - } - internal IConverter Converter { get; } + PropertyOption = propertyInfo; + CommandMetadata = commandMetadata; + Converter = propertyInfo.ExtractConverter(converters, DisplayInfo.Name, CommandMetadata.Name); + } + internal IConverter Converter { get; } - internal PropertyInfo PropertyOption { get; } + internal PropertyInfo PropertyOption { get; } - internal ICommandMetadata CommandMetadata { get; } + internal ICommandMetadata CommandMetadata { get; } - internal Type OptionType + internal Type OptionType + { + get { - get + if (PropertyOption.PropertyType.IsMultiValuedType()) { - if (PropertyOption.PropertyType.IsMultiValuedType()) - { - return PropertyOption.PropertyType.GetUnderlyingCollectionType(); - } - return PropertyOption.PropertyType; + return PropertyOption.PropertyType.GetUnderlyingCollectionType() ?? throw new InvalidOperationException($"The property type ('{PropertyOption.PropertyType}') is multi-valued but is not collection-based."); } + return PropertyOption.PropertyType; } + } - internal static ClassBasedCommandOptionMetadata Create(PropertyInfo propertyInfo, ICommandMetadata commandMetadata, List converters, IEnumerable optionAlternateNameGenerators) - { - Guard.NotNull(propertyInfo, nameof(propertyInfo)); - Guard.NotNull(commandMetadata, nameof(commandMetadata)); - Guard.NotNull(converters, nameof(converters)); - Guard.NotNull(optionAlternateNameGenerators, nameof(optionAlternateNameGenerators)); + internal static ClassBasedCommandOptionMetadata? Create(PropertyInfo propertyInfo, ICommandMetadata commandMetadata, List converters, IEnumerable optionAlternateNameGenerators) + { + Guard.NotNull(propertyInfo, nameof(propertyInfo)); + Guard.NotNull(commandMetadata, nameof(commandMetadata)); + Guard.NotNull(converters, nameof(converters)); + Guard.NotNull(optionAlternateNameGenerators, nameof(optionAlternateNameGenerators)); - if (propertyInfo.ShouldBeIgnored()) - { - return null; - } - if (!propertyInfo.IsValidOptionProperty()) - { - throw new CommandLineParserException( - Constants.ExceptionMessages.ParserExtractMetadataPropertyShouldBeWritableOrICollection( - propertyInfo.Name, commandMetadata.Name)); - } - var commandOption = new ClassBasedCommandOptionMetadata(propertyInfo, commandMetadata, converters, optionAlternateNameGenerators); - return commandOption; + if (propertyInfo.ShouldBeIgnored()) + { + return null; + } + if (!propertyInfo.IsValidOptionProperty()) + { + throw new CommandLineParserException( + Constants.ExceptionMessages.ParserExtractMetadataPropertyShouldBeWritableOrICollection( + propertyInfo.Name, commandMetadata.Name)); } + var commandOption = new ClassBasedCommandOptionMetadata(propertyInfo, commandMetadata, converters, optionAlternateNameGenerators); + return commandOption; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType.cs index d638732..b51e2a0 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType.cs @@ -1,62 +1,34 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.Command; using MGR.CommandLineParser.Extensibility.Converters; -using Microsoft.Extensions.DependencyInjection; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class ClassBasedCommandType : ICommandType { - internal sealed class ClassBasedCommandType : ICommandType + private readonly ICommandType _typedClassBasedCommandType; + + internal ClassBasedCommandType(Type commandHandlerType, IEnumerable converters, IEnumerable optionAlternateNameGenerators) { - private readonly Lazy _commandMetadata; - private readonly Lazy> _commandOptions; - - internal ClassBasedCommandType(Type commandType, IEnumerable converters, IEnumerable optionAlternateNameGenerators) - { - Type = commandType; - _commandMetadata = new Lazy(() => new ClassBasedCommandMetadata(Type)); - _commandOptions = new Lazy>(() => new List(ExtractCommandOptions(Type, Metadata, converters.ToList(), optionAlternateNameGenerators.ToList()))); - - } - - [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] - internal Type Type { get; } - - public ICommandMetadata Metadata => _commandMetadata.Value; - - public IEnumerable Options => _commandOptions.Value; - - public ICommandObjectBuilder CreateCommandObjectBuilder(IServiceProvider serviceProvider) - { - Guard.NotNull(serviceProvider, nameof(serviceProvider)); - - var commandActivator = serviceProvider.GetRequiredService(); - var command = commandActivator.ActivateCommand(Type); - if (command == null) - { - return null; - } - var commandObject = new ClassBasedCommandObjectBuilder(Metadata, _commandOptions.Value, command); - - var commandBase = command as CommandBase; - commandBase?.Configure(this); - return commandObject; - } - - private static IEnumerable ExtractCommandOptions(Type commandType, ICommandMetadata commandMetadata, List converters, List optionAlternateNameGenerators) - { - foreach (var propertyInfo in commandType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(pi => pi.Name != nameof(ICommand.Arguments))) - { - var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, converters, optionAlternateNameGenerators); - if (commandOption != null) - { - yield return commandOption; - } - } - } + Type = commandHandlerType; + var concreteClassBasedCommandType = typeof(ClassBasedCommandType<,>).MakeGenericType(commandHandlerType, commandHandlerType.GetInterfaces() + .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICommandHandler<>)) + .GetGenericArguments() + .Single()); + _typedClassBasedCommandType = (ICommandType)Activator.CreateInstance(concreteClassBasedCommandType, BindingFlags.Instance | BindingFlags.NonPublic, null, [converters, optionAlternateNameGenerators], null); + } + + internal Type Type { get; } + + public ICommandMetadata Metadata => _typedClassBasedCommandType.Metadata; + + public IEnumerable Options => _typedClassBasedCommandType.Options; + + public ICommandObjectBuilder? CreateCommandObjectBuilder(IServiceProvider serviceProvider) + => _typedClassBasedCommandType.CreateCommandObjectBuilder(serviceProvider); } diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType`2.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType`2.cs new file mode 100644 index 0000000..5b06356 --- /dev/null +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedCommandType`2.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using MGR.CommandLineParser.Command; +using MGR.CommandLineParser.Extensibility.Command; +using MGR.CommandLineParser.Extensibility.Converters; +using Microsoft.Extensions.DependencyInjection; + +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class ClassBasedCommandType : ICommandType + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() +{ + private readonly Lazy _commandMetadata; + private readonly Lazy> _commandOptions; + + internal ClassBasedCommandType(IEnumerable converters, IEnumerable optionAlternateNameGenerators) + { + _commandMetadata = new Lazy(() => new ClassBasedCommandMetadata()); + _commandOptions = new Lazy>(() => new List(ExtractCommandOptions(Metadata, converters.ToList(), optionAlternateNameGenerators.ToList()))); + + } + + public ICommandMetadata Metadata => _commandMetadata.Value; + + public IEnumerable Options => _commandOptions.Value; + + public ICommandObjectBuilder? CreateCommandObjectBuilder(IServiceProvider serviceProvider) + { + Guard.NotNull(serviceProvider, nameof(serviceProvider)); + + var commandActivator = serviceProvider.GetRequiredService(); + var commandHandler = commandActivator.ActivateCommand(); + if (commandHandler == null) + { + return null; + } + var commandData = new TCommandData(); + var commandObject = new ClassBasedCommandObjectBuilder(Metadata, _commandOptions.Value, commandHandler, commandData); + commandData.Configure(this); + return commandObject; + } + + private static IEnumerable ExtractCommandOptions(ICommandMetadata commandMetadata, List converters, List optionAlternateNameGenerators) + { + var commandDataType = typeof(TCommandData); + foreach (var propertyInfo in commandDataType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(pi => pi.Name != nameof(CommandData.Arguments))) + { + var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, converters, optionAlternateNameGenerators); + if (commandOption != null) + { + yield return commandOption; + } + } + } +} diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedDependencyResolverCommandActivator.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedDependencyResolverCommandActivator.cs index d78d28d..cc6dd0f 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedDependencyResolverCommandActivator.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedDependencyResolverCommandActivator.cs @@ -3,61 +3,67 @@ using System.Reflection; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Implementation of based on . +/// +public sealed class ClassBasedDependencyResolverCommandActivator : IClassBasedCommandActivator { + private readonly IServiceProvider _serviceProvider; + /// - /// Implementation of based on . + /// Creates a new instance of . /// - public sealed class ClassBasedDependencyResolverCommandActivator : IClassBasedCommandActivator + public ClassBasedDependencyResolverCommandActivator(IServiceProvider serviceProvider) { - private readonly IServiceProvider _serviceProvider; - - /// - /// Creates a new instance of . - /// - public ClassBasedDependencyResolverCommandActivator(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } + _serviceProvider = serviceProvider; + } - /// - public ICommand ActivateCommand(Type commandType) + /// + public TCommandHandler ActivateCommand() + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var commandType = typeof(TCommandHandler); + var commandInstance = _serviceProvider.GetService(commandType); + if (commandInstance == null) { - var commandInstance = _serviceProvider.GetService(commandType); - if (commandInstance == null) + var constructors = commandType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .OrderBy(constructor => constructor.GetParameters().Length); + foreach (var constructorInfo in constructors) { - var constructors = commandType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .OrderBy(constructor => constructor.GetParameters().Length); - foreach (var constructorInfo in constructors) + try { - try + var parameterInfos = constructorInfo.GetParameters(); + var parameters = new object?[parameterInfos.Length]; + for (var i = 0; i < parameterInfos.Length; i++) { - var parameterInfos = constructorInfo.GetParameters(); - var parameters = new object[parameterInfos.Length]; - for (int i = 0; i < parameterInfos.Length; i++) + var parameterInfo = parameterInfos[i]; + var parameterValue = _serviceProvider.GetService(parameterInfo.ParameterType); + if (parameterValue != null || parameterInfo.TryGetDefaultValue(out parameterValue)) { - var parameterInfo = parameterInfos[i]; - var parameterValue = _serviceProvider.GetService(parameterInfo.ParameterType); - if (parameterValue != null || parameterInfo.TryGetDefaultValue(out parameterValue)) - { - parameters[i] = parameterValue; - } - } - - commandInstance = constructorInfo.Invoke(parameters); - if (commandInstance != null) - { - break; + parameters[i] = parameterValue; } } - catch + + commandInstance = constructorInfo.Invoke(parameters); + if (commandInstance != null) { - // ignored: this is normal: we try to instantiate a command with each constructor. + break; } } + catch + { + // ignored: this is normal: we try to instantiate a command with each constructor. + } } - var command = commandInstance as ICommand; - return command; } + if(commandInstance == null) + { + throw new InvalidOperationException($"No constructor found for the command {commandType.FullName}"); + } + var command = (TCommandHandler)commandInstance; + return command; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedOptionDisplayInfo.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedOptionDisplayInfo.cs index ae7d337..bf41d4e 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedOptionDisplayInfo.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/ClassBasedOptionDisplayInfo.cs @@ -2,42 +2,39 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +[DebuggerDisplay("ClassBased:Name={Name};ShortName={ShortName}")] +internal sealed class ClassBasedOptionDisplayInfo : IOptionDisplayInfo { - [DebuggerDisplay("ClassBased:Name={Name};ShortName={ShortName}")] - internal sealed class ClassBasedOptionDisplayInfo : IOptionDisplayInfo + internal ClassBasedOptionDisplayInfo(PropertyInfo propertyInfo, IEnumerable optionAlternateNameGenerators) { - internal ClassBasedOptionDisplayInfo(PropertyInfo propertyInfo, IEnumerable optionAlternateNameGenerators) - { - Guard.NotNull(propertyInfo, nameof(propertyInfo)); - var displayAttribute = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute; - Name = displayAttribute?.GetName() ?? propertyInfo.Name.AsKebabCase(); - ShortName = displayAttribute?.GetShortName() ?? string.Empty; - Description = displayAttribute?.GetDescription() ?? string.Empty; + Guard.NotNull(propertyInfo, nameof(propertyInfo)); + var displayAttribute = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute; + Name = displayAttribute?.GetName() ?? propertyInfo.Name.AsKebabCase(); + ShortName = displayAttribute?.GetShortName() ?? string.Empty; + Description = displayAttribute?.GetDescription() ?? string.Empty; - AlternateNames = optionAlternateNameGenerators.SelectMany( - generator => generator.GenerateAlternateNames(propertyInfo)) - .Distinct(StringComparer.CurrentCultureIgnoreCase) - .Where(alternateName => !alternateName.Equals(Name, StringComparison.CurrentCultureIgnoreCase)) - .ToList(); - } + AlternateNames = optionAlternateNameGenerators.SelectMany( + generator => generator.GenerateAlternateNames(propertyInfo)) + .Distinct(StringComparer.CurrentCultureIgnoreCase) + .Where(alternateName => !alternateName.Equals(Name, StringComparison.CurrentCultureIgnoreCase)) + .ToList(); + } - /// - public string Name { get; } + /// + public string Name { get; } - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public IEnumerable AlternateNames { get; } + /// + public IEnumerable AlternateNames { get; } - /// - public string ShortName { get; } + /// + public string ShortName { get; } - /// - public string Description { get; } - } + /// + public string Description { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/CurrentDirectoryAssemblyProvider.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/CurrentDirectoryAssemblyProvider.cs index fcd77b3..eeae240 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/CurrentDirectoryAssemblyProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/CurrentDirectoryAssemblyProvider.cs @@ -1,25 +1,20 @@ -using System.Diagnostics.CodeAnalysis; -using System.IO; -using JetBrains.Annotations; +using System.IO; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Implementation of for providing all files (*.dll and *.exe) in the current folder NOT recursively (this is the current default implementation). +/// +public sealed class CurrentDirectoryAssemblyProvider : AssemblyProviderBase { /// - /// Implementation of for providing all files (*.dll and *.exe) in the current folder NOT recursively (this is the current default implementation). + /// Gets the singleton instance of . + /// + public static readonly IAssemblyProvider Instance = new CurrentDirectoryAssemblyProvider(); + /// + /// Create a new . /// - public sealed class CurrentDirectoryAssemblyProvider : AssemblyProviderBase - { - /// - /// Gets the singleton instance of . - /// - [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - [PublicAPI, NotNull] - public static readonly IAssemblyProvider Instance = new CurrentDirectoryAssemblyProvider(); - /// - /// Create a new . - /// - /// - protected override SearchOption SearchOption => SearchOption.TopDirectoryOnly; - } + /// + protected override SearchOption SearchOption => SearchOption.TopDirectoryOnly; } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/DefaultAssemblyProvider.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/DefaultAssemblyProvider.cs index d160741..d1b7049 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/DefaultAssemblyProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/DefaultAssemblyProvider.cs @@ -1,20 +1,19 @@ using System.Collections.Generic; using System.Reflection; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +internal sealed class DefaultAssemblyProvider : IAssemblyProvider { - internal sealed class DefaultAssemblyProvider : IAssemblyProvider - { - private readonly Assembly _assembly; + private readonly Assembly _assembly; - internal DefaultAssemblyProvider(Assembly assembly) - { - _assembly = assembly; - } + internal DefaultAssemblyProvider(Assembly assembly) + { + _assembly = assembly; + } - public IEnumerable GetAssembliesToBrowse() - { - yield return _assembly; - } + public IEnumerable GetAssembliesToBrowse() + { + yield return _assembly; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/IAssemblyProvider.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/IAssemblyProvider.cs index fb5a152..d99a7e5 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/IAssemblyProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/IAssemblyProvider.cs @@ -1,21 +1,16 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Reflection; -using JetBrains.Annotations; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Defines the contract for the provider of assemblies to load, used by . +/// +public interface IAssemblyProvider { /// - /// Defines the contract for the provider of assemblies to load, used by . + /// Returns the list of the files to load. /// - public interface IAssemblyProvider - { - /// - /// Returns the list of the files to load. - /// - /// A list of path. - [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] - [NotNull, ItemNotNull] - IEnumerable GetAssembliesToBrowse(); - } + /// A list of path. + IEnumerable GetAssembliesToBrowse(); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandActivator.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandActivator.cs index fd56acc..1f1151f 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandActivator.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandActivator.cs @@ -1,19 +1,19 @@ -using System; -using JetBrains.Annotations; -using MGR.CommandLineParser.Command; +using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Defines the contract for the activator of . +/// +public interface IClassBasedCommandActivator { /// - /// Defines the contract for the activator of . + /// Activates (create an instance) of a . /// - public interface IClassBasedCommandActivator - { - /// - /// Activates (create an instance) of a . - /// - /// The type of the command. - /// The command. - ICommand ActivateCommand([NotNull] Type commandType); - } + /// The type of the command handler. + /// The type of the command data. + /// The command handler. + TCommandHandler ActivateCommand() + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new(); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandObject.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandObject.cs index f06c7e0..ace52df 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandObject.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/IClassBasedCommandObject.cs @@ -1,15 +1,22 @@ using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Represents an interface that allow accessing to the raw instance. +/// +/// The type of the . +/// The type of the . +public interface IClassBasedCommandObject + where TCommandHandler : class, ICommandHandler +where TCommandData : CommandData, new() { /// - /// Represents an interface that allow accessing to the raw instance. + /// Gets the raw instance for the . + /// + TCommandHandler Command { get; } + /// + /// Gets the data associated with the current parsing session. /// - public interface IClassBasedCommandObject - { - /// - /// Gets the raw instance for the . - /// - ICommand Command { get; } - } + TCommandData CommandData { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/IPropertyOptionAlternateNameGenerator.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/IPropertyOptionAlternateNameGenerator.cs index d0e30db..bde1cb4 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/IPropertyOptionAlternateNameGenerator.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/IPropertyOptionAlternateNameGenerator.cs @@ -1,18 +1,17 @@ using System.Collections.Generic; using System.Reflection; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Defines the contract for the generation of alternate names. +/// +public interface IPropertyOptionAlternateNameGenerator { /// - /// Defines the contract for the generation of alternate names. + /// Gets the alternate names for an option. /// - public interface IPropertyOptionAlternateNameGenerator - { - /// - /// Gets the alternate names for an option. - /// - /// The for the option. - /// The alternate names for the option. - IEnumerable GenerateAlternateNames(PropertyInfo propertyInfo); - } + /// The for the option. + /// The alternate names for the option. + IEnumerable GenerateAlternateNames(PropertyInfo propertyInfo); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/ClassBased/RecursiveAssemblyProvider.cs b/src/MGR.CommandLineParser/Extensibility/ClassBased/RecursiveAssemblyProvider.cs index c467f09..3f8827d 100644 --- a/src/MGR.CommandLineParser/Extensibility/ClassBased/RecursiveAssemblyProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/ClassBased/RecursiveAssemblyProvider.cs @@ -1,23 +1,18 @@ -using System.Diagnostics.CodeAnalysis; -using System.IO; -using JetBrains.Annotations; +using System.IO; -namespace MGR.CommandLineParser.Extensibility.ClassBased +namespace MGR.CommandLineParser.Extensibility.ClassBased; + +/// +/// Implementation of for providing all files (*.dll and *.exe) in the current folder recursively. +/// +public sealed class RecursiveAssemblyProvider : AssemblyProviderBase { /// - /// Implementation of for providing all files (*.dll and *.exe) in the current folder recursively. + /// Gets the singleton instance of . /// - public sealed class RecursiveAssemblyProvider : AssemblyProviderBase - { - /// - /// Gets the singleton instance of . - /// - [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] - [PublicAPI, NotNull] - public static readonly IAssemblyProvider Instance = new RecursiveAssemblyProvider(); - private RecursiveAssemblyProvider() { } + public static readonly IAssemblyProvider Instance = new RecursiveAssemblyProvider(); + private RecursiveAssemblyProvider() { } - /// - protected override SearchOption SearchOption => SearchOption.AllDirectories; - } + /// + protected override SearchOption SearchOption => SearchOption.AllDirectories; } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/CombinedCommandOption.cs b/src/MGR.CommandLineParser/Extensibility/Command/CombinedCommandOption.cs index 6fc75e3..92ddd7c 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/CombinedCommandOption.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/CombinedCommandOption.cs @@ -2,54 +2,53 @@ using System.Collections.Generic; using System.Linq; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents an that combines a collection of . +/// +/// This class can be used to combined options together (for example boolean options). +public class CombinedCommandOption : ICommandOption { + private readonly string _commandName; + private readonly IEnumerable _commandOptions; + private readonly string _optionName; /// - /// Represents an that combines a collection of . + /// Create an instance of . /// - /// This class can be used to combined options together (for example boolean options). - public class CombinedCommandOption : ICommandOption + /// The name of the option used in the command line. + /// The name of the command being parsed. + /// The that are combined together. + public CombinedCommandOption(string optionName, string commandName, IEnumerable commandOptions) { - private readonly string _commandName; - private readonly IEnumerable _commandOptions; - private readonly string _optionName; - /// - /// Create an instance of . - /// - /// The name of the option used in the command line. - /// The name of the command being parsed. - /// The that are combined together. - public CombinedCommandOption(string optionName, string commandName, IEnumerable commandOptions) - { - _commandOptions = commandOptions; - _optionName = optionName; - _commandName = commandName; - } + _commandOptions = commandOptions; + _optionName = optionName; + _commandName = commandName; + } - /// - public bool ShouldProvideValue => _commandOptions.Aggregate(false, (optionalValue, commandOption) => optionalValue || commandOption.ShouldProvideValue); + /// + public bool ShouldProvideValue => _commandOptions.Aggregate(false, (optionalValue, commandOption) => optionalValue || commandOption.ShouldProvideValue); - /// - public void AssignValue(string optionValue) + /// + public void AssignValue(string optionValue) + { + if (ShouldProvideValue && optionValue == null) { - if (ShouldProvideValue && optionValue == null) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatParserOptionValueRequired(_commandName, _optionName)); - } - - foreach (var commandOption in _commandOptions) - { - commandOption.AssignValue(optionValue); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatParserOptionValueRequired(_commandName, _optionName)); } - /// - /// Always throws an because the cannot be combined. - /// - /// - public ICommandOptionMetadata Metadata + foreach (var commandOption in _commandOptions) { - get { throw new InvalidOperationException(); } + commandOption.AssignValue(optionValue); } } + + /// + /// Always throws an because the cannot be combined. + /// + /// + public ICommandOptionMetadata Metadata + { + get { throw new InvalidOperationException(); } + } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/CommandObjectBuilderBase.cs b/src/MGR.CommandLineParser/Extensibility/Command/CommandObjectBuilderBase.cs index b13ea9f..4db7905 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/CommandObjectBuilderBase.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/CommandObjectBuilderBase.cs @@ -6,122 +6,121 @@ using MGR.CommandLineParser.Properties; using Microsoft.Extensions.DependencyInjection; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +///Represents a basic implementation for that provide implementation for retrieving (potentially combined for boolean options) and validation (especially writing of validation errors). +/// +public abstract class CommandObjectBuilderBase : ICommandObjectBuilder +where TCommandOption : ICommandOption { /// - ///Represents a basic implementation for that provide implementation for retrieving (potentially combined for boolean options) and validation (especially writing of validation errors). + ///Gets the metadata of the command being build. /// - public abstract class CommandObjectBuilderBase : ICommandObjectBuilder - where TCommandOption : ICommandOption - { - /// - ///Gets the metadata of the command being build. - /// - protected ICommandMetadata CommandMetadata { get; } + protected ICommandMetadata CommandMetadata { get; } - /// - ///Gets the list of options of the command being build. - /// - protected IEnumerable CommandOptions { get; } + /// + ///Gets the list of options of the command being build. + /// + protected IEnumerable CommandOptions { get; } - /// - /// Initializes a new instance of . - /// - /// The command metadata. - /// The command's options. - protected CommandObjectBuilderBase(ICommandMetadata commandMetadata, IEnumerable commandOptions) - { - CommandMetadata = commandMetadata; - CommandOptions = commandOptions; - } + /// + /// Initializes a new instance of . + /// + /// The command metadata. + /// The command's options. + protected CommandObjectBuilderBase(ICommandMetadata commandMetadata, IEnumerable commandOptions) + { + CommandMetadata = commandMetadata; + CommandOptions = commandOptions; + } - /// - public abstract void AddArguments(string argument); + /// + public abstract void AddArguments(string argument); - /// - public virtual ICommandOption FindOption(string optionName) + /// + public virtual ICommandOption? FindOption(string optionName) + { + var commandOption = CommandOptions.FirstOrDefault(option => option.Metadata.DisplayInfo.Name.Equals(optionName, StringComparison.Ordinal)); + if (commandOption != null) { - var commandOption = CommandOptions.FirstOrDefault(option => option.Metadata.DisplayInfo.Name.Equals(optionName, StringComparison.Ordinal)); - if (commandOption != null) - { - return commandOption; - } - var alternateOption = CommandOptions.FirstOrDefault(option => option.Metadata.DisplayInfo.AlternateNames.Any(alternateName => alternateName.Equals(optionName, StringComparison.Ordinal))); - return alternateOption; + return commandOption; } + var alternateOption = CommandOptions.FirstOrDefault(option => option.Metadata.DisplayInfo.AlternateNames.Any(alternateName => alternateName.Equals(optionName, StringComparison.Ordinal))); + return alternateOption; + } - /// - public virtual ICommandOption FindOptionByShortName(string optionShortName) + /// + public virtual ICommandOption? FindOptionByShortName(string optionShortName) + { + var shortOption = CommandOptions.FirstOrDefault(option => (option.Metadata.DisplayInfo.ShortName ?? string.Empty).Equals(optionShortName, StringComparison.Ordinal)); + if (shortOption != null) { - var shortOption = CommandOptions.FirstOrDefault(option => (option.Metadata.DisplayInfo.ShortName ?? string.Empty).Equals(optionShortName, StringComparison.Ordinal)); - if (shortOption != null) - { - return shortOption; - } - return FindCombinedBooleanOptionsByShortName(optionShortName); + return shortOption; } + return FindCombinedBooleanOptionsByShortName(optionShortName); + } - /// - public abstract ICommandObject GenerateCommandObject(); + /// + public abstract ICommandObject GenerateCommandObject(); - /// - public virtual CommandValidationResult Validate(IServiceProvider serviceProvider) + /// + public virtual CommandValidationResult Validate(IServiceProvider serviceProvider) + { + var results = new List(); + var isCommandValid = DoValidate(results, serviceProvider); + if (!isCommandValid) { - var results = new List(); - var isCommandValid = DoValidate(results, serviceProvider); - if (!isCommandValid) - { - var console = serviceProvider.GetRequiredService(); - WriteErrorsToConsole(console, results); - } - return new CommandValidationResult(isCommandValid, results); + var console = serviceProvider.GetRequiredService(); + WriteErrorsToConsole(console, results); } + return new CommandValidationResult(isCommandValid, results); + } - /// - /// Perform the validation of the command. - /// - /// The list of validation errors to populate. - /// The current that can be used to gets services. - /// true if the command being build is valid, false elsewhere. - protected virtual bool DoValidate(List validationResults, IServiceProvider serviceProvider) => true; + /// + /// Perform the validation of the command. + /// + /// The list of validation errors to populate. + /// The current that can be used to gets services. + /// true if the command being build is valid, false elsewhere. + protected virtual bool DoValidate(List validationResults, IServiceProvider serviceProvider) => true; - /// - /// Write the validation errors to the current . - /// - /// The to write to. - /// the validation errors to write to the . - protected void WriteErrorsToConsole(IConsole console, List results) + /// + /// Write the validation errors to the current . + /// + /// The to write to. + /// the validation errors to write to the . + protected void WriteErrorsToConsole(IConsole console, List results) + { + console.WriteError(Strings.Parser_CommandInvalidArgumentsFormat, CommandMetadata.Name); + foreach (var validation in results) { - console.WriteError(Strings.Parser_CommandInvalidArgumentsFormat, CommandMetadata.Name); - foreach (var validation in results) + console.WriteError(string.Format(CultureInfo.CurrentUICulture, "-{0} :", validation.ErrorMessage)); + foreach (var memberName in validation.MemberNames) { - console.WriteError(string.Format(CultureInfo.CurrentUICulture, "-{0} :", validation.ErrorMessage)); - foreach (var memberName in validation.MemberNames) - { - console.WriteError(string.Format(CultureInfo.CurrentUICulture, " -{0}", memberName)); - } + console.WriteError(string.Format(CultureInfo.CurrentUICulture, " -{0}", memberName)); } - console.WriteLine(); } + console.WriteLine(); + } - private ICommandOption FindCombinedBooleanOptionsByShortName(string optionShortName) + private ICommandOption? FindCombinedBooleanOptionsByShortName(string optionShortName) + { + var shortName = optionShortName; + var options = new List(); + while (!string.IsNullOrEmpty(shortName)) { - var shortName = optionShortName; - var options = new List(); - while (!string.IsNullOrEmpty(shortName)) + var shortOption = CommandOptions.FirstOrDefault(option => !string.IsNullOrEmpty(option.Metadata.DisplayInfo.ShortName) && shortName.StartsWith(option.Metadata.DisplayInfo.ShortName, StringComparison.Ordinal)); + if (shortOption != null) + { + options.Add(shortOption); + shortName = shortName.Substring(shortOption.Metadata.DisplayInfo.ShortName.Length); + } + else { - var shortOption = CommandOptions.FirstOrDefault(option => !string.IsNullOrEmpty(option.Metadata.DisplayInfo.ShortName) && shortName.StartsWith(option.Metadata.DisplayInfo.ShortName, StringComparison.Ordinal)); - if (shortOption != null) - { - options.Add(shortOption); - shortName = shortName.Substring(shortOption.Metadata.DisplayInfo.ShortName.Length); - } - else - { - return null; - } + return null; } - return new CombinedCommandOption(optionShortName, CommandMetadata.Name, options); } + return new CombinedCommandOption(optionShortName, CommandMetadata.Name, options); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionCollectionType.cs b/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionCollectionType.cs index 254a947..4ee93e3 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionCollectionType.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionCollectionType.cs @@ -1,23 +1,22 @@ -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// The different types of collection that an command's option can be. +/// +public enum CommandOptionCollectionType { /// - /// The different types of collection that an command's option can be. + /// Not a collection. /// - public enum CommandOptionCollectionType - { - /// - /// Not a collection. - /// - None = 0, + None = 0, - /// - /// A simple collection. - /// - Collection = 1, + /// + /// A simple collection. + /// + Collection = 1, - /// - /// A dictionary. - /// - Dictionary = 2 - } + /// + /// A dictionary. + /// + Dictionary = 2 } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionMetadataBase.cs b/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionMetadataBase.cs index d10f28c..2dd4ac9 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionMetadataBase.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/CommandOptionMetadataBase.cs @@ -1,58 +1,57 @@ using System; using System.Diagnostics; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents a base container for . +/// + +[DebuggerDisplay("Option {DisplayInfo.Name}, default value: {DefaultValue}")] +public abstract class CommandOptionMetadataBase : ICommandOptionMetadata { /// - /// Represents a base container for . + /// Creates a new instance of . /// - - [DebuggerDisplay("Option {DisplayInfo.Name}, default value: {DefaultValue}")] - public abstract class CommandOptionMetadataBase : ICommandOptionMetadata + /// Indicates if the option is required. + /// Indicates the type of collection of the option. + /// The of the option. + /// The default value of the option. + protected CommandOptionMetadataBase(bool isRequired, CommandOptionCollectionType collectionType, IOptionDisplayInfo displayInfo, string defaultValue) { - /// - /// Creates a new instance of . - /// - /// Indicates if the option is required. - /// Indicates the type of collection of the option. - /// The of the option. - /// The default value of the option. - protected CommandOptionMetadataBase(bool isRequired, CommandOptionCollectionType collectionType, IOptionDisplayInfo displayInfo, string defaultValue) - { - IsRequired = isRequired; - CollectionType = collectionType; - DisplayInfo = displayInfo; - DefaultValue = defaultValue; - } + IsRequired = isRequired; + CollectionType = collectionType; + DisplayInfo = displayInfo; + DefaultValue = defaultValue; + } - /// - public bool IsRequired { get; } + /// + public bool IsRequired { get; } - /// - public CommandOptionCollectionType CollectionType { get; } + /// + public CommandOptionCollectionType CollectionType { get; } - /// - public IOptionDisplayInfo DisplayInfo { get; } + /// + public IOptionDisplayInfo DisplayInfo { get; } - /// - public string DefaultValue { get; } + /// + public string DefaultValue { get; } - /// - /// Compute the based on the of the option. - /// - /// The of the option. - /// The . - protected static CommandOptionCollectionType GetMultiValueIndicator(Type type) + /// + /// Compute the based on the of the option. + /// + /// The of the option. + /// The . + protected static CommandOptionCollectionType GetMultiValueIndicator(Type type) + { + if (type.IsDictionaryType()) + { + return CommandOptionCollectionType.Dictionary; + } + if (type.IsCollectionType()) { - if (type.IsDictionaryType()) - { - return CommandOptionCollectionType.Dictionary; - } - if (type.IsCollectionType()) - { - return CommandOptionCollectionType.Collection; - } - return CommandOptionCollectionType.None; + return CommandOptionCollectionType.Collection; } + return CommandOptionCollectionType.None; } } diff --git a/src/MGR.CommandLineParser/Extensibility/Command/CommandValidationResult.cs b/src/MGR.CommandLineParser/Extensibility/Command/CommandValidationResult.cs index 2075e41..f85e3fd 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/CommandValidationResult.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/CommandValidationResult.cs @@ -1,31 +1,30 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents the result of the validation of a command. +/// +public class CommandValidationResult { /// - /// Represents the result of the validation of a command. + /// Creates a new instance of . /// - public class CommandValidationResult + /// Specify if the validation pass or not. + /// The list of validation errors. + public CommandValidationResult(bool isValid, IEnumerable validationErrors) { - /// - /// Creates a new instance of . - /// - /// Specify if the validation pass or not. - /// The list of validation errors. - public CommandValidationResult(bool isValid, IEnumerable validationErrors) - { - IsValid = isValid; - ValidationErrors = validationErrors; - } - /// - /// Gets true if the validation pass, false elsewhere. - /// - public bool IsValid { get; } - - /// - /// Gets the validation errors. - /// - public IEnumerable ValidationErrors { get; } + IsValid = isValid; + ValidationErrors = validationErrors; } + /// + /// Gets true if the validation pass, false elsewhere. + /// + public bool IsValid { get; } + + /// + /// Gets the validation errors. + /// + public IEnumerable ValidationErrors { get; } } diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandMetadata.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandMetadata.cs index 7a24d5b..0dc83ca 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandMetadata.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandMetadata.cs @@ -1,36 +1,32 @@ -using System.Diagnostics.CodeAnalysis; +namespace MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility.Command +/// +/// Represents the metadata of a command. +/// +public interface ICommandMetadata { /// - /// Represents the metadata of a command. + /// Gets the name of the command. /// - public interface ICommandMetadata - { - /// - /// Gets the name of the command. - /// - string Name { get; } + string Name { get; } - /// - /// Gets the description of the command (if defined). - /// - string Description { get; } + /// + /// Gets the description of the command (if defined). + /// + string Description { get; } - /// - /// Gets the usage of the command (if defined). - /// - string Usage { get; } + /// + /// Gets the usage of the command (if defined). + /// + string Usage { get; } - /// - /// Gets the samples for the command. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - string[] Samples { get; } + /// + /// Gets the samples for the command. + /// + string[] Samples { get; } - /// - /// Determine if the command should be hidden from the help listing. - /// - bool HideFromHelpListing { get; } - } + /// + /// Determine if the command should be hidden from the help listing. + /// + bool HideFromHelpListing { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandObjectBuilder.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandObjectBuilder.cs index 1dcccab..cdbb12d 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandObjectBuilder.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandObjectBuilder.cs @@ -1,42 +1,41 @@  using System; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Encapsulates a command +/// +public interface ICommandObjectBuilder { /// - /// Encapsulates a command + /// + /// + /// + void AddArguments(string argument); + /// + /// Find an option based on its name. + /// + /// The name (short or long form) of the option. + /// The representing the option of the command. + ICommandOption? FindOption(string optionName); + /// + /// Find an option based on its short name. /// - public interface ICommandObjectBuilder - { - /// - /// - /// - /// - void AddArguments(string argument); - /// - /// Find an option based on its name. - /// - /// The name (short or long form) of the option. - /// The representing the option of the command. - ICommandOption FindOption(string optionName); - /// - /// Find an option based on its short name. - /// - /// The short name of the option. - /// The representing the option of the command. - ICommandOption FindOptionByShortName(string optionShortName); + /// The short name of the option. + /// The representing the option of the command. + ICommandOption? FindOptionByShortName(string optionShortName); - /// - /// Generate the command object representing the command being parsed. - /// - /// An object representing the parsed command. - ICommandObject GenerateCommandObject(); + /// + /// Generate the command object representing the command being parsed. + /// + /// An object representing the parsed command. + ICommandObject GenerateCommandObject(); - /// - /// Validates the command after having been parsed, and before being used. - /// - /// The current . - /// The result of the validation of the command. - CommandValidationResult Validate(IServiceProvider serviceProvider); - } + /// + /// Validates the command after having been parsed, and before being used. + /// + /// The current . + /// The result of the validation of the command. + CommandValidationResult Validate(IServiceProvider serviceProvider); } diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandOption.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandOption.cs index 992417e..07915e9 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandOption.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandOption.cs @@ -1,26 +1,25 @@  -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents a command's option. +/// +public interface ICommandOption { /// - /// Represents a command's option. + /// Defines if a value should be provided when assigned to the command's option /// - public interface ICommandOption - { - /// - /// Defines if a value should be provided when assigned to the command's option - /// - /// This is the case for the for example, where no value indicates a true value. - bool ShouldProvideValue { get; } + /// This is the case for the for example, where no value indicates a true value. + bool ShouldProvideValue { get; } - /// - /// Gets the metadata of the option. - /// - ICommandOptionMetadata Metadata { get; } + /// + /// Gets the metadata of the option. + /// + ICommandOptionMetadata Metadata { get; } - /// - /// Assigns a value to the command's option. - /// - /// - void AssignValue(string optionValue); - } + /// + /// Assigns a value to the command's option. + /// + /// + void AssignValue(string optionValue); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandOptionMetadata.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandOptionMetadata.cs index 9fefbe7..ac5048d 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandOptionMetadata.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandOptionMetadata.cs @@ -1,28 +1,27 @@ -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents the metadata of a command's option. +/// +public interface ICommandOptionMetadata { /// - /// Represents the metadata of a command's option. + /// Defines if an option is required or not. /// - public interface ICommandOptionMetadata - { - /// - /// Defines if an option is required or not. - /// - bool IsRequired { get; } + bool IsRequired { get; } - /// - /// Defines the type of collection of the option. - /// - CommandOptionCollectionType CollectionType { get; } + /// + /// Defines the type of collection of the option. + /// + CommandOptionCollectionType CollectionType { get; } - /// - /// Gets the display information of the option. - /// - IOptionDisplayInfo DisplayInfo { get; } + /// + /// Gets the display information of the option. + /// + IOptionDisplayInfo DisplayInfo { get; } - /// - /// Gets the default value of the option, if explicitly defined. - /// - string DefaultValue { get; } - } + /// + /// Gets the default value of the option, if explicitly defined. + /// + string DefaultValue { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandType.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandType.cs index 251e760..fa380fe 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandType.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandType.cs @@ -1,28 +1,27 @@ using System; using System.Collections.Generic; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents a type of command. +/// +public interface ICommandType { /// - /// Represents a type of command. + /// Gets the metadata of the command. /// - public interface ICommandType - { - /// - /// Gets the metadata of the command. - /// - ICommandMetadata Metadata { get; } + ICommandMetadata Metadata { get; } - /// - /// Gets the option's metadata of the command type. - /// - IEnumerable Options { get; } + /// + /// Gets the option's metadata of the command type. + /// + IEnumerable Options { get; } - /// - /// Create the command from its type. - /// - /// The scoped dependency resolver. - /// - ICommandObjectBuilder CreateCommandObjectBuilder(IServiceProvider serviceProvider); - } + /// + /// Create the command from its type. + /// + /// The scoped dependency resolver. + /// + ICommandObjectBuilder? CreateCommandObjectBuilder(IServiceProvider serviceProvider); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/ICommandTypeProvider.cs b/src/MGR.CommandLineParser/Extensibility/Command/ICommandTypeProvider.cs index 9bbce69..7c9372d 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/ICommandTypeProvider.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/ICommandTypeProvider.cs @@ -1,32 +1,29 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using MGR.CommandLineParser.Extensibility.ClassBased; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Define a command provider. +/// +/// +/// This is the starting point to implement another way to define commands. +/// +public interface ICommandTypeProvider { /// - /// Define a command provider. + /// Returns all commands types. /// - /// - /// This is the starting point to implement another way to define commands. - /// - public interface ICommandTypeProvider - { - /// - /// Returns all commands types. - /// - [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] - Task> GetAllCommandTypes(); + Task> GetAllCommandTypes(); - /// - /// Retrieve the of the command with the specified . - /// - /// The command name. - /// - /// The of the command with the specified or null if - /// the command's type is not found. - /// - Task GetCommandType(string commandName); - } + /// + /// Retrieve the of the command with the specified . + /// + /// The command name. + /// + /// The of the command with the specified or null if + /// the command's type is not found. + /// + Task GetCommandType(string commandName); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Command/IOptionDisplayInfo.cs b/src/MGR.CommandLineParser/Extensibility/Command/IOptionDisplayInfo.cs index fd7bcef..b1da128 100644 --- a/src/MGR.CommandLineParser/Extensibility/Command/IOptionDisplayInfo.cs +++ b/src/MGR.CommandLineParser/Extensibility/Command/IOptionDisplayInfo.cs @@ -1,30 +1,29 @@ using System.Collections.Generic; -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +/// +/// Represents the display information of an option. +/// +public interface IOptionDisplayInfo { /// - /// Represents the display information of an option. + /// Gets the name of the option. /// - public interface IOptionDisplayInfo - { - /// - /// Gets the name of the option. - /// - string Name { get; } + string Name { get; } - /// - /// Gets the alternates names of the option. - /// - IEnumerable AlternateNames { get; } + /// + /// Gets the alternates names of the option. + /// + IEnumerable AlternateNames { get; } - /// - /// Gets the short name of the option. - /// - string ShortName { get; } + /// + /// Gets the short name of the option. + /// + string ShortName { get; } - /// - /// Gets the description of the option. - /// - string Description { get; } - } + /// + /// Gets the description of the option. + /// + string Description { get; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/CommandLineParserBuilder.cs b/src/MGR.CommandLineParser/Extensibility/CommandLineParserBuilder.cs index 6c23439..dab5507 100644 --- a/src/MGR.CommandLineParser/Extensibility/CommandLineParserBuilder.cs +++ b/src/MGR.CommandLineParser/Extensibility/CommandLineParserBuilder.cs @@ -1,19 +1,17 @@ -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.DependencyInjection +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// A class to add configuration to the command line parser. +/// +public sealed class CommandLineParserBuilder { - /// - /// A class to add configuration to the command line parser. - /// - public sealed class CommandLineParserBuilder + internal CommandLineParserBuilder(IServiceCollection services) { - internal CommandLineParserBuilder(IServiceCollection services) - { - Services = services; - } - - /// - /// Gets the being used to configure the command line parser. - /// - public IServiceCollection Services { get; } + Services = services; } + + /// + /// Gets the being used to configure the command line parser. + /// + public IServiceCollection Services { get; } } diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/BooleanConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/BooleanConverter.cs index 2db56d0..8404a12 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/BooleanConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/BooleanConverter.cs @@ -1,54 +1,53 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class BooleanConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class BooleanConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (bool); + public Type TargetType => typeof (bool); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// - /// The value can be '-', 'False' or 'false' to specify false, '+', 'True' or 'true' to specify true. - /// - /// - /// Thrown if the - /// - /// is not valid. - /// - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// + /// The value can be '-', 'False' or 'false' to specify false, '+', 'True' or 'true' to specify true. + /// + /// + /// Thrown if the + /// + /// is not valid. + /// + public object Convert(string value, Type concreteTargetType) + { + if (string.IsNullOrEmpty(value)) + { + return true; + } + if (value.Equals("-", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + if (value.Equals("+", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + try + { + return bool.Parse(value); + } + catch (FormatException exception) { - if (string.IsNullOrEmpty(value)) - { - return true; - } - if (value.Equals("-", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - if (value.Equals("+", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - try - { - return bool.Parse(value); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/ByteConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/ByteConverter.cs index ca302f9..023b594 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/ByteConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/ByteConverter.cs @@ -1,38 +1,37 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class ByteConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class ByteConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (byte); + public Type TargetType => typeof (byte); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return byte.Parse(value, CultureInfo.InvariantCulture); + } + catch (FormatException exception) { - try - { - return byte.Parse(value, CultureInfo.InvariantCulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), - exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), + exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/CharConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/CharConverter.cs index 8674631..84f7311 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/CharConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/CharConverter.cs @@ -1,37 +1,36 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class CharConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class CharConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (char); + public Type TargetType => typeof (char); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return char.Parse(value); + } + catch (FormatException exception) { - try - { - return char.Parse(value); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), - exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), + exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/DateTimeConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/DateTimeConverter.cs index 5897f2b..d2ba659 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/DateTimeConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/DateTimeConverter.cs @@ -1,40 +1,37 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class DateTimeConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class DateTimeConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (DateTime); + public Type TargetType => typeof (DateTime); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - //[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "DateTime")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.DateTime.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return DateTime.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return DateTime.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), - exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), + exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/DecimalConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/DecimalConverter.cs index 9c612a7..c211c8d 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/DecimalConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/DecimalConverter.cs @@ -1,39 +1,37 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class DecimalConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class DecimalConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (decimal); + public Type TargetType => typeof (decimal); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Decimal.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return decimal.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return decimal.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), - exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), + exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/DoubleConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/DoubleConverter.cs index 226b2e1..bbbfb4e 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/DoubleConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/DoubleConverter.cs @@ -1,39 +1,37 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class DoubleConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class DoubleConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (double); + public Type TargetType => typeof (double); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Double.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return double.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return double.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), - exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), + exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/EnumConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/EnumConverter.cs index 3c74549..324a891 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/EnumConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/EnumConverter.cs @@ -1,49 +1,48 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class EnumConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). + /// + public Type TargetType => typeof(Enum); + + /// + /// Convert the to an instance of . /// - public sealed class EnumConverter : IConverter + /// The original value provided by the user. + /// The concrete enum type. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid or if + /// + /// is not an enum. + public object Convert(string value, Type concreteTargetType) { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof(Enum); + Guard.NotNull(concreteTargetType, nameof(concreteTargetType)); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// The concrete enum type. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid or if - /// - /// is not an enum. - public object Convert(string value, Type concreteTargetType) + if (!TargetType.IsAssignableFrom(concreteTargetType)) { - Guard.NotNull(concreteTargetType, nameof(concreteTargetType)); - - if (!TargetType.IsAssignableFrom(concreteTargetType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.EnumConverterConcreteTargetTypeIsNotAnEnum(concreteTargetType)); - } - try - { - var enumValue = Enum.Parse(concreteTargetType, value, true); - if (!(Enum.IsDefined(concreteTargetType, enumValue) || enumValue.ToString().Contains(","))) - { - throw new CommandLineParserException(Constants.ExceptionMessages.EnumConverterParsedValueIsNotOfConcreteType(value, concreteTargetType)); - } - return enumValue; - } - catch (ArgumentException exception) + throw new CommandLineParserException(Constants.ExceptionMessages.EnumConverterConcreteTargetTypeIsNotAnEnum(concreteTargetType)); + } + try + { + var enumValue = Enum.Parse(concreteTargetType, value, true); + if (!(Enum.IsDefined(concreteTargetType, enumValue) || enumValue.ToString().Contains(","))) { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType), exception); + throw new CommandLineParserException(Constants.ExceptionMessages.EnumConverterParsedValueIsNotOfConcreteType(value, concreteTargetType)); } + return enumValue; + } + catch (ArgumentException exception) + { + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/FileSystemInfoConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/FileSystemInfoConverter.cs index 60a4731..cd8e128 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/FileSystemInfoConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/FileSystemInfoConverter.cs @@ -1,44 +1,43 @@ using System; using System.IO; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class FileSystemInfoConverter : IConverter { /// - /// Converter for the type . + /// The target type for the converter (). /// - public sealed class FileSystemInfoConverter : IConverter - { - /// - /// The target type for the converter (). - /// - public Type TargetType => typeof (FileSystemInfo); + public Type TargetType => typeof (FileSystemInfo); - /// - /// Converts the to an instnace of or . - /// - /// The original value provided by the user. - /// Not used. - /// The or . - public object Convert(string value, Type concreteTargetType) + /// + /// Converts the to an instnace of or . + /// + /// The original value provided by the user. + /// Not used. + /// The or . + public object Convert(string value, Type concreteTargetType) + { + try { - try + if (concreteTargetType == typeof (FileInfo)) { - if (concreteTargetType == typeof (FileInfo)) - { - var fileInfo = new FileInfo(value); - return fileInfo; - } - if (concreteTargetType == typeof (DirectoryInfo)) - { - var fileInfo = new DirectoryInfo(value); - return fileInfo; - } - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType)); + var fileInfo = new FileInfo(value); + return fileInfo; } - catch (Exception exception) + if (concreteTargetType == typeof (DirectoryInfo)) { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType), exception); + var fileInfo = new DirectoryInfo(value); + return fileInfo; } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType)); + } + catch (Exception exception) + { + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, concreteTargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/GuidConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/GuidConverter.cs index a9781ea..243c92c 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/GuidConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/GuidConverter.cs @@ -1,36 +1,35 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class GuidConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class GuidConverter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (Guid); + public Type TargetType => typeof (Guid); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return Guid.Parse(value); + } + catch (FormatException exception) { - try - { - return Guid.Parse(value); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/IConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/IConverter.cs index 41a53ac..63d7b7a 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/IConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/IConverter.cs @@ -1,22 +1,21 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Define a converter. +/// +public interface IConverter { /// - /// Define a converter + /// The target type of the converter. + /// + Type TargetType { get; } + /// + /// Convert the to an instance of . /// - public interface IConverter - { - /// - /// The target type of the converter. - /// - Type TargetType { get; } - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// The concrete type expected by the option. - /// The converted value. - object Convert(string value, Type concreteTargetType); - } + /// The original value provided by the user. + /// The concrete type expected by the option. + /// The converted value. + object Convert(string value, Type concreteTargetType); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/Int16Converter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/Int16Converter.cs index a326f5d..98b0265 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/Int16Converter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/Int16Converter.cs @@ -1,38 +1,36 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class Int16Converter : IConverter { /// - /// Converter for the type . + /// The target type of the converter ( ). /// - public sealed class Int16Converter : IConverter - { - /// - /// The target type of the converter ( ).. - /// - public Type TargetType => typeof (short); + public Type TargetType => typeof (short); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the - /// - /// is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int16.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the + /// + /// is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return short.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return short.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/Int32Converter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/Int32Converter.cs index e035134..36c8168 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/Int32Converter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/Int32Converter.cs @@ -1,36 +1,34 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class Int32Converter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class Int32Converter : IConverter - { - /// - /// The target type of the converter ().. - /// - public Type TargetType => typeof (int); + public Type TargetType => typeof (int); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return int.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return int.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/Int64Converter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/Int64Converter.cs index 7a69b96..4da2fc4 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/Int64Converter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/Int64Converter.cs @@ -1,36 +1,34 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class Int64Converter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class Int64Converter : IConverter - { - /// - /// The target type of the converter ().. - /// - public Type TargetType => typeof (long); + public Type TargetType => typeof (long); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int64.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return long.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return long.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/KeyValueConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/KeyValueConverter.cs index 3479c1e..9e956f4 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/KeyValueConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/KeyValueConverter.cs @@ -1,35 +1,34 @@ using System; using System.Collections.Generic; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +internal sealed class KeyValueConverter : IConverter { - internal sealed class KeyValueConverter : IConverter - { - private readonly IConverter _keyConverter; - private readonly IConverter _valueConverter; + private readonly IConverter _keyConverter; + private readonly IConverter _valueConverter; - internal KeyValueConverter(IConverter keyConverter, IConverter valueConverter) - { - Guard.NotNull(keyConverter, nameof(keyConverter)); - Guard.NotNull(valueConverter, nameof(valueConverter)); + internal KeyValueConverter(IConverter keyConverter, IConverter valueConverter) + { + Guard.NotNull(keyConverter, nameof(keyConverter)); + Guard.NotNull(valueConverter, nameof(valueConverter)); - _keyConverter = keyConverter; - _valueConverter = valueConverter; - } + _keyConverter = keyConverter; + _valueConverter = valueConverter; + } - public Type TargetType => typeof (KeyValuePair<,>).MakeGenericType(_keyConverter.TargetType, _valueConverter.TargetType); + public Type TargetType => typeof (KeyValuePair<,>).MakeGenericType(_keyConverter.TargetType, _valueConverter.TargetType); - public object Convert(string value, Type concreteTargetType) + public object Convert(string value, Type concreteTargetType) + { + Guard.NotNullOrEmpty(value, nameof(value)); + var eqIndex = value.IndexOf("=", StringComparison.OrdinalIgnoreCase); + if (eqIndex > -1) { - Guard.NotNullOrEmpty(value, nameof(value)); - var eqIndex = value.IndexOf("=", StringComparison.OrdinalIgnoreCase); - if (eqIndex > -1) - { - var propertyKey = _keyConverter.Convert(value.Substring(0, eqIndex), _keyConverter.TargetType); - var propertyValue = _valueConverter.Convert(value.Substring(eqIndex + 1), _valueConverter.TargetType); - return new KeyValuePair(propertyKey, propertyValue); - } - return new KeyValuePair(_keyConverter.Convert(value, _keyConverter.TargetType), null); + var propertyKey = _keyConverter.Convert(value.Substring(0, eqIndex), _keyConverter.TargetType); + var propertyValue = _valueConverter.Convert(value.Substring(eqIndex + 1), _valueConverter.TargetType); + return new KeyValuePair(propertyKey, propertyValue); } + return new KeyValuePair(_keyConverter.Convert(value, _keyConverter.TargetType), null); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/SingleConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/SingleConverter.cs index d270de8..b2fb3d9 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/SingleConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/SingleConverter.cs @@ -1,36 +1,34 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class SingleConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class SingleConverter : IConverter - { - /// - /// The target type of the converter ().. - /// - public Type TargetType => typeof (float); + public Type TargetType => typeof (float); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the is not valid. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Single.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return float.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return float.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/StringConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/StringConverter.cs index 8a063f2..e928e4f 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/StringConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/StringConverter.cs @@ -1,23 +1,22 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class StringConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class StringConverter : IConverter - { - /// - /// The target type of the converter (). - /// - public Type TargetType => typeof (string); + public Type TargetType => typeof (string); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - public object Convert(string value, Type concreteTargetType) => value; - } + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + public object Convert(string value, Type concreteTargetType) => value; } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/TimeSpanConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/TimeSpanConverter.cs index 0268181..9f018fc 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/TimeSpanConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/TimeSpanConverter.cs @@ -1,37 +1,34 @@ using System; using System.Globalization; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class TimeSpanConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class TimeSpanConverter : IConverter - { - /// - /// The target type of the converter (). - /// - public Type TargetType => typeof (TimeSpan); + public Type TargetType => typeof (TimeSpan); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - /// Thrown if the is not valid. - //[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "TimeSpan")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.TimeSpan.Parse(System.String,System.IFormatProvider)")] - public object Convert(string value, Type concreteTargetType) + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + /// Thrown if the is not valid. + public object Convert(string value, Type concreteTargetType) + { + try + { + return TimeSpan.Parse(value, CultureInfo.CurrentUICulture); + } + catch (FormatException exception) { - try - { - return TimeSpan.Parse(value, CultureInfo.CurrentUICulture); - } - catch (FormatException exception) - { - throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); - } + throw new CommandLineParserException(Constants.ExceptionMessages.FormatConverterUnableConvert(value, TargetType), exception); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/Converters/UriConverter.cs b/src/MGR.CommandLineParser/Extensibility/Converters/UriConverter.cs index 801174a..ed7880b 100644 --- a/src/MGR.CommandLineParser/Extensibility/Converters/UriConverter.cs +++ b/src/MGR.CommandLineParser/Extensibility/Converters/UriConverter.cs @@ -1,23 +1,22 @@ using System; -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Converter for the type . +/// +public sealed class UriConverter : IConverter { /// - /// Converter for the type . + /// The target type of the converter (). /// - public sealed class UriConverter : IConverter - { - /// - /// The target type of the converter ().. - /// - public Type TargetType => typeof (Uri); + public Type TargetType => typeof (Uri); - /// - /// Convert the to an instance of . - /// - /// The original value provided by the user. - /// Not used. - /// The converted from the value. - public object Convert(string value, Type concreteTargetType) => new Uri(value, UriKind.RelativeOrAbsolute); - } + /// + /// Convert the to an instance of . + /// + /// The original value provided by the user. + /// Not used. + /// The converted from the value. + public object Convert(string value, Type concreteTargetType) => new Uri(value, UriKind.RelativeOrAbsolute); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/DefaultConsole.cs b/src/MGR.CommandLineParser/Extensibility/DefaultConsole.cs index 894a181..f2e0db4 100644 --- a/src/MGR.CommandLineParser/Extensibility/DefaultConsole.cs +++ b/src/MGR.CommandLineParser/Extensibility/DefaultConsole.cs @@ -1,62 +1,59 @@ using System; using System.Globalization; using System.IO; -using JetBrains.Annotations; using MGR.CommandLineParser.Properties; -namespace MGR.CommandLineParser.Extensibility +namespace MGR.CommandLineParser.Extensibility; + +/// +/// Forward to . +/// +public sealed class DefaultConsole : IConsole { + private readonly TextWriter _consoleOut; + private readonly TextWriter _consoleError; + /// - /// Forward to . + /// Create a new . /// - public sealed class DefaultConsole : IConsole - { - private readonly TextWriter _consoleOut; - private readonly TextWriter _consoleError; + public DefaultConsole() : this(Console.Out, Console.Error) { } - /// - /// Create a new . - /// - [PublicAPI] - public DefaultConsole() : this(Console.Out, Console.Error) { } + internal DefaultConsole(TextWriter consoleOut, TextWriter consoleError) + { + _consoleOut = consoleOut; + _consoleError = consoleError; + } - internal DefaultConsole(TextWriter consoleOut, TextWriter consoleError) - { - _consoleOut = consoleOut; - _consoleError = consoleError; - } + /// + public void Write(string format, params object[] args) + { + WriteColor(_consoleOut, Console.ForegroundColor, format, args); + } - /// - public void Write(string format, params object[] args) - { - WriteColor(_consoleOut, Console.ForegroundColor, format, args); - } + /// + public void WriteError(string format, params object[] args) + { + WriteColor(_consoleError, ConsoleColor.Red, format, args); + } - /// - public void WriteError(string format, params object[] args) - { - WriteColor(_consoleError, ConsoleColor.Red, format, args); - } + /// + public void WriteWarning(string format, params object[] args) + { + var message = string.Format(CultureInfo.CurrentUICulture, Strings.Console_WarningFormat, format); + WriteColor(_consoleOut, ConsoleColor.Yellow, message, args); + } - /// - public void WriteWarning(string format, params object[] args) + private static void WriteColor(TextWriter writer, ConsoleColor color, string value, params object[] args) + { + var currentColor = Console.ForegroundColor; + try { - var message = string.Format(CultureInfo.CurrentUICulture, Strings.Console_WarningFormat, format); - WriteColor(_consoleOut, ConsoleColor.Yellow, message, args); + Console.ForegroundColor = color; + writer.Write(value, args); } - - private static void WriteColor(TextWriter writer, ConsoleColor color, string value, params object[] args) + finally { - var currentColor = Console.ForegroundColor; - try - { - Console.ForegroundColor = color; - writer.Write(value, args); - } - finally - { - Console.ForegroundColor = currentColor; - } + Console.ForegroundColor = currentColor; } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/DefaultHelpWriter.cs b/src/MGR.CommandLineParser/Extensibility/DefaultHelpWriter.cs index 896e11a..c77d486 100644 --- a/src/MGR.CommandLineParser/Extensibility/DefaultHelpWriter.cs +++ b/src/MGR.CommandLineParser/Extensibility/DefaultHelpWriter.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Threading.Tasks; @@ -9,156 +8,152 @@ using MGR.CommandLineParser.Properties; using Microsoft.Extensions.Options; -namespace MGR.CommandLineParser.Extensibility +namespace MGR.CommandLineParser.Extensibility; + +/// +/// The default help writer. Writes to the . +/// +public sealed class DefaultHelpWriter : IHelpWriter { + internal const string CollectionIndicator = "+"; + internal const string DictionaryIndicator = "#"; + internal const string MultiOptionNameSeparator = "|"; + + private readonly IConsole _console; + private readonly IEnumerable _commandTypeProviders; + private readonly IOptions _parserOptionsAccessor; + /// - /// The default help writer. Writes to the . + /// Create a new . /// - public sealed class DefaultHelpWriter : IHelpWriter + /// + /// + /// + public DefaultHelpWriter(IConsole console, IEnumerable commandTypeProviders, IOptions parserOptionsAccessor) { - internal const string CollectionIndicator = "+"; - internal const string DictionaryIndicator = "#"; - internal const string MultiOptionNameSeparator = "|"; - - private readonly IConsole _console; - private readonly IEnumerable _commandTypeProviders; - private readonly IOptions _parserOptionsAccessor; - - /// - /// Create a new . - /// - /// - /// - /// - public DefaultHelpWriter(IConsole console, IEnumerable commandTypeProviders, IOptions parserOptionsAccessor) - { - _console = console; - _commandTypeProviders = commandTypeProviders; - _parserOptionsAccessor = parserOptionsAccessor; - } + _console = console; + _commandTypeProviders = commandTypeProviders; + _parserOptionsAccessor = parserOptionsAccessor; + } - /// - public async Task WriteCommandListing() - { - WriteGeneralInformation(); + /// + public async Task WriteCommandListing() + { + WriteGeneralInformation(); - _console.WriteLine(Strings.DefaultHelpWriter_GlobalHelp_AvailableCommands); - var commandTypes = (await _commandTypeProviders.GetAllVisibleCommandsTypes()).OrderBy(commandType => commandType.Metadata.Name).ToList(); - WriteDescriptionForSomeCommands(commandTypes); - } + _console.WriteLine(Strings.DefaultHelpWriter_GlobalHelp_AvailableCommands); + var commandTypes = (await _commandTypeProviders.GetAllVisibleCommandsTypes()).OrderBy(commandType => commandType.Metadata.Name).ToList(); + WriteDescriptionForSomeCommands(commandTypes); + } - private void WriteDescriptionForSomeCommands(List commandTypes) + private void WriteDescriptionForSomeCommands(List commandTypes) + { + if (commandTypes.Any()) { - if (commandTypes.Any()) - { - WriteDescriptionForAllCommands(commandTypes); - } - else - { - _console.WriteLine("No commands found."); - } + WriteDescriptionForAllCommands(commandTypes); } - - private void WriteDescriptionForAllCommands(List commandTypes) + else { - var maxNameLength = commandTypes.Max(m => m.Metadata.Name.Length); - foreach (var commandType in commandTypes) - { - WriteDescriptionForOneCommand(commandType, maxNameLength); - } + _console.WriteLine("No commands found."); } + } - [SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")] - private void WriteDescriptionForOneCommand(ICommandType commandType, int maxNameLength) + private void WriteDescriptionForAllCommands(List commandTypes) + { + var maxNameLength = commandTypes.Max(m => m.Metadata.Name.Length); + foreach (var commandType in commandTypes) { - _console.Write($" {{0, -{maxNameLength}}} ", commandType.Metadata.Name); - // Starting index of the description - _console.WriteLine(commandType.Metadata.Description); + WriteDescriptionForOneCommand(commandType, maxNameLength); } + } + + private void WriteDescriptionForOneCommand(ICommandType commandType, int maxNameLength) + { + _console.Write($" {{0, -{maxNameLength}}} ", commandType.Metadata.Name); + // Starting index of the description + _console.WriteLine(commandType.Metadata.Description); + } + + /// + public void WriteHelpForCommand(params ICommandType[] commandTypes) + { + Guard.NotNull(commandTypes, nameof(commandTypes)); - /// - public void WriteHelpForCommand(params ICommandType[] commandTypes) + WriteGeneralInformation(); + var parserOptions = _parserOptionsAccessor.Value; + foreach (var commandType in commandTypes.OrderBy(ct => ct.Metadata.Name)) { - Guard.NotNull(commandTypes, nameof(commandTypes)); + var metadata = commandType.Metadata; + _console.WriteLine(Strings.DefaultHelpWriter_CommandUsageFormat, parserOptions.CommandLineName, metadata.Name, metadata.Usage); + _console.WriteLine(metadata.Description); + _console.WriteLine(); - WriteGeneralInformation(); - var parserOptions = _parserOptionsAccessor.Value; - foreach (var commandType in commandTypes.OrderBy(ct => ct.Metadata.Name)) + var options = commandType.Options.ToList(); + if (options.Count > 0) { - var metadata = commandType.Metadata; - _console.WriteLine(Strings.DefaultHelpWriter_CommandUsageFormat, parserOptions.CommandLineName, metadata.Name, metadata.Usage); - _console.WriteLine(metadata.Description); - _console.WriteLine(); - - var options = commandType.Options.ToList(); - if (options.Count > 0) + _console.WriteLine(Strings.DefaultHelpWriter_OptionsListTitle); + var maxOptionWidth = commandType.Options.Max(o => o.DisplayInfo.Name.Length + o.DisplayInfo.AlternateNames.Sum( + alternateName => alternateName.Length + 1)) + 2; + var maxAltOptionWidth = commandType.Options.Max(o => (o.DisplayInfo.ShortName ?? string.Empty).Length); + foreach (var commandOptionMetadata in options) { - _console.WriteLine(Strings.DefaultHelpWriter_OptionsListTitle); - var maxOptionWidth = commandType.Options.Max(o => o.DisplayInfo.Name.Length + o.DisplayInfo.AlternateNames.Sum( - alternateName => alternateName.Length + 1)) + 2; - var maxAltOptionWidth = commandType.Options.Max(o => (o.DisplayInfo.ShortName ?? string.Empty).Length); - foreach (var commandOptionMetadata in options) + var alternateNames = string.Join(MultiOptionNameSeparator, commandOptionMetadata.DisplayInfo.AlternateNames); + var prefixAlternateNames = MultiOptionNameSeparator; + if (string.IsNullOrEmpty(alternateNames)) { - var alternateNames = string.Join(MultiOptionNameSeparator, commandOptionMetadata.DisplayInfo.AlternateNames); - var prefixAlternateNames = MultiOptionNameSeparator; - if (string.IsNullOrEmpty(alternateNames)) - { - prefixAlternateNames = String.Empty; - } - var optionName = string.Concat(commandOptionMetadata.DisplayInfo.Name, prefixAlternateNames, alternateNames, GetMultiValueIndicator(commandOptionMetadata)); - var optionShortName = FormatShortName(commandOptionMetadata.DisplayInfo.ShortName); - _console.Write(" {0}{1, -" + maxOptionWidth + "}", Constants.LongNameOptionStarter, optionName); - _console.Write("{0, -" + (maxAltOptionWidth + 4) + "}", optionShortName); - - _console.Write(commandOptionMetadata.DisplayInfo.Description); - _console.WriteLine(); + prefixAlternateNames = string.Empty; } + var optionName = string.Concat(commandOptionMetadata.DisplayInfo.Name, prefixAlternateNames, alternateNames, GetMultiValueIndicator(commandOptionMetadata)); + var optionShortName = FormatShortName(commandOptionMetadata.DisplayInfo.ShortName); + _console.Write(" {0}{1, -" + maxOptionWidth + "}", Constants.LongNameOptionStarter, optionName); + _console.Write("{0, -" + (maxAltOptionWidth + 4) + "}", optionShortName); + + _console.Write(commandOptionMetadata.DisplayInfo.Description); + _console.WriteLine(); } + } - var samples = commandType.Metadata.Samples; - if (samples.Length > 0) + var samples = commandType.Metadata.Samples; + if (samples.Length > 0) + { + _console.WriteLine(); + _console.WriteLine("Samples:"); + foreach (var usage in samples) { - _console.WriteLine(); - _console.WriteLine("Samples:"); - foreach (var usage in samples) - { - _console.WriteLine(usage); - } + _console.WriteLine(usage); } } } + } - private void WriteGeneralInformation() - { - var parserOptions = _parserOptionsAccessor.Value; - _console.WriteLine(parserOptions.Logo); - _console.WriteLine(Strings.DefaultHelpWriter_GlobalUsageFormat, string.Format(CultureInfo.CurrentUICulture, Strings.DefaultHelpWriter_GlobalCommandLineCommandFormat, parserOptions.CommandLineName).Trim()); - _console.WriteLine(Strings.DefaultHelpWriter_GlobalHelpCommandUsageFormat, string.Format(CultureInfo.CurrentUICulture, "{0} {1}", parserOptions.CommandLineName, HelpCommand.Name).Trim()); - _console.WriteLine(); - } + private void WriteGeneralInformation() + { + var parserOptions = _parserOptionsAccessor.Value; + _console.WriteLine(parserOptions.Logo); + _console.WriteLine(Strings.DefaultHelpWriter_GlobalUsageFormat, string.Format(CultureInfo.CurrentUICulture, Strings.DefaultHelpWriter_GlobalCommandLineCommandFormat, parserOptions.CommandLineName).Trim()); + _console.WriteLine(Strings.DefaultHelpWriter_GlobalHelpCommandUsageFormat, string.Format(CultureInfo.CurrentUICulture, "{0} {1}", parserOptions.CommandLineName, HelpCommand.Name).Trim()); + _console.WriteLine(); + } - internal static string GetMultiValueIndicator(ICommandOptionMetadata commandOptionMetadata) + internal static string GetMultiValueIndicator(ICommandOptionMetadata commandOptionMetadata) + { + switch (commandOptionMetadata.CollectionType) { -#pragma warning disable CC0073 // Add braces to switch sections. - switch (commandOptionMetadata.CollectionType) - { - case CommandOptionCollectionType.Collection: - return CollectionIndicator; - case CommandOptionCollectionType.Dictionary: - return DictionaryIndicator; - default: - return string.Empty; - } -#pragma warning restore CC0073 // Add braces to switch sections. + case CommandOptionCollectionType.Collection: + return CollectionIndicator; + case CommandOptionCollectionType.Dictionary: + return DictionaryIndicator; + default: + return string.Empty; } + } - private static string FormatShortName(string shortName) + private static string FormatShortName(string shortName) + { + if (string.IsNullOrEmpty(shortName)) { - if (string.IsNullOrEmpty(shortName)) - { - return string.Empty; - } - return string.Format(CultureInfo.CurrentUICulture, "({0})", shortName); + return string.Empty; } + return string.Format(CultureInfo.CurrentUICulture, "({0})", shortName); } } diff --git a/src/MGR.CommandLineParser/Extensibility/IConsole.cs b/src/MGR.CommandLineParser/Extensibility/IConsole.cs index eb2ddf7..3fe833d 100644 --- a/src/MGR.CommandLineParser/Extensibility/IConsole.cs +++ b/src/MGR.CommandLineParser/Extensibility/IConsole.cs @@ -1,29 +1,28 @@ -namespace MGR.CommandLineParser.Extensibility +namespace MGR.CommandLineParser.Extensibility; + +/// +/// Defines the console to log the parser activity. +/// +public interface IConsole { /// - /// Defines the console to log the parser activity. + /// Writes the value representation of the specified array of objects to the standard output stream using the specified format information. /// - public interface IConsole - { - /// - /// Writes the value representation of the specified array of objects to the standard output stream using the specified format information. - /// - /// A composite format string. - /// An array of objects to write using . - void Write(string format, params object[] args); + /// A composite format string. + /// An array of objects to write using . + void Write(string format, params object[] args); - /// - /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the error output stream using the specified format information. - /// - /// A composite format string. - /// An array of objects to write using . - void WriteError(string format, params object[] args); + /// + /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the error output stream using the specified format information. + /// + /// A composite format string. + /// An array of objects to write using . + void WriteError(string format, params object[] args); - /// - /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the warning output stream using the specified format information. - /// - /// A composite format string. - /// An array of objects to write using . - void WriteWarning(string format, params object[] args); - } + /// + /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the warning output stream using the specified format information. + /// + /// A composite format string. + /// An array of objects to write using . + void WriteWarning(string format, params object[] args); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensibility/IHelpWriter.cs b/src/MGR.CommandLineParser/Extensibility/IHelpWriter.cs index 8765875..46f54e7 100644 --- a/src/MGR.CommandLineParser/Extensibility/IHelpWriter.cs +++ b/src/MGR.CommandLineParser/Extensibility/IHelpWriter.cs @@ -1,22 +1,21 @@ using System.Threading.Tasks; using MGR.CommandLineParser.Extensibility.Command; -namespace MGR.CommandLineParser.Extensibility +namespace MGR.CommandLineParser.Extensibility; + +/// +/// Display the help. +/// +public interface IHelpWriter { /// - /// Display the help. + /// Write command listing. /// - public interface IHelpWriter - { - /// - /// Write command listing. - /// - Task WriteCommandListing(); + Task WriteCommandListing(); - /// - /// Write the help for some commands. - /// - /// The of the commands to display help. - void WriteHelpForCommand(params ICommandType[] commandTypes); - } + /// + /// Write the help for some commands. + /// + /// The of the commands to display help. + void WriteHelpForCommand(params ICommandType[] commandTypes); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/AssemblyExtensions.cs b/src/MGR.CommandLineParser/Extensions/AssemblyExtensions.cs index 38893a4..c231d4b 100644 --- a/src/MGR.CommandLineParser/Extensions/AssemblyExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/AssemblyExtensions.cs @@ -2,49 +2,44 @@ using System.Linq; using MGR.CommandLineParser; -// ReSharper disable once CheckNamespace -namespace System.Reflection +namespace System.Reflection; + +internal static class AssemblyExtensions { - internal static class AssemblyExtensions + internal static IEnumerable GetTypes(this IEnumerable source, Func predicate) { - [Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] - internal static IEnumerable GetTypes(this IEnumerable source, Func predicate) + Guard.NotNull(predicate, nameof(predicate)); + + var result = new List(); + if (source == null) { - Guard.NotNull(predicate, nameof(predicate)); + return result; + } - var result = new List(); - if (source == null) + foreach (var assembly in source.Where(assembly => assembly != null && !assembly.IsDynamic)) + { + Type[] exportedTypes; + + try { - return result; + exportedTypes = assembly.GetTypes(); } - - foreach (var assembly in source.Where(assembly => assembly != null && !assembly.IsDynamic)) + catch (ReflectionTypeLoadException ex) { - Type[] exportedTypes; - - try - { - exportedTypes = assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - exportedTypes = ex.Types; - } + exportedTypes = ex.Types; + } -#pragma warning disable CC0003 // Your catch maybe include some Exception - catch -#pragma warning restore CC0003 // Your catch maybe include some Exception - { - // We deliberately ignore all other exceptions. - continue; - } + catch + { + // We deliberately ignore all other exceptions. + continue; + } - if (exportedTypes != null) - { - result.AddRange(exportedTypes.Where(predicate)); - } + if (exportedTypes != null) + { + result.AddRange(exportedTypes.Where(predicate)); } - return result; } + return result; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/CommandLineParserBuilderExtensions.cs b/src/MGR.CommandLineParser/Extensions/CommandLineParserBuilderExtensions.cs index f8d45a1..c6ef7f9 100644 --- a/src/MGR.CommandLineParser/Extensions/CommandLineParserBuilderExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/CommandLineParserBuilderExtensions.cs @@ -3,43 +3,43 @@ using MGR.CommandLineParser.Extensibility.Command; using Microsoft.Extensions.DependencyInjection.Extensions; -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.DependencyInjection +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extensions methods for the type . +/// +public static class CommandLineParserBuilderExtensions { /// - /// Extensions methods for the type . + /// Add a based on browsing all types in all loaded assemblies after having loaded all assemblies present on the current folder. /// - public static class CommandLineParserBuilderExtensions + /// The to configure. + /// If you are running on .NET Core, do not use this method. + /// The so that additional calls can be chained. + public static CommandLineParserBuilder AddClassBasedCommands(this CommandLineParserBuilder builder) { - /// - /// Add a based on browsing all types in all loaded assemblies after having loaded all assemblies present on the current folder. - /// - /// The to configure. - /// If you are running on .NET Core, do not use this method. - /// The so that additional calls can be chained. - public static CommandLineParserBuilder AddClassBasedCommands(this CommandLineParserBuilder builder) - { - builder.Services.AddSingleton(); - builder.Services.TryAddScoped(); - builder.Services.TryAddScoped(); + builder.Services.AddSingleton(); + builder.Services.TryAddScoped(); + builder.Services.TryAddScoped(); - return builder; - } + return builder; + } - /// - /// Add a based on browsing all types in the assembly containing the specified . - /// - /// The command type used to specify the assembly to browse. - /// The to configure. - /// The so that additional calls can be chained. - public static CommandLineParserBuilder AddCommands(this CommandLineParserBuilder builder) - where TCommand : class, ICommand - { - builder.Services.AddSingleton(new DefaultAssemblyProvider(typeof(TCommand).Assembly)); - builder.Services.TryAddScoped(); - builder.Services.TryAddScoped(); + /// + /// Add a based on browsing all types in the assembly containing the specified . + /// + /// The command type used to specify the assembly to browse. + /// The command type used to specify the assembly to browse. + /// The to configure. + /// The so that additional calls can be chained. + public static CommandLineParserBuilder AddCommands(this CommandLineParserBuilder builder) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + builder.Services.AddSingleton(new DefaultAssemblyProvider(typeof(TCommandHandler).Assembly)); + builder.Services.TryAddScoped(); + builder.Services.TryAddScoped(); - return builder; - } + return builder; } } diff --git a/src/MGR.CommandLineParser/Extensions/ConsoleExtensions.cs b/src/MGR.CommandLineParser/Extensions/ConsoleExtensions.cs index 15327d9..a2bb756 100644 --- a/src/MGR.CommandLineParser/Extensions/ConsoleExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/ConsoleExtensions.cs @@ -1,62 +1,54 @@ using System; -// ReSharper disable once CheckNamespace -namespace MGR.CommandLineParser.Extensibility +namespace MGR.CommandLineParser.Extensibility; + +/// +/// Extensions methods for . +/// +public static class ConsoleExtensions { + private static readonly object[] EmptyArgs = []; /// - /// Extensions methods for . + /// Writes the current line terminator. /// - public static class ConsoleExtensions - { - private static readonly object[] EmptyArgs = new object[0]; - /// - /// Writes the current line terminator. - /// - /// The current console. - public static void WriteLine(this IConsole console) - { - console.Write(Environment.NewLine); - } + /// The current console. + public static void WriteLine(this IConsole console) => console.Write(Environment.NewLine); - /// - /// Writes the specified string value, followed by the current line terminator to the standard output stream . - /// - /// The current console. - /// The value to write. - public static void WriteLine(this IConsole console, string value) - { - console.WriteLine(value, EmptyArgs); - } - /// - /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the standard output stream using the specified format information. - /// - /// The current console. - /// A composite format string. - /// An array of objects to write using . - public static void WriteLine(this IConsole console, string format, params object[] args) - { - console.Write(format, args); - console.Write(Environment.NewLine); - } - /// - /// Writes the specified string value, followed by the current line terminator to the error output stream . - /// - /// The current console. - /// The error message to write. - public static void WriteLineError(this IConsole console, string value) - { - console.WriteError(value); - console.WriteError(Environment.NewLine, EmptyArgs); - } - /// - /// Writes the specified string value, followed by the current line terminator to the warning output stream . - /// - /// The current console. - /// The warning message to write. - public static void WriteLineWarning(this IConsole console, string value) - { - console.WriteWarning(value, EmptyArgs); - console.WriteWarning(Environment.NewLine); - } + /// + /// Writes the specified string value, followed by the current line terminator to the standard output stream. + /// + /// The current console. + /// The value to write. + public static void WriteLine(this IConsole console, string value) => console.WriteLine(value, EmptyArgs); + /// + /// Writes the value representation of the specified array of objects, followed by the current line terminator, to the standard output stream using the specified format information. + /// + /// The current console. + /// A composite format string. + /// An array of objects to write using . + public static void WriteLine(this IConsole console, string format, params object[] args) + { + console.Write(format, args); + console.Write(Environment.NewLine); + } + /// + /// Writes the specified string value, followed by the current line terminator to the error output stream. + /// + /// The current console. + /// The error message to write. + public static void WriteLineError(this IConsole console, string value) + { + console.WriteError(value); + console.WriteError(Environment.NewLine, EmptyArgs); + } + /// + /// Writes the specified string value, followed by the current line terminator to the warning output stream. + /// + /// The current console. + /// The warning message to write. + public static void WriteLineWarning(this IConsole console, string value) + { + console.WriteWarning(value, EmptyArgs); + console.WriteWarning(Environment.NewLine); } } diff --git a/src/MGR.CommandLineParser/Extensions/ConverterAttributeExtensions.cs b/src/MGR.CommandLineParser/Extensions/ConverterAttributeExtensions.cs index c6110a8..150a1f3 100644 --- a/src/MGR.CommandLineParser/Extensions/ConverterAttributeExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/ConverterAttributeExtensions.cs @@ -1,34 +1,35 @@ using System; using MGR.CommandLineParser.Extensibility.Converters; -// ReSharper disable once CheckNamespace -namespace MGR.CommandLineParser.Command +namespace MGR.CommandLineParser.Command; + +internal static class ConverterAttributeExtensions { - internal static class ConverterAttributeExtensions - { #pragma warning disable CS0618 // Type or member is obsolete - internal static IConverter BuildConverter(this ConverterAttribute source) + internal static IConverter BuildConverter(this ConverterAttribute source) #pragma warning restore CS0618 // Type or member is obsolete - { - Guard.NotNull(source, nameof(source)); + { + Guard.NotNull(source, nameof(source)); - return Activator.CreateInstance(source.ConverterType) as IConverter; - } + return Activator.CreateInstance(source.ConverterType) as IConverter + ?? throw new CommandLineParserException(Constants.ExceptionMessages.ConverterAttributeTypeMustBeIConverter); + } #pragma warning disable CS0618 // Type or member is obsolete - internal static IConverter BuildKeyConverter(this ConverterKeyValueAttribute source) + internal static IConverter BuildKeyConverter(this ConverterKeyValueAttribute source) #pragma warning restore CS0618 // Type or member is obsolete - { - Guard.NotNull(source, nameof(source)); + { + Guard.NotNull(source, nameof(source)); - return Activator.CreateInstance(source.KeyConverterType) as IConverter; - } + return Activator.CreateInstance(source.KeyConverterType) as IConverter + ?? throw new CommandLineParserException(Constants.ExceptionMessages.ConverterAttributeTypeMustBeIConverter); + } #pragma warning disable CS0618 // Type or member is obsolete - internal static IConverter BuildValueConverter(this ConverterKeyValueAttribute source) + internal static IConverter BuildValueConverter(this ConverterKeyValueAttribute source) #pragma warning restore CS0618 // Type or member is obsolete - { - Guard.NotNull(source, nameof(source)); + { + Guard.NotNull(source, nameof(source)); - return Activator.CreateInstance(source.ValueConverterType) as IConverter; - } + return Activator.CreateInstance(source.ValueConverterType) as IConverter + ?? throw new CommandLineParserException(Constants.ExceptionMessages.ConverterAttributeTypeMustBeIConverter); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/ConverterExtensions.cs b/src/MGR.CommandLineParser/Extensions/ConverterExtensions.cs index 6319ec3..fe2e037 100644 --- a/src/MGR.CommandLineParser/Extensions/ConverterExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/ConverterExtensions.cs @@ -1,30 +1,28 @@ using System; -// ReSharper disable once CheckNamespace -namespace MGR.CommandLineParser.Extensibility.Converters +namespace MGR.CommandLineParser.Extensibility.Converters; + +/// +/// Extensions methods for the type . +/// +public static class ConverterExtensions { /// - /// Extensions methods for the type . + /// Indicates if the specified can convert to the specified . /// - public static class ConverterExtensions + /// The converter. + /// + /// The target . + /// + /// + /// true if the can convert, false otherwise. + /// + public static bool CanConvertTo(this IConverter source, Type targetType) { - /// - /// Indicates if the specified can convert to the specified . - /// - /// The converter. - /// - /// The target . - /// - /// - /// true if the can convert, false otherwise. - /// - public static bool CanConvertTo(this IConverter source, Type targetType) - { - Guard.NotNull(source, nameof(source)); - Guard.NotNull(targetType, nameof(targetType)); + Guard.NotNull(source, nameof(source)); + Guard.NotNull(targetType, nameof(targetType)); - var type = targetType.IsMultiValuedType() ? targetType.GetUnderlyingCollectionType() : targetType; - return type.IsType(source.TargetType); - } + var type = targetType.IsMultiValuedType() ? targetType.GetUnderlyingCollectionType() : targetType; + return type == null ? false : type.IsType(source.TargetType); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/EnumerableCommandTypeProviderExtensions.cs b/src/MGR.CommandLineParser/Extensions/EnumerableCommandTypeProviderExtensions.cs index 3d138d2..efe7137 100644 --- a/src/MGR.CommandLineParser/Extensions/EnumerableCommandTypeProviderExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/EnumerableCommandTypeProviderExtensions.cs @@ -1,68 +1,65 @@ using System; using System.Linq; -using JetBrains.Annotations; using MGR.CommandLineParser.Extensibility.ClassBased; using System.Collections.Generic; using System.Threading.Tasks; -// ReSharper disable once CheckNamespace -namespace MGR.CommandLineParser.Extensibility.Command +namespace MGR.CommandLineParser.Extensibility.Command; + +internal static class EnumerableCommandTypeProviderExtensions { - internal static class EnumerableCommandTypeProviderExtensions + internal static async Task> GetAllVisibleCommandsTypes(this IEnumerable commandTypeProviders) { - internal static async Task> GetAllVisibleCommandsTypes([NotNull, ItemNotNull]this IEnumerable commandTypeProviders) + var visibleCommandTypes = new List(); + foreach (var commandTypeProvider in commandTypeProviders) { - var visibleCommandTypes = new List(); - foreach (var commandTypeProvider in commandTypeProviders) + var commandTypes = await commandTypeProvider.GetAllCommandTypes(); + foreach (var commandType in commandTypes) { - var commandTypes = await commandTypeProvider.GetAllCommandTypes(); - foreach (var commandType in commandTypes) + if (!commandType.Metadata.HideFromHelpListing) { - if (!commandType.Metadata.HideFromHelpListing) - { - visibleCommandTypes.Add(commandType); - } + visibleCommandTypes.Add(commandType); } } - - return visibleCommandTypes; } - internal static async Task GetCommandType([NotNull, ItemNotNull]this IEnumerable commandTypeProviders, string commandName) + return visibleCommandTypes; + } + + internal static async Task GetCommandType(this IEnumerable commandTypeProviders, string commandName) + { + var commandTypes = new List(); + foreach (var commandTypeProvider in commandTypeProviders) { - var commandTypes = new List(); - foreach (var commandTypeProvider in commandTypeProviders) + var commandType = await commandTypeProvider.GetCommandType(commandName); + if (commandType != null) { - var commandType = await commandTypeProvider.GetCommandType(commandName); - if (commandType != null) - { - commandTypes.Add(commandType); - } + commandTypes.Add(commandType); } - - return commandTypes.SingleOrDefault(); } - internal static async Task GetCommandType([NotNull, ItemNotNull]this IEnumerable commandTypeProviders) + return commandTypes.SingleOrDefault(); + } + + internal static async Task GetCommandType(this IEnumerable commandTypeProviders) + { + var commandType = default(ICommandType); + foreach (var commandTypeProvider in commandTypeProviders.OfType()) { - var commandType = default(ICommandType); - foreach (var commandTypeProvider in commandTypeProviders.OfType()) + var commands = await commandTypeProvider.GetAllCommandTypes(); + foreach (var classBasedCommandType in commands.OfType()) { - var commands = await commandTypeProvider.GetAllCommandTypes(); - foreach (var classBasedCommandType in commands.OfType()) + if (classBasedCommandType.Type == typeof(TCommand)) { - if (classBasedCommandType.Type == typeof(TCommand)) + if (commandType != default(ICommandType)) { - if (commandType != default(ICommandType)) - { - throw new InvalidOperationException(); - } - commandType = classBasedCommandType; + throw new InvalidOperationException(); } + commandType = classBasedCommandType; } } - - return commandType ?? throw new ArgumentException(); } + + return commandType ?? throw new ArgumentException(); } } diff --git a/src/MGR.CommandLineParser/Extensions/EnumerableExtensions.cs b/src/MGR.CommandLineParser/Extensions/EnumerableExtensions.cs index 3e1c447..7d30151 100644 --- a/src/MGR.CommandLineParser/Extensions/EnumerableExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/EnumerableExtensions.cs @@ -1,35 +1,32 @@ using System.IO; using System.Linq; -using JetBrains.Annotations; -// ReSharper disable once CheckNamespace -namespace System.Collections.Generic +namespace System.Collections.Generic; + +internal static class EnumerableExtensions { - internal static class EnumerableExtensions + internal static IEnumerator GetArgumentsEnumerator(this IEnumerable arguments) { - internal static IEnumerator GetArgumentsEnumerator([NotNull]this IEnumerable arguments) + var enumerable = arguments as IList ?? arguments.ToList(); + var firstArgument = enumerable.FirstOrDefault(); + if (string.IsNullOrEmpty(firstArgument)) { - var enumerable = arguments as IList ?? arguments.ToList(); - var firstArgument = enumerable.FirstOrDefault(); - if (string.IsNullOrEmpty(firstArgument)) - { - return enumerable.GetEnumerator(); - } - if (firstArgument.StartsWith("@", StringComparison.CurrentCulture)) + return enumerable.GetEnumerator(); + } + if (firstArgument.StartsWith("@", StringComparison.CurrentCulture)) + { + if (!firstArgument.StartsWith("@@", StringComparison.CurrentCulture)) { - if (!firstArgument.StartsWith("@@", StringComparison.CurrentCulture)) + var responseFileName = firstArgument.Remove(0, 1); + if (Path.GetExtension(responseFileName) == ".rsp" && File.Exists(responseFileName)) { - var responseFileName = firstArgument.Remove(0, 1); - if (Path.GetExtension(responseFileName) == ".rsp" && File.Exists(responseFileName)) - { - var responseFileContent = File.ReadAllLines(responseFileName); - return responseFileContent.AsEnumerable().GetEnumerator(); - } + var responseFileContent = File.ReadAllLines(responseFileName); + return responseFileContent.AsEnumerable().GetEnumerator(); } - var firstArgumentWithoutAt = firstArgument.Remove(0, 1); - return new[] { firstArgumentWithoutAt }.Concat(enumerable.Skip(1)).GetEnumerator(); } - return enumerable.GetEnumerator(); + var firstArgumentWithoutAt = firstArgument.Remove(0, 1); + return new[] { firstArgumentWithoutAt }.Concat(enumerable.Skip(1)).GetEnumerator(); } + return enumerable.GetEnumerator(); } } diff --git a/src/MGR.CommandLineParser/Extensions/EnumeratorExtensions.cs b/src/MGR.CommandLineParser/Extensions/EnumeratorExtensions.cs index 0b5f105..91091cf 100644 --- a/src/MGR.CommandLineParser/Extensions/EnumeratorExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/EnumeratorExtensions.cs @@ -1,26 +1,23 @@ - -// ReSharper disable once CheckNamespace -namespace System.Collections.Generic +namespace System.Collections.Generic; + +internal static class EnumeratorExtensions { - internal static class EnumeratorExtensions + internal static string? GetNextCommandLineItem(this IEnumerator argsEnumerator) { - internal static string GetNextCommandLineItem(this IEnumerator argsEnumerator) + if (argsEnumerator == null || !argsEnumerator.MoveNext()) { - if (argsEnumerator == null || !argsEnumerator.MoveNext()) - { - return null; - } - return argsEnumerator.Current; + return null; } + return argsEnumerator.Current; + } - internal static IEnumerator PrefixWith(this IEnumerator argsEnumerator, string prefix) + internal static IEnumerator PrefixWith(this IEnumerator argsEnumerator, string prefix) + { + var list = new List {prefix}; + while (argsEnumerator != null && argsEnumerator.MoveNext()) { - var list = new List {prefix}; - while (argsEnumerator != null && argsEnumerator.MoveNext()) - { - list.Add(argsEnumerator.Current); - } - return list.GetEnumerator(); + list.Add(argsEnumerator.Current); } + return list.GetEnumerator(); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Messages.cs b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Messages.cs index 75425d7..7aa98dd 100644 --- a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Messages.cs +++ b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Messages.cs @@ -6,98 +6,96 @@ using MGR.CommandLineParser; using MGR.CommandLineParser.Diagnostics; -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging; + +internal static partial class LoggerParserExtensions { - internal static partial class LoggerParserExtensions - { - private static readonly Action, Exception> CreationOfParserEngineAction = LoggerMessage.Define(LogLevel.Debug, CreateParserId(ParserEventId.CreationOfParserEngine), "Creation of the parser engine"); - private static readonly Action, Type, Exception> ParseForSpecificCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseForSpecificCommandType), "Parse for a specific command type: '{SpecificCommandType}'"); - private static readonly Action, Exception> NoCommandFoundAfterSpecificParsingAction = LoggerMessage.Define(LogLevel.Warning, CreateParserId(ParserEventId.NoCommandFoundAfterSpecificParsing), "No command found after parsing a specific type"); - private static readonly Action, Type, CommandParsingResultCode, int, Exception> CommandFoundAfterSpecificParsingAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandFoundAfterSpecificParsing), "Command found after parsing a specific type: Type '{CommandType}', ParsingResultCode: {ParsingResultCode}, Number of failed validations: {NbFailedValidations}"); - private static readonly Action, Type, Exception> ParseWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseWithDefaultCommandType), "Parsing with default command type: '{DefaultCommandType}'"); - private static readonly Action, string, Exception> ArgumentProvidedWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ArgumentProvidedWithDefaultCommandType), "Argument provided that can be command name: '{CommandName}'"); - private static readonly Action, string, Exception> CommandFoundWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandFoundWithDefaultCommandType), "Command type found for command name '{CommandName}' when parsing with default command type"); - private static readonly Action, string, Type, Exception> NoCommandFoundWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.NoCommandFoundWithDefaultCommandType), "No command found corresponding to commandName: '{CommandName}' when parsing with default command type. Fallback to parsing with specific command using the default command type '{DefaultCommandType}'"); - private static readonly Action, Type, Exception> NoArgumentProvidedWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.NoArgumentProvidedWithDefaultCommandType), "No arguments provided to parse with default command. Fallback to parsing specific command using the default command type '{DefaultCommandType}', but without additional arguments."); - private static readonly Action, Exception> ParseForNotAlreadyKnownCommandAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseForNotAlreadyKnownCommand), "Parse arguments for not already known command."); - private static readonly Action, Exception> NoCommandNameForNotAlreadyKnownCommandAction = LoggerMessage.Define(LogLevel.Error, CreateParserId(ParserEventId.NoCommandNameForNotAlreadyKnownCommand), "No command name provided for parsing not already known command."); - private static readonly Action, string, Exception> ParseUsingCommandNameAction = - LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseUsingCommandName), "Parse using command name '{CommandName}'"); - private static readonly Action, string, Exception> NoCommandTypeFoundForNotAlreadyKnownCommandAction = - LoggerMessage.Define(LogLevel.Error, CreateParserId(ParserEventId.NoCommandTypeFoundForNotAlreadyKnownCommand), "No CommandType found for the command name '{CommandName}'"); - private static readonly Action, string, Exception> CommandTypeFoundForNotAlreadyKnownCommandAction = - LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandTypeFoundForNotAlreadyKnownCommand), "CommandType found for the command name '{CommandName}'"); - private static readonly Action, Exception> ParsedCommandIsNotValidAction = - LoggerMessage.Define(LogLevel.Warning, CreateParserId(ParserEventId.ParsedCommandIsNotValid), "Parsed command is not valid"); + private static readonly Action, Exception?> CreationOfParserEngineAction = LoggerMessage.Define(LogLevel.Debug, CreateParserId(ParserEventId.CreationOfParserEngine), "Creation of the parser engine"); + private static readonly Action, Type, Exception?> ParseForSpecificCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseForSpecificCommandType), "Parse for a specific command type: '{SpecificCommandType}'"); + private static readonly Action, Exception?> NoCommandFoundAfterSpecificParsingAction = LoggerMessage.Define(LogLevel.Warning, CreateParserId(ParserEventId.NoCommandFoundAfterSpecificParsing), "No command found after parsing a specific type"); + private static readonly Action, Type, CommandParsingResultCode, int, Exception?> CommandFoundAfterSpecificParsingAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandFoundAfterSpecificParsing), "Command found after parsing a specific type: Type '{CommandType}', ParsingResultCode: {ParsingResultCode}, Number of failed validations: {NbFailedValidations}"); + private static readonly Action, Type, Exception?> ParseWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseWithDefaultCommandType), "Parsing with default command type: '{DefaultCommandType}'"); + private static readonly Action, string, Exception?> ArgumentProvidedWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ArgumentProvidedWithDefaultCommandType), "Argument provided that can be command name: '{CommandName}'"); + private static readonly Action, string, Exception?> CommandFoundWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandFoundWithDefaultCommandType), "Command type found for command name '{CommandName}' when parsing with default command type"); + private static readonly Action, string, Type, Exception?> NoCommandFoundWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.NoCommandFoundWithDefaultCommandType), "No command found corresponding to commandName: '{CommandName}' when parsing with default command type. Fallback to parsing with specific command using the default command type '{DefaultCommandType}'"); + private static readonly Action, Type, Exception?> NoArgumentProvidedWithDefaultCommandTypeAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.NoArgumentProvidedWithDefaultCommandType), "No arguments provided to parse with default command. Fallback to parsing specific command using the default command type '{DefaultCommandType}', but without additional arguments."); + private static readonly Action, Exception?> ParseForNotAlreadyKnownCommandAction = LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseForNotAlreadyKnownCommand), "Parse arguments for not already known command."); + private static readonly Action, Exception?> NoCommandNameForNotAlreadyKnownCommandAction = LoggerMessage.Define(LogLevel.Error, CreateParserId(ParserEventId.NoCommandNameForNotAlreadyKnownCommand), "No command name provided for parsing not already known command."); + private static readonly Action, string, Exception?> ParseUsingCommandNameAction = + LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.ParseUsingCommandName), "Parse using command name '{CommandName}'"); + private static readonly Action, string, Exception?> NoCommandTypeFoundForNotAlreadyKnownCommandAction = + LoggerMessage.Define(LogLevel.Error, CreateParserId(ParserEventId.NoCommandTypeFoundForNotAlreadyKnownCommand), "No CommandType found for the command name '{CommandName}'"); + private static readonly Action, string, Exception?> CommandTypeFoundForNotAlreadyKnownCommandAction = + LoggerMessage.Define(LogLevel.Information, CreateParserId(ParserEventId.CommandTypeFoundForNotAlreadyKnownCommand), "CommandType found for the command name '{CommandName}'"); + private static readonly Action, Exception?> ParsedCommandIsNotValidAction = + LoggerMessage.Define(LogLevel.Warning, CreateParserId(ParserEventId.ParsedCommandIsNotValid), "Parsed command is not valid"); - private static EventId CreateParserId(ParserEventId eventId) => new EventId((int)eventId, LoggerCategory.Parser.Name + "." + (int)eventId); + private static EventId CreateParserId(ParserEventId eventId) => new EventId((int)eventId, LoggerCategory.Parser.Name + "." + (int)eventId); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CreationOfParserEngine(this ILogger logger) - { - CreationOfParserEngineAction(logger, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void NoCommandFoundAfterSpecificParsing(this ILogger logger) - { - NoCommandFoundAfterSpecificParsingAction(logger, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CommandFoundAfterSpecificParsing(this ILogger logger, Type commandType, CommandParsingResultCode parsingResultCode, IEnumerable validationResults) - { - if (logger.IsEnabled(LogLevel.Information)) - { - CommandFoundAfterSpecificParsingAction(logger, commandType, parsingResultCode, validationResults.Count(), null); - } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ParseForSpecificCommandType(this ILogger logger, Type specificCommandType) - { - ParseForSpecificCommandTypeAction(logger, specificCommandType, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ParseWithDefaultCommandType(this ILogger logger, Type defaultCommandType) - { - ParseWithDefaultCommandTypeAction(logger, defaultCommandType, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ArgumentProvidedWithDefaultCommandType(this ILogger logger, string commandName) - { - ArgumentProvidedWithDefaultCommandTypeAction(logger, commandName, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CommandTypeFoundWithDefaultCommandType(this ILogger logger, string commandName) - { - CommandFoundWithDefaultCommandTypeAction(logger, commandName, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void NoCommandTypeFoundWithDefaultCommandType(this ILogger logger, string commandName, Type defaultCommandType) - { - NoCommandFoundWithDefaultCommandTypeAction(logger, commandName, defaultCommandType, null); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void NoArgumentProvidedWithDefaultCommandType(this ILogger logger, Type defaultCommandType) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CreationOfParserEngine(this ILogger logger) + { + CreationOfParserEngineAction(logger, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NoCommandFoundAfterSpecificParsing(this ILogger logger) + { + NoCommandFoundAfterSpecificParsingAction(logger, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandFoundAfterSpecificParsing(this ILogger logger, Type commandType, CommandParsingResultCode parsingResultCode, IEnumerable validationResults) + { + if (logger.IsEnabled(LogLevel.Information)) { - NoArgumentProvidedWithDefaultCommandTypeAction(logger, defaultCommandType, null); + CommandFoundAfterSpecificParsingAction(logger, commandType, parsingResultCode, validationResults.Count(), null); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ParseForNotAlreadyKnownCommand(this ILogger logger) => - ParseForNotAlreadyKnownCommandAction(logger, null); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void NoCommandNameForNotAlreadyKnownCommand(this ILogger logger) => - NoCommandNameForNotAlreadyKnownCommandAction(logger, null); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ParseUsingCommandName(this ILogger logger, string commandName) => - ParseUsingCommandNameAction(logger, commandName, null); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void NoCommandTypeFoundForNotAlreadyKnownCommand(this ILogger logger, string commandName) => - NoCommandTypeFoundForNotAlreadyKnownCommandAction(logger, commandName, null); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void CommandTypeFoundForNotAlreadyKnownCommand(this ILogger logger, string commandName) => - CommandTypeFoundForNotAlreadyKnownCommandAction(logger, commandName, null); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ParsedCommandIsNotValid(this ILogger logger) => - ParsedCommandIsNotValidAction(logger, null); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ParseForSpecificCommandType(this ILogger logger, Type specificCommandType) + { + ParseForSpecificCommandTypeAction(logger, specificCommandType, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ParseWithDefaultCommandType(this ILogger logger, Type defaultCommandType) + { + ParseWithDefaultCommandTypeAction(logger, defaultCommandType, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentProvidedWithDefaultCommandType(this ILogger logger, string commandName) + { + ArgumentProvidedWithDefaultCommandTypeAction(logger, commandName, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandTypeFoundWithDefaultCommandType(this ILogger logger, string commandName) + { + CommandFoundWithDefaultCommandTypeAction(logger, commandName, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NoCommandTypeFoundWithDefaultCommandType(this ILogger logger, string commandName, Type defaultCommandType) + { + NoCommandFoundWithDefaultCommandTypeAction(logger, commandName, defaultCommandType, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NoArgumentProvidedWithDefaultCommandType(this ILogger logger, Type defaultCommandType) + { + NoArgumentProvidedWithDefaultCommandTypeAction(logger, defaultCommandType, null); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ParseForNotAlreadyKnownCommand(this ILogger logger) => + ParseForNotAlreadyKnownCommandAction(logger, null); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NoCommandNameForNotAlreadyKnownCommand(this ILogger logger) => + NoCommandNameForNotAlreadyKnownCommandAction(logger, null); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ParseUsingCommandName(this ILogger logger, string commandName) => + ParseUsingCommandNameAction(logger, commandName, null); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NoCommandTypeFoundForNotAlreadyKnownCommand(this ILogger logger, string commandName) => + NoCommandTypeFoundForNotAlreadyKnownCommandAction(logger, commandName, null); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandTypeFoundForNotAlreadyKnownCommand(this ILogger logger, string commandName) => + CommandTypeFoundForNotAlreadyKnownCommandAction(logger, commandName, null); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ParsedCommandIsNotValid(this ILogger logger) => + ParsedCommandIsNotValidAction(logger, null); } diff --git a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Scope.cs b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Scope.cs index bbd8569..c97bb9e 100644 --- a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Scope.cs +++ b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.Scope.cs @@ -3,34 +3,32 @@ using System.Runtime.CompilerServices; using MGR.CommandLineParser.Diagnostics; -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging; + +internal static partial class LoggerParserExtensions { - internal static partial class LoggerParserExtensions - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IDisposable BeginParsingArguments(this ILogger logger, string correlationId) => logger.BeginScope(new Dictionary{{"ParsingId", correlationId}}); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IDisposable? BeginParsingArguments(this ILogger logger, string correlationId) => logger.BeginScope(new Dictionary{{"ParsingId", correlationId}}); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IDisposable BeginParsingForSpecificCommandType(this ILogger logger, Type specificCommandType) - { - var scope = logger.BeginScope(new Dictionary { { "SpecificCommandType", specificCommandType } }); - logger.ParseForSpecificCommandType(specificCommandType); - return scope; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IDisposable BeginParsingWithDefaultCommandType(this ILogger logger, Type defaultCommandType) - { - var scope = logger.BeginScope(new Dictionary { { "DefaultCommandType", defaultCommandType } }); - logger.ParseWithDefaultCommandType(defaultCommandType); - return scope; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static IDisposable BeginParsingUsingCommandName(this ILogger logger, string commandName) - { - var scope = logger.BeginScope(new Dictionary { { "CommandName", commandName } }); - logger.ParseUsingCommandName(commandName); - return scope; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IDisposable? BeginParsingForSpecificCommandType(this ILogger logger, Type specificCommandType) + { + var scope = logger.BeginScope(new Dictionary { { "SpecificCommandType", specificCommandType } }); + logger.ParseForSpecificCommandType(specificCommandType); + return scope; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IDisposable? BeginParsingWithDefaultCommandType(this ILogger logger, Type defaultCommandType) + { + var scope = logger.BeginScope(new Dictionary { { "DefaultCommandType", defaultCommandType } }); + logger.ParseWithDefaultCommandType(defaultCommandType); + return scope; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IDisposable? BeginParsingUsingCommandName(this ILogger logger, string commandName) + { + var scope = logger.BeginScope(new Dictionary { { "CommandName", commandName } }); + logger.ParseUsingCommandName(commandName); + return scope; } } diff --git a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.cs b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.cs index c99e908..c3c22df 100644 --- a/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/LoggerParserExtensions.cs @@ -1,25 +1,23 @@ -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging; + +internal static partial class LoggerParserExtensions { - internal static partial class LoggerParserExtensions + private enum ParserEventId { - private enum ParserEventId - { - CreationOfParserEngine = 1000, - ParseForSpecificCommandType, - NoCommandFoundAfterSpecificParsing, - CommandFoundAfterSpecificParsing, - ParseWithDefaultCommandType, - ArgumentProvidedWithDefaultCommandType, - CommandFoundWithDefaultCommandType, - NoCommandFoundWithDefaultCommandType, - NoArgumentProvidedWithDefaultCommandType, - ParseForNotAlreadyKnownCommand, - NoCommandNameForNotAlreadyKnownCommand, - ParseUsingCommandName, - NoCommandTypeFoundForNotAlreadyKnownCommand, - CommandTypeFoundForNotAlreadyKnownCommand, - ParsedCommandIsNotValid - } + CreationOfParserEngine = 1000, + ParseForSpecificCommandType, + NoCommandFoundAfterSpecificParsing, + CommandFoundAfterSpecificParsing, + ParseWithDefaultCommandType, + ArgumentProvidedWithDefaultCommandType, + CommandFoundWithDefaultCommandType, + NoCommandFoundWithDefaultCommandType, + NoArgumentProvidedWithDefaultCommandType, + ParseForNotAlreadyKnownCommand, + NoCommandNameForNotAlreadyKnownCommand, + ParseUsingCommandName, + NoCommandTypeFoundForNotAlreadyKnownCommand, + CommandTypeFoundForNotAlreadyKnownCommand, + ParsedCommandIsNotValid } } diff --git a/src/MGR.CommandLineParser/Extensions/ParameterInfoExtensions.cs b/src/MGR.CommandLineParser/Extensions/ParameterInfoExtensions.cs index f8a2ee6..20c367d 100644 --- a/src/MGR.CommandLineParser/Extensions/ParameterInfoExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/ParameterInfoExtensions.cs @@ -1,35 +1,33 @@ -// ReSharper disable once CheckNamespace -namespace System.Reflection +namespace System.Reflection; + +internal static class ParameterInfoExtensions { - internal static class ParameterInfoExtensions + public static bool TryGetDefaultValue(this ParameterInfo parameter, out object? defaultValue) { - public static bool TryGetDefaultValue(this ParameterInfo parameter, out object defaultValue) + var useDefaultValueFromParameterInfo = true; + defaultValue = null; + bool hasDefaultValue; + try { - var useDefaultValueFromParameterInfo = true; - defaultValue = null; - bool hasDefaultValue; - try - { - hasDefaultValue = parameter.HasDefaultValue; - } - catch (FormatException) when (parameter.ParameterType == typeof(DateTime)) + hasDefaultValue = parameter.HasDefaultValue; + } + catch (FormatException) when (parameter.ParameterType == typeof(DateTime)) + { + hasDefaultValue = true; + useDefaultValueFromParameterInfo = false; + } + if (hasDefaultValue) + { + if (useDefaultValueFromParameterInfo) { - hasDefaultValue = true; - useDefaultValueFromParameterInfo = false; + defaultValue = parameter.DefaultValue; } - if (hasDefaultValue) - { - if (useDefaultValueFromParameterInfo) - { - defaultValue = parameter.DefaultValue; - } - if (defaultValue == null && parameter.ParameterType.IsValueType) - { - defaultValue = Activator.CreateInstance(parameter.ParameterType); - } + if (defaultValue == null && parameter.ParameterType.IsValueType) + { + defaultValue = Activator.CreateInstance(parameter.ParameterType); } - return hasDefaultValue; } + return hasDefaultValue; } } diff --git a/src/MGR.CommandLineParser/Extensions/ParserExtensions.cs b/src/MGR.CommandLineParser/Extensions/ParserExtensions.cs deleted file mode 100644 index 9b0dd95..0000000 --- a/src/MGR.CommandLineParser/Extensions/ParserExtensions.cs +++ /dev/null @@ -1,55 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Diagnostics.CodeAnalysis; -//using JetBrains.Annotations; -//using MGR.CommandLineParser.Command; -//using Microsoft.Extensions.DependencyInjection; - -//// ReSharper disable once CheckNamespace -//namespace MGR.CommandLineParser -//{ -// /// -// /// Extension's methods for . -// /// -// public static class ParserExtensions -// { -// private static readonly Lazy ServiceProviderLazy = new Lazy( -// CreateRootServiceProvider); -// private static ServiceProvider CreateRootServiceProvider() -// { -// var serviceCollection = new ServiceCollection(); -// serviceCollection.AddCommandLineParser().AddClassBasedCommands(); -// var serviceProvider = serviceCollection.BuildServiceProvider(); -// return serviceProvider; -// } - -// ///// -// ///// Parse the supplied arguments for a specific command. The name of the command should not be in the arguments list using the default . -// ///// -// ///// The type of the command. -// ///// The current parser. -// ///// The arguments. -// ///// This method can only be used with class-based command. -// ///// The result of the parsing of the arguments. -// //public static ParsingResult Parse(this IParser parser, [ItemNotNull] IEnumerable arguments) -// // where TCommand : class, ICommand => parser.Parse(arguments, ServiceProviderLazy.Value.CreateScope().ServiceProvider); - -// ///// -// ///// Parse the supplied arguments using the default . -// ///// -// ///// The current parser. -// ///// The arguments. -// ///// The result of the parsing of the arguments. -// //public static ParsingResult Parse(this IParser parser, [ItemNotNull] IEnumerable arguments) => parser.Parse(arguments, ServiceProviderLazy.Value.CreateScope().ServiceProvider); - -// ///// -// ///// Parse the supplied arguments using the default . If the name of the command is not the first argument, fallback to the specified command. The default command can only be class-based. -// ///// -// ///// The type of the default command. -// ///// The current parser. -// ///// The arguments. -// ///// The result of the parsing of the arguments. -// //[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] -// //public static ParsingResult ParseWithDefaultCommand(this IParser parser, [ItemNotNull] IEnumerable arguments) where TCommand : class, ICommand => parser.ParseWithDefaultCommand(arguments, ServiceProviderLazy.Value.CreateScope().ServiceProvider); -// } -//} diff --git a/src/MGR.CommandLineParser/Extensions/PropertyInfoExtensions.cs b/src/MGR.CommandLineParser/Extensions/PropertyInfoExtensions.cs index a589984..a133e7c 100644 --- a/src/MGR.CommandLineParser/Extensions/PropertyInfoExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/PropertyInfoExtensions.cs @@ -2,224 +2,240 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; -using JetBrains.Annotations; using MGR.CommandLineParser; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; using MGR.CommandLineParser.Extensibility.Converters; -// ReSharper disable once CheckNamespace -namespace System.Reflection +namespace System.Reflection; + +internal static class PropertyInfoExtensions { - internal static class PropertyInfoExtensions + internal static bool IsValidOptionProperty(this PropertyInfo source) { - internal static bool IsValidOptionProperty(this PropertyInfo source) - { - Guard.NotNull(source, nameof(source)); + Guard.NotNull(source, nameof(source)); - return source.CanWrite || source.PropertyType.IsMultiValuedType(); - } + return source.CanWrite || source.PropertyType.IsMultiValuedType(); + } - internal static IConverter ExtractConverter(this PropertyInfo source, List converters, string optionName, string commandName) + internal static IConverter ExtractConverter(this PropertyInfo source, List converters, string optionName, string commandName) + { + Guard.NotNull(source, nameof(source)); + Guard.NotNullOrEmpty(optionName, nameof(optionName)); + Guard.NotNullOrEmpty(commandName, nameof(commandName)); + + var converter = GetConverterFromAttribute(source, commandName) + ?? GetKeyValueConverterFromAttribute(source, optionName, commandName) + ?? FindConverter(source, converters, optionName, commandName); + if (converter == null) { - Guard.NotNull(source, nameof(source)); - Guard.NotNullOrEmpty(optionName, nameof(optionName)); - Guard.NotNullOrEmpty(commandName, nameof(commandName)); - - var converter = GetConverterFromAttribute(source, commandName) - ?? GetKeyValueConverterFromAttribute(source, optionName, commandName) - ?? FindConverter(source, converters, optionName, commandName); - if (converter == null) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoConverterFound(optionName, commandName, source.PropertyType)); - } - return converter; + throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoConverterFound(optionName, commandName, source.PropertyType)); } - private static IConverter FindConverter(PropertyInfo propertyInfo, List converters, string optionName, string commandName) + return converter; + } + private static IConverter FindConverter(PropertyInfo propertyInfo, List converters, string optionName, string commandName) + { + if (propertyInfo.PropertyType.IsDictionaryType()) { - if (propertyInfo.PropertyType.IsDictionaryType()) - { - var keyConverter = FindKeyConverter(propertyInfo, converters, optionName, commandName); - var valueConverter = FindValueConverter(propertyInfo, converters, optionName, commandName); + var keyConverter = FindKeyConverter(propertyInfo, converters, optionName, commandName); + var valueConverter = FindValueConverter(propertyInfo, converters, optionName, commandName); - return new KeyValueConverter(keyConverter, valueConverter); - } - var converter = GetConverterFromType(propertyInfo.PropertyType, converters); - return converter; + return new KeyValueConverter(keyConverter, valueConverter); } - private static IConverter FindValueConverter(PropertyInfo propertyInfo, IEnumerable converters, string optionName, string commandName) + var converter = GetConverterFromType(propertyInfo.PropertyType, converters); + return converter; + } + private static IConverter FindValueConverter(PropertyInfo propertyInfo, IEnumerable converters, string optionName, string commandName) + { + var valueType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(false); + if(valueType == null) { - var valueType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(false); - var valueConverter = GetConverterFromType(valueType, converters); - if (valueConverter == null) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoValueConverterFound(optionName, commandName, valueType)); - } - return valueConverter; + throw new InvalidOperationException("Unable to find the underlying dictionary value type"); } - private static IConverter FindKeyConverter(PropertyInfo propertyInfo, IEnumerable converters, string optionName, string commandName) + var valueConverter = GetConverterFromType(valueType, converters); + if (valueConverter == null) { - var keyType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(true); - var keyConverter = GetConverterFromType(keyType, converters); - if (keyConverter == null) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoKeyConverterFound(optionName, commandName, keyType)); - } - return keyConverter; + throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoValueConverterFound(optionName, commandName, valueType)); } + return valueConverter; + } + private static IConverter FindKeyConverter(PropertyInfo propertyInfo, IEnumerable converters, string optionName, string commandName) + { + var keyType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(true); + if (keyType == null) + { + throw new InvalidOperationException("Unable to find the underlying dictionary key type"); + } + var keyConverter = GetConverterFromType(keyType, converters); + if (keyConverter == null) + { + throw new CommandLineParserException(Constants.ExceptionMessages.ParserNoKeyConverterFound(optionName, commandName, keyType)); + } + return keyConverter; + } - private static IConverter GetConverterFromAttribute(PropertyInfo propertyInfo, string commandName) + private static IConverter? GetConverterFromAttribute(PropertyInfo propertyInfo, string commandName) + { + var genericConverterAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterAttribute<>), true).FirstOrDefault(); + if (genericConverterAttribute != null) { - var genericConverterAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterAttribute<>), true).FirstOrDefault(); - if (genericConverterAttribute != null) + var converterType = genericConverterAttribute.GetType().GetGenericArguments()[0]; + var converter = (IConverter)Activator.CreateInstance(converterType); + + if (!converter.CanConvertTo(propertyInfo.PropertyType)) { - var converterType = genericConverterAttribute.GetType().GetGenericArguments()[0]; - var converter = Activator.CreateInstance(converterType) as IConverter; - - if (!converter.CanConvertTo(propertyInfo.PropertyType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyInfo.Name, commandName, propertyInfo.PropertyType, converter.TargetType)); - } - return converter; + throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyInfo.Name, commandName, propertyInfo.PropertyType, converter.TargetType)); } + return converter; + } #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterAttribute), true).FirstOrDefault() as ConverterAttribute; + var converterAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterAttribute), true).FirstOrDefault() as ConverterAttribute; #pragma warning restore CS0618 // Type or member is obsolete - if (converterAttribute != null) - { - var converter = converterAttribute.BuildConverter(); + if (converterAttribute != null) + { + var converter = converterAttribute.BuildConverter(); - if (!converter.CanConvertTo(propertyInfo.PropertyType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyInfo.Name, commandName, propertyInfo.PropertyType, converter.TargetType)); - } - return converter; + if (!converter.CanConvertTo(propertyInfo.PropertyType)) + { + throw new CommandLineParserException(Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyInfo.Name, commandName, propertyInfo.PropertyType, converter.TargetType)); } - return null; + return converter; } + return null; + } - private static IConverter GetKeyValueConverterFromAttribute(PropertyInfo propertyInfo, string optionName, string commandName) + private static IConverter? GetKeyValueConverterFromAttribute(PropertyInfo propertyInfo, string optionName, string commandName) + { + var genericConverterKeyValuePairAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterKeyValueAttribute<,>), true).FirstOrDefault(); + if (genericConverterKeyValuePairAttribute != null) { - var genericConverterKeyValuePairAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterKeyValueAttribute<,>), true).FirstOrDefault(); - if (genericConverterKeyValuePairAttribute != null) + if (!propertyInfo.PropertyType.IsDictionaryType()) { - if (!propertyInfo.PropertyType.IsDictionaryType()) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(optionName, commandName)); - } - var genericArguments = genericConverterKeyValuePairAttribute.GetType().GetGenericArguments(); - var keyConverterType = genericArguments[0]; - var keyConverter = Activator.CreateInstance(keyConverterType) as IConverter; - var valueConverterType = genericArguments.Length == 1 ? typeof(MGR.CommandLineParser.Extensibility.Converters.StringConverter) : genericConverterKeyValuePairAttribute.GetType().GetGenericArguments()[1]; - var valueConverter = Activator.CreateInstance(valueConverterType) as IConverter; - - return new KeyValueConverter(keyConverter, valueConverter); + throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(optionName, commandName)); } + var genericArguments = genericConverterKeyValuePairAttribute.GetType().GetGenericArguments(); + var keyConverterType = genericArguments[0]; + var keyConverter = (IConverter)Activator.CreateInstance(keyConverterType); + var valueConverterType = genericArguments.Length == 1 ? typeof(MGR.CommandLineParser.Extensibility.Converters.StringConverter) : genericConverterKeyValuePairAttribute.GetType().GetGenericArguments()[1]; + var valueConverter = (IConverter)Activator.CreateInstance(valueConverterType); + + return new KeyValueConverter(keyConverter, valueConverter); + } #pragma warning disable CS0618 // Type or member is obsolete - var converterKeyValuePairAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterKeyValueAttribute), true).FirstOrDefault() as ConverterKeyValueAttribute; + var converterKeyValuePairAttribute = propertyInfo.GetCustomAttributes(typeof(ConverterKeyValueAttribute), true).FirstOrDefault() as ConverterKeyValueAttribute; #pragma warning restore CS0618 // Type or member is obsolete - if (converterKeyValuePairAttribute != null) + if (converterKeyValuePairAttribute != null) + { + if (!propertyInfo.PropertyType.IsDictionaryType()) { - if (!propertyInfo.PropertyType.IsDictionaryType()) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(optionName, commandName)); - } - var keyConverter = GetKeyConverter(propertyInfo, optionName, commandName, converterKeyValuePairAttribute); - var valueConverter = GetValueConverter(propertyInfo, optionName, commandName, converterKeyValuePairAttribute); - - return new KeyValueConverter(keyConverter, valueConverter); + throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(optionName, commandName)); } - return null; + var keyConverter = GetKeyConverter(propertyInfo, optionName, commandName, converterKeyValuePairAttribute); + var valueConverter = GetValueConverter(propertyInfo, optionName, commandName, converterKeyValuePairAttribute); + + return new KeyValueConverter(keyConverter, valueConverter); } + return null; + } #pragma warning disable CS0618 // Type or member is obsolete - private static IConverter GetValueConverter(PropertyInfo propertyInfo, string optionName, string commandName, ConverterKeyValueAttribute converterKeyValuePairAttribute) + private static IConverter GetValueConverter(PropertyInfo propertyInfo, string optionName, string commandName, ConverterKeyValueAttribute converterKeyValuePairAttribute) #pragma warning restore CS0618 // Type or member is obsolete + { + var valueType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(false); + if (valueType == null) { - var valueType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(false); - var valueConverter = converterKeyValuePairAttribute.BuildValueConverter(); - if (!valueType.IsType(valueConverter.TargetType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractValueConverterIsNotValid(optionName, commandName, valueType, valueConverter.TargetType)); - } - return valueConverter; + throw new InvalidOperationException("Unable to find the underlying dictionary value type"); } + var valueConverter = converterKeyValuePairAttribute.BuildValueConverter(); + if (!valueType.IsType(valueConverter.TargetType)) + { + throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractValueConverterIsNotValid(optionName, commandName, valueType, valueConverter.TargetType)); + } + return valueConverter; + } #pragma warning disable CS0618 // Type or member is obsolete - private static IConverter GetKeyConverter(PropertyInfo propertyInfo, string optionName, string commandName, ConverterKeyValueAttribute converterKeyValuePairAttribute) + private static IConverter GetKeyConverter(PropertyInfo propertyInfo, string optionName, string commandName, ConverterKeyValueAttribute converterKeyValuePairAttribute) #pragma warning restore CS0618 // Type or member is obsolete + { + var keyType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(true); + if (keyType == null) { - var keyType = propertyInfo.PropertyType.GetUnderlyingDictionaryType(true); - var keyConverter = converterKeyValuePairAttribute.BuildKeyConverter(); - if (!keyType.IsType(keyConverter.TargetType)) - { - throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractKeyConverterIsNotValid(optionName, commandName, keyType, keyConverter.TargetType)); - } - - return keyConverter; + throw new InvalidOperationException("Unable to find the underlying dictionary key type"); } - - private static IConverter GetConverterFromType(Type type, IEnumerable converters) + var keyConverter = converterKeyValuePairAttribute.BuildKeyConverter(); + if (!keyType.IsType(keyConverter.TargetType)) { - var converter = (from kvp in converters - where kvp.CanConvertTo(type) - select kvp).FirstOrDefault(); - return converter; + throw new CommandLineParserException(Constants.ExceptionMessages.ParserExtractKeyConverterIsNotValid(optionName, commandName, keyType, keyConverter.TargetType)); } - internal static bool ExtractIsRequiredMetadata(this PropertyInfo source) - { - Guard.NotNull(source, nameof(source)); + return keyConverter; + } - var requiredAttribute = source.GetCustomAttributes(typeof(RequiredAttribute), true).FirstOrDefault() as RequiredAttribute; - return requiredAttribute != null; - } + private static IConverter GetConverterFromType(Type type, IEnumerable converters) + { + var converter = (from kvp in converters + where kvp.CanConvertTo(type) + select kvp).FirstOrDefault(); + return converter; + } - [NotNull] - internal static ClassBasedOptionDisplayInfo ExtractOptionDisplayInfoMetadata(this PropertyInfo source, IEnumerable optionAlternateNameGenerators) - { - Guard.NotNull(source, nameof(source)); - var optionDisplayInfo = new ClassBasedOptionDisplayInfo(source, optionAlternateNameGenerators); - return optionDisplayInfo; - } + internal static bool ExtractIsRequiredMetadata(this PropertyInfo source) + { + Guard.NotNull(source, nameof(source)); - internal static object ExtractDefaultValue([NotNull] this PropertyInfo source, [NotNull] Func valueConverter) - { - Guard.NotNull(source, nameof(source)); - Guard.NotNull(valueConverter, nameof(valueConverter)); + var requiredAttribute = source.GetCustomAttributes(typeof(RequiredAttribute), true).FirstOrDefault() as RequiredAttribute; + return requiredAttribute != null; + } - if (!source.PropertyType.IsMultiValuedType()) - { - var defaultValueAttribute = source.GetCustomAttributes(typeof(DefaultValueAttribute), true).OfType().FirstOrDefault(); - var originalDefaultValue = defaultValueAttribute?.Value; - var defaultValue = valueConverter(originalDefaultValue); - return defaultValue; - } - return null; - } - internal static string ExtractDefaultValue([NotNull] this PropertyInfo source) - { - Guard.NotNull(source, nameof(source)); + internal static ClassBasedOptionDisplayInfo ExtractOptionDisplayInfoMetadata(this PropertyInfo source, IEnumerable optionAlternateNameGenerators) + { + Guard.NotNull(source, nameof(source)); + var optionDisplayInfo = new ClassBasedOptionDisplayInfo(source, optionAlternateNameGenerators); + return optionDisplayInfo; + } - if (!source.PropertyType.IsMultiValuedType()) + internal static object? ExtractDefaultValue(this PropertyInfo source, Func valueConverter) + { + Guard.NotNull(source, nameof(source)); + Guard.NotNull(valueConverter, nameof(valueConverter)); + + if (!source.PropertyType.IsMultiValuedType()) + { + var defaultValueAttribute = source.GetCustomAttributes(typeof(DefaultValueAttribute), true).OfType().FirstOrDefault(); + var originalDefaultValue = defaultValueAttribute?.Value; + if (originalDefaultValue == null) { - var defaultValueAttribute = source.GetCustomAttributes(typeof(DefaultValueAttribute), true).OfType().FirstOrDefault(); - var originalDefaultValue = defaultValueAttribute?.Value; - return originalDefaultValue?.ToString(); + return null; } - return null; + var defaultValue = valueConverter(originalDefaultValue); + return defaultValue; } + return null; + } + internal static string ExtractDefaultValue(this PropertyInfo source) + { + Guard.NotNull(source, nameof(source)); - /// - /// Indicates if the given should be ignored as option by the parse. - /// - /// The . - /// true if the should be ignored, false otherwise. - internal static bool ShouldBeIgnored(this PropertyInfo source) + if (!source.PropertyType.IsMultiValuedType()) { - Guard.NotNull(source, nameof(source)); - - return source.GetCustomAttributes(typeof(IgnoreOptionPropertyAttribute), true).Any(); + var defaultValueAttribute = source.GetCustomAttributes(typeof(DefaultValueAttribute), true).OfType().FirstOrDefault(); + var originalDefaultValue = defaultValueAttribute?.Value; + return originalDefaultValue?.ToString() ?? string.Empty; } + return string.Empty; + } + + /// + /// Indicates if the given should be ignored as option by the parse. + /// + /// The . + /// true if the should be ignored, false otherwise. + internal static bool ShouldBeIgnored(this PropertyInfo source) + { + Guard.NotNull(source, nameof(source)); + + return source.GetCustomAttributes(typeof(IgnoreOptionPropertyAttribute), true).Any(); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/ServiceCollectionExtensions.cs b/src/MGR.CommandLineParser/Extensions/ServiceCollectionExtensions.cs index 9177108..e30c6d4 100644 --- a/src/MGR.CommandLineParser/Extensions/ServiceCollectionExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/ServiceCollectionExtensions.cs @@ -5,67 +5,65 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -// ReSharper disable once CheckNamespace -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Extensions methods for the type . +/// +public static class ServiceCollectionExtensions { /// - /// Extensions methods for the type . + /// Adds the default services for the command line parsing. No are registered. Add one or more via the returned . /// - public static class ServiceCollectionExtensions + /// The to add the parser's services to. + /// The so that can be registered. + public static CommandLineParserBuilder AddCommandLineParser(this IServiceCollection services) { - /// - /// Adds the default services for the command line parsing. No are registered. Add one or more via the returned . - /// - /// The to add the parser's services to. - /// The so that can be registered. - public static CommandLineParserBuilder AddCommandLineParser(this IServiceCollection services) - { - var builder = services.AddCommandLineParser(options => {}); + var builder = services.AddCommandLineParser(options => {}); - return builder; - } + return builder; + } - /// - /// Adds the default services for the command line parsing. No are registered. Add one or more via the returned . - /// - /// The to add the parser's services to. - /// An to configure the provided - /// . - /// The so that can be registered. - public static CommandLineParserBuilder AddCommandLineParser(this IServiceCollection services, Action configureParserOptions) - { - services.AddLogging(); - services.AddOptions(); + /// + /// Adds the default services for the command line parsing. No are registered. Add one or more via the returned . + /// + /// The to add the parser's services to. + /// An to configure the provided + /// . + /// The so that can be registered. + public static CommandLineParserBuilder AddCommandLineParser(this IServiceCollection services, Action configureParserOptions) + { + services.AddLogging(); + services.AddOptions(); - services.Configure(configureParserOptions); - services.TryAddSingleton(); - services.TryAddScoped(); - services.TryAddScoped(); - services.TryAddScoped(serviceProvider => - { - var factory = serviceProvider.GetRequiredService(); - return factory.CreateParser(); - }); + services.Configure(configureParserOptions); + services.TryAddSingleton(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(serviceProvider => + { + var factory = serviceProvider.GetRequiredService(); + return factory.CreateParser(); + }); - services - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton(); + services + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(); - return new CommandLineParserBuilder(services); - } + return new CommandLineParserBuilder(services); } } diff --git a/src/MGR.CommandLineParser/Extensions/StringExtensions.cs b/src/MGR.CommandLineParser/Extensions/StringExtensions.cs index 5d81554..5baa46a 100644 --- a/src/MGR.CommandLineParser/Extensions/StringExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/StringExtensions.cs @@ -3,55 +3,53 @@ using System.Text; using MGR.CommandLineParser; -// ReSharper disable once CheckNamespace -namespace System +namespace System; + +internal static class StringExtensions { - internal static class StringExtensions + public static bool StartsWith(this string source, StringComparison comparisonType, params string[] values) { - public static bool StartsWith(this string source, StringComparison comparisonType, params string[] values) - { - Guard.NotNull(source, nameof(source)); + Guard.NotNull(source, nameof(source)); - return values.Any(value => source.StartsWith(value, comparisonType)); - } - public static int IndexOf(this string source, params char[] values) - { - Guard.NotNull(source, nameof(source)); + return values.Any(value => source.StartsWith(value, comparisonType)); + } + public static int IndexOf(this string source, params char[] values) + { + Guard.NotNull(source, nameof(source)); - var firstIndex = values.Select(c => source.IndexOf(c)) - .FirstOrDefault(index => index >= 0); - return firstIndex; - } + var firstIndex = values.Select(c => source.IndexOf(c)) + .FirstOrDefault(index => index >= 0); + return firstIndex; + } - public static string AsKebabCase(this string source) + public static string AsKebabCase(this string source) + { + if (string.IsNullOrEmpty(source)) { - if (string.IsNullOrEmpty(source)) - { - return source; - } + return source; + } - var builder = new StringBuilder(); - builder.Append(char.ToLower(source.First(), CultureInfo.CurrentUICulture)); - var introduceDash = false; - foreach (var c in source.Skip(1)) + var builder = new StringBuilder(); + builder.Append(char.ToLower(source.First(), CultureInfo.CurrentUICulture)); + var introduceDash = false; + foreach (var c in source.Skip(1)) + { + if (char.IsUpper(c)) { - if (char.IsUpper(c)) - { - if (introduceDash) - { - builder.Append('-'); - introduceDash = false; - } - builder.Append(char.ToLower(c, CultureInfo.CurrentUICulture)); - } - else + if (introduceDash) { - introduceDash = true; - builder.Append(c); + builder.Append('-'); + introduceDash = false; } + builder.Append(char.ToLower(c, CultureInfo.CurrentUICulture)); + } + else + { + introduceDash = true; + builder.Append(c); } - - return builder.ToString(); } + + return builder.ToString(); } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Extensions/TypeExtensions.cs b/src/MGR.CommandLineParser/Extensions/TypeExtensions.cs index 90de96c..3bec860 100644 --- a/src/MGR.CommandLineParser/Extensions/TypeExtensions.cs +++ b/src/MGR.CommandLineParser/Extensions/TypeExtensions.cs @@ -2,126 +2,151 @@ using System.Linq; using MGR.CommandLineParser; -// ReSharper disable once CheckNamespace -namespace System +namespace System; + +internal static class TypeExtensions { - internal static class TypeExtensions + internal static bool IsCollectionType(this Type source) { - internal static bool IsCollectionType(this Type source) - { - Guard.NotNull(source, nameof(source)); + Guard.NotNull(source, nameof(source)); - return source.GetCollectionType() != null && !source.IsDictionaryType(); - } + return source.GetCollectionType() != null && !source.IsDictionaryType(); + } - internal static Type GetCollectionType(this Type source) - { - Guard.NotNull(source, nameof(source)); + internal static Type GetCollectionType(this Type source) + { + Guard.NotNull(source, nameof(source)); - return GetInterfaceType(source, typeof (ICollection<>)); - } + return GetInterfaceType(source, typeof (ICollection<>)); + } - internal static Type GetUnderlyingGenericType(this Type source, int index = 0) - { - Guard.NotNull(source, nameof(source)); + internal static Type? GetUnderlyingGenericType(this Type source, int index = 0) + { + Guard.NotNull(source, nameof(source)); - if (!source.IsGenericType) - { - return null; - } - return source.GetGenericArguments()[index]; + if (!source.IsGenericType) + { + return null; } + return source.GetGenericArguments()[index]; + } - internal static Type GetUnderlyingCollectionType(this Type source, int index = 0) - { - Guard.NotNull(source, nameof(source)); + internal static Type? GetUnderlyingCollectionType(this Type source, int index = 0) + { + Guard.NotNull(source, nameof(source)); - var collectionType = source.GetCollectionType(); - if (collectionType == null) - { - return null; - } - return collectionType.GetUnderlyingGenericType(index); + var collectionType = source.GetCollectionType(); + if (collectionType == null) + { + return null; } + return collectionType.GetUnderlyingGenericType(index); + } - internal static Type GetUnderlyingDictionaryType(this Type source, bool key) - { - Guard.NotNull(source, nameof(source)); + internal static Type? GetUnderlyingDictionaryType(this Type source, bool key) + { + Guard.NotNull(source, nameof(source)); - var collectionType = source.GetDictionaryType(); - if (collectionType == null) - { - return null; - } - return collectionType.GetUnderlyingGenericType(key ? 0 : 1); + var collectionType = source.GetDictionaryType(); + if (collectionType == null) + { + return null; } + return collectionType.GetUnderlyingGenericType(key ? 0 : 1); + } - internal static bool IsMultiValuedType(this Type source) - { - Guard.NotNull(source, nameof(source)); + internal static bool IsMultiValuedType(this Type source) + { + Guard.NotNull(source, nameof(source)); - return source.IsCollectionType() || source.IsDictionaryType(); - } + return source.IsCollectionType() || source.IsDictionaryType(); + } - internal static bool IsDictionaryType(this Type source) - { - Guard.NotNull(source, nameof(source)); + internal static bool IsDictionaryType(this Type source) + { + Guard.NotNull(source, nameof(source)); - return source.GetDictionaryType() != null; - } + return source.GetDictionaryType() != null; + } - internal static Type GetDictionaryType(this Type source) - { - Guard.NotNull(source, nameof(source)); + internal static Type GetDictionaryType(this Type source) + { + Guard.NotNull(source, nameof(source)); - return source.GetInterfaceType(typeof (IDictionary<,>)); - } + return source.GetInterfaceType(typeof (IDictionary<,>)); + } - private static Type GetInterfaceType(this Type source, Type interfaceType) + private static Type GetInterfaceType(this Type source, Type interfaceType) + { + if (source.IsGenericType && source.GetGenericTypeDefinition() == interfaceType) { - if (source.IsGenericType && source.GetGenericTypeDefinition() == interfaceType) - { - return source; - } - return (from t in source.GetInterfaces() - where t.IsGenericType && t.GetGenericTypeDefinition() == interfaceType - select t).SingleOrDefault(); + return source; } + return (from t in source.GetInterfaces() + where t.IsGenericType && t.GetGenericTypeDefinition() == interfaceType + select t).SingleOrDefault(); + } + + internal static bool IsType(this Type source) + { + Guard.NotNull(source, nameof(source)); + return source.IsType(typeof (T)) && source.IsClass; + } + internal static bool IsType(this Type source, Type baseType) + { + Guard.NotNull(source, nameof(source)); - internal static bool IsType(this Type source) + if (source == baseType) { - Guard.NotNull(source, nameof(source)); - return source.IsType(typeof (T)) && source.IsClass; + return true; } - internal static bool IsType(this Type source, Type baseType) - { - Guard.NotNull(source, nameof(source)); - if (source == baseType) + return !source.IsAbstract && (baseType.IsAssignableFrom(source) || IsAssignableToGenericType(source, baseType)); + } + private static bool IsAssignableToGenericType(Type source, Type interfaceType) + { + var interfaceTypes = source.GetInterfaces(); + + foreach (var it in interfaceTypes) + { + if (it.IsGenericType && it.GetGenericTypeDefinition() == interfaceType) { return true; } - - return !source.IsAbstract && baseType.IsAssignableFrom(source); } - internal static string GetFullCommandName(this Type commandType) + if (source.IsGenericType && source.GetGenericTypeDefinition() == interfaceType) { - Guard.NotNull(commandType, nameof(commandType)); + return true; + } - var fullCommandName = commandType.Name; - if (fullCommandName.EndsWith(Constants.CommandSuffix, StringComparison.Ordinal)) - { - fullCommandName = fullCommandName.Substring(0, fullCommandName.Length - Constants.CommandSuffix.Length); - } - return fullCommandName; + Type baseType = source.BaseType; + if (baseType == null) + { + return false; } - internal static TAttribute GetAttribute(this Type source) - where TAttribute : Attribute + return IsAssignableToGenericType(baseType, interfaceType); + } + + + + internal static string GetFullCommandName(this Type commandType) + { + Guard.NotNull(commandType, nameof(commandType)); + + var fullCommandName = commandType.Name; + if (fullCommandName.EndsWith(Constants.CommandSuffix, StringComparison.Ordinal)) { - var attribute = source.GetCustomAttributes(typeof(TAttribute), true).FirstOrDefault() as TAttribute; - return attribute; + fullCommandName = fullCommandName.Substring(0, fullCommandName.Length - Constants.CommandSuffix.Length); } + return fullCommandName; + } + + internal static TAttribute? GetAttribute(this Type source) + where TAttribute : Attribute + { + var attribute = source.GetCustomAttributes(typeof(TAttribute), true).FirstOrDefault() as TAttribute; + return attribute; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/GlobalSuppressions.cs b/src/MGR.CommandLineParser/GlobalSuppressions.cs index 3762582..e5e85b5 100644 --- a/src/MGR.CommandLineParser/GlobalSuppressions.cs +++ b/src/MGR.CommandLineParser/GlobalSuppressions.cs @@ -15,7 +15,4 @@ [assembly: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = nameof(MGR), Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility")] [assembly: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = nameof(MGR), Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility.Command")] [assembly: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = nameof(MGR), Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility.Converters")] -[assembly: SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = nameof(MGR), Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility.DependencyInjection")] [assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility.Command")] -[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "MGR.CommandLineParser.Extensibility.DependencyInjection")] - diff --git a/src/MGR.CommandLineParser/Guard.cs b/src/MGR.CommandLineParser/Guard.cs index 2287f6f..85eedfb 100644 --- a/src/MGR.CommandLineParser/Guard.cs +++ b/src/MGR.CommandLineParser/Guard.cs @@ -1,42 +1,40 @@ using System; -using JetBrains.Annotations; using MGR.CommandLineParser.Extensibility.Converters; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +internal static class Guard { - internal static class Guard + internal static void NotNull(object? item, string name) { - internal static void NotNull(object item, [InvokerParameterName] string name) + if (item == null) { - if (item == null) - { - throw new ArgumentNullException(name); - } + throw new ArgumentNullException(name); } - internal static void NotNullOrEmpty(string item, [InvokerParameterName] string name) + } + internal static void NotNullOrEmpty(string? item, string name) + { + if (string.IsNullOrEmpty(item)) { - if (string.IsNullOrEmpty(item)) - { - throw new ArgumentNullException(name); - } + throw new ArgumentNullException(name); } + } - internal static void IsIConverter([NotNull] Type type, string message) + internal static void IsIConverter(Type type, string message) + { + if (!typeof (IConverter).IsAssignableFrom(type)) { - if (!typeof (IConverter).IsAssignableFrom(type)) - { - throw new CommandLineParserException(message); - } + throw new CommandLineParserException(message); } + } - internal static void OfType(Type type, [InvokerParameterName] string name) - { - NotNull(type, name); + internal static void OfType(Type type, string name) + { + NotNull(type, name); - if (!typeof (T).IsAssignableFrom(type)) - { - throw new ArgumentOutOfRangeException(name); - } + if (!typeof (T).IsAssignableFrom(type)) + { + throw new ArgumentOutOfRangeException(name); } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/ICommandObject.cs b/src/MGR.CommandLineParser/ICommandObject.cs index 7bd08bf..35c64c6 100644 --- a/src/MGR.CommandLineParser/ICommandObject.cs +++ b/src/MGR.CommandLineParser/ICommandObject.cs @@ -1,16 +1,17 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Represents the instance of the command. +/// +public interface ICommandObject { /// - /// Represents the instance of the command. + /// Executes the command. /// - public interface ICommandObject - { - /// - /// Executes the command. - /// - /// The result of the command execution. - Task ExecuteAsync(); - } + /// A cancellation token to stop processing the command. + /// The result of the command execution. + Task ExecuteAsync(CancellationToken cancellationToken); } diff --git a/src/MGR.CommandLineParser/IParser.cs b/src/MGR.CommandLineParser/IParser.cs index 4c43f83..7cd5044 100644 --- a/src/MGR.CommandLineParser/IParser.cs +++ b/src/MGR.CommandLineParser/IParser.cs @@ -1,52 +1,50 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; -using JetBrains.Annotations; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Represents a parser. +/// +public interface IParser { /// - /// Represents a parser. + /// Gets the name of the current tools. /// - [PublicAPI] - public interface IParser - { - /// - /// Gets the name of the current tools. - /// - [NotNull] - string CommandLineName { get; } + string CommandLineName { get; } - /// - /// Gets the current logo (name + version) of the current tools. - /// - [NotNull] - string Logo { get; } + /// + /// Gets the current logo (name + version) of the current tools. + /// + string Logo { get; } - /// - /// Parse the supplied arguments for a specific command. The name of the command should not be in the arguments list. - /// - /// The type of the command. - /// The arguments. - /// This method can only be used with class-based command. - /// The result of the parsing of the arguments. - Task Parse([ItemNotNull] IEnumerable arguments) where TCommand : class, ICommand; + /// + /// Parse the supplied arguments for a specific command. The name of the command should not be in the arguments list. + /// + /// The type of the command. + /// The type of the command. + /// The arguments. + /// This method can only be used with class-based command. + /// The result of the parsing of the arguments. + Task Parse(IEnumerable arguments) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new(); - /// - /// Parse the supplied arguments. - /// - /// The arguments. - /// The result of the parsing of the arguments. - Task Parse([ItemNotNull] IEnumerable arguments); + /// + /// Parse the supplied arguments. + /// + /// The arguments. + /// The result of the parsing of the arguments. + Task Parse(IEnumerable arguments); - /// - /// Parse the supplied arguments. If the name of the command is not the first argument, fallback to the specified command. The default command can only be class-based. - /// - /// The type of the default command. - /// The arguments. - /// The result of the parsing of the arguments. - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] - Task ParseWithDefaultCommand([ItemNotNull] IEnumerable arguments) where TCommand : class, ICommand; - } + /// + /// Parse the supplied arguments. If the name of the command is not the first argument, fallback to the specified command. The default command can only be class-based. + /// + /// The type of the command. + /// The type of the default command. + /// The arguments. + /// The result of the parsing of the arguments. + Task ParseWithDefaultCommand(IEnumerable arguments) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new(); } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/IParserFactory.cs b/src/MGR.CommandLineParser/IParserFactory.cs index 34ca96b..94d8753 100644 --- a/src/MGR.CommandLineParser/IParserFactory.cs +++ b/src/MGR.CommandLineParser/IParserFactory.cs @@ -1,15 +1,14 @@  -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// A factory abstractions to create a . +/// +public interface IParserFactory { /// - /// A factory abstractions to create a . + /// Creates a new instance of . /// - public interface IParserFactory - { - /// - /// Creates a new instance of . - /// - /// A new . - IParser CreateParser(); - } + /// A new . + IParser CreateParser(); } diff --git a/src/MGR.CommandLineParser/Parser.cs b/src/MGR.CommandLineParser/Parser.cs index fa95758..cbfd923 100644 --- a/src/MGR.CommandLineParser/Parser.cs +++ b/src/MGR.CommandLineParser/Parser.cs @@ -7,50 +7,51 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +internal sealed class Parser : IParser { - internal sealed class Parser : IParser + private readonly ParserOptions _parserOptions; + private readonly IServiceProvider _serviceProvider; + + internal Parser(ParserOptions parserOptions, IServiceProvider serviceProvider) { - private readonly ParserOptions _parserOptions; - private readonly IServiceProvider _serviceProvider; + _parserOptions = parserOptions; + _serviceProvider = serviceProvider; + } - internal Parser(ParserOptions parserOptions, IServiceProvider serviceProvider) - { - _parserOptions = parserOptions; - _serviceProvider = serviceProvider; - } + public string Logo => _parserOptions.Logo; - public string Logo => _parserOptions.Logo; + public string CommandLineName => _parserOptions.CommandLineName; - public string CommandLineName => _parserOptions.CommandLineName; + public async Task Parse(IEnumerable arguments) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => + parserEngine.Parse(argumentsEnumerator)); - public async Task Parse(IEnumerable arguments) where TCommand : class, ICommand => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => - parserEngine.Parse(argumentsEnumerator)); + public async Task Parse(IEnumerable arguments) => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => + parserEngine.Parse(argumentsEnumerator)); - public async Task Parse(IEnumerable arguments) => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => - parserEngine.Parse(argumentsEnumerator)); + public async Task ParseWithDefaultCommand(IEnumerable arguments) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => + parserEngine.ParseWithDefaultCommand(argumentsEnumerator)); - public async Task ParseWithDefaultCommand(IEnumerable arguments) where TCommand : class, ICommand => await ParseArguments(arguments, (parserEngine, argumentsEnumerator) => - parserEngine.ParseWithDefaultCommand(argumentsEnumerator)); + private async Task ParseArguments(IEnumerable arguments, Func, Task> callParse) + { + if (arguments == null) + { + return new ParsingResult(null, null, CommandParsingResultCode.NoArgumentsProvided); + } - private async Task ParseArguments(IEnumerable arguments, Func, Task> callParse) + var loggerFactory = _serviceProvider.GetService() ?? NullLoggerFactory.Instance; + var logger = loggerFactory.CreateLogger(); + using (logger.BeginParsingArguments(Guid.NewGuid().ToString())) { - if (arguments == null) - { - return new ParsingResult(null, null, CommandParsingResultCode.NoArgumentsProvided); - } - - var loggerFactory = _serviceProvider.GetService() ?? NullLoggerFactory.Instance; - var logger = loggerFactory.CreateLogger(); - using (logger.BeginParsingArguments(Guid.NewGuid().ToString())) - { - logger.CreationOfParserEngine(); - var parserEngine = new ParserEngine(_serviceProvider, loggerFactory); - var argumentsEnumerator = arguments.GetArgumentsEnumerator(); - - var result = await callParse(parserEngine, argumentsEnumerator); - return result; - } + logger.CreationOfParserEngine(); + var parserEngine = new ParserEngine(_serviceProvider, loggerFactory); + var argumentsEnumerator = arguments.GetArgumentsEnumerator(); + + var result = await callParse(parserEngine, argumentsEnumerator); + return result; } } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/ParserBuilder.cs b/src/MGR.CommandLineParser/ParserBuilder.cs index 5cf7a08..07f2193 100644 --- a/src/MGR.CommandLineParser/ParserBuilder.cs +++ b/src/MGR.CommandLineParser/ParserBuilder.cs @@ -1,62 +1,58 @@ using System; -using JetBrains.Annotations; using MGR.CommandLineParser.Command; using Microsoft.Extensions.DependencyInjection; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Represents the constructor of a parser. +/// +public sealed class ParserBuilder { + private readonly CommandLineParserBuilder _commandLineParserBuilder; + /// - /// Represents the constructor of a parser. + /// Creates a new . /// - [PublicAPI] - public sealed class ParserBuilder - { - private readonly CommandLineParserBuilder _commandLineParserBuilder; - - /// - /// Creates a new . - /// - /// The options of the parser. - public ParserBuilder([NotNull] ParserOptions parserOptions) - : this(parserOptions, new ServiceCollection()) - { - } + /// The options of the parser. + public ParserBuilder(ParserOptions parserOptions) + : this(parserOptions, new ServiceCollection()) + { } - /// - /// Creates a new . - /// - /// The options of the parser. - /// The services to uses. - public ParserBuilder([NotNull] ParserOptions parserOptions, [NotNull] IServiceCollection services) + /// + /// Creates a new . + /// + /// The options of the parser. + /// The services to uses. + public ParserBuilder(ParserOptions parserOptions, IServiceCollection services) + { + _commandLineParserBuilder = services.AddCommandLineParser(options => { - _commandLineParserBuilder = services.AddCommandLineParser(options => - { - options.Logo = parserOptions.Logo; - options.CommandLineName = parserOptions.CommandLineName; - }).AddCommands(); - } + options.Logo = parserOptions.Logo; + options.CommandLineName = parserOptions.CommandLineName; + }).AddCommands(); + } - /// - /// Add the commands to the . - /// - /// The action to add the commands. - /// This configured with the commands. - public ParserBuilder AddCommands(Action configureCommands) - { - configureCommands(_commandLineParserBuilder); - return this; - } + /// + /// Add the commands to the . + /// + /// The action to add the commands. + /// This configured with the commands. + public ParserBuilder AddCommands(Action configureCommands) + { + configureCommands(_commandLineParserBuilder); + return this; + } - /// - /// Creates a new instance of with the default options. - /// - /// A new instance of . - public IParser BuildParser() - { - var serviceProvider = _commandLineParserBuilder.Services.BuildServiceProvider(); - var serviceProviderScope = serviceProvider.CreateScope(); - var parser = serviceProviderScope.ServiceProvider.GetService(); - return parser; - } + /// + /// Creates a new instance of with the default options. + /// + /// A new instance of . + public IParser BuildParser() + { + var serviceProvider = _commandLineParserBuilder.Services.BuildServiceProvider(); + var serviceProviderScope = serviceProvider.CreateScope(); + var parser = serviceProviderScope.ServiceProvider.GetRequiredService(); + return parser; } } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/ParserEngine.cs b/src/MGR.CommandLineParser/ParserEngine.cs index 753f093..0bc612e 100644 --- a/src/MGR.CommandLineParser/ParserEngine.cs +++ b/src/MGR.CommandLineParser/ParserEngine.cs @@ -8,175 +8,179 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +internal class ParserEngine { - internal class ParserEngine + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + + internal ParserEngine(IServiceProvider serviceProvider, ILoggerFactory loggerFactory) { - private readonly IServiceProvider _serviceProvider; - private readonly ILogger _logger; + _serviceProvider = serviceProvider; + _logger = loggerFactory.CreateLogger(); + } - internal ParserEngine(IServiceProvider serviceProvider, ILoggerFactory loggerFactory) + internal async Task Parse(IEnumerator argumentsEnumerator) where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + using (_logger.BeginParsingForSpecificCommandType(typeof(TCommandHandler))) { - _serviceProvider = serviceProvider; - _logger = loggerFactory.CreateLogger(); + var commandTypeProviders = _serviceProvider.GetServices(); + var commandType = await commandTypeProviders.GetCommandType(); + var parsingResult = ParseImpl(argumentsEnumerator, commandType); + if (parsingResult.ParsingResultCode == CommandParsingResultCode.NoCommandFound) + { + _logger.NoCommandFoundAfterSpecificParsing(); + } + else + { + _logger.CommandFoundAfterSpecificParsing(typeof(TCommandHandler), parsingResult.ParsingResultCode, + parsingResult.ValidationResults); + } + + return parsingResult; } + } - internal async Task Parse(IEnumerator argumentsEnumerator) where TCommand : class, ICommand + internal async Task ParseWithDefaultCommand(IEnumerator argumentsEnumerator) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + using (_logger.BeginParsingWithDefaultCommandType(typeof(TCommandHandler))) { - using (_logger.BeginParsingForSpecificCommandType(typeof(TCommand))) + var commandName = argumentsEnumerator.GetNextCommandLineItem(); + if (commandName != null) { + _logger.ArgumentProvidedWithDefaultCommandType(commandName); var commandTypeProviders = _serviceProvider.GetServices(); - var commandType = await commandTypeProviders.GetCommandType(); - var parsingResult = ParseImpl(argumentsEnumerator, commandType); - if (parsingResult.ParsingResultCode == CommandParsingResultCode.NoCommandFound) - { - _logger.NoCommandFoundAfterSpecificParsing(); - } - else + var commandType = await commandTypeProviders.GetCommandType(commandName); + if (commandType != null) { - _logger.CommandFoundAfterSpecificParsing(typeof(TCommand), parsingResult.ParsingResultCode, - parsingResult.ValidationResults); + _logger.CommandTypeFoundWithDefaultCommandType(commandName); + return ParseImpl(argumentsEnumerator, commandType); } - return parsingResult; + _logger.NoCommandTypeFoundWithDefaultCommandType(commandName, typeof(TCommandHandler)); + var withArgumentsCommandResult = await Parse(argumentsEnumerator.PrefixWith(commandName)); + return withArgumentsCommandResult; + } + + _logger.NoArgumentProvidedWithDefaultCommandType(typeof(TCommandHandler)); + var noArgumentsCommandResult = await Parse(argumentsEnumerator); + return noArgumentsCommandResult; } + } - internal async Task ParseWithDefaultCommand(IEnumerator argumentsEnumerator) - where TCommand : class, ICommand + internal async Task Parse(IEnumerator argumentsEnumerator) + { + _logger.ParseForNotAlreadyKnownCommand(); + var commandName = argumentsEnumerator.GetNextCommandLineItem(); + if (commandName == null) { - using (_logger.BeginParsingWithDefaultCommandType(typeof(TCommand))) - { - var commandName = argumentsEnumerator.GetNextCommandLineItem(); - if (commandName != null) - { - _logger.ArgumentProvidedWithDefaultCommandType(commandName); - var commandTypeProviders = _serviceProvider.GetServices(); - var commandType = await commandTypeProviders.GetCommandType(commandName); - if (commandType != null) - { - _logger.CommandTypeFoundWithDefaultCommandType(commandName); - return ParseImpl(argumentsEnumerator, commandType); - } - - _logger.NoCommandTypeFoundWithDefaultCommandType(commandName, typeof(TCommand)); - var withArgumentsCommandResult = await Parse(argumentsEnumerator.PrefixWith(commandName)); - return withArgumentsCommandResult; - - } - - _logger.NoArgumentProvidedWithDefaultCommandType(typeof(TCommand)); - var noArgumentsCommandResult = await Parse(argumentsEnumerator); - return noArgumentsCommandResult; - } + _logger.NoCommandNameForNotAlreadyKnownCommand(); + var helpWriter = _serviceProvider.GetRequiredService(); + await helpWriter.WriteCommandListing(); + return new ParsingResult(null, null, CommandParsingResultCode.NoCommandNameProvided); } - internal async Task Parse(IEnumerator argumentsEnumerator) + using (_logger.BeginParsingUsingCommandName(commandName)) { - _logger.ParseForNotAlreadyKnownCommand(); - var commandName = argumentsEnumerator.GetNextCommandLineItem(); - if (commandName == null) + var commandTypeProviders = _serviceProvider.GetServices(); + var commandType = await commandTypeProviders.GetCommandType(commandName); + if (commandType == null) { - _logger.NoCommandNameForNotAlreadyKnownCommand(); + _logger.NoCommandTypeFoundForNotAlreadyKnownCommand(commandName); var helpWriter = _serviceProvider.GetRequiredService(); await helpWriter.WriteCommandListing(); - return new ParsingResult(null, null, CommandParsingResultCode.NoCommandNameProvided); + return new ParsingResult(null, null, CommandParsingResultCode.NoCommandFound); } - using (_logger.BeginParsingUsingCommandName(commandName)) - { - var commandTypeProviders = _serviceProvider.GetServices(); - var commandType = await commandTypeProviders.GetCommandType(commandName); - if (commandType == null) - { - _logger.NoCommandTypeFoundForNotAlreadyKnownCommand(commandName); - var helpWriter = _serviceProvider.GetRequiredService(); - await helpWriter.WriteCommandListing(); - return new ParsingResult(null, null, CommandParsingResultCode.NoCommandFound); - } + _logger.CommandTypeFoundForNotAlreadyKnownCommand(commandName); + return ParseImpl(argumentsEnumerator, commandType); + } - _logger.CommandTypeFoundForNotAlreadyKnownCommand(commandName); - return ParseImpl(argumentsEnumerator, commandType); - } + } + private ParsingResult ParseImpl(IEnumerator argumentsEnumerator, ICommandType commandType) + { + var commandObjectBuilder = ExtractCommandLineOptions(commandType, argumentsEnumerator); + if (commandObjectBuilder == null) + { + return new ParsingResult(null, null, CommandParsingResultCode.CommandParametersNotValid); } - - private ParsingResult ParseImpl(IEnumerator argumentsEnumerator, ICommandType commandType) + var validation = commandObjectBuilder.Validate(_serviceProvider); + if (!validation.IsValid) { - var commandObjectBuilder = ExtractCommandLineOptions(commandType, argumentsEnumerator); - if (commandObjectBuilder == null) - { - return new ParsingResult(null, null, CommandParsingResultCode.CommandParametersNotValid); - } - var validation = commandObjectBuilder.Validate(_serviceProvider); - if (!validation.IsValid) - { - _logger.ParsedCommandIsNotValid(); - var helpWriter = _serviceProvider.GetRequiredService(); - helpWriter.WriteHelpForCommand(commandType); - return new ParsingResult(commandObjectBuilder.GenerateCommandObject(), validation.ValidationErrors, CommandParsingResultCode.CommandParametersNotValid); - } - return new ParsingResult(commandObjectBuilder.GenerateCommandObject(), null, CommandParsingResultCode.Success); + _logger.ParsedCommandIsNotValid(); + var helpWriter = _serviceProvider.GetRequiredService(); + helpWriter.WriteHelpForCommand(commandType); + return new ParsingResult(commandObjectBuilder.GenerateCommandObject(), validation.ValidationErrors, CommandParsingResultCode.CommandParametersNotValid); + } + return new ParsingResult(commandObjectBuilder.GenerateCommandObject(), null, CommandParsingResultCode.Success); + } + private ICommandObjectBuilder? ExtractCommandLineOptions(ICommandType commandType, IEnumerator argumentsEnumerator) + { + var commandObjectBuilder = commandType.CreateCommandObjectBuilder(_serviceProvider); + if (commandObjectBuilder == null) + { + return null; } - private ICommandObjectBuilder ExtractCommandLineOptions(ICommandType commandType, IEnumerator argumentsEnumerator) + var alwaysPutInArgumentList = false; + while (true) { - var commandObjectBuilder = commandType.CreateCommandObjectBuilder(_serviceProvider); - if (commandObjectBuilder == null) + var argument = argumentsEnumerator.GetNextCommandLineItem(); + if (argument == null) { - return null; + break; } - var alwaysPutInArgumentList = false; - while (true) + if (argument.Equals(Constants.EndOfOptions)) { - var argument = argumentsEnumerator.GetNextCommandLineItem(); - if (argument == null) - { - break; - } - if (argument.Equals(Constants.EndOfOptions)) - { - alwaysPutInArgumentList = true; - continue; - } + alwaysPutInArgumentList = true; + continue; + } - if (alwaysPutInArgumentList || !argument.StartsWith(StringComparison.OrdinalIgnoreCase, Constants.OptionStarter)) - { - commandObjectBuilder.AddArguments(argument); - continue; - } + if (alwaysPutInArgumentList || !argument.StartsWith(StringComparison.OrdinalIgnoreCase, Constants.OptionStarter)) + { + commandObjectBuilder.AddArguments(argument); + continue; + } - var starterLength = 2; - Func commandOptionFinder = (co, optionName) => co.FindOption(optionName); - if (!argument.StartsWith(Constants.LongNameOptionStarter)) - { - starterLength = Constants.ShortNameOptionStarter.Length; - commandOptionFinder = (co, optionName) => co.FindOptionByShortName(optionName); - } - var optionText = argument.Substring(starterLength); - string value = null; - var splitIndex = optionText.IndexOf(Constants.OptionSplitter); - if (splitIndex > 0) - { - value = optionText.Substring(splitIndex + 1); - optionText = optionText.Substring(0, splitIndex); - } + var starterLength = 2; + Func commandOptionFinder = (co, optionName) => co.FindOption(optionName); + if (!argument.StartsWith(Constants.LongNameOptionStarter)) + { + starterLength = Constants.ShortNameOptionStarter.Length; + commandOptionFinder = (co, optionName) => co.FindOptionByShortName(optionName); + } + var optionText = argument.Substring(starterLength); + var value = string.Empty; + var splitIndex = optionText.IndexOf(Constants.OptionSplitter); + if (splitIndex > 0) + { + value = optionText.Substring(splitIndex + 1); + optionText = optionText.Substring(0, splitIndex); + } - var option = commandOptionFinder(commandObjectBuilder, optionText); - if (option == null) - { - var console = _serviceProvider.GetRequiredService(); - console.WriteLineError(Constants.ExceptionMessages.FormatParserOptionNotFoundForCommand(commandType.Metadata.Name, optionText)); - return null; - } + var option = commandOptionFinder(commandObjectBuilder, optionText); + if (option == null) + { + var console = _serviceProvider.GetRequiredService(); + console.WriteLineError(Constants.ExceptionMessages.FormatParserOptionNotFoundForCommand(commandType.Metadata.Name, optionText)); + return null; + } - if (option.ShouldProvideValue) + if (option.ShouldProvideValue) + { + if (string.IsNullOrEmpty(value)) { - value = value ?? argumentsEnumerator.GetNextCommandLineItem(); + value = argumentsEnumerator.GetNextCommandLineItem() ?? string.Empty; } - - option.AssignValue(value); } - return commandObjectBuilder; + + option.AssignValue(value); } + return commandObjectBuilder; } } diff --git a/src/MGR.CommandLineParser/ParserOptions.cs b/src/MGR.CommandLineParser/ParserOptions.cs index 105fdd5..920d066 100644 --- a/src/MGR.CommandLineParser/ParserOptions.cs +++ b/src/MGR.CommandLineParser/ParserOptions.cs @@ -2,44 +2,43 @@ using System.Reflection; using MGR.CommandLineParser.Properties; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Defines the options for the parser. +/// +public sealed class ParserOptions { /// - /// Defines the options for the parser. + /// Creates a new instance of . /// - public sealed class ParserOptions + public ParserOptions() { - /// - /// Creates a new instance of . - /// - public ParserOptions() - { - var entryAssembly = Assembly.GetEntryAssembly(); - if (entryAssembly != null) - { - FromAssembly(entryAssembly); - } - } - /// - /// Initializes the and the based on an assembly. - /// - /// The from which to extract the and the . - public void FromAssembly(Assembly entryAssembly) + var entryAssembly = Assembly.GetEntryAssembly(); + if (entryAssembly != null) { - Guard.NotNull(entryAssembly, nameof(entryAssembly)); - - var entryAssemblyName = entryAssembly.GetName(); - CommandLineName = entryAssemblyName.Name; - Logo = string.Format(CultureInfo.CurrentUICulture, Strings.ParserOptions_LogoFormat, entryAssemblyName.Name, entryAssemblyName.Version); + FromAssembly(entryAssembly); } - /// - /// Gets or sets the logo used in the help by the parser. - /// - public string Logo { get; set; } + } + /// + /// Initializes the and the based on an assembly. + /// + /// The from which to extract the and the . + public void FromAssembly(Assembly entryAssembly) + { + Guard.NotNull(entryAssembly, nameof(entryAssembly)); - /// - /// Gets or sets the name of the executable to run used in the help by the parser. - /// - public string CommandLineName { get; set; } + var entryAssemblyName = entryAssembly.GetName(); + CommandLineName = entryAssemblyName.Name; + Logo = string.Format(CultureInfo.CurrentUICulture, Strings.ParserOptions_LogoFormat, entryAssemblyName.Name, entryAssemblyName.Version); } + /// + /// Gets or sets the logo used in the help by the parser. + /// + public string Logo { get; set; } = "Not initialized logo"; + + /// + /// Gets or sets the name of the executable to run used in the help by the parser. + /// + public string CommandLineName { get; set; } = "Not initialized command line name"; } \ No newline at end of file diff --git a/src/MGR.CommandLineParser/ParserOptionsBuilder.cs b/src/MGR.CommandLineParser/ParserOptionsBuilder.cs index 5e65849..5c94a76 100644 --- a/src/MGR.CommandLineParser/ParserOptionsBuilder.cs +++ b/src/MGR.CommandLineParser/ParserOptionsBuilder.cs @@ -1,55 +1,54 @@ -using System.Globalization; -using System.Reflection; -using MGR.CommandLineParser.Properties; +//using System.Globalization; +//using System.Reflection; +//using MGR.CommandLineParser.Properties; -namespace MGR.CommandLineParser -{ - /// - /// Represents a builder for the . - /// - public class ParserOptionsBuilder - { - internal static ParserOptionsBuilder Default => new ParserOptionsBuilder(); +//namespace MGR.CommandLineParser; - internal ParserOptionsBuilder() - { - var entryAssembly = Assembly.GetEntryAssembly(); - if (entryAssembly != null) - { - ForAssembly(entryAssembly); - } - } - /// - /// Initializes the and the based on an assembly. - /// - /// The from which to extract the and the . - public void ForAssembly(Assembly entryAssembly) - { - Guard.NotNull(entryAssembly, nameof(entryAssembly)); +///// +///// Represents a builder for the . +///// +//public class ParserOptionsBuilder +//{ +// internal static ParserOptionsBuilder Default => new ParserOptionsBuilder(); - var entryAssemblyName = entryAssembly.GetName(); - CommandLineName = entryAssemblyName.Name; - Logo = string.Format(CultureInfo.CurrentUICulture, Strings.ParserOptions_LogoFormat, entryAssemblyName.Name, entryAssemblyName.Version); - } +// internal ParserOptionsBuilder() +// { +// var entryAssembly = Assembly.GetEntryAssembly(); +// if (entryAssembly != null) +// { +// ForAssembly(entryAssembly); +// } +// } +// /// +// /// Initializes the and the based on an assembly. +// /// +// /// The from which to extract the and the . +// public void ForAssembly(Assembly entryAssembly) +// { +// Guard.NotNull(entryAssembly, nameof(entryAssembly)); - /// - /// Gets ir sets the logo of the parser. - /// - public string Logo { get; set; } - /// - /// Gets or sets the executable name. - /// - public string CommandLineName { get; set; } +// var entryAssemblyName = entryAssembly.GetName(); +// CommandLineName = entryAssemblyName.Name; +// Logo = string.Format(CultureInfo.CurrentUICulture, Strings.ParserOptions_LogoFormat, entryAssemblyName.Name, entryAssemblyName.Version); +// } - internal ParserOptions ToParserOptions() - { - var parserOptions = new ParserOptions - { - CommandLineName = CommandLineName, - Logo = Logo ?? string.Empty - }; +// /// +// /// Gets ir sets the logo of the parser. +// /// +// public string Logo { get; set; } +// /// +// /// Gets or sets the executable name. +// /// +// public string CommandLineName { get; set; } - return parserOptions; - } - } -} \ No newline at end of file +// internal ParserOptions ToParserOptions() +// { +// var parserOptions = new ParserOptions +// { +// CommandLineName = CommandLineName, +// Logo = Logo ?? string.Empty +// }; + +// return parserOptions; +// } +//} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/ParsingResult.cs b/src/MGR.CommandLineParser/ParsingResult.cs index 91fe654..4fd80b2 100644 --- a/src/MGR.CommandLineParser/ParsingResult.cs +++ b/src/MGR.CommandLineParser/ParsingResult.cs @@ -1,54 +1,55 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Threading; using System.Threading.Tasks; -namespace MGR.CommandLineParser +namespace MGR.CommandLineParser; + +/// +/// Represents the result of the parsing operation. +/// +public sealed class ParsingResult { - /// - /// Represents the result of the parsing operation. - /// - public sealed class ParsingResult + internal ParsingResult(ICommandObject? commandObject, IEnumerable? validationResults, CommandParsingResultCode parsingResultCode) { - internal ParsingResult(ICommandObject commandObject, IEnumerable validationResults, CommandParsingResultCode parsingResultCode) - { - CommandObject = commandObject; - ValidationResults = validationResults ?? Enumerable.Empty(); - ParsingResultCode = parsingResultCode; - } + CommandObject = commandObject; + ValidationResults = validationResults ?? []; + ParsingResultCode = parsingResultCode; + } - /// - /// Gets the validation results. If there was no validation errors, the enumeration is empty. - /// - public IEnumerable ValidationResults { get; } + /// + /// Gets the validation results. If there was no validation errors, the enumeration is empty. + /// + public IEnumerable ValidationResults { get; } - /// - /// Defines if the command is in a valid state (parsing and validating the options). - /// - public bool IsValid => ParsingResultCode == CommandParsingResultCode.Success && !ValidationResults.Any(); + /// + /// Defines if the command is in a valid state (parsing and validating the options). + /// + public bool IsValid => CommandObject != null && ParsingResultCode == CommandParsingResultCode.Success && !ValidationResults.Any(); - /// - /// The return code of the parsing operation. - /// - public CommandParsingResultCode ParsingResultCode { get; } + /// + /// The return code of the parsing operation. + /// + public CommandParsingResultCode ParsingResultCode { get; } - /// - /// Gets the raw command object; - /// - public ICommandObject CommandObject { get; } + /// + /// Gets the raw command object; + /// + public ICommandObject? CommandObject { get; } - /// - /// Executes the command. - /// - /// Thrown if the is null or is false. - /// A task that represents the execution of the command. - public Task ExecuteAsync() + /// + /// Executes the command. + /// + /// A cancellation token to stop processing the command. + /// Thrown if the is null or is false. + /// A task that represents the execution of the command. + public Task ExecuteAsync(CancellationToken cancellationToken) + { + if (CommandObject == null || !IsValid) { - if (CommandObject == null || !IsValid) - { - throw new CommandLineParserException(Constants.ExceptionMessages.NoValidCommand); - } - return CommandObject.ExecuteAsync(); + throw new CommandLineParserException(Constants.ExceptionMessages.NoValidCommand); } + return CommandObject.ExecuteAsync(cancellationToken); } } diff --git a/src/MGR.CommandLineParser/Properties/JetBrains.Annotations.cs b/src/MGR.CommandLineParser/Properties/JetBrains.Annotations.cs deleted file mode 100644 index a94460c..0000000 --- a/src/MGR.CommandLineParser/Properties/JetBrains.Annotations.cs +++ /dev/null @@ -1,949 +0,0 @@ -using System; - -#pragma warning disable 1591 -// ReSharper disable UnusedMember.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global -// ReSharper disable IntroduceOptionalParameters.Global -// ReSharper disable MemberCanBeProtected.Global -// ReSharper disable InconsistentNaming -// ReSharper disable CheckNamespace - -namespace JetBrains.Annotations -{ - /// - /// Indicates that the value of the marked element could be null sometimes, - /// so the check for null is necessary before its usage. - /// - /// - /// [CanBeNull] public object Test() { return null; } - /// public void UseTest() { - /// var p = Test(); - /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' - /// } - /// - [AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] - internal sealed class CanBeNullAttribute : Attribute { } - - /// - /// Indicates that the value of the marked element could never be null. - /// - /// - /// [NotNull] public object Foo() { - /// return null; // Warning: Possible 'null' assignment - /// } - /// - [AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event)] - internal sealed class NotNullAttribute : Attribute { } - - /// - /// Indicates that collection or enumerable value does not contain null elements. - /// - [AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field)] - internal sealed class ItemNotNullAttribute : Attribute { } - - /// - /// Indicates that collection or enumerable value can contain null elements. - /// - [AttributeUsage( - AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | - AttributeTargets.Delegate | AttributeTargets.Field)] - internal sealed class ItemCanBeNullAttribute : Attribute { } - - /// - /// Indicates that the marked method builds string by format pattern and (optional) arguments. - /// Parameter, which contains format string, should be given in constructor. The format string - /// should be in -like form. - /// - /// - /// [StringFormatMethod("message")] - /// public void ShowError(string message, params object[] args) { /* do something */ } - /// public void Foo() { - /// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string - /// } - /// - [AttributeUsage( - AttributeTargets.Constructor | AttributeTargets.Method | - AttributeTargets.Property | AttributeTargets.Delegate)] - internal sealed class StringFormatMethodAttribute : Attribute - { - /// - /// Specifies which parameter of an annotated method should be treated as format-string - /// - public StringFormatMethodAttribute(string formatParameterName) - { - FormatParameterName = formatParameterName; - } - - public string FormatParameterName { get; } - } - - /// - /// For a parameter that is expected to be one of the limited set of values. - /// Specify fields of which type should be used as values for this parameter. - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] - internal sealed class ValueProviderAttribute : Attribute - { - public ValueProviderAttribute(string name) - { - Name = name; - } - - [NotNull] - public string Name { get; } - } - - /// - /// Indicates that the function argument should be string literal and match one - /// of the parameters of the caller function. For example, ReSharper annotates - /// the parameter of . - /// - /// - /// public void Foo(string param) { - /// if (param == null) - /// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol - /// } - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class InvokerParameterNameAttribute : Attribute { } - - /// - /// Indicates that the method is contained in a type that implements - /// System.ComponentModel.INotifyPropertyChanged interface and this method - /// is used to notify that some property value changed. - /// - /// - /// The method should be non-static and conform to one of the supported signatures: - /// - /// NotifyChanged(string) - /// NotifyChanged(params string[]) - /// NotifyChanged{T}(Expression{Func{T}}) - /// NotifyChanged{T,U}(Expression{Func{T,U}}) - /// SetProperty{T}(ref T, T, string) - /// - /// - /// - /// public class Foo : INotifyPropertyChanged { - /// public event PropertyChangedEventHandler PropertyChanged; - /// [NotifyPropertyChangedInvocator] - /// protected virtual void NotifyChanged(string propertyName) { ... } - /// - /// private string _name; - /// public string Name { - /// get { return _name; } - /// set { _name = value; NotifyChanged("LastName"); /* Warning */ } - /// } - /// } - /// - /// Examples of generated notifications: - /// - /// NotifyChanged("Property") - /// NotifyChanged(() => Property) - /// NotifyChanged((VM x) => x.Property) - /// SetProperty(ref myField, value, "Property") - /// - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class NotifyPropertyChangedInvocatorAttribute : Attribute - { - public NotifyPropertyChangedInvocatorAttribute() { } - public NotifyPropertyChangedInvocatorAttribute(string parameterName) - { - ParameterName = parameterName; - } - - public string ParameterName { get; } - } - - /// - /// Describes dependency between method input and output. - /// - /// - ///

Function Definition Table syntax:

- /// - /// FDT ::= FDTRow [;FDTRow]* - /// FDTRow ::= Input => Output | Output <= Input - /// Input ::= ParameterName: Value [, Input]* - /// Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value} - /// Value ::= true | false | null | notnull | canbenull - /// - /// If method has single input parameter, it's name could be omitted.
- /// Using halt (or void/nothing, which is the same) - /// for method output means that the methos doesn't return normally.
- /// canbenull annotation is only applicable for output parameters.
- /// You can use multiple [ContractAnnotation] for each FDT row, - /// or use single attribute with rows separated by semicolon.
- ///
- /// - /// - /// [ContractAnnotation("=> halt")] - /// public void TerminationMethod() - /// - /// - /// [ContractAnnotation("halt <= condition: false")] - /// public void Assert(bool condition, string text) // regular assertion method - /// - /// - /// [ContractAnnotation("s:null => true")] - /// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty() - /// - /// - /// // A method that returns null if the parameter is null, - /// // and not null if the parameter is not null - /// [ContractAnnotation("null => null; notnull => notnull")] - /// public object Transform(object data) - /// - /// - /// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")] - /// public bool TryParse(string s, out Person result) - /// - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - internal sealed class ContractAnnotationAttribute : Attribute - { - public ContractAnnotationAttribute([NotNull] string contract) - : this(contract, false) - { } - - public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates) - { - Contract = contract; - ForceFullStates = forceFullStates; - } - - public string Contract { get; } - public bool ForceFullStates { get; } - } - - /// - /// Indicates that marked element should be localized or not. - /// - /// - /// [LocalizationRequiredAttribute(true)] - /// public class Foo { - /// private string str = "my string"; // Warning: Localizable string - /// } - /// - [AttributeUsage(AttributeTargets.All)] - internal sealed class LocalizationRequiredAttribute : Attribute - { - public LocalizationRequiredAttribute() : this(true) { } - public LocalizationRequiredAttribute(bool required) - { - Required = required; - } - - public bool Required { get; } - } - - /// - /// Indicates that the value of the marked type (or its derivatives) - /// cannot be compared using '==' or '!=' operators and Equals() - /// should be used instead. However, using '==' or '!=' for comparison - /// with null is always permitted. - /// - /// - /// [CannotApplyEqualityOperator] - /// class NoEquality { } - /// class UsesNoEquality { - /// public void Test() { - /// var ca1 = new NoEquality(); - /// var ca2 = new NoEquality(); - /// if (ca1 != null) { // OK - /// bool condition = ca1 == ca2; // Warning - /// } - /// } - /// } - /// - [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct)] - internal sealed class CannotApplyEqualityOperatorAttribute : Attribute { } - - /// - /// When applied to a target attribute, specifies a requirement for any type marked - /// with the target attribute to implement or inherit specific type or types. - /// - /// - /// [BaseTypeRequired(typeof(IComponent)] // Specify requirement - /// public class ComponentAttribute : Attribute { } - /// [Component] // ComponentAttribute requires implementing IComponent interface - /// public class MyComponent : IComponent { } - /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - [BaseTypeRequired(typeof(Attribute))] - internal sealed class BaseTypeRequiredAttribute : Attribute - { - public BaseTypeRequiredAttribute([NotNull] Type baseType) - { - BaseType = baseType; - } - - [NotNull] - public Type BaseType { get; } - } - - /// - /// Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), - /// so this symbol will not be marked as unused (as well as by other usage inspections). - /// - [AttributeUsage(AttributeTargets.All)] - internal sealed class UsedImplicitlyAttribute : Attribute - { - public UsedImplicitlyAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) - { } - - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) - { } - - public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) - { } - - public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { - UseKindFlags = useKindFlags; - TargetFlags = targetFlags; - } - - public ImplicitUseKindFlags UseKindFlags { get; } - public ImplicitUseTargetFlags TargetFlags { get; } - } - - /// - /// Should be used on attributes and causes ReSharper to not mark symbols marked with such attributes - /// as unused (as well as by other usage inspections) - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.GenericParameter)] - internal sealed class MeansImplicitUseAttribute : Attribute - { - public MeansImplicitUseAttribute() - : this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) - { } - - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags) - : this(useKindFlags, ImplicitUseTargetFlags.Default) - { } - - public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags) - : this(ImplicitUseKindFlags.Default, targetFlags) - { } - - public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags) - { - UseKindFlags = useKindFlags; - TargetFlags = targetFlags; - } - - [UsedImplicitly] - public ImplicitUseKindFlags UseKindFlags { get; } - [UsedImplicitly] - public ImplicitUseTargetFlags TargetFlags { get; } - } - - [Flags] - internal enum ImplicitUseKindFlags - { - Default = Access | Assign | InstantiatedWithFixedConstructorSignature, - /// Only entity marked with attribute considered used. - Access = 1, - /// Indicates implicit assignment to a member. - Assign = 2, - /// - /// Indicates implicit instantiation of a type with fixed constructor signature. - /// That means any unused constructor parameters won't be reported as such. - /// - InstantiatedWithFixedConstructorSignature = 4, - /// Indicates implicit instantiation of a type. - InstantiatedNoFixedConstructorSignature = 8, - } - - /// - /// Specify what is considered used implicitly when marked - /// with or . - /// - [Flags] - internal enum ImplicitUseTargetFlags - { - Default = Itself, - Itself = 1, - /// Members of entity marked with attribute are considered used. - Members = 2, - /// Entity marked with attribute and all its members considered used. - WithMembers = Itself | Members - } - - /// - /// This attribute is intended to mark publicly available API - /// which should not be removed and so is treated as used. - /// - [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] - internal sealed class PublicAPIAttribute : Attribute - { - public PublicAPIAttribute() { } - public PublicAPIAttribute([NotNull] string comment) - { - Comment = comment; - } - - public string Comment { get; } - } - - /// - /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. - /// If the parameter is a delegate, indicates that delegate is executed while the method is executed. - /// If the parameter is an enumerable, indicates that it is enumerated while the method is executed. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class InstantHandleAttribute : Attribute { } - - /// - /// Indicates that a method does not make any observable state changes. - /// The same as System.Diagnostics.Contracts.PureAttribute. - /// - /// - /// [Pure] private int Multiply(int x, int y) { return x * y; } - /// public void Foo() { - /// const int a = 2, b = 2; - /// Multiply(a, b); // Waring: Return value of pure method is not used - /// } - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class PureAttribute : Attribute { } - - /// - /// Indicates that a parameter is a path to a file or a folder within a web project. - /// Path can be relative or absolute, starting from web root (~). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class PathReferenceAttribute : Attribute - { - public PathReferenceAttribute() { } - public PathReferenceAttribute([PathReference] string basePath) - { - BasePath = basePath; - } - - public string BasePath { get; } - } - - /// - /// An extension method marked with this attribute is processed by ReSharper code completion - /// as a 'Source Template'. When extension method is completed over some expression, it's source code - /// is automatically expanded like a template at call site. - /// - /// - /// Template method body can contain valid source code and/or special comments starting with '$'. - /// Text inside these comments is added as source code when the template is applied. Template parameters - /// can be used either as additional method parameters or as identifiers wrapped in two '$' signs. - /// Use the attribute to specify macros for parameters. - /// - /// - /// In this example, the 'forEach' method is a source template available over all values - /// of enumerable types, producing ordinary C# 'foreach' statement and placing caret inside block: - /// - /// [SourceTemplate] - /// public static void forEach<T>(this IEnumerable<T> xs) { - /// foreach (var x in xs) { - /// //$ $END$ - /// } - /// } - /// - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class SourceTemplateAttribute : Attribute { } - - /// - /// Allows specifying a macro for a parameter of a source template. - /// - /// - /// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression - /// is defined in the property. When applied on a method, the target - /// template parameter is defined in the property. To apply the macro silently - /// for the parameter, set the property value = -1. - /// - /// - /// Applying the attribute on a source template method: - /// - /// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")] - /// public static void forEach<T>(this IEnumerable<T> collection) { - /// foreach (var item in collection) { - /// //$ $END$ - /// } - /// } - /// - /// Applying the attribute on a template method parameter: - /// - /// [SourceTemplate] - /// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) { - /// /*$ var $x$Id = "$newguid$" + x.ToString(); - /// x.DoSomething($x$Id); */ - /// } - /// - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)] - internal sealed class MacroAttribute : Attribute - { - /// - /// Allows specifying a macro that will be executed for a source template - /// parameter when the template is expanded. - /// - public string Expression { get; set; } - - /// - /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. - /// - /// - /// If the target parameter is used several times in the template, only one occurrence becomes editable; - /// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence, - /// use values >= 0. To make the parameter non-editable when the template is expanded, use -1. - /// > - public int Editable { get; set; } - - /// - /// Identifies the target parameter of a source template if the - /// is applied on a template method. - /// - public string Target { get; set; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute - { - public AspMvcAreaMasterLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute - { - public AspMvcAreaPartialViewLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcAreaViewLocationFormatAttribute : Attribute - { - public AspMvcAreaViewLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcMasterLocationFormatAttribute : Attribute - { - public AspMvcMasterLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcPartialViewLocationFormatAttribute : Attribute - { - public AspMvcPartialViewLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class AspMvcViewLocationFormatAttribute : Attribute - { - public AspMvcViewLocationFormatAttribute(string format) - { - Format = format; - } - - public string Format { get; } - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC action. If applied to a method, the MVC action name is calculated - /// implicitly from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class AspMvcActionAttribute : Attribute - { - public AspMvcActionAttribute() { } - public AspMvcActionAttribute(string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC area. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcAreaAttribute : Attribute - { - public AspMvcAreaAttribute() { } - public AspMvcAreaAttribute(string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is - /// an MVC controller. If applied to a method, the MVC controller name is calculated - /// implicitly from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class AspMvcControllerAttribute : Attribute - { - public AspMvcControllerAttribute() { } - public AspMvcControllerAttribute(string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC Master. Use this attribute - /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, String). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcMasterAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC model type. Use this attribute - /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, Object). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcModelTypeAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC - /// partial view. If applied to a method, the MVC partial view name is calculated implicitly - /// from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class AspMvcPartialViewAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] - internal sealed class AspMvcSupressViewErrorAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcDisplayTemplateAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC editor template. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcEditorTemplateAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC template. - /// Use this attribute for custom wrappers similar to - /// System.ComponentModel.DataAnnotations.UIHintAttribute(System.String). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcTemplateAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC view. If applied to a method, the MVC view name is calculated implicitly - /// from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Controller.View(Object). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class AspMvcViewAttribute : Attribute { } - - /// - /// ASP.NET MVC attribute. When applied to a parameter of an attribute, - /// indicates that this parameter is an MVC action name. - /// - /// - /// [ActionName("Foo")] - /// public ActionResult Login(string returnUrl) { - /// ViewBag.ReturnUrl = Url.Action("Foo"); // OK - /// return RedirectToAction("Bar"); // Error: Cannot resolve action - /// } - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] - internal sealed class AspMvcActionSelectorAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] - internal sealed class HtmlElementAttributesAttribute : Attribute - { - public HtmlElementAttributesAttribute() { } - public HtmlElementAttributesAttribute(string name) - { - Name = name; - } - - public string Name { get; } - } - - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class HtmlAttributeValueAttribute : Attribute - { - public HtmlAttributeValueAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] - public string Name { get; } - } - - /// - /// Razor attribute. Indicates that a parameter or a method is a Razor section. - /// Use this attribute for custom wrappers similar to - /// System.Web.WebPages.WebPageBase.RenderSection(String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class RazorSectionAttribute : Attribute { } - - /// - /// Indicates how method invocation affects content of the collection. - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class CollectionAccessAttribute : Attribute - { - public CollectionAccessAttribute(CollectionAccessType collectionAccessType) - { - CollectionAccessType = collectionAccessType; - } - - public CollectionAccessType CollectionAccessType { get; } - } - - [Flags] - internal enum CollectionAccessType - { - /// Method does not use or modify content of the collection. - None = 0, - /// Method only reads content of the collection but does not modify it. - Read = 1, - /// Method can change content of the collection but does not add new elements. - ModifyExistingContent = 2, - /// Method can add new elements to the collection. - UpdatedContent = ModifyExistingContent | 4 - } - - /// - /// Indicates that the marked method is assertion method, i.e. it halts control flow if - /// one of the conditions is satisfied. To set the condition, mark one of the parameters with - /// attribute. - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class AssertionMethodAttribute : Attribute { } - - /// - /// Indicates the condition parameter of the assertion method. The method itself should be - /// marked by attribute. The mandatory argument of - /// the attribute is the assertion type. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AssertionConditionAttribute : Attribute - { - public AssertionConditionAttribute(AssertionConditionType conditionType) - { - ConditionType = conditionType; - } - - public AssertionConditionType ConditionType { get; } - } - - /// - /// Specifies assertion type. If the assertion method argument satisfies the condition, - /// then the execution continues. Otherwise, execution is assumed to be halted. - /// - internal enum AssertionConditionType - { - /// Marked parameter should be evaluated to true. - IS_TRUE = 0, - /// Marked parameter should be evaluated to false. - IS_FALSE = 1, - /// Marked parameter should be evaluated to null value. - IS_NULL = 2, - /// Marked parameter should be evaluated to not null value. - IS_NOT_NULL = 3, - } - - /// - /// Indicates that the marked method unconditionally terminates control flow execution. - /// For example, it could unconditionally throw exception. - /// - [Obsolete("Use [ContractAnnotation('=> halt')] instead")] - [AttributeUsage(AttributeTargets.Method)] - internal sealed class TerminatesProgramAttribute : Attribute { } - - /// - /// Indicates that method is pure LINQ method, with postponed enumeration (like Enumerable.Select, - /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters - /// of delegate type by analyzing LINQ method chains. - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class LinqTunnelAttribute : Attribute { } - - /// - /// Indicates that IEnumerable, passed as parameter, is not enumerated. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class NoEnumerationAttribute : Attribute { } - - /// - /// Indicates that parameter is regular expression pattern. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class RegexPatternAttribute : Attribute { } - - /// - /// XAML attribute. Indicates the type that has ItemsSource property and should be treated - /// as ItemsControl-derived type, to enable inner items DataContext type resolve. - /// - [AttributeUsage(AttributeTargets.Class)] - internal sealed class XamlItemsControlAttribute : Attribute { } - - /// - /// XAML attibute. Indicates the property of some BindingBase-derived type, that - /// is used to bind some item of ItemsControl-derived type. This annotation will - /// enable the DataContext type resolve for XAML bindings for such properties. - /// - /// - /// Property should have the tree ancestor of the ItemsControl type or - /// marked with the attribute. - /// - [AttributeUsage(AttributeTargets.Property)] - internal sealed class XamlItemBindingOfItemsControlAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class AspChildControlTypeAttribute : Attribute - { - public AspChildControlTypeAttribute(string tagName, Type controlType) - { - TagName = tagName; - ControlType = controlType; - } - - public string TagName { get; } - public Type ControlType { get; } - } - - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] - internal sealed class AspDataFieldAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] - internal sealed class AspDataFieldsAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class AspMethodPropertyAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class AspRequiredAttributeAttribute : Attribute - { - public AspRequiredAttributeAttribute([NotNull] string attribute) - { - Attribute = attribute; - } - - public string Attribute { get; } - } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class AspTypePropertyAttribute : Attribute - { - public bool CreateConstructorReferences { get; } - - public AspTypePropertyAttribute(bool createConstructorReferences) - { - CreateConstructorReferences = createConstructorReferences; - } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorImportNamespaceAttribute : Attribute - { - public RazorImportNamespaceAttribute(string name) - { - Name = name; - } - - public string Name { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorInjectionAttribute : Attribute - { - public RazorInjectionAttribute(string type, string fieldName) - { - Type = type; - FieldName = fieldName; - } - - public string Type { get; } - public string FieldName { get; } - } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorHelperCommonAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class RazorLayoutAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorWriteLiteralMethodAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorWriteMethodAttribute : Attribute { } - - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class RazorWriteMethodParameterAttribute : Attribute { } - - /// - /// Prevents the Member Reordering feature from tossing members of the marked class. - /// - /// - /// The attribute must be mentioned in your member reordering patterns - /// - [AttributeUsage(AttributeTargets.All)] - internal sealed class NoReorder : Attribute { } -} \ No newline at end of file diff --git a/src/MGR.CommandLineParser/Properties/Strings.Designer.cs b/src/MGR.CommandLineParser/Properties/Strings.Designer.cs index 2e8f7dc..c33829e 100644 --- a/src/MGR.CommandLineParser/Properties/Strings.Designer.cs +++ b/src/MGR.CommandLineParser/Properties/Strings.Designer.cs @@ -12,7 +12,7 @@ namespace MGR.CommandLineParser.Properties { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. @@ -32,7 +32,7 @@ internal Strings() { } /// - /// Returns the cached ResourceManager instance used by this class. + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { @@ -46,8 +46,8 @@ internal Strings() { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { @@ -60,7 +60,7 @@ internal Strings() { } /// - /// Looks up a localized string similar to Help. + /// Looks up a localized string similar to Help. /// public static string Command_HelpOption_DescriptionMessage { get { @@ -69,7 +69,7 @@ public static string Command_HelpOption_DescriptionMessage { } /// - /// Looks up a localized string similar to ?. + /// Looks up a localized string similar to ?. /// public static string Command_HelpOption_ShortNameMessage { get { @@ -78,7 +78,7 @@ public static string Command_HelpOption_ShortNameMessage { } /// - /// Looks up a localized string similar to WARNING: {0}. + /// Looks up a localized string similar to WARNING: {0}. /// public static string Console_WarningFormat { get { @@ -87,7 +87,7 @@ public static string Console_WarningFormat { } /// - /// Looks up a localized string similar to {0} Command help :. + /// Looks up a localized string similar to {0} Command help :. /// public static string DefaultHelpWriter_CommandTitleFormat { get { @@ -96,7 +96,7 @@ public static string DefaultHelpWriter_CommandTitleFormat { } /// - /// Looks up a localized string similar to Usage: {0} {1} {2}. + /// Looks up a localized string similar to Usage: {0} {1} {2}. /// public static string DefaultHelpWriter_CommandUsageFormat { get { @@ -105,7 +105,7 @@ public static string DefaultHelpWriter_CommandUsageFormat { } /// - /// Looks up a localized string similar to {0} <command>. + /// Looks up a localized string similar to {0} <command>. /// public static string DefaultHelpWriter_GlobalCommandLineCommandFormat { get { @@ -114,7 +114,7 @@ public static string DefaultHelpWriter_GlobalCommandLineCommandFormat { } /// - /// Looks up a localized string similar to Available commands:. + /// Looks up a localized string similar to Available commands:. /// public static string DefaultHelpWriter_GlobalHelp_AvailableCommands { get { @@ -123,7 +123,7 @@ public static string DefaultHelpWriter_GlobalHelp_AvailableCommands { } /// - /// Looks up a localized string similar to Type '{0} <command>' for help on a specific command.. + /// Looks up a localized string similar to Type '{0} <command>' for help on a specific command. /// public static string DefaultHelpWriter_GlobalHelpCommandUsageFormat { get { @@ -132,7 +132,7 @@ public static string DefaultHelpWriter_GlobalHelpCommandUsageFormat { } /// - /// Looks up a localized string similar to Usage: {0} [options] [args]. + /// Looks up a localized string similar to Usage: {0} [options] [args]. /// public static string DefaultHelpWriter_GlobalUsageFormat { get { @@ -141,7 +141,7 @@ public static string DefaultHelpWriter_GlobalUsageFormat { } /// - /// Looks up a localized string similar to Options:. + /// Looks up a localized string similar to Options:. /// public static string DefaultHelpWriter_OptionsListTitle { get { @@ -150,7 +150,7 @@ public static string DefaultHelpWriter_OptionsListTitle { } /// - /// Looks up a localized string similar to Command {0} : invalid arguments :. + /// Looks up a localized string similar to Command {0} : invalid arguments :. /// public static string Parser_CommandInvalidArgumentsFormat { get { @@ -159,7 +159,7 @@ public static string Parser_CommandInvalidArgumentsFormat { } /// - /// Looks up a localized string similar to {0} Version: {1}. + /// Looks up a localized string similar to {0} Version: {1}. /// public static string ParserOptions_LogoFormat { get { diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props new file mode 100644 index 0000000..f3ee11b --- /dev/null +++ b/tests/Directory.Build.props @@ -0,0 +1,6 @@ + + + disable + latest + + \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/ConsoleLoggingTestsBase.cs b/tests/MGR.CommandLineParser.IntegrationTests/ConsoleLoggingTestsBase.cs index b1f9a57..ebc652c 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/ConsoleLoggingTestsBase.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/ConsoleLoggingTestsBase.cs @@ -7,94 +7,97 @@ using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests +namespace MGR.CommandLineParser.IntegrationTests; + +public abstract class ConsoleLoggingTestsBase { - public abstract class ConsoleLoggingTestsBase + private readonly IServiceCollection _serviceCollection; + protected FakeConsole Console; + protected ConsoleLoggingTestsBase() { - private readonly IServiceCollection _serviceCollection; - protected FakeConsole Console; - protected ConsoleLoggingTestsBase() - { - _serviceCollection = new ServiceCollection(); - _serviceCollection.AddScoped(_ => - { - Console = new FakeConsole(); - return Console; - }); - } + _serviceCollection = new ServiceCollection(); + _serviceCollection.AddScoped(_ => + { + Console = new FakeConsole(); + return Console; + }); + } - private static ParserOptions CreateParserOptions() - { - return new ParserOptions { - Logo = "Integration Tests", - CommandLineName = "test.exe" - }; - } + private static ParserOptions CreateParserOptions() + { + return new ParserOptions { + Logo = "Integration Tests", + CommandLineName = "test.exe" + }; + } - protected async Task CallParse(IEnumerable args) - { - var parsingResult = await CallParse(CreateParserOptions(), args); - return parsingResult; - } - protected async Task CallParse(ParserOptions parserOptions, IEnumerable args) - { - var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); - parserBuilder.AddCommands(builder => builder.AddCommands()); - var parser = parserBuilder.BuildParser(); - var parsingResult = await parser.Parse(args); + protected async Task CallParse(IEnumerable args) + { + var parsingResult = await CallParse(CreateParserOptions(), args); + return parsingResult; + } + protected async Task CallParse(ParserOptions parserOptions, IEnumerable args) + { + var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); + parserBuilder.AddCommands(builder => builder.AddCommands()); + var parser = parserBuilder.BuildParser(); + var parsingResult = await parser.Parse(args); - return parsingResult; - } - protected async Task CallParse(IEnumerable args) - where TCommand : class, ICommand - { - var parsingResult = await CallParse(CreateParserOptions(), args); + return parsingResult; + } + protected async Task CallParse(IEnumerable args) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var parsingResult = await CallParse(CreateParserOptions(), args); - return parsingResult; - } + return parsingResult; + } - protected async Task CallParse(ParserOptions parserOptions, IEnumerable args) - where TCommand : class, ICommand - { - var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); - parserBuilder.AddCommands(builder => builder.AddCommands()); - var parser = parserBuilder.BuildParser(); - var parsingResult = await parser.Parse(args); + protected async Task CallParse(ParserOptions parserOptions, IEnumerable args) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); + parserBuilder.AddCommands(builder => builder.AddCommands()); + var parser = parserBuilder.BuildParser(); + var parsingResult = await parser.Parse(args); - return parsingResult; - } - protected async Task CallParseWithDefaultCommand(IEnumerable args) - where TCommand : class, ICommand - { - var parsingResult = await CallParseWithDefaultCommand(CreateParserOptions(), args); + return parsingResult; + } + protected async Task CallParseWithDefaultCommand(IEnumerable args) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var parsingResult = await CallParseWithDefaultCommand(CreateParserOptions(), args); - return parsingResult; - } + return parsingResult; + } - protected async Task CallParseWithDefaultCommand(ParserOptions parserOptions, IEnumerable args) - where TCommand : class, ICommand - { - var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); - parserBuilder.AddCommands(builder => builder.AddCommands()); - var parser = parserBuilder.BuildParser(); - var parsingResult = await parser.ParseWithDefaultCommand(args); + protected async Task CallParseWithDefaultCommand(ParserOptions parserOptions, IEnumerable args) + where TCommandHandler : class, ICommandHandler + where TCommandData : CommandData, new() + { + var parserBuilder = new ParserBuilder(parserOptions, _serviceCollection); + parserBuilder.AddCommands(builder => builder.AddCommands()); + var parser = parserBuilder.BuildParser(); + var parsingResult = await parser.ParseWithDefaultCommand(args); - return parsingResult; - } + return parsingResult; + } - protected void AssertNoMessage() - { - var messages = Console.Messages; - Assert.Empty(messages); - } + protected void AssertNoMessage() + { + var messages = Console.Messages; + Assert.Empty(messages); + } - protected void AssertOneMessageLoggedToConsole(string expectedMessage) - where TMessage : FakeConsole.Message - { - var messages = Console.Messages; - Assert.Single(messages); - Assert.IsType(messages[0]); - Assert.Equal(expectedMessage, messages[0].ToString(), ignoreLineEndingDifferences: true); - } + protected void AssertOneMessageLoggedToConsole(string expectedMessage) + where TMessage : FakeConsole.Message + { + var messages = Console.Messages; + Assert.Single(messages); + Assert.IsType(messages[0]); + Assert.Equal(expectedMessage, messages[0].ToString(), ignoreLineEndingDifferences: true); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/Help/AsOptionsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/Help/AsOptionsTests.cs index 96bd157..d840f84 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/Help/AsOptionsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/Help/AsOptionsTests.cs @@ -5,17 +5,17 @@ using MGR.CommandLineParser.UnitTests; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.Help +namespace MGR.CommandLineParser.IntegrationTests.Help; + +public class AsOptionsTests : ConsoleLoggingTestsBase { - public class AsOptionsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgs() { - [Fact] - public async Task ParseWithValidArgs() - { - // Arrange - IEnumerable args = new[] { "--help" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedHelpMessage = @"Integration Tests + // Arrange + IEnumerable args = new[] { "--help" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedHelpMessage = @"Integration Tests Usage: test.exe [options] [args] Type 'test.exe help ' for help on a specific command. @@ -29,25 +29,23 @@ public async Task ParseWithValidArgs() --int-list-value+ (il) A list of integer value --help (?) Help "; - //var expectedNbOfArguments = 1; - //var expectedArgumentsValue = "Custom argument value"; - //var expectedIntValue = 42; - - // Act - var actual = await CallParseWithDefaultCommand(args); - - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - - Assert.Equal(0, await rawCommand.ExecuteAsync()); - var message = Assert.Single(Console.Messages); - - Assert.IsType< FakeConsole.InformationMessage>(message); - Assert.Equal(expectedHelpMessage, message.ToString()); - } + //var expectedNbOfArguments = 1; + //var expectedArgumentsValue = "Custom argument value"; + //var expectedIntValue = 42; + + // Act + var actual = await CallParseWithDefaultCommand(args); + + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommand = classBasedCommandObject.Command; + + Assert.Equal(0, await rawCommand.ExecuteAsync(classBasedCommandObject.CommandData, default)); + var message = Assert.Single(Console.Messages); + + Assert.IsType< FakeConsole.InformationMessage>(message); + Assert.Equal(expectedHelpMessage, message.ToString()); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InexistingShortOptionTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InexistingShortOptionTests.cs index 9106e9a..91e110e 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InexistingShortOptionTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InexistingShortOptionTests.cs @@ -3,24 +3,23 @@ using MGR.CommandLineParser.UnitTests; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.InvalidArguments +namespace MGR.CommandLineParser.IntegrationTests.InvalidArguments; + +public class InexistingShortOptionTests : ConsoleLoggingTestsBase { - public class InexistingShortOptionTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithInvalidArgs() { - [Fact] - public async Task ParseWithInvalidArgs() - { - // Arrange - IEnumerable args = new[] { "delete", "--source:custom value", "-pn", "ApiKey", "MyApiKey", "Custom argument value", "b" }; - var expected = @"There is no option 'pn' for the command 'Delete'. + // Arrange + IEnumerable args = new[] { "delete", "--source:custom value", "-pn", "ApiKey", "MyApiKey", "Custom argument value", "b" }; + var expected = @"There is no option 'pn' for the command 'Delete'. "; - // Act - var parsingResult = await CallParse(args); + // Act + var parsingResult = await CallParse(args); - // Assert - Assert.NotNull(parsingResult); - Assert.Equal(CommandParsingResultCode.CommandParametersNotValid, parsingResult.ParsingResultCode); - AssertOneMessageLoggedToConsole(expected); - } + // Assert + Assert.NotNull(parsingResult); + Assert.Equal(CommandParsingResultCode.CommandParametersNotValid, parsingResult.ParsingResultCode); + AssertOneMessageLoggedToConsole(expected); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InvalidShortNameFormatTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InvalidShortNameFormatTests.cs index de12754..2c862c7 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InvalidShortNameFormatTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/InvalidArguments/InvalidShortNameFormatTests.cs @@ -3,25 +3,24 @@ using MGR.CommandLineParser.UnitTests; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.InvalidArguments +namespace MGR.CommandLineParser.IntegrationTests.InvalidArguments; + +public class InvalidShortNameFormatTests : ConsoleLoggingTestsBase { - public class InvalidShortNameFormatTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithInvalidShortOption() { - [Fact] - public async Task ParseWithInvalidShortOption() - { - // Arrange - IEnumerable args = new[] { "import", "--p:50" }; - var expected = @"There is no option 'p' for the command 'Import'. + // Arrange + IEnumerable args = new[] { "import", "--p:50" }; + var expected = @"There is no option 'p' for the command 'Import'. "; - // Act - var parsingResult = await CallParse(args); + // Act + var parsingResult = await CallParse(args); - // Assert - Assert.NotNull(parsingResult); - Assert.Equal(CommandParsingResultCode.CommandParametersNotValid, parsingResult.ParsingResultCode); - AssertOneMessageLoggedToConsole(expected); - } + // Assert + Assert.NotNull(parsingResult); + Assert.Equal(CommandParsingResultCode.CommandParametersNotValid, parsingResult.ParsingResultCode); + AssertOneMessageLoggedToConsole(expected); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/MGR.CommandLineParser.IntegrationTests.csproj b/tests/MGR.CommandLineParser.IntegrationTests/MGR.CommandLineParser.IntegrationTests.csproj index 2f7208b..a4aeffb 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/MGR.CommandLineParser.IntegrationTests.csproj +++ b/tests/MGR.CommandLineParser.IntegrationTests/MGR.CommandLineParser.IntegrationTests.csproj @@ -1,26 +1,27 @@  - - - net8.0;net48 - - false - false - + + + net8.0;net48 + + false + false + latest + - - - - - - - - + + + + + + + + - - - - - + + + + + diff --git a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/CommandParameterNotValidTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/CommandParameterNotValidTests.cs index c979c87..f41b5a5 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/CommandParameterNotValidTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/CommandParameterNotValidTests.cs @@ -5,60 +5,57 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode +namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode; + +public class CommandParameterNotValidTests : ConsoleLoggingTestsBase { - public class CommandParameterNotValidTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithCommandNameAndInvalidArgs() { - [Fact] - public async Task ParseWithCommandNameAndInvalidArgs() - { - // Arrange - IEnumerable args = new[] {"IntTest", "-i", "42", "Custom argument value", "-b"}; - var expectedReturnCode = CommandParsingResultCode.CommandParametersNotValid; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + // Arrange + IEnumerable args = new[] {"IntTest", "-i", "42", "Custom argument value", "-b"}; + var expectedReturnCode = CommandParsingResultCode.CommandParametersNotValid; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.False(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.Null(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.False(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.Null(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommandData.Arguments.Single()); + Assert.True(rawCommandData.BoolValue); + } - [Fact] - public async Task ParseWithSpecifiedCommandAndInvalidArgs() - { - // Arrange - IEnumerable args = new[] { "-i", "42", "Custom argument value", "-b" }; - var expectedReturnCode = CommandParsingResultCode.CommandParametersNotValid; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + [Fact] + public async Task ParseWithSpecifiedCommandAndInvalidArgs() + { + // Arrange + IEnumerable args = new[] { "-i", "42", "Custom argument value", "-b" }; + var expectedReturnCode = CommandParsingResultCode.CommandParametersNotValid; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.False(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.Null(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.False(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.Null(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommandData.Arguments.Single()); + Assert.True(rawCommandData.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoArgsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoArgsTests.cs index ddbd589..00c6da4 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoArgsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoArgsTests.cs @@ -1,23 +1,22 @@ using System.Threading.Tasks; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode +namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode; + +public class NoArgsTests : ConsoleLoggingTestsBase { - public class NoArgsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithoutParameter() { - [Fact] - public async Task ParseWithoutParameter() - { - // Arrange - var expectedReturnCode = CommandParsingResultCode.NoArgumentsProvided; + // Arrange + var expectedReturnCode = CommandParsingResultCode.NoArgumentsProvided; - // Act - var actual = await CallParse(null); + // Act + var actual = await CallParse(null); - // Assert - Assert.False(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.Null(actual.CommandObject); - } + // Assert + Assert.False(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + Assert.Null(actual.CommandObject); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandFoundTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandFoundTests.cs index 58df821..c5f5f4a 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandFoundTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandFoundTests.cs @@ -2,24 +2,23 @@ using System.Threading.Tasks; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode +namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode; + +public class NoCommandFoundTests : ConsoleLoggingTestsBase { - public class NoCommandFoundTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithBadCommandName() { - [Fact] - public async Task ParseWithBadCommandName() - { - // Arrange - IEnumerable args = new[] {"NotValid", "-option:true"}; - var expectedReturnCode = CommandParsingResultCode.NoCommandFound; + // Arrange + IEnumerable args = new[] {"NotValid", "-option:true"}; + var expectedReturnCode = CommandParsingResultCode.NoCommandFound; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.False(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.Null(actual.CommandObject); - } + // Assert + Assert.False(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + Assert.Null(actual.CommandObject); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandNameTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandNameTests.cs index f023175..47aff0e 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandNameTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/NotOkResultCode/NoCommandNameTests.cs @@ -2,24 +2,23 @@ using System.Threading.Tasks; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode +namespace MGR.CommandLineParser.IntegrationTests.NotOkResultCode; + +public class NoCommandNameTests : ConsoleLoggingTestsBase { - public class NoCommandNameTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithEmptyParameter() { - [Fact] - public async Task ParseWithEmptyParameter() - { - // Arrange - IEnumerable args = new List(); - var expectedReturnCode = CommandParsingResultCode.NoCommandNameProvided; + // Arrange + IEnumerable args = new List(); + var expectedReturnCode = CommandParsingResultCode.NoCommandNameProvided; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.False(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.Null(actual.CommandObject); - } + // Assert + Assert.False(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + Assert.Null(actual.CommandObject); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/CollectionOptionsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/CollectionOptionsTests.cs index 81eb858..b1d71b0 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/CollectionOptionsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/CollectionOptionsTests.cs @@ -5,39 +5,37 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand +namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand; + +public class CollectionOptionsTests : ConsoleLoggingTestsBase { - public class CollectionOptionsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidListArgs() { - [Fact] - public async Task ParseWithValidListArgs() - { - // Arrange - IEnumerable args = new[] - {"--str-value:custom value", "-i", "42", "-il", "42", "Custom argument value", "-b"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedStrValue = "custom value"; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + // Arrange + IEnumerable args = new[] + {"--str-value:custom value", "-i", "42", "-il", "42", "Custom argument value", "-b"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedStrValue = "custom value"; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedStrValue, rawCommand.StrValue); - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.NotNull(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.Equal(expectedNbOfArguments, rawCommand.IntListValue.Count); - Assert.Equal(expectedIntValue, rawCommand.IntListValue.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommand = classBasedCommandObject.CommandData; + Assert.Equal(expectedStrValue, rawCommand.StrValue); + Assert.Equal(expectedIntValue, rawCommand.IntValue); + Assert.NotNull(rawCommand.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); + Assert.Equal(expectedNbOfArguments, rawCommand.IntListValue.Count); + Assert.Equal(expectedIntValue, rawCommand.IntListValue.Single()); + Assert.True(rawCommand.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EnumTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EnumTests.cs index 3dc2fd6..2ec8e88 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EnumTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EnumTests.cs @@ -17,13 +17,13 @@ public async Task ParseWithValidArgs() var expectedTargets = AttributeTargets.Assembly; // Act - var actual = await CallParse(args); + var actual = await CallParse(args); // Assert Assert.True(actual.IsValid); Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - var classBasedCommandObject = Assert.IsAssignableFrom(actual.CommandObject); - var rawCommand = Assert.IsType(classBasedCommandObject.Command); - Assert.Equal(expectedTargets, rawCommand.Target); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedTargets, rawCommandData.Target); } } diff --git a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EscapedTraillingArgumentTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EscapedTraillingArgumentTests.cs index 2fd3b75..c68218a 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EscapedTraillingArgumentTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/EscapedTraillingArgumentTests.cs @@ -4,36 +4,34 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand +namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand; + +public class EscapedTraillingArgumentTests : ConsoleLoggingTestsBase { - public class EscapedTraillingArgumentTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgsAnDoubleDash() { - [Fact] - public async Task ParseWithValidArgsAnDoubleDash() - { - // Arrange - IEnumerable args = new[] {"--str-value:custom value", "-i", "42", "Custom argument value", "-b", "--", "firstArg", "-i", "32"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedStrValue = "custom value"; - var expectedNbOfArguments = 4; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + // Arrange + IEnumerable args = new[] {"--str-value:custom value", "-i", "42", "Custom argument value", "-b", "--", "firstArg", "-i", "32"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedStrValue = "custom value"; + var expectedNbOfArguments = 4; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedStrValue, rawCommand.StrValue); - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.Null(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(new List {expectedArgumentsValue, "firstArg", "-i", "32"}, rawCommand.Arguments); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedStrValue, rawCommandData.StrValue); + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.Null(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(new List {expectedArgumentsValue, "firstArg", "-i", "32"}, rawCommandData.Arguments); + Assert.True(rawCommandData.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/InternalTypesTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/InternalTypesTests.cs index 4a0657d..ea2dede 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/InternalTypesTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/InternalTypesTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; @@ -16,24 +17,27 @@ public async Task ParseInternalCommand() var expectedReturnCode = CommandParsingResultCode.Success; // Act - var actual = await CallParseWithDefaultCommand(args); + var actual = await CallParseWithDefaultCommand(args); // Assert Assert.True(actual.IsValid); Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - var classBasedCommandObject = Assert.IsAssignableFrom(actual.CommandObject); - var rawCommand = Assert.IsType(classBasedCommandObject.Command); - Assert.Equal(123, await rawCommand.ExecuteAsync()); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommand = classBasedCommandObject.Command; + Assert.Equal(123, await rawCommand.ExecuteAsync(classBasedCommandObject.CommandData, default)); } } internal class Test { - internal class InternalCommand : CommandBase + internal class InternalCommand : CommandBase { + internal class InternalCommandData : HelpedCommandData + { + } public InternalCommand(IServiceProvider serviceProvider) : base(serviceProvider) { } - protected override Task ExecuteCommandAsync() => Task.FromResult(123); + protected override Task ExecuteCommandAsync(InternalCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(123); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/SimpleOptionsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/SimpleOptionsTests.cs index 811fdb2..5bff8e6 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/SimpleOptionsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/SpecificCommand/SimpleOptionsTests.cs @@ -5,36 +5,34 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand +namespace MGR.CommandLineParser.IntegrationTests.SpecificCommand; + +public class SimpleOptionsTests : ConsoleLoggingTestsBase { - public class SimpleOptionsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgs() { - [Fact] - public async Task ParseWithValidArgs() - { - // Arrange - IEnumerable args = new[] {"--str-value:custom value", "-i", "42", "Custom argument value", "-b"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedStrValue = "custom value"; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + // Arrange + IEnumerable args = new[] {"--str-value:custom value", "-i", "42", "Custom argument value", "-b"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedStrValue = "custom value"; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedStrValue, rawCommand.StrValue); - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.Null(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedStrValue, rawCommandData.StrValue); + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.Null(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommandData.Arguments.Single()); + Assert.True(rawCommandData.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/ArgumentsInResponseFileTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/ArgumentsInResponseFileTests.cs index 0443000..010a115 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/ArgumentsInResponseFileTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/ArgumentsInResponseFileTests.cs @@ -4,41 +4,39 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class ArgumentsInResponseFileTests : ConsoleLoggingTestsBase { - public class ArgumentsInResponseFileTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithAResponseFile() { - [Fact] - public async Task ParseWithAResponseFile() + // Arrange + var tempFile = Path.GetRandomFileName(); + var tempResponseFileName = Path.ChangeExtension(tempFile, ".rsp"); + var tempFolder = Path.GetTempPath(); + var tempResponseFile = Path.Combine(tempFolder, tempResponseFileName); + File.WriteAllLines(tempResponseFile, new[] { - // Arrange - var tempFile = Path.GetRandomFileName(); - var tempResponseFileName = Path.ChangeExtension(tempFile, ".rsp"); - var tempFolder = Path.GetTempPath(); - var tempResponseFile = Path.Combine(tempFolder, tempResponseFileName); - File.WriteAllLines(tempResponseFile, new[] - { - "install", - "--version:12.34", - "--exclude-version" - }); + "install", + "--version:12.34", + "--exclude-version" + }); - // Act - var actual = await CallParse(new[] { "@" + tempResponseFile }); + // Act + var actual = await CallParse(new[] { "@" + tempResponseFile }); - // Assert - Assert.True(actual.IsValid); - Assert.Empty(actual.ValidationResults); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var installCommand = (InstallCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Empty(installCommand.Source); - Assert.True(string.IsNullOrEmpty(installCommand.OutputDirectory)); - Assert.Equal("12.34", installCommand.Version); - Assert.True(installCommand.ExcludeVersion); - Assert.False(installCommand.Prerelease); - Assert.False(installCommand.NoCache); - Assert.Empty(installCommand.Arguments); - } + // Assert + Assert.True(actual.IsValid); + Assert.Empty(actual.ValidationResults); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var installCommandData = classBasedCommandObject.CommandData; + Assert.Empty(installCommandData.Source); + Assert.True(string.IsNullOrEmpty(installCommandData.OutputDirectory)); + Assert.Equal("12.34", installCommandData.Version); + Assert.True(installCommandData.ExcludeVersion); + Assert.False(installCommandData.Prerelease); + Assert.False(installCommandData.NoCache); + Assert.Empty(installCommandData.Arguments); } } diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CollectionArgumentWithArgumentsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CollectionArgumentWithArgumentsTests.cs index 5ac9d7b..1423f49 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CollectionArgumentWithArgumentsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CollectionArgumentWithArgumentsTests.cs @@ -5,39 +5,37 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class CollectionArgumentWithArgumentsTests : ConsoleLoggingTestsBase { - public class CollectionArgumentWithArgumentsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidListArgs() { - [Fact] - public async Task ParseWithValidListArgs() - { - // Arrange - IEnumerable args = new[] - {"IntTest", "--str-value:custom value", "-i", "42", "-il", "42", "Custom argument value", "-b"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedStrValue = "custom value"; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + // Arrange + IEnumerable args = new[] + {"IntTest", "--str-value:custom value", "-i", "42", "-il", "42", "Custom argument value", "-b"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedStrValue = "custom value"; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand) ((IClassBasedCommandObject) actual.CommandObject).Command; - Assert.Equal(expectedStrValue, rawCommand.StrValue); - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.NotNull(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.Equal(expectedNbOfArguments, rawCommand.IntListValue.Count); - Assert.Equal(expectedIntValue, rawCommand.IntListValue.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedStrValue, rawCommandData.StrValue); + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.NotNull(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommandData.Arguments.Single()); + Assert.Equal(expectedNbOfArguments, rawCommandData.IntListValue.Count); + Assert.Equal(expectedIntValue, rawCommandData.IntListValue.Single()); + Assert.True(rawCommandData.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CombinedShortSimpleOptionsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CombinedShortSimpleOptionsTests.cs index affe3d5..79b4dfa 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CombinedShortSimpleOptionsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/CombinedShortSimpleOptionsTests.cs @@ -4,53 +4,51 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class CombinedShortSimpleOptionsTests : ConsoleLoggingTestsBase { - public class CombinedShortSimpleOptionsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgs() { - [Fact] - public async Task ParseWithValidArgs() - { - // Arrange - IEnumerable args = new[] { "pack", "--version:abc", "-vt" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedVersion = "abc"; + // Arrange + IEnumerable args = new[] { "pack", "--version:abc", "-vt" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedVersion = "abc"; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (PackCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.True(rawCommand.Verbose); - Assert.True(rawCommand.Tool); - Assert.False(rawCommand.Build); - Assert.Equal(expectedVersion, rawCommand.Version); - } - [Fact] - public async Task ParseWithValidArgsWithFalse() - { - // Arrange - IEnumerable args = new[] { "pack", "--version:abc", "-vt:-", "-b" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedVersion = "abc"; + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + Assert.IsAssignableFrom>(actual.CommandObject); + Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); + var rawCommandData = ((IClassBasedCommandObject)actual.CommandObject).CommandData; + Assert.True(rawCommandData.Verbose); + Assert.True(rawCommandData.Tool); + Assert.False(rawCommandData.Build); + Assert.Equal(expectedVersion, rawCommandData.Version); + } + [Fact] + public async Task ParseWithValidArgsWithFalse() + { + // Arrange + IEnumerable args = new[] { "pack", "--version:abc", "-vt:-", "-b" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedVersion = "abc"; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (PackCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.False(rawCommand.Verbose); - Assert.False(rawCommand.Tool); - Assert.True(rawCommand.Build); - Assert.Equal(expectedVersion, rawCommand.Version); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.False(rawCommandData.Verbose); + Assert.False(rawCommandData.Tool); + Assert.True(rawCommandData.Build); + Assert.Equal(expectedVersion, rawCommandData.Version); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/HelpCommandTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/HelpCommandTests.cs index 920e2dc..07bdde8 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/HelpCommandTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/HelpCommandTests.cs @@ -2,27 +2,25 @@ using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; -using MGR.CommandLineParser.Tests.Commands; using MGR.CommandLineParser.UnitTests; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class HelpCommandTests : ConsoleLoggingTestsBase { - public class HelpCommandTests : ConsoleLoggingTestsBase + [Fact] + public async Task ShowGenericHelpForAllCommand() { - [Fact] - - public async Task ShowGenericHelpForAllCommand() - { - // Arrange - var parserOptions = new ParserOptions { - Logo = "Display generic help", - CommandLineName = "myHelpTest.exe" - }; - IEnumerable args = new[] { "help" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedResult = 0; - var expected = @"Display generic help + // Arrange + var parserOptions = new ParserOptions { + Logo = "Display generic help", + CommandLineName = "myHelpTest.exe" + }; + IEnumerable args = new[] { "help" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedResult = 0; + var expected = @"Display generic help Usage: myHelpTest.exe [options] [args] Type 'myHelpTest.exe help ' for help on a specific command. @@ -43,21 +41,18 @@ Spec SpecCommandDescription Update UpdateCommandDescription "; - // Act - using (new LangageSwitcher("en-us")) - { - var actual = await CallParse(parserOptions, args); - var actualResult = await actual.ExecuteAsync(); + // Act + using (new LangageSwitcher("en-us")) + { + var actual = await CallParse(parserOptions, args); + var actualResult = await actual.ExecuteAsync(default); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - Assert.IsNotType(((IClassBasedCommandObject)actual.CommandObject).Command); - AssertOneMessageLoggedToConsole(expected); - Assert.Equal(expectedResult, actualResult); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + Assert.IsAssignableFrom>(actual.CommandObject); + AssertOneMessageLoggedToConsole(expected); + Assert.Equal(expectedResult, actualResult); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/OptionsHasDefaultValueTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/OptionsHasDefaultValueTests.cs index 0bf3044..c973bd7 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/OptionsHasDefaultValueTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/OptionsHasDefaultValueTests.cs @@ -4,31 +4,29 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class OptionsHasDefaultValueTests : ConsoleLoggingTestsBase { - public class OptionsHasDefaultValueTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgsAndDefaultValue() { - [Fact] - public async Task ParseWithValidArgsAndDefaultValue() - { - // Arrange - IEnumerable args = new[] - {"SetApiKey"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedSource = "DefaultSource"; - var expectedNbOfArguments = 0; + // Arrange + IEnumerable args = new[] + {"SetApiKey"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedSource = "DefaultSource"; + var expectedNbOfArguments = 0; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (SetApiKeyCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedSource, rawCommand.Source); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedSource, rawCommandData.Source); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsTests.cs index f79084f..5932d5f 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsTests.cs @@ -4,40 +4,38 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class SimpleOptionsTests : ConsoleLoggingTestsBase { - public class SimpleOptionsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgs() { - [Fact] - public async Task ParseWithValidArgs() - { - // Arrange - IEnumerable args = new[] {"delete", "--source:custom value", "-np", "--api-key", "MyApiKey", "Custom argument value", "b"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedSource = "custom value"; - var expectedApiKey = "MyApiKey"; - var expectedNbOfArguments = 2; - var expectedArgumentsValue = new List {"Custom argument value", "b"}; + // Arrange + IEnumerable args = new[] {"delete", "--source:custom value", "-np", "--api-key", "MyApiKey", "Custom argument value", "b"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedSource = "custom value"; + var expectedApiKey = "MyApiKey"; + var expectedNbOfArguments = 2; + var expectedArgumentsValue = new List {"Custom argument value", "b"}; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (DeleteCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedSource, rawCommand.Source); - Assert.Equal(expectedApiKey, rawCommand.ApiKey); - Assert.True(rawCommand.NoPrompt); - Assert.Null(rawCommand.SourceProvider); - Assert.Null(rawCommand.Settings); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - for (var i = 0; i < expectedNbOfArguments; i++) - { - Assert.Equal(expectedArgumentsValue[i], ((IClassBasedCommandObject)actual.CommandObject).Command.Arguments[i]); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedSource, rawCommandData.Source); + Assert.Equal(expectedApiKey, rawCommandData.ApiKey); + Assert.True(rawCommandData.NoPrompt); + Assert.Null(rawCommandData.SourceProvider); + Assert.Null(rawCommandData.Settings); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + for (var i = 0; i < expectedNbOfArguments; i++) + { + Assert.Equal(expectedArgumentsValue[i], rawCommandData.Arguments[i]); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsWithArgumentsTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsWithArgumentsTests.cs index 87fd850..7d53055 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsWithArgumentsTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/SimpleOptionsWithArgumentsTests.cs @@ -5,68 +5,65 @@ using MGR.CommandLineParser.Tests.Commands; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class SimpleOptionsWithArgumentsTests : ConsoleLoggingTestsBase { - public class SimpleOptionsWithArgumentsTests : ConsoleLoggingTestsBase + [Fact] + public async Task ParseWithValidArgs() { - [Fact] - public async Task ParseWithValidArgs() - { - // Arrange - var fileArgument = @"C:\temp\file.txt"; - var expectedOutputDirectory = @"C:\Temp"; - var expectedOutputFile = @"C:\Temp\otherfile.txt"; - IEnumerable args = new[] {"import", fileArgument, "-p:50", @"-o:" + expectedOutputDirectory, @"-of:" + expectedOutputFile}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedMaxParallel = 50; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = new List {fileArgument}; + // Arrange + var fileArgument = @"C:\temp\file.txt"; + var expectedOutputDirectory = @"C:\Temp"; + var expectedOutputFile = @"C:\Temp\otherfile.txt"; + IEnumerable args = new[] {"import", fileArgument, "-p:50", @"-o:" + expectedOutputDirectory, @"-of:" + expectedOutputFile}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedMaxParallel = 50; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = new List {fileArgument}; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var importCommand = (ImportCommand) ((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedOutputDirectory, importCommand.OutputDirectory.FullName); - Assert.Equal(expectedOutputFile, importCommand.OutputFile.FullName); - Assert.Equal(expectedMaxParallel, importCommand.MaxItemInParallel); - Assert.Equal(expectedNbOfArguments, importCommand.Arguments.Count); - for (var i = 0; i < expectedNbOfArguments; i++) - { - Assert.Equal(expectedArgumentsValue[i], importCommand.Arguments[i]); - } - } - [Fact] - public async Task ParseWithValidArgs2() + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var importCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedOutputDirectory, importCommandData.OutputDirectory.FullName); + Assert.Equal(expectedOutputFile, importCommandData.OutputFile.FullName); + Assert.Equal(expectedMaxParallel, importCommandData.MaxItemInParallel); + Assert.Equal(expectedNbOfArguments, importCommandData.Arguments.Count); + for (var i = 0; i < expectedNbOfArguments; i++) { - // Arrange - IEnumerable args = new[] - {"IntTest", "--str-value:custom value", "-i", "42", "Custom argument value", "-b"}; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedStrValue = "custom value"; - var expectedNbOfArguments = 1; - var expectedArgumentsValue = "Custom argument value"; - var expectedIntValue = 42; + Assert.Equal(expectedArgumentsValue[i], importCommandData.Arguments[i]); + } + } + [Fact] + public async Task ParseWithValidArgs2() + { + // Arrange + IEnumerable args = new[] + {"IntTest", "--str-value:custom value", "-i", "42", "Custom argument value", "-b"}; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedStrValue = "custom value"; + var expectedNbOfArguments = 1; + var expectedArgumentsValue = "Custom argument value"; + var expectedIntValue = 42; - // Act - var actual = await CallParse(args); + // Act + var actual = await CallParse(args); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - var rawCommand = (IntTestCommand)((IClassBasedCommandObject)actual.CommandObject).Command; - Assert.Equal(expectedStrValue, rawCommand.StrValue); - Assert.Equal(expectedIntValue, rawCommand.IntValue); - Assert.Null(rawCommand.IntListValue); - Assert.Equal(expectedNbOfArguments, rawCommand.Arguments.Count); - Assert.Equal(expectedArgumentsValue, rawCommand.Arguments.Single()); - Assert.True(rawCommand.BoolValue); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + var rawCommandData = classBasedCommandObject.CommandData; + Assert.Equal(expectedStrValue, rawCommandData.StrValue); + Assert.Equal(expectedIntValue, rawCommandData.IntValue); + Assert.Null(rawCommandData.IntListValue); + Assert.Equal(expectedNbOfArguments, rawCommandData.Arguments.Count); + Assert.Equal(expectedArgumentsValue, rawCommandData.Arguments.Single()); + Assert.True(rawCommandData.BoolValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/UseHelpOptionTests.cs b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/UseHelpOptionTests.cs index b0ca4ae..7d7d2fc 100644 --- a/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/UseHelpOptionTests.cs +++ b/tests/MGR.CommandLineParser.IntegrationTests/UnspecifiedCommand/UseHelpOptionTests.cs @@ -5,22 +5,22 @@ using MGR.CommandLineParser.UnitTests; using Xunit; -namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand +namespace MGR.CommandLineParser.IntegrationTests.UnspecifiedCommand; + +public class UseHelpOptionTests : ConsoleLoggingTestsBase { - public class UseHelpOptionTests : ConsoleLoggingTestsBase + [Fact] + public async Task ShowHelpForTheListCommand() { - [Fact] - public async Task ShowHelpForTheListCommand() - { - // Arrange - var parserOptions = new ParserOptions { - Logo = "Display help for list command", - CommandLineName = "myListTest.exe" - }; - IEnumerable args = new[] { "list", "--help" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedResult = 0; - var expected = @"Display help for list command + // Arrange + var parserOptions = new ParserOptions { + Logo = "Display help for list command", + CommandLineName = "myListTest.exe" + }; + IEnumerable args = new[] { "list", "--help" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedResult = 0; + var expected = @"Display help for list command Usage: myListTest.exe [options] [args] Type 'myListTest.exe help ' for help on a specific command. @@ -39,33 +39,33 @@ List sample 1 List sample number 2 "; - // Act - using (new LangageSwitcher("en-us")) - { - var actual = await CallParse(parserOptions, args); - var actualResult = await actual.ExecuteAsync(); + // Act + using (new LangageSwitcher("en-us")) + { + var actual = await CallParse(parserOptions, args); + var actualResult = await actual.ExecuteAsync(default); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - Assert.Equal(expectedResult, actualResult); - AssertOneMessageLoggedToConsole(expected); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + Assert.Equal(expectedResult, actualResult); + AssertOneMessageLoggedToConsole(expected); } + } - [Fact] - public async Task ShowHelpForThePackCommand() - { - // Arrange - var parserOptions = new ParserOptions { - Logo = "Display help for pack command", - CommandLineName = "myPackTest.exe" - }; - IEnumerable args = new[] { "pack", "--help" }; - var expectedReturnCode = CommandParsingResultCode.Success; - var expectedResult = 0; - var expected = @"Display help for pack command + [Fact] + public async Task ShowHelpForThePackCommand() + { + // Arrange + var parserOptions = new ParserOptions { + Logo = "Display help for pack command", + CommandLineName = "myPackTest.exe" + }; + IEnumerable args = new[] { "pack", "--help" }; + var expectedReturnCode = CommandParsingResultCode.Success; + var expectedResult = 0; + var expected = @"Display help for pack command Usage: myPackTest.exe [options] [args] Type 'myPackTest.exe help ' for help on a specific command. @@ -88,20 +88,18 @@ public async Task ShowHelpForThePackCommand() --help (?) Help "; - // Act - using (new LangageSwitcher("en-us")) - { - var actual = await CallParse(parserOptions, args); - var actualResult = await actual.ExecuteAsync(); + // Act + using (new LangageSwitcher("en-us")) + { + var actual = await CallParse(parserOptions, args); + var actualResult = await actual.ExecuteAsync(default); - // Assert - Assert.True(actual.IsValid); - Assert.Equal(expectedReturnCode, actual.ParsingResultCode); - Assert.IsAssignableFrom(actual.CommandObject); - Assert.IsType(((IClassBasedCommandObject)actual.CommandObject).Command); - Assert.Equal(expectedResult, actualResult); - AssertOneMessageLoggedToConsole(expected); - } + // Assert + Assert.True(actual.IsValid); + Assert.Equal(expectedReturnCode, actual.ParsingResultCode); + var classBasedCommandObject = Assert.IsAssignableFrom>(actual.CommandObject); + Assert.Equal(expectedResult, actualResult); + AssertOneMessageLoggedToConsole(expected); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/DeleteCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/DeleteCommand.cs index a80d932..6a0e41a 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/DeleteCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/DeleteCommand.cs @@ -1,12 +1,15 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "DeleteCommandDescription", Usage = "DeleteCommandUsageDescription")] +public class DeleteCommand : CommandBase { - [Command(Description = "DeleteCommandDescription", Usage = "DeleteCommandUsageDescription")] - public class DeleteCommand : CommandBase + public class DeleteCommandData : HelpedCommandData { [Display(Description = "DeleteCommandSourceDescription", ShortName = "src")] public string Source { get; set; } @@ -18,17 +21,14 @@ public class DeleteCommand : CommandBase public string ApiKey { get; set; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object Settings { get; } + } + protected override Task ExecuteCommandAsync(DeleteCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public DeleteCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public DeleteCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/EnumCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/EnumCommand.cs index fccd6b9..ffd45c1 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/EnumCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/EnumCommand.cs @@ -1,14 +1,18 @@ using System; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; namespace MGR.CommandLineParser.Tests.Commands; -public class EnumCommand : CommandBase +public class EnumCommand : CommandBase { - public AttributeTargets Target { get; set; } + public class EnumCommandData:HelpedCommandData + { + public AttributeTargets Target { get; set; } + } public EnumCommand(IServiceProvider serviceProvider) : base(serviceProvider) { } - protected override Task ExecuteCommandAsync() => Task.FromResult(0); + protected override Task ExecuteCommandAsync(EnumCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); } diff --git a/tests/MGR.CommandLineParser.Tests.Commands/HiddenCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/HiddenCommand.cs index 1cc2ca7..166af68 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/HiddenCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/HiddenCommand.cs @@ -1,19 +1,20 @@ using System; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "HiddenCommandDescription", Usage = "HiddenCommandUsage", HideFromHelpListing = true)] +public class HiddenCommand : CommandBase { - [Command(Description = "HiddenCommandDescription", Usage = "HiddenCommandUsage", HideFromHelpListing = true)] - public class HiddenCommand : CommandBase + public class HiddenCommandData : HelpedCommandData { } + protected override Task ExecuteCommandAsync(HiddenCommandData commandData, CancellationToken cancellationToken) { - protected override Task ExecuteCommandAsync() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); + } - public HiddenCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public HiddenCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/ImportCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/ImportCommand.cs index caf7fd0..3a1359c 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/ImportCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/ImportCommand.cs @@ -2,12 +2,15 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.IO; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +public class ImportCommand : CommandBase { - public class ImportCommand : CommandBase + public class ImportCommandData : HelpedCommandData { [Display(ShortName = "p")] [DefaultValue(50)] @@ -18,11 +21,10 @@ public class ImportCommand : CommandBase [Display(ShortName = "of")] public FileInfo OutputFile { get; set; } + } + protected override Task ExecuteCommandAsync(ImportCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public ImportCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public ImportCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/InstallCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/InstallCommand.cs index 1817f79..c301f5f 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/InstallCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/InstallCommand.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "InstallCommandDescription", Usage = "InstallCommandUsageSummary")] +public class InstallCommand : CommandBase { - [Command(Description = "InstallCommandDescription", Usage = "InstallCommandUsageSummary")] - public class InstallCommand : CommandBase + public class InstallCommandData : HelpedCommandData { private readonly ICollection _sources = new List(); @@ -30,11 +33,9 @@ public class InstallCommand : CommandBase public bool NoCache { get; set; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object RepositoryFactory { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } /// @@ -44,13 +45,11 @@ public class InstallCommand : CommandBase protected object CacheRepository => null; [IgnoreOptionProperty] - // ReSharper disable once UnusedMember.Local private bool AllowMultipleVersions => !ExcludeVersion; + } + protected override Task ExecuteCommandAsync(InstallCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public InstallCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public InstallCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/IntTestCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/IntTestCommand.cs index f64ae87..4525bf7 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/IntTestCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/IntTestCommand.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +public class IntTestCommand : CommandBase { - public class IntTestCommand : CommandBase + public class IntTestCommandData : HelpedCommandData { [Display(ShortName = "s", Description = "A simple string value")] [Required] @@ -17,15 +20,14 @@ public class IntTestCommand : CommandBase public bool BoolValue { get; set; } [Display(ShortName = "il", Description = "A list of integer value")] public List IntListValue { get; set; } + } + protected override Task ExecuteCommandAsync(IntTestCommandData commandData, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } - protected override Task ExecuteCommandAsync() - { - throw new NotImplementedException(); - } - - public IntTestCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public IntTestCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/ListCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/ListCommand.cs index e5551ba..1a505bb 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/ListCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/ListCommand.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "ListCommandDescription", Usage = "ListCommandUsageDescription", Samples = new[] { "List sample 1", "List sample number 2" })] +public class ListCommand : CommandBase { - [Command(Description = "ListCommandDescription", Usage = "ListCommandUsageDescription", Samples = new []{"List sample 1", "List sample number 2"})] - public class ListCommand : CommandBase + public class ListCommandData : HelpedCommandData { private readonly List _sources = new List(); @@ -24,17 +27,16 @@ public class ListCommand : CommandBase public bool Prerelease { get; set; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object RepositoryFactory { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - public ListCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + } + protected override Task ExecuteCommandAsync(ListCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); + + public ListCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/MGR.CommandLineParser.Tests.Commands.csproj b/tests/MGR.CommandLineParser.Tests.Commands/MGR.CommandLineParser.Tests.Commands.csproj index 932eb9b..82e9351 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/MGR.CommandLineParser.Tests.Commands.csproj +++ b/tests/MGR.CommandLineParser.Tests.Commands/MGR.CommandLineParser.Tests.Commands.csproj @@ -1,13 +1,13 @@  - - netstandard2.0 - - false - + + netstandard2.0 + + false + - - - + + + diff --git a/tests/MGR.CommandLineParser.Tests.Commands/PackCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/PackCommand.cs index b20a6bd..d070c71 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/PackCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/PackCommand.cs @@ -1,29 +1,28 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "PackageCommandDescription", Usage = "PackageCommandUsageSummary")] +public class PackCommand : CommandBase { - [Command(Description = "PackageCommandDescription", Usage = "PackageCommandUsageSummary")] - public class PackCommand : CommandBase + public class PackCommandData : HelpedCommandData { - // ReSharper disable once UnusedMember.Local - // ReSharper disable once InconsistentNaming private static readonly string[] _libPackageExcludes = new[] { - @"**\*.pdb", - @"src\**\*" - }; + @"**\*.pdb", + @"src\**\*" + }; - // ReSharper disable once InconsistentNaming - // ReSharper disable once UnusedMember.Local private static readonly string[] _symbolPackageExcludes = new[] { - @"content\**\*", - @"tools\**\*.ps1" - }; + @"content\**\*", + @"tools\**\*.ps1" + }; private readonly HashSet _excludes = new HashSet(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _properties = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -52,8 +51,6 @@ public class PackCommand : CommandBase [Display(Description = "PackageCommandBuildDescription", ShortName = "b")] public bool Build { get; set; } [Display(Description = "CommandMSBuildVersion")] - // ReSharper disable once UnusedMember.Global - // ReSharper disable once InconsistentNaming public string MSBuildVersion { get; set; } [Display(Description = "PackageCommandNoDefaultExcludes")] public bool NoDefaultExcludes { get; set; } @@ -66,11 +63,10 @@ public class PackCommand : CommandBase [IgnoreOptionProperty] public IEnumerable Rules { get; set; } + } + protected override Task ExecuteCommandAsync(PackCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public PackCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public PackCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/PublishCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/PublishCommand.cs index 38ab358..2b54516 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/PublishCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/PublishCommand.cs @@ -1,20 +1,22 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "PublishCommandDescription", Usage = "PublishCommandUsageDescription")] +public class PublishCommand : CommandBase { - [Command(Description = "PublishCommandDescription", Usage = "PublishCommandUsageDescription")] - public class PublishCommand : CommandBase + public class PublishCommandData : HelpedCommandData { [Display(Description = "PublishCommandSourceDescription", ShortName = "src")] public string Source { get; set; } + } + protected override Task ExecuteCommandAsync(PublishCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public PublishCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public PublishCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/PushCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/PushCommand.cs index dd212e0..4f7dd50 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/PushCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/PushCommand.cs @@ -1,12 +1,15 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "PushCommandDescription", Usage = "PushCommandUsageDescription")] +public class PushCommand : CommandBase { - [Command(Description = "PushCommandDescription", Usage = "PushCommandUsageDescription")] - public class PushCommand : CommandBase + public class PushCommandData : HelpedCommandData { [Display(Description = "PushCommandCreateOnlyDescription", ShortName = "co")] public bool CreateOnly { get; set; } @@ -21,17 +24,14 @@ public class PushCommand : CommandBase public int Timeout { get; set; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object Settings { get; } + } + protected override Task ExecuteCommandAsync(PushCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public PushCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public PushCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/SetApiKeyCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/SetApiKeyCommand.cs index a0d30bc..225c11f 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/SetApiKeyCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/SetApiKeyCommand.cs @@ -1,30 +1,31 @@ using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "SetApiKeyCommandDescription", Usage = "SetApiKeyCommandUsageDescription")] +public class SetApiKeyCommand : CommandBase { - [Command(Description = "SetApiKeyCommandDescription", Usage = "SetApiKeyCommandUsageDescription")] - public class SetApiKeyCommand : CommandBase + public class SetApiKeyCommandData : HelpedCommandData { [Display(Description = "SetApiKeyCommandSourceDescription", ShortName = "src")] [DefaultValue("DefaultSource")] public string Source { get; set; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object Settings { get; } + } - protected override Task ExecuteCommandAsync() => Task.FromResult(0); + protected override Task ExecuteCommandAsync(SetApiKeyCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - public SetApiKeyCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public SetApiKeyCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/SourcesCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/SourcesCommand.cs index 4a2b413..43dcd27 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/SourcesCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/SourcesCommand.cs @@ -1,12 +1,15 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "SourcesCommandDescription", Usage = "SourcesCommandUsageSummary")] +public class SourcesCommand : CommandBase { - [Command(Description = "SourcesCommandDescription", Usage = "SourcesCommandUsageSummary")] - public class SourcesCommand : CommandBase + public class SourcesCommandData : HelpedCommandData { [Display(Description = "SourcesCommandNameDescription")] public string Name { get; set; } @@ -19,11 +22,10 @@ public class SourcesCommand : CommandBase [Display(Description = "SourcesCommandPasswordDescription")] public string Password { get; set; } + } + protected override Task ExecuteCommandAsync(SourcesCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - protected override Task ExecuteCommandAsync() => Task.FromResult(0); - - public SourcesCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public SourcesCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/SpecCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/SpecCommand.cs index 0106300..c743e1b 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/SpecCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/SpecCommand.cs @@ -1,12 +1,15 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "SpecCommandDescription", Usage = "SpecCommandUsageSummary")] +public class SpecCommand : CommandBase { - [Command(Description = "SpecCommandDescription", Usage = "SpecCommandUsageSummary")] - public class SpecCommand : CommandBase + public class SpecCommandData : HelpedCommandData { internal static readonly string SampleProjectUrl = "http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE"; internal static readonly string SampleLicenseUrl = "http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE"; @@ -20,11 +23,11 @@ public class SpecCommand : CommandBase [Display(Description = "SpecCommandForceDescription")] public bool Force { get; set; } + } - protected override Task ExecuteCommandAsync() => Task.FromResult(0); + protected override Task ExecuteCommandAsync(SpecCommandData commandData, CancellationToken cancellationToken) => Task.FromResult(0); - public SpecCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public SpecCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.Tests.Commands/UpdateCommand.cs b/tests/MGR.CommandLineParser.Tests.Commands/UpdateCommand.cs index 072c688..edea91f 100644 --- a/tests/MGR.CommandLineParser.Tests.Commands/UpdateCommand.cs +++ b/tests/MGR.CommandLineParser.Tests.Commands/UpdateCommand.cs @@ -1,23 +1,24 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; -namespace MGR.CommandLineParser.Tests.Commands +namespace MGR.CommandLineParser.Tests.Commands; + +[Command(Description = "UpdateCommandDescription", Usage = "")] +public class UpdateCommand : CommandBase { - [Command(Description = "UpdateCommandDescription", Usage = "")] - public class UpdateCommand : CommandBase + public class UpdateCommandOptions : HelpedCommandData { private readonly List _sources = new List(); private readonly List _ids = new List(); [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object RepositoryFactory { get; } [IgnoreOptionProperty] - // ReSharper disable once UnassignedGetOnlyAutoProperty public object SourceProvider { get; } [Display(Description = "UpdateCommandSourceDescription")] @@ -40,11 +41,11 @@ public class UpdateCommand : CommandBase [Display(Description = "UpdateCommandPrerelease")] public bool Prerelease { get; set; } + } - protected override Task ExecuteCommandAsync() => Task.FromResult(0); + protected override Task ExecuteCommandAsync(UpdateCommandOptions commandData, CancellationToken cancellationToken) => Task.FromResult(0); - public UpdateCommand(IServiceProvider serviceProvider) : base(serviceProvider) - { - } + public UpdateCommand(IServiceProvider serviceProvider) : base(serviceProvider) + { } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.AssignValue.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.AssignValue.cs index 387a76a..e3a530c 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.AssignValue.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.AssignValue.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; using MGR.CommandLineParser.Extensibility.Command; @@ -11,110 +10,106 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandOptionTests { - public partial class ClassBasedCommandOptionTests + public class AssignValue { - public class AssignValue + private static (TestCommand Command, ClassBasedCommandOption CommandOption) CreateCommandOptionForProperty( + Expression> propertyExpression) { - private static (TestCommand Command, ClassBasedCommandOption CommandOption) CreateCommandOptionForProperty( - Expression> propertyExpression) + var propertyInfo = + typeof(TestCommand).GetProperty(TypeHelpers.ExtractPropertyName(propertyExpression)); + return CreateCommandOptionForProperty(propertyInfo); + } + private static (TestCommand Command, ClassBasedCommandOption CommandOption) CreateCommandOptionForProperty( + PropertyInfo propertyInfo) { - var propertyInfo = - typeof(TestCommand).GetProperty(TypeHelpers.ExtractPropertyName(propertyExpression)); - return CreateCommandOptionForProperty(propertyInfo); + var testCommand = new TestCommand(); + var commandMetadataMock = new Mock(); + commandMetadataMock.SetupGet(_ => _.Name) + .Returns("test"); + var commandOption = new ClassBasedCommandOption( + ClassBasedCommandOptionMetadata.Create( + propertyInfo, + commandMetadataMock.Object, + new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, + new List() + ), + testCommand); + return (testCommand, commandOption); } - private static (TestCommand Command, ClassBasedCommandOption CommandOption) CreateCommandOptionForProperty( - PropertyInfo propertyInfo) - { - var testCommand = new TestCommand(); - var commandMetadataMock = new Mock(); - commandMetadataMock.SetupGet(_ => _.Name) - .Returns("test"); - var commandOption = new ClassBasedCommandOption( - ClassBasedCommandOptionMetadata.Create( - propertyInfo, - commandMetadataMock.Object, - new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, - new List() - ), - testCommand); - return (testCommand, commandOption); - } - - private class TestCommand : ICommand - { - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public List PropertyList { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public Dictionary PropertyDictionary { get; set; } - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public int PropertySimple { get; set; } - #region ICommand Members + private class TestCommand : CommandData + { + public List PropertyList { get; set; } + public Dictionary PropertyDictionary { get; set; } + public int PropertySimple { get; set; } - public Task ExecuteAsync() => throw new NotImplementedException(); + //#region ICommand Members - public IList Arguments => throw new NotImplementedException(); + //public Task ExecuteAsync() => throw new NotImplementedException(); - #endregion - } + //public IList Arguments => throw new NotImplementedException(); - [Fact] - public void PropertyDictionaryAddTest() - { - // Arrange - var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertyDictionary); - var expectedKey = "keyTest"; - var guid = "18591394-096C-476F-A8B7-71903E27DAB5"; - var expectedValue = Guid.Parse(guid); - var expectedLength = 1; - var option = "keyTest=" + guid; - - // Act - commandOption.AssignValue(option); - - // Assert - Assert.NotNull(testCommand.PropertyDictionary); - Assert.Equal(expectedLength, testCommand.PropertyDictionary.Count); - var first = testCommand.PropertyDictionary.First(); - Assert.Equal(expectedKey, first.Key); - Assert.Equal(expectedValue, first.Value); - } + //#endregion + } - [Fact] - public void PropertyListAddTest() - { - // Arrange - var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertyList); - var expected = 42; - var expectedLength = 1; - var option = "42"; - - // Act - commandOption.AssignValue(option); - - // Assert - Assert.NotNull(testCommand.PropertyList); - Assert.IsType>(testCommand.PropertyList); - Assert.Equal(expectedLength, testCommand.PropertyList.Count); - Assert.Equal(expected, testCommand.PropertyList[0]); - } + [Fact] + public void PropertyDictionaryAddTest() + { + // Arrange + var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertyDictionary); + var expectedKey = "keyTest"; + var guid = "18591394-096C-476F-A8B7-71903E27DAB5"; + var expectedValue = Guid.Parse(guid); + var expectedLength = 1; + var option = "keyTest=" + guid; - [Fact] - public void PropertySimpleTest() - { - // Arrange - var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertySimple); - var expected = 42; - var option = "42"; + // Act + commandOption.AssignValue(option); - // Act - commandOption.AssignValue(option); + // Assert + Assert.NotNull(testCommand.PropertyDictionary); + Assert.Equal(expectedLength, testCommand.PropertyDictionary.Count); + var first = testCommand.PropertyDictionary.First(); + Assert.Equal(expectedKey, first.Key); + Assert.Equal(expectedValue, first.Value); + } - // Assert - Assert.Equal(expected, testCommand.PropertySimple); - } + [Fact] + public void PropertyListAddTest() + { + // Arrange + var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertyList); + var expected = 42; + var expectedLength = 1; + var option = "42"; + + // Act + commandOption.AssignValue(option); + + // Assert + Assert.NotNull(testCommand.PropertyList); + Assert.IsType>(testCommand.PropertyList); + Assert.Equal(expectedLength, testCommand.PropertyList.Count); + Assert.Equal(expected, testCommand.PropertyList[0]); + } + + [Fact] + public void PropertySimpleTest() + { + // Arrange + var (testCommand, commandOption) = CreateCommandOptionForProperty(_ => _.PropertySimple); + var expected = 42; + var option = "42"; + + // Act + commandOption.AssignValue(option); + + // Assert + Assert.Equal(expected, testCommand.PropertySimple); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.cs index 5c37884..e167215 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandOptionTests.cs @@ -1,6 +1,5 @@ -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandOptionTests { - public partial class ClassBasedCommandOptionTests - { - } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.CreateCommand.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.CreateCommand.cs index ad59af9..9adcc1b 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.CreateCommand.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.CreateCommand.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; @@ -7,63 +8,48 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandTypeTests { - public partial class ClassBasedCommandTypeTests + public class CreateCommand { - public class CreateCommand + [Fact] + public void PropertyWithNoConverterException() { - [Fact] - public void PropertyWithNoConverterException() - { - // Arrange - var testCommandType = new ClassBasedCommandType(typeof(TestBadConverterCommand), - new List - { - new StringConverter(), - new GuidConverter(), - new Int32Converter(), - new BooleanConverter() - }, new List()); - var serviceProviderMock = new Mock(); - serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) - .Returns(ClassBasedBasicCommandActivator.Instance); - var optionName = nameof(TestBadConverterCommand.PropertySimpleWithBadConverter); - var expectedMessageException = - Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(optionName, - testCommandType.Metadata.Name, typeof(int), typeof(bool)); + // Arrange + var testCommandType = new ClassBasedCommandType(typeof(TestBadConverterCommand), + new List + { + new StringConverter(), + new GuidConverter(), + new Int32Converter(), + new BooleanConverter() + }, new List()); + var serviceProviderMock = new Mock(); + serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) + .Returns(ClassBasedBasicCommandActivator.Instance); + var optionName = nameof(TestBadConverterCommand.PropertySimpleWithBadConverter); + var expectedMessageException = + Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(optionName, + testCommandType.Metadata.Name, typeof(int), typeof(bool)); - // Act - var actualException = - Assert.Throws( - () => testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object)); + // Act + var actualException = + Assert.Throws( + () => testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object)); - // Assert - Assert.Equal(expectedMessageException, actualException.Message); - } - private class TestBadConverterCommand : ICommand - { + // Assert + Assert.Equal(expectedMessageException, actualException.Message); + } + private class TestBadConverterCommand : CommandData, ICommandHandler + { #pragma warning disable CS0618 // Type or member is obsolete - [Converter(typeof(BooleanConverter))] + [Converter(typeof(BooleanConverter))] #pragma warning restore CS0618 // Type or member is obsolete - // ReSharper disable once UnusedMember.Local - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public int PropertySimpleWithBadConverter { get; set; } - - #region ICommand Members - - public Task ExecuteAsync() - { - throw new NotImplementedException(); - } - - public IList Arguments - { - get { throw new NotImplementedException(); } - } + public int PropertySimpleWithBadConverter { get; set; } - #endregion - } + public Task ExecuteAsync(TestBadConverterCommand commandData, CancellationToken cancellationToken) => throw new NotImplementedException(); } } } diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOption.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOption.cs index 7c5d0b5..d0fded2 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOption.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOption.cs @@ -3,6 +3,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; @@ -10,73 +11,60 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandTypeTests { - public partial class ClassBasedCommandTypeTests + public class FindOption { - public class FindOption + [Theory] + [InlineData("property-list")] + [InlineData("OtherName")] + public void FoundWithLongOrAlternateName(string optionName) { - [Theory] - [InlineData("property-list")] - [InlineData("OtherName")] - public void FoundWithLongOrAlternateName(string optionName) - { - // Arrange - var propertyOptionAlternateNameGeneratorMock = new Mock(); - propertyOptionAlternateNameGeneratorMock.Setup(_ => _.GenerateAlternateNames(It.IsAny())) - .Returns(p => + // Arrange + var propertyOptionAlternateNameGeneratorMock = new Mock(); + propertyOptionAlternateNameGeneratorMock.Setup(_ => _.GenerateAlternateNames(It.IsAny())) + .Returns(p => + { + if (p.Name == "PropertyList") { - if (p.Name == "PropertyList") - { - return new List {"OtherName"}; - } - - return Enumerable.Empty(); - }); - var testCommandType = new ClassBasedCommandType(typeof(TestCommand), - new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, - new List{ propertyOptionAlternateNameGeneratorMock .Object}); - var serviceProviderMock = new Mock(); - serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) - .Returns(ClassBasedBasicCommandActivator.Instance); - var classBasedCommandObjectBuilder = - (ClassBasedCommandObjectBuilder)testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object); - var testCommand = (TestCommand)((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).Command; - - // Act - var actual = classBasedCommandObjectBuilder.FindOption(optionName); - - // Assert - Assert.NotNull(actual); - Assert.NotNull(testCommand); - Assert.True(actual.ShouldProvideValue); - actual.AssignValue("42"); - Assert.Single(testCommand.PropertyList); - Assert.Equal(42, testCommand.PropertyList.First()); + return new List {"OtherName"}; + } - } + return Enumerable.Empty(); + }); + var testCommandType = new ClassBasedCommandType(typeof(TestCommand), + new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, + new List{ propertyOptionAlternateNameGeneratorMock .Object}); + var serviceProviderMock = new Mock(); + serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) + .Returns(ClassBasedBasicCommandActivator.Instance); + var classBasedCommandObjectBuilder = testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object); + var testCommand = ((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).Command; + var testCommandData = ((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).CommandData; - internal class TestCommand : ICommand - { - [Display(ShortName = "pl")] - public List PropertyList { get; set; } - public Dictionary PropertyDictionary { get; set; } - public int PropertySimple { get; set; } + // Act + var actual = classBasedCommandObjectBuilder.FindOption(optionName); - #region ICommand Members + // Assert + Assert.NotNull(actual); + Assert.NotNull(testCommand); + Assert.True(actual.ShouldProvideValue); + actual.AssignValue("42"); + Assert.Single(testCommandData.PropertyList); + Assert.Equal(42, testCommandData.PropertyList.First()); - public Task ExecuteAsync() - { - throw new NotImplementedException(); - } + } - public IList Arguments - { - get { throw new NotImplementedException(); } - } + internal class TestCommand : CommandData, ICommandHandler + { + [Display(ShortName = "pl")] + public List PropertyList { get; set; } + public Dictionary PropertyDictionary { get; set; } + public int PropertySimple { get; set; } - #endregion - } + public Task ExecuteAsync(TestCommand commandData, CancellationToken cancellationToken) => throw new NotImplementedException(); } } } diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOptionByShortName.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOptionByShortName.cs index 09fb674..46add91 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOptionByShortName.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.FindOptionByShortName.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; @@ -9,64 +10,49 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandTypeTests { - public partial class ClassBasedCommandTypeTests + public class FindOptionByShortName { - public class FindOptionByShortName + [Theory] + [InlineData("pl")] + public void FoundWithLongOrAlternateName(string optionName) { - [Theory] - [InlineData("pl")] - public void FoundWithLongOrAlternateName(string optionName) - { - // Arrange - var testCommandType = new ClassBasedCommandType(typeof(TestCommand), - new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, new List()); - var serviceProviderMock = new Mock(); - serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) - .Returns(ClassBasedBasicCommandActivator.Instance); - var classBasedCommandObjectBuilder = - (ClassBasedCommandObjectBuilder)testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object); - var testCommand = (TestCommand)((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).Command; - - // Act - var actual = classBasedCommandObjectBuilder.FindOptionByShortName(optionName); - - // Assert - Assert.NotNull(actual); - Assert.NotNull(testCommand); - Assert.True(actual.ShouldProvideValue); - actual.AssignValue("42"); - Assert.Single(testCommand.PropertyList); - Assert.Equal(42, testCommand.PropertyList.First()); + // Arrange + var testCommandType = new ClassBasedCommandType(typeof(TestCommand), + new List { new StringConverter(), new GuidConverter(), new Int32Converter() }, new List()); + var serviceProviderMock = new Mock(); + serviceProviderMock.Setup(_ => _.GetService(typeof(IClassBasedCommandActivator))) + .Returns(ClassBasedBasicCommandActivator.Instance); + var classBasedCommandObjectBuilder = testCommandType.CreateCommandObjectBuilder(serviceProviderMock.Object); + var testCommand = ((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).Command; + var testCommandData = ((IClassBasedCommandObject)classBasedCommandObjectBuilder.GenerateCommandObject()).CommandData; + + // Act + var actual = classBasedCommandObjectBuilder.FindOptionByShortName(optionName); + + // Assert + Assert.NotNull(actual); + Assert.NotNull(testCommand); + Assert.True(actual.ShouldProvideValue); + actual.AssignValue("42"); + Assert.Single(testCommandData.PropertyList); + Assert.Equal(42, testCommandData.PropertyList.First()); - } - - private class TestCommand : ICommand - { - [Display(ShortName = "pl")] - // ReSharper disable once CollectionNeverUpdated.Local - // ReSharper disable once UnusedAutoPropertyAccessor.Local - public List PropertyList { get; set; } - // ReSharper disable once UnusedMember.Local - public Dictionary PropertyDictionary { get; set; } - // ReSharper disable once UnusedMember.Local - public int PropertySimple { get; set; } + } - #region ICommand Members + private class TestCommand : CommandData, ICommandHandler + { + [Display(ShortName = "pl")] + public List PropertyList { get; set; } - public Task ExecuteAsync() - { - throw new NotImplementedException(); - } + public Dictionary PropertyDictionary { get; set; } - public IList Arguments - { - get { throw new NotImplementedException(); } - } + public int PropertySimple { get; set; } - #endregion - } + public Task ExecuteAsync(TestCommand commandData, CancellationToken cancellationToken) => throw new NotImplementedException(); } } } diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.Metadata.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.Metadata.cs index d4ef41f..0cc8690 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.Metadata.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.Metadata.cs @@ -1,50 +1,42 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility.ClassBased; using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandTypeTests { - public partial class ClassBasedCommandTypeTests + public class Metadata { - public class Metadata + [Fact] + public void TestCommandMetadataExtraction() { - [Fact] - public void TestCommandMetadataExtraction() - { - // Arrange - var testCommandType = - new ClassBasedCommandType(typeof (TestCommand), - new List(), new List()); - var expectedName = "Test"; - var expectedDescription = "My great description"; - var expectedUsage = "test arg [option]"; - - // Act - var metadata = testCommandType.Metadata; + // Arrange + var testCommandType = + new ClassBasedCommandType(typeof (TestCommand), + new List(), new List()); + var expectedName = "Test"; + var expectedDescription = "My great description"; + var expectedUsage = "test arg [option]"; - // Assert - Assert.Equal(expectedName, metadata.Name); - Assert.Equal(expectedDescription, metadata.Description); - Assert.Equal(expectedUsage, metadata.Usage); - } + // Act + var metadata = testCommandType.Metadata; - [Command(Description = "My great description", Usage = "test arg [option]")] - private class TestCommand : ICommand - { - public Task ExecuteAsync() - { - throw new NotImplementedException(); - } + // Assert + Assert.Equal(expectedName, metadata.Name); + Assert.Equal(expectedDescription, metadata.Description); + Assert.Equal(expectedUsage, metadata.Usage); + } - public IList Arguments - { - get { throw new NotImplementedException(); } - } - } + [Command(Description = "My great description", Usage = "test arg [option]")] + private class TestCommand : CommandData, ICommandHandler + { + public Task ExecuteAsync(TestCommand commandData, CancellationToken cancellationToken) => throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.cs index 230c690..16c6336 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/ClassBased/ClassBasedCommandTypeTests.cs @@ -1,6 +1,5 @@ -namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased +namespace MGR.CommandLineParser.UnitTests.Extensibility.ClassBased; + +public partial class ClassBasedCommandTypeTests { - public partial class ClassBasedCommandTypeTests - { - } } diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/BooleanConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/BooleanConverterTests.cs index 499db64..0a5c25c 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/BooleanConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/BooleanConverterTests.cs @@ -2,161 +2,160 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class BooleanConverterTests { - public class BooleanConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new BooleanConverter(); - var expectedType = typeof(bool); + // Arrange + IConverter converter = new BooleanConverter(); + var expectedType = typeof(bool); - // Act - var actual = converter.TargetType; + // Act + var actual = converter.TargetType; - // Assert - Assert.Equal(expectedType, actual); - } + // Assert + Assert.Equal(expectedType, actual); + } - [Fact] - public void StringEmptyConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = string.Empty; + [Fact] + public void StringEmptyConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = string.Empty; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.True((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.True((bool)actual); + } - [Fact] - public void LowerTrueConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "true"; + [Fact] + public void LowerTrueConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "true"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.True((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.True((bool)actual); + } - [Fact] - public void UpperTrueConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "True"; + [Fact] + public void UpperTrueConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "True"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.True((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.True((bool)actual); + } - [Fact] - public void LowerFalseConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "false"; + [Fact] + public void LowerFalseConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "false"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.False((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.False((bool)actual); + } - [Fact] - public void UpperFalseConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "False"; + [Fact] + public void UpperFalseConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "False"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.False((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.False((bool)actual); + } - [Fact] - public void MinusConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "-"; + [Fact] + public void MinusConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "-"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.False((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.False((bool)actual); + } - [Fact] - public void PlusConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "+"; + [Fact] + public void PlusConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "+"; - // Act - var actual = converter.Convert(value, converter.TargetType); + // Act + var actual = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.True((bool)actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.True((bool)actual); + } - [Fact] - [Trait(nameof(Exception), nameof(CommandLineParserException))] - public void BadValueConversion() - { - // Arrange - IConverter converter = new BooleanConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(bool)); + [Fact] + [Trait(nameof(Exception), nameof(CommandLineParserException))] + public void BadValueConversion() + { + // Arrange + IConverter converter = new BooleanConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(bool)); #if NET48 - var expectedInnerExceptionMessage = "String was not recognized as a valid Boolean."; + var expectedInnerExceptionMessage = "String was not recognized as a valid Boolean."; #else - var expectedInnerExceptionMessage = "String 'Hello' was not recognized as a valid Boolean."; + var expectedInnerExceptionMessage = "String 'Hello' was not recognized as a valid Boolean."; #endif - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/ByteConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/ByteConverterTests.cs index 3b8b95a..f8eec8b 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/ByteConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/ByteConverterTests.cs @@ -2,66 +2,65 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class ByteConverterTests { - public class ByteConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new ByteConverter(); - var expectedType = typeof (Byte); + // Arrange + IConverter converter = new ByteConverter(); + var expectedType = typeof (byte); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new ByteConverter(); - var value = "42"; - byte expectedValue = 42; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new ByteConverter(); + var value = "42"; + byte expectedValue = 42; - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Byte) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (byte) actualValue); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new ByteConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(byte)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new ByteConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(byte)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + ; + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/CharConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/CharConverterTests.cs index 721edf2..cc47b91 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/CharConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/CharConverterTests.cs @@ -2,61 +2,60 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class CharConverterTests { - public class CharConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new CharConverter(); - var expectedType = typeof (Char); + // Arrange + IConverter converter = new CharConverter(); + var expectedType = typeof (char); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new CharConverter(); - var value = "c"; - var expectedValue = 'c'; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new CharConverter(); + var value = "c"; + var expectedValue = 'c'; + + // Act + var actualValue = converter.Convert(value, converter.TargetType); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (char) actualValue); + } - // Act - var actualValue = converter.Convert(value, converter.TargetType); + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new CharConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(char)); + var expectedInnerExceptionMessage = "String must be exactly one character long."; + + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Char) actualValue); - } - - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new CharConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(char)); - var expectedInnerExceptionMessage = "String must be exactly one character long."; - - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DateTimeConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DateTimeConverterTests.cs index badba55..ac02493 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DateTimeConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DateTimeConverterTests.cs @@ -2,83 +2,82 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class DateTimeConverterTests { - public class DateTimeConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new DateTimeConverter(); - var expectedType = typeof (DateTime); + // Arrange + IConverter converter = new DateTimeConverter(); + var expectedType = typeof (DateTime); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void ConversionFrench() - { - // Arrange - IConverter converter = new DateTimeConverter(); - var value = "01/10/2012"; - var expectedValue = new DateTime(2012, 10, 01); + [Fact] + public void ConversionFrench() + { + // Arrange + IConverter converter = new DateTimeConverter(); + var value = "01/10/2012"; + var expectedValue = new DateTime(2012, 10, 01); - // Act - using (new LangageSwitcher("fr-fr")) - { - var actualValue = converter.Convert(value, converter.TargetType); + // Act + using (new LangageSwitcher("fr-fr")) + { + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (DateTime) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (DateTime) actualValue); } + } - [Fact] - public void ConversionAmerican() - { - // Arrange - IConverter converter = new DateTimeConverter(); - var value = "2012/10/01"; - var expectedValue = new DateTime(2012, 10, 01); + [Fact] + public void ConversionAmerican() + { + // Arrange + IConverter converter = new DateTimeConverter(); + var value = "2012/10/01"; + var expectedValue = new DateTime(2012, 10, 01); - // Act - using (new LangageSwitcher("en-us")) - { - var actualValue = converter.Convert(value, converter.TargetType); + // Act + using (new LangageSwitcher("en-us")) + { + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (DateTime) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (DateTime) actualValue); } + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new DateTimeConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(DateTime)); + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new DateTimeConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(DateTime)); - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = - Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = + Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - Assert.IsAssignableFrom(actualException.InnerException); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + Assert.IsAssignableFrom(actualException.InnerException); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DecimalConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DecimalConverterTests.cs index 437d9e4..8b6cfde 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DecimalConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DecimalConverterTests.cs @@ -2,70 +2,69 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class DecimalConverterTests { - public class DecimalConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new DecimalConverter(); - var expectedType = typeof (Decimal); + // Arrange + IConverter converter = new DecimalConverter(); + var expectedType = typeof (decimal); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new DecimalConverter(); - var value = "42,1"; - var expectedValue = (Decimal) 42.1; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new DecimalConverter(); + var value = "42,1"; + var expectedValue = (decimal) 42.1; - // Act - using (new LangageSwitcher("fr-fr")) - { - var actualValue = converter.Convert(value, converter.TargetType); + // Act + using (new LangageSwitcher("fr-fr")) + { + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Decimal) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (decimal) actualValue); } + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new DecimalConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(decimal)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new DecimalConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(decimal)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DoubleConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DoubleConverterTests.cs index c709275..29cbc1b 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DoubleConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/DoubleConverterTests.cs @@ -2,70 +2,69 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class DoubleConverterTests { - public class DoubleConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new DoubleConverter(); - var expectedType = typeof (Double); + // Arrange + IConverter converter = new DoubleConverter(); + var expectedType = typeof (double); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new DoubleConverter(); - var value = "42,35"; - var expectedValue = 42.35; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new DoubleConverter(); + var value = "42,35"; + var expectedValue = 42.35; - // Act - using (new LangageSwitcher("fr-fr")) - { - var actualValue = converter.Convert(value, converter.TargetType); + // Act + using (new LangageSwitcher("fr-fr")) + { + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Double) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (double) actualValue); } + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new DoubleConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(double)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new DoubleConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(double)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/EnumConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/EnumConverterTests.cs index a4cabfc..c112fda 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/EnumConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/EnumConverterTests.cs @@ -2,137 +2,136 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class EnumConverterTests { - public class EnumConverterTests + [Fact] + public void TargetType() + { + // Arrange + IConverter converter = new EnumConverter(); + var expectedType = typeof (Enum); + + // Act + var actualType = converter.TargetType; + + // Assert + Assert.Equal(expectedType, actualType); + } + + [Fact] + public void ParseSimpleEnumValue() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "1"; + var expectedValue = AttributeTargets.Assembly; + + // Act + var actualValue = converter.Convert(value, typeof (AttributeTargets)); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (AttributeTargets) actualValue); + } + + [Fact] + public void ParseSimpleEnumNameValue() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "Assembly"; + var expectedValue = AttributeTargets.Assembly; + + // Act + var actualValue = converter.Convert(value, typeof (AttributeTargets)); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (AttributeTargets) actualValue); + } + + [Fact] + public void ParseMultipleEnumNameValue() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "Assembly, Class"; + var expectedValue = AttributeTargets.Assembly | AttributeTargets.Class; + + // Act + var actualValue = converter.Convert(value, typeof (AttributeTargets)); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (AttributeTargets) actualValue); + } + + [Fact] + public void BadValueException() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new EnumConverter(); - var expectedType = typeof (Enum); - - // Act - var actualType = converter.TargetType; - - // Assert - Assert.Equal(expectedType, actualType); - } - - [Fact] - public void ParseSimpleEnumValue() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "1"; - var expectedValue = AttributeTargets.Assembly; - - // Act - var actualValue = converter.Convert(value, typeof (AttributeTargets)); - - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (AttributeTargets) actualValue); - } - - [Fact] - public void ParseSimpleEnumNameValue() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "Assembly"; - var expectedValue = AttributeTargets.Assembly; - - // Act - var actualValue = converter.Convert(value, typeof (AttributeTargets)); - - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (AttributeTargets) actualValue); - } - - [Fact] - public void ParseMultipleEnumNameValue() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "Assembly, Class"; - var expectedValue = AttributeTargets.Assembly | AttributeTargets.Class; - - // Act - var actualValue = converter.Convert(value, typeof (AttributeTargets)); - - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (AttributeTargets) actualValue); - } - - [Fact] - public void BadValueException() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "10"; - var expectedExceptionMessage = "The specified value '10' is not correct the type 'System.ConsoleModifiers'."; - - // Act - var actualException = Assert.Throws(() => converter.Convert(value, typeof (ConsoleModifiers))); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void BadNameValueException() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(Enum)); - var expectedInnerExceptionMessage = "enumType"; - - // Act - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.ParamName); - } - - [Fact] - public void NullConcreteTargetTypeException() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "Hello"; - var expectedExceptionMessage = @"concreteTargetType"; - - // Act - var actualException = Assert.Throws(() => converter.Convert(value, null)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } - - [Fact] - public void NotEnumConcreteTargetTypeException() - { - // Arrange - IConverter converter = new EnumConverter(); - var value = "Hello"; - var expectedExceptionMessage = "The specified concrete target type (System.Exception) is not an enum type."; - - // Act - var actualException = Assert.Throws(() => converter.Convert(value, typeof (Exception))); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } + // Arrange + IConverter converter = new EnumConverter(); + var value = "10"; + var expectedExceptionMessage = "The specified value '10' is not correct the type 'System.ConsoleModifiers'."; + + // Act + var actualException = Assert.Throws(() => converter.Convert(value, typeof (ConsoleModifiers))); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void BadNameValueException() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(Enum)); + var expectedInnerExceptionMessage = "enumType"; + + // Act + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.ParamName); + } + + [Fact] + public void NullConcreteTargetTypeException() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "Hello"; + var expectedExceptionMessage = @"concreteTargetType"; + + // Act + var actualException = Assert.Throws(() => converter.Convert(value, null)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); + } + + [Fact] + public void NotEnumConcreteTargetTypeException() + { + // Arrange + IConverter converter = new EnumConverter(); + var value = "Hello"; + var expectedExceptionMessage = "The specified concrete target type (System.Exception) is not an enum type."; + + // Act + var actualException = Assert.Throws(() => converter.Convert(value, typeof (Exception))); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/FileSystemInfoConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/FileSystemInfoConverterTests.cs index 0277974..851adca 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/FileSystemInfoConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/FileSystemInfoConverterTests.cs @@ -2,54 +2,53 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class FileSystemInfoConverterTests { - public class FileSystemInfoConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new FileSystemInfoConverter(); - var expectedType = typeof(FileSystemInfo); - - // Act - var actual = converter.TargetType; - - // Assert - Assert.Equal(expectedType, actual); - } - - [Fact] - public void FileInfo_WithValidPath_Conversion() - { - // Arrange - IConverter converter = new FileSystemInfoConverter(); - var value = @"C:\temp\file.txt"; - - // Act - var actual = converter.Convert(value, typeof(FileInfo)); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.Equal(value, ((FileInfo)actual).FullName); - } - - [Fact] - public void DirectoryInfo_WithValidPath_Conversion() - { - // Arrange - IConverter converter = new FileSystemInfoConverter(); - var value = @"C:\temp\file.txt"; - - // Act - var actual = converter.Convert(value, typeof(DirectoryInfo)); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - Assert.Equal(value, ((DirectoryInfo)actual).FullName); - } + // Arrange + IConverter converter = new FileSystemInfoConverter(); + var expectedType = typeof(FileSystemInfo); + + // Act + var actual = converter.TargetType; + + // Assert + Assert.Equal(expectedType, actual); + } + + [Fact] + public void FileInfo_WithValidPath_Conversion() + { + // Arrange + IConverter converter = new FileSystemInfoConverter(); + var value = @"C:\temp\file.txt"; + + // Act + var actual = converter.Convert(value, typeof(FileInfo)); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.Equal(value, ((FileInfo)actual).FullName); + } + + [Fact] + public void DirectoryInfo_WithValidPath_Conversion() + { + // Arrange + IConverter converter = new FileSystemInfoConverter(); + var value = @"C:\temp\file.txt"; + + // Act + var actual = converter.Convert(value, typeof(DirectoryInfo)); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + Assert.Equal(value, ((DirectoryInfo)actual).FullName); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/GuidConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/GuidConverterTests.cs index 356f402..9b2cf6a 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/GuidConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/GuidConverterTests.cs @@ -2,65 +2,64 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class GuidConverterTests { - public class GuidConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new GuidConverter(); - var expectedType = typeof (Guid); + // Arrange + IConverter converter = new GuidConverter(); + var expectedType = typeof (Guid); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new GuidConverter(); - var expectedValue = Guid.NewGuid(); - var value = expectedValue.ToString(); + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new GuidConverter(); + var expectedValue = Guid.NewGuid(); + var value = expectedValue.ToString(); - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Guid) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (Guid) actualValue); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new GuidConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(Guid)); + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new GuidConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(Guid)); #if NET - var expectedInnerExceptionMessage = "Unrecognized Guid format."; + var expectedInnerExceptionMessage = "Unrecognized Guid format."; #else - var expectedInnerExceptionMessage = "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."; + var expectedInnerExceptionMessage = "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."; #endif - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int16ConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int16ConverterTests.cs index 17657ac..0ba9035 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int16ConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int16ConverterTests.cs @@ -2,67 +2,66 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class Int16ConverterTests { - public class Int16ConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new Int16Converter(); - var expectedType = typeof (Int16); + // Arrange + IConverter converter = new Int16Converter(); + var expectedType = typeof (short); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new Int16Converter(); - var value = "42"; - Int16 expectedValue = 42; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new Int16Converter(); + var value = "42"; + short expectedValue = 42; - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Int16) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (short) actualValue); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new Int16Converter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(short)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new Int16Converter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(short)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int32ConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int32ConverterTests.cs index 0e2de00..bfd83e5 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int32ConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int32ConverterTests.cs @@ -2,68 +2,67 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class Int32ConverterTests { - public class Int32ConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new Int32Converter(); - var expectedType = typeof (Int32); + // Arrange + IConverter converter = new Int32Converter(); + var expectedType = typeof (int); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new Int32Converter(); - var value = "42"; - var expectedValue = 42; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new Int32Converter(); + var value = "42"; + var expectedValue = 42; - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Int32) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (int) actualValue); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new Int32Converter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(int)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new Int32Converter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(int)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = - Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = + Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int64ConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int64ConverterTests.cs index d984ff1..2cc28c7 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int64ConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/Int64ConverterTests.cs @@ -2,68 +2,67 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class Int64ConverterTests { - public class Int64ConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new Int64Converter(); - var expectedType = typeof (Int64); + // Arrange + IConverter converter = new Int64Converter(); + var expectedType = typeof (long); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new Int64Converter(); - var value = "42"; - Int64 expectedValue = 42; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new Int64Converter(); + var value = "42"; + long expectedValue = 42; - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Int64) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (long) actualValue); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new Int64Converter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(long)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new Int64Converter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(long)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = - Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = + Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/KeyValueConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/KeyValueConverterTests.cs index cfc6f0c..f58b2aa 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/KeyValueConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/KeyValueConverterTests.cs @@ -3,128 +3,127 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class KeyValueConverterTests { - public class KeyValueConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); - var expectedType = typeof (KeyValuePair); - - // Act - var actualType = converter.TargetType; - - // Assert - Assert.Equal(expectedType, actualType); - } - - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); - var value = "Test=42"; - var expectedKeyValue = "Test"; - var expectedValueValue = 42; + // Arrange + IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); + var expectedType = typeof (KeyValuePair); - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualType = converter.TargetType; - // Assert - Assert.NotNull(actualValue); - var actualTuple = Assert.IsAssignableFrom>(actualValue); - Assert.Equal(expectedKeyValue, (string) actualTuple.Key); - Assert.Equal(expectedValueValue, (int) actualTuple.Value); - } - - [Fact] - public void ConversionWithNullValue() - { - // Arrange - IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); - var value = "Test"; - var expectedKeyValue = "Test"; + // Assert + Assert.Equal(expectedType, actualType); + } - // Act - var actualValue = converter.Convert(value, converter.TargetType); + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); + var value = "Test=42"; + var expectedKeyValue = "Test"; + var expectedValueValue = 42; + + // Act + var actualValue = converter.Convert(value, converter.TargetType); + + // Assert + Assert.NotNull(actualValue); + var actualTuple = Assert.IsAssignableFrom>(actualValue); + Assert.Equal(expectedKeyValue, (string) actualTuple.Key); + Assert.Equal(expectedValueValue, (int) actualTuple.Value); + } - // Assert - Assert.NotNull(actualValue); - var actualTuple = Assert.IsAssignableFrom>(actualValue); - Assert.Equal(expectedKeyValue, (string) actualTuple.Key); - Assert.Null(actualTuple.Value); - } + [Fact] + public void ConversionWithNullValue() + { + // Arrange + IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); + var value = "Test"; + var expectedKeyValue = "Test"; + + // Act + var actualValue = converter.Convert(value, converter.TargetType); + + // Assert + Assert.NotNull(actualValue); + var actualTuple = Assert.IsAssignableFrom>(actualValue); + Assert.Equal(expectedKeyValue, (string) actualTuple.Key); + Assert.Null(actualTuple.Value); + } - [Fact] - public void BadValueConversion() - { - // Arrange - IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); - var value = "Hello=Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert("Hello", typeof(int)); - var expectedInnerExceptionMessage = + [Fact] + public void BadValueConversion() + { + // Arrange + IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); + var value = "Hello=Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert("Hello", typeof(int)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; - - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } - } + ; - [Fact] - public void ArgumentNullExceptionForNullKeyConverter() + // Act + using (new LangageSwitcher("en-us")) { - // Arrange - var expectedInnerExceptionMessage = @"keyConverter"; - - // Act - var actualException = Assert.Throws(() => new KeyValueConverter(null, new Int32Converter())); + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); // Assert - Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } + } - [Fact] - public void ArgumentNullExceptionForNullValueConverter() - { - // Arrange - var expectedInnerExceptionMessage = @"valueConverter"; + [Fact] + public void ArgumentNullExceptionForNullKeyConverter() + { + // Arrange + var expectedInnerExceptionMessage = @"keyConverter"; - // Act - var actualException = Assert.Throws(() => new KeyValueConverter(new StringConverter(), null)); + // Act + var actualException = Assert.Throws(() => new KeyValueConverter(null, new Int32Converter())); - // Assert - Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); - } + // Assert + Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); + } - [Fact] - public void EmptyValueConverter() - { - // Arrange - IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); - var expectedInnerExceptionMessage = @"value"; - var value = string.Empty; + [Fact] + public void ArgumentNullExceptionForNullValueConverter() + { + // Arrange + var expectedInnerExceptionMessage = @"valueConverter"; - // Act - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + var actualException = Assert.Throws(() => new KeyValueConverter(new StringConverter(), null)); - // Assert - Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); - } + // Assert + Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); + } + + [Fact] + public void EmptyValueConverter() + { + // Arrange + IConverter converter = new KeyValueConverter(new StringConverter(), new Int32Converter()); + var expectedInnerExceptionMessage = @"value"; + var value = string.Empty; + + // Act + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + + // Assert + Assert.Equal(expectedInnerExceptionMessage, actualException.ParamName); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/SingleConvertersTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/SingleConvertersTests.cs index 9e30f00..aeedc71 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/SingleConvertersTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/SingleConvertersTests.cs @@ -2,71 +2,70 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class SingleConvertersTests { - public class SingleConvertersTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new SingleConverter(); - var expectedType = typeof (Single); + // Arrange + IConverter converter = new SingleConverter(); + var expectedType = typeof (float); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new SingleConverter(); - var value = "42,1"; - var expectedValue = (Single) 42.1; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new SingleConverter(); + var value = "42,1"; + var expectedValue = (float) 42.1; - // Act - using (new LangageSwitcher("fr-fr")) - { - var actualValue = converter.Convert(value, converter.TargetType); + // Act + using (new LangageSwitcher("fr-fr")) + { + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Single) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (float) actualValue); } + } - [Fact] - [Trait(nameof(Exception), nameof(CommandLineParserException))] - public void BadValueConversion() - { - // Arrange - IConverter converter = new SingleConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(float)); - var expectedInnerExceptionMessage = + [Fact] + [Trait(nameof(Exception), nameof(CommandLineParserException))] + public void BadValueConversion() + { + // Arrange + IConverter converter = new SingleConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(float)); + var expectedInnerExceptionMessage = #if NETFRAMEWORK - "Input string was not in a correct format." + "Input string was not in a correct format." #else - "The input string 'Hello' was not in a correct format." + "The input string 'Hello' was not in a correct format." #endif - ; + ; - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/StringConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/StringConverterTests.cs index 8e2d65d..1c4a0fc 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/StringConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/StringConverterTests.cs @@ -1,38 +1,37 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class StringConverterTests { - public class StringConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new StringConverter(); - var expectedType = typeof (string); + // Arrange + IConverter converter = new StringConverter(); + var expectedType = typeof (string); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new StringConverter(); - var expectedValue = "value"; + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new StringConverter(); + var expectedValue = "value"; - // Act - var actualValue = converter.Convert(expectedValue, converter.TargetType); + // Act + var actualValue = converter.Convert(expectedValue, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (string) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (string) actualValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/TimeSpanConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/TimeSpanConverterTests.cs index e48f840..d9a8454 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/TimeSpanConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/TimeSpanConverterTests.cs @@ -2,66 +2,65 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class TimeSpanConverterTests { - public class TimeSpanConverterTests + [Fact] + public void TargetType() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new TimeSpanConverter(); - var expectedType = typeof (TimeSpan); + // Arrange + IConverter converter = new TimeSpanConverter(); + var expectedType = typeof (TimeSpan); - // Act - var actualType = converter.TargetType; + // Act + var actualType = converter.TargetType; - // Assert - Assert.Equal(expectedType, actualType); - } + // Assert + Assert.Equal(expectedType, actualType); + } - [Fact] - public void Conversion() - { - // Arrange - IConverter converter = new TimeSpanConverter(); - var value = "3:15:14"; - var expectedValue = new TimeSpan(3, 15, 14); + [Fact] + public void Conversion() + { + // Arrange + IConverter converter = new TimeSpanConverter(); + var value = "3:15:14"; + var expectedValue = new TimeSpan(3, 15, 14); - // Act - var actualValue = converter.Convert(value, converter.TargetType); + // Act + var actualValue = converter.Convert(value, converter.TargetType); - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (TimeSpan) actualValue); - } + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (TimeSpan) actualValue); + } - [Fact] - [Trait(nameof(Exception), nameof(CommandLineParserException))] - public void BadValueConversion() - { - // Arrange - IConverter converter = new TimeSpanConverter(); - var value = "Hello"; - var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(TimeSpan)); + [Fact] + [Trait(nameof(Exception), nameof(CommandLineParserException))] + public void BadValueConversion() + { + // Arrange + IConverter converter = new TimeSpanConverter(); + var value = "Hello"; + var expectedExceptionMessage = Constants.ExceptionMessages.FormatConverterUnableConvert(value, typeof(TimeSpan)); #if NET48 - var expectedInnerExceptionMessage = "String was not recognized as a valid TimeSpan."; + var expectedInnerExceptionMessage = "String was not recognized as a valid TimeSpan."; #else - var expectedInnerExceptionMessage = "String 'Hello' was not recognized as a valid TimeSpan."; + var expectedInnerExceptionMessage = "String 'Hello' was not recognized as a valid TimeSpan."; #endif - // Act - using (new LangageSwitcher("en-us")) - { - var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); + // Act + using (new LangageSwitcher("en-us")) + { + var actualException = Assert.Throws(() => converter.Convert(value, converter.TargetType)); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - Assert.NotNull(actualException.InnerException); - var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); - Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + Assert.NotNull(actualException.InnerException); + var actualInnerExecption = Assert.IsAssignableFrom(actualException.InnerException); + Assert.Equal(expectedInnerExceptionMessage, actualInnerExecption.Message); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/UriConverterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/UriConverterTests.cs index 733a3c9..39c2655 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/UriConverterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/Converters/UriConverterTests.cs @@ -2,56 +2,55 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters +namespace MGR.CommandLineParser.UnitTests.Extensibility.Converters; + +public class UriConverterTests { - public class UriConverterTests + [Fact] + public void TargetType() + { + // Arrange + IConverter converter = new UriConverter(); + var expectedType = typeof (Uri); + + // Act + var actualType = converter.TargetType; + + // Assert + Assert.Equal(expectedType, actualType); + } + + [Fact] + public void AbsoluteConversion() + { + // Arrange + IConverter converter = new UriConverter(); + var value = "http://mgrcommandlineparser.codeplex.com"; + var expectedValue = new Uri("http://mgrcommandlineparser.codeplex.com"); + + // Act + var actualValue = converter.Convert(value, converter.TargetType); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (Uri) actualValue); + } + + [Fact] + public void RelativeConversion() { - [Fact] - public void TargetType() - { - // Arrange - IConverter converter = new UriConverter(); - var expectedType = typeof (Uri); - - // Act - var actualType = converter.TargetType; - - // Assert - Assert.Equal(expectedType, actualType); - } - - [Fact] - public void AbsoluteConversion() - { - // Arrange - IConverter converter = new UriConverter(); - var value = "http://mgrcommandlineparser.codeplex.com"; - var expectedValue = new Uri("http://mgrcommandlineparser.codeplex.com"); - - // Act - var actualValue = converter.Convert(value, converter.TargetType); - - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Uri) actualValue); - } - - [Fact] - public void RelativeConversion() - { - // Arrange - IConverter converter = new UriConverter(); - var value = "hello"; - var expectedValue = new Uri("hello", UriKind.Relative); - - // Act - var actualValue = converter.Convert(value, converter.TargetType); - - // Assert - Assert.NotNull(actualValue); - Assert.IsType(actualValue); - Assert.Equal(expectedValue, (Uri) actualValue); - } + // Arrange + IConverter converter = new UriConverter(); + var value = "hello"; + var expectedValue = new Uri("hello", UriKind.Relative); + + // Act + var actualValue = converter.Convert(value, converter.TargetType); + + // Assert + Assert.NotNull(actualValue); + Assert.IsType(actualValue); + Assert.Equal(expectedValue, (Uri) actualValue); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.GetMultiValueIndicator.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.GetMultiValueIndicator.cs index 1a0eb4d..bd7805a 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.GetMultiValueIndicator.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.GetMultiValueIndicator.cs @@ -1,69 +1,75 @@ using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MGR.CommandLineParser.Command; using MGR.CommandLineParser.Extensibility; using MGR.CommandLineParser.Extensibility.ClassBased; using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility +namespace MGR.CommandLineParser.UnitTests.Extensibility; + +public partial class DefaultHelpWriterTests { - public partial class DefaultHelpWriterTests + public class GetMultiValueIndicator : ICommandHandler { - public class GetMultiValueIndicator + + public class GetMultiValueIndicatorData : CommandData { public int SimpleIntProperty { get; set; } public List ListIntProperty { get; set; } public Dictionary DictionaryProperty { get; set; } + } + [Fact] + public void TestSimpleProperty() + { + // Arrange + var propertyInfo = + typeof(GetMultiValueIndicatorData).GetProperty(TypeHelpers.ExtractPropertyName((o) => o.SimpleIntProperty)); + var commandMetadata = new ClassBasedCommandMetadata(); + var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List { new Int32Converter() }, new List()); + var expected = string.Empty; - [Fact] - public void TestSimpleProperty() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => SimpleIntProperty)); - var commandMetadata = new ClassBasedCommandMetadata(typeof (GetMultiValueIndicator)); - var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List {new Int32Converter()}, new List()); - var expected = string.Empty; - - // Act - var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); + // Act + var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); - // Assert - Assert.Equal(expected, actual); - } + // Assert + Assert.Equal(expected, actual); + } - [Fact] - public void TestListProperty() - { - // Arrange - var propertyInfo = GetType() - .GetProperty(TypeHelpers.ExtractPropertyName(() => ListIntProperty)); - var commandMetadata = new ClassBasedCommandMetadata(typeof (GetMultiValueIndicator)); - var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List {new Int32Converter()}, new List()); - var expected = DefaultHelpWriter.CollectionIndicator; + [Fact] + public void TestListProperty() + { + // Arrange + var propertyInfo = typeof(GetMultiValueIndicatorData) + .GetProperty(TypeHelpers.ExtractPropertyName>((o) => o.ListIntProperty)); + var commandMetadata = new ClassBasedCommandMetadata(); + var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List { new Int32Converter() }, new List()); + var expected = DefaultHelpWriter.CollectionIndicator; - // Act - var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); + // Act + var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); - // Assert - Assert.Equal(expected, actual); - } + // Assert + Assert.Equal(expected, actual); + } - [Fact] - public void TestDictionaryProperty() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => DictionaryProperty)); - var commandMetadata = new ClassBasedCommandMetadata(typeof (GetMultiValueIndicator)); - var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List {new StringConverter(), new Int32Converter()}, new List()); - var expected = DefaultHelpWriter.DictionaryIndicator; + [Fact] + public void TestDictionaryProperty() + { + // Arrange + var propertyInfo = + typeof(GetMultiValueIndicatorData).GetProperty(TypeHelpers.ExtractPropertyName>((o) => o.DictionaryProperty)); + var commandMetadata = new ClassBasedCommandMetadata(); + var commandOption = ClassBasedCommandOptionMetadata.Create(propertyInfo, commandMetadata, new List { new StringConverter(), new Int32Converter() }, new List()); + var expected = DefaultHelpWriter.DictionaryIndicator; - // Act - var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); + // Act + var actual = DefaultHelpWriter.GetMultiValueIndicator(commandOption); - // Assert - Assert.Equal(expected, actual); - } + // Assert + Assert.Equal(expected, actual); } + public Task ExecuteAsync(GetMultiValueIndicatorData commandData, CancellationToken cancellationToken) => throw new System.NotImplementedException(); } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.WriteCommandListing.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.WriteCommandListing.cs index 3dd9355..642fcb9 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.WriteCommandListing.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.WriteCommandListing.cs @@ -5,47 +5,14 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensibility +namespace MGR.CommandLineParser.UnitTests.Extensibility; + +public partial class DefaultHelpWriterTests { - public partial class DefaultHelpWriterTests + public class WriteCommandListing { - public class WriteCommandListing - { - [Fact] - public void NoCommandTypesDisplayOnlyGeneralInformation() - { - var console = new FakeConsole(); - var parserOptions = new ParserOptions { - Logo = "Logo Unit Test", - CommandLineName = "tool.exe" - }; - var parserOptionsAccessorMock = new Mock>(); - parserOptionsAccessorMock.SetupGet(_ => _.Value).Returns(parserOptions); - var commandTypeProviderMock = new Mock(); - commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(Enumerable.Empty); - var helpWriter = new DefaultHelpWriter(console, new[] { commandTypeProviderMock.Object }, parserOptionsAccessorMock.Object); - var expected = @"Logo Unit Test -Usage: tool.exe [options] [args] -Type 'tool.exe help ' for help on a specific command. - -Available commands: -No commands found. -"; - - using (new LangageSwitcher("en-us")) - { - helpWriter.WriteCommandListing(); - } - var messages = console.Messages; - - Assert.Single(messages); - Assert.IsType(messages[0]); - Assert.Equal(expected, messages[0].ToString(), ignoreLineEndingDifferences: true); - } - } - [Fact] - public void OneCommandTypeDisplayOnlyGeneralInformationThenHelpForTheCommand() + public void NoCommandTypesDisplayOnlyGeneralInformation() { var console = new FakeConsole(); var parserOptions = new ParserOptions { @@ -55,20 +22,14 @@ public void OneCommandTypeDisplayOnlyGeneralInformationThenHelpForTheCommand() var parserOptionsAccessorMock = new Mock>(); parserOptionsAccessorMock.SetupGet(_ => _.Value).Returns(parserOptions); var commandTypeProviderMock = new Mock(); - var commandMetadataMock = new Mock(); - commandMetadataMock.SetupGet(_ => _.HideFromHelpListing).Returns(false); - commandMetadataMock.SetupGet(_ => _.Name).Returns("test"); - commandMetadataMock.SetupGet(_ => _.Description).Returns("test command"); - var commandTypeMock = new Mock(); - commandTypeMock.SetupGet(_ => _.Metadata).Returns(commandMetadataMock.Object); - commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(new[] { commandTypeMock.Object }); + commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(Enumerable.Empty); var helpWriter = new DefaultHelpWriter(console, new[] { commandTypeProviderMock.Object }, parserOptionsAccessorMock.Object); var expected = @"Logo Unit Test Usage: tool.exe [options] [args] Type 'tool.exe help ' for help on a specific command. Available commands: - test test command +No commands found. "; using (new LangageSwitcher("en-us")) @@ -81,33 +42,72 @@ test test command Assert.IsType(messages[0]); Assert.Equal(expected, messages[0].ToString(), ignoreLineEndingDifferences: true); } + } - [Fact] - public void TwoCommandTypesDisplayOnlyGeneralInformationThenHelpForTheCommand() + [Fact] + public void OneCommandTypeDisplayOnlyGeneralInformationThenHelpForTheCommand() + { + var console = new FakeConsole(); + var parserOptions = new ParserOptions { + Logo = "Logo Unit Test", + CommandLineName = "tool.exe" + }; + var parserOptionsAccessorMock = new Mock>(); + parserOptionsAccessorMock.SetupGet(_ => _.Value).Returns(parserOptions); + var commandTypeProviderMock = new Mock(); + var commandMetadataMock = new Mock(); + commandMetadataMock.SetupGet(_ => _.HideFromHelpListing).Returns(false); + commandMetadataMock.SetupGet(_ => _.Name).Returns("test"); + commandMetadataMock.SetupGet(_ => _.Description).Returns("test command"); + var commandTypeMock = new Mock(); + commandTypeMock.SetupGet(_ => _.Metadata).Returns(commandMetadataMock.Object); + commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(new[] { commandTypeMock.Object }); + var helpWriter = new DefaultHelpWriter(console, new[] { commandTypeProviderMock.Object }, parserOptionsAccessorMock.Object); + var expected = @"Logo Unit Test +Usage: tool.exe [options] [args] +Type 'tool.exe help ' for help on a specific command. + +Available commands: + test test command +"; + + using (new LangageSwitcher("en-us")) { - var console = new FakeConsole(); - var parserOptions = new ParserOptions { - Logo = "Logo Unit Test", - CommandLineName = "tool.exe" - }; - var parserOptionsAccessorMock = new Mock>(); - parserOptionsAccessorMock.SetupGet(_ => _.Value).Returns(parserOptions); - var commandTypeProviderMock = new Mock(); - var commandMetadata1Mock = new Mock(); - commandMetadata1Mock.SetupGet(_ => _.HideFromHelpListing).Returns(false); - commandMetadata1Mock.SetupGet(_ => _.Name).Returns("build"); - commandMetadata1Mock.SetupGet(_ => _.Description).Returns("description for build command"); - var commandType1Mock = new Mock(); - commandType1Mock.SetupGet(_ => _.Metadata).Returns(commandMetadata1Mock.Object); - var commandMetadata2Mock = new Mock(); - commandMetadata2Mock.SetupGet(_ => _.HideFromHelpListing).Returns(false); - commandMetadata2Mock.SetupGet(_ => _.Name).Returns("test"); - commandMetadata2Mock.SetupGet(_ => _.Description).Returns("description for test command"); - var commandType2Mock = new Mock(); - commandType2Mock.SetupGet(_ => _.Metadata).Returns(commandMetadata2Mock.Object); - commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(new[] { commandType1Mock.Object, commandType2Mock.Object }); - var helpWriter = new DefaultHelpWriter(console, new[] { commandTypeProviderMock.Object }, parserOptionsAccessorMock.Object); - var expected = @"Logo Unit Test + helpWriter.WriteCommandListing(); + } + var messages = console.Messages; + + Assert.Single(messages); + Assert.IsType(messages[0]); + Assert.Equal(expected, messages[0].ToString(), ignoreLineEndingDifferences: true); + } + + [Fact] + public void TwoCommandTypesDisplayOnlyGeneralInformationThenHelpForTheCommand() + { + var console = new FakeConsole(); + var parserOptions = new ParserOptions { + Logo = "Logo Unit Test", + CommandLineName = "tool.exe" + }; + var parserOptionsAccessorMock = new Mock>(); + parserOptionsAccessorMock.SetupGet(_ => _.Value).Returns(parserOptions); + var commandTypeProviderMock = new Mock(); + var commandMetadata1Mock = new Mock(); + commandMetadata1Mock.SetupGet(_ => _.HideFromHelpListing).Returns(false); + commandMetadata1Mock.SetupGet(_ => _.Name).Returns("build"); + commandMetadata1Mock.SetupGet(_ => _.Description).Returns("description for build command"); + var commandType1Mock = new Mock(); + commandType1Mock.SetupGet(_ => _.Metadata).Returns(commandMetadata1Mock.Object); + var commandMetadata2Mock = new Mock(); + commandMetadata2Mock.SetupGet(_ => _.HideFromHelpListing).Returns(false); + commandMetadata2Mock.SetupGet(_ => _.Name).Returns("test"); + commandMetadata2Mock.SetupGet(_ => _.Description).Returns("description for test command"); + var commandType2Mock = new Mock(); + commandType2Mock.SetupGet(_ => _.Metadata).Returns(commandMetadata2Mock.Object); + commandTypeProviderMock.Setup(_ => _.GetAllCommandTypes()).ReturnsAsync(new[] { commandType1Mock.Object, commandType2Mock.Object }); + var helpWriter = new DefaultHelpWriter(console, new[] { commandTypeProviderMock.Object }, parserOptionsAccessorMock.Object); + var expected = @"Logo Unit Test Usage: tool.exe [options] [args] Type 'tool.exe help ' for help on a specific command. @@ -116,15 +116,14 @@ public void TwoCommandTypesDisplayOnlyGeneralInformationThenHelpForTheCommand() test description for test command "; - using (new LangageSwitcher("en-us")) - { - helpWriter.WriteCommandListing(); - } - var messages = console.Messages; - - Assert.Single(messages); - Assert.IsType(messages[0]); - Assert.Equal(expected, messages[0].ToString(), ignoreLineEndingDifferences: true); + using (new LangageSwitcher("en-us")) + { + helpWriter.WriteCommandListing(); } + var messages = console.Messages; + + Assert.Single(messages); + Assert.IsType(messages[0]); + Assert.Equal(expected, messages[0].ToString(), ignoreLineEndingDifferences: true); } } diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.cs index 965e431..e99a68f 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensibility/DefaultHelpWriterTests.cs @@ -1,6 +1,5 @@ -namespace MGR.CommandLineParser.UnitTests.Extensibility +namespace MGR.CommandLineParser.UnitTests.Extensibility; + +public partial class DefaultHelpWriterTests { - public partial class DefaultHelpWriterTests - { - } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildConverter.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildConverter.cs index d943dc6..01fb9a1 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildConverter.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildConverter.cs @@ -3,45 +3,43 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterAttributeExtensionsTests { - public partial class ConverterAttributeExtensionsTests + public class BuildConverter { - public class BuildConverter + [Fact] + public void Int32ConverterActivation() { - [Fact] - public void Int32ConverterActivation() - { - // Arrange - var expected = typeof (Int32Converter); + // Arrange + var expected = typeof (Int32Converter); #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = new ConverterAttribute(expected); + var converterAttribute = new ConverterAttribute(expected); #pragma warning restore CS0618 // Type or member is obsolete - // Act - var actual = converterAttribute.BuildConverter(); + // Act + var actual = converterAttribute.BuildConverter(); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } - [Fact] - public void NullConverterAttributeException() - { - // Arrange + [Fact] + public void NullConverterAttributeException() + { + // Arrange #pragma warning disable CS0618 // Type or member is obsolete - ConverterAttribute converterAttribute = null; + ConverterAttribute converterAttribute = null; #pragma warning restore CS0618 // Type or member is obsolete - var expectedExceptionMessage = SourceParameterName; + var expectedExceptionMessage = SourceParameterName; - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => converterAttribute.BuildConverter()); + // Act + var actualException = Assert.Throws(() => converterAttribute.BuildConverter()); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildKeyConverter.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildKeyConverter.cs index ca031ed..fb21f25 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildKeyConverter.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildKeyConverter.cs @@ -3,63 +3,61 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterAttributeExtensionsTests { - public partial class ConverterAttributeExtensionsTests + public class BuildKeyConverter { - public class BuildKeyConverter + [Fact] + public void Int32ConverterActivation() { - [Fact] - public void Int32ConverterActivation() - { - // Arrange - var expected = typeof (Int32Converter); - var valueConverterType = typeof (GuidConverter); + // Arrange + var expected = typeof (Int32Converter); + var valueConverterType = typeof (GuidConverter); #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = new ConverterKeyValueAttribute(valueConverterType, expected); + var converterAttribute = new ConverterKeyValueAttribute(valueConverterType, expected); #pragma warning restore CS0618 // Type or member is obsolete - // Act - var actual = converterAttribute.BuildKeyConverter(); + // Act + var actual = converterAttribute.BuildKeyConverter(); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } - [Fact] - public void DefaultStringConverterActivation() - { - // Arrange - var valueConverterType = typeof (Int32Converter); + [Fact] + public void DefaultStringConverterActivation() + { + // Arrange + var valueConverterType = typeof (Int32Converter); #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = new ConverterKeyValueAttribute(valueConverterType); + var converterAttribute = new ConverterKeyValueAttribute(valueConverterType); #pragma warning restore CS0618 // Type or member is obsolete - // Act - var actual = converterAttribute.BuildKeyConverter(); + // Act + var actual = converterAttribute.BuildKeyConverter(); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } - [Fact] - public void NullConverterAttributeException() - { - // Arrange + [Fact] + public void NullConverterAttributeException() + { + // Arrange #pragma warning disable CS0618 // Type or member is obsolete - ConverterKeyValueAttribute converterAttribute = null; + ConverterKeyValueAttribute converterAttribute = null; #pragma warning restore CS0618 // Type or member is obsolete - var expectedExceptionMessage = SourceParameterName; + var expectedExceptionMessage = SourceParameterName; - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => converterAttribute.BuildKeyConverter()); + // Act + var actualException = Assert.Throws(() => converterAttribute.BuildKeyConverter()); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildValueConverter.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildValueConverter.cs index 9fe5836..02975b6 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildValueConverter.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.BuildValueConverter.cs @@ -3,64 +3,62 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterAttributeExtensionsTests { - public partial class ConverterAttributeExtensionsTests + public class BuildValueConverter { - public class BuildValueConverter + [Fact] + public void Int32ConverterActivation() { - [Fact] - public void Int32ConverterActivation() - { - // Arrange - var keyConverterType = typeof (GuidConverter); - var expected = typeof (Int32Converter); + // Arrange + var keyConverterType = typeof (GuidConverter); + var expected = typeof (Int32Converter); #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = new ConverterKeyValueAttribute(expected, keyConverterType); + var converterAttribute = new ConverterKeyValueAttribute(expected, keyConverterType); #pragma warning restore CS0618 // Type or member is obsolete - // Act - var actual = converterAttribute.BuildValueConverter(); + // Act + var actual = converterAttribute.BuildValueConverter(); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } - [Fact] - public void DefaultStringConverterActivation() - { - // Arrange - var expected = typeof (Int32Converter); + [Fact] + public void DefaultStringConverterActivation() + { + // Arrange + var expected = typeof (Int32Converter); #pragma warning disable CS0618 // Type or member is obsolete - var converterAttribute = new ConverterKeyValueAttribute(expected); + var converterAttribute = new ConverterKeyValueAttribute(expected); #pragma warning restore CS0618 // Type or member is obsolete - // Act - var actual = converterAttribute.BuildValueConverter(); + // Act + var actual = converterAttribute.BuildValueConverter(); - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } - [Fact] - public void NullConverterAttributeException() - { - // Arrange + [Fact] + public void NullConverterAttributeException() + { + // Arrange #pragma warning disable CS0618 // Type or member is obsolete - ConverterKeyValueAttribute converterAttribute = null; + ConverterKeyValueAttribute converterAttribute = null; #pragma warning restore CS0618 // Type or member is obsolete - var expectedExceptionMessage = SourceParameterName; + var expectedExceptionMessage = SourceParameterName; - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => converterAttribute.BuildValueConverter()); + // Act + var actualException = + Assert.Throws(() => converterAttribute.BuildValueConverter()); - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.cs index 952f281..2dfd9e0 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterAttributeExtensionsTests.cs @@ -1,7 +1,6 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterAttributeExtensionsTests { - public partial class ConverterAttributeExtensionsTests - { - private static readonly string SourceParameterName = "source"; - } + private static readonly string SourceParameterName = "source"; } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.CanConvertTo.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.CanConvertTo.cs index 9c03556..9348d98 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.CanConvertTo.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.CanConvertTo.cs @@ -4,126 +4,123 @@ using Moq; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterExtensionsTests { - public partial class ConverterExtensionsTests + public class CanConvertTo { - public class CanConvertTo + [Fact] + public void ConvertInt() + { + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); + var expected = true; + var assignableType = typeof (int); + + // Act + var actual = converterMoq.Object.CanConvertTo(assignableType); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ConvertListIntAndInt() + { + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); + var expected = true; + var assignableType = typeof (List); + + // Act + var actual = converterMoq.Object.CanConvertTo(assignableType); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ConvertListIntAndString() + { + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (string)); + var expected = false; + var assignableType = typeof (List); + + // Act + var actual = converterMoq.Object.CanConvertTo(assignableType); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ConvertDictionaryIntStringAndInt() + { + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); + var expected = false; + var assignableType = typeof (Dictionary); + + // Act + var actual = converterMoq.Object.CanConvertTo(assignableType); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ConvertDictionaryIntIntAndString() + { + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (KeyValuePair)); + var expected = true; + var assignableType = typeof (KeyValuePair); + + // Act + var actual = converterMoq.Object.CanConvertTo(assignableType); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullConverterException() + { + // Arrange + IConverter testedConverter = null; + var expectedExceptionType = typeof (ArgumentNullException); + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws(() => testedConverter.CanConvertTo(expectedExceptionType)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); + } + + [Fact] + public void NullValueException() { - [Fact] - public void ConvertInt() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); - var expected = true; - var assignableType = typeof (int); - - // Act - var actual = converterMoq.Object.CanConvertTo(assignableType); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void ConvertListIntAndInt() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); - var expected = true; - var assignableType = typeof (List); - - // Act - var actual = converterMoq.Object.CanConvertTo(assignableType); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void ConvertListIntAndString() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (string)); - var expected = false; - var assignableType = typeof (List); - - // Act - var actual = converterMoq.Object.CanConvertTo(assignableType); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void ConvertDictionaryIntStringAndInt() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); - var expected = false; - var assignableType = typeof (Dictionary); - - // Act - var actual = converterMoq.Object.CanConvertTo(assignableType); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void ConvertDictionaryIntIntAndString() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (KeyValuePair)); - var expected = true; - var assignableType = typeof (KeyValuePair); - - // Act - var actual = converterMoq.Object.CanConvertTo(assignableType); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullConverterException() - { - // Arrange - IConverter testedConverter = null; - var expectedExceptionType = typeof (ArgumentNullException); - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => testedConverter.CanConvertTo(expectedExceptionType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } - - [Fact] - public void NullValueException() - { - // Arrange - var converterMoq = new Mock(); - converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); - Type targetType = null; - var expectedExceptionMessage = nameof(targetType); - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => converterMoq.Object.CanConvertTo(targetType)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var converterMoq = new Mock(); + converterMoq.SetupGet(converter => converter.TargetType).Returns(typeof (int)); + Type targetType = null; + var expectedExceptionMessage = nameof(targetType); + + // Act + var actualException = + Assert.Throws(() => converterMoq.Object.CanConvertTo(targetType)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.cs index 7bdc0a8..7d55d6e 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/ConverterExtensionsTests.cs @@ -1,7 +1,6 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class ConverterExtensionsTests { - public partial class ConverterExtensionsTests - { - private static readonly string SourceParameterName = "source"; - } + private static readonly string SourceParameterName = "source"; } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.PrependWith.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.PrependWith.cs index 66c1c84..29b6e53 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.PrependWith.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.PrependWith.cs @@ -1,37 +1,36 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class EnumeratorExtensionsTests { - public partial class EnumeratorExtensionsTests + public class PrependWith { - public class PrependWith + [Fact] + public void Prepend_Correctly_Add_Before_Items() { - [Fact] - public void Prepend_Correctly_Add_Before_Items() - { - // Arrange - var initialList = new List {"Should", "Be", "Prefixed"}; - var prefix = "This"; - var expected = new List {"This", "Should", "Be", "Prefixed"}.GetEnumerator(); + // Arrange + var initialList = new List {"Should", "Be", "Prefixed"}; + var prefix = "This"; + var expected = new List {"This", "Should", "Be", "Prefixed"}.GetEnumerator(); - // Act - var actual = initialList.GetEnumerator().PrefixWith(prefix); + // Act + var actual = initialList.GetEnumerator().PrefixWith(prefix); - // Assert - while (true) + // Assert + while (true) + { + var shouldHaveNext = expected.MoveNext(); + Assert.Equal(shouldHaveNext, actual.MoveNext()); + Assert.Equal(expected.Current, actual.Current); + if (!shouldHaveNext) { - var shouldHaveNext = expected.MoveNext(); - Assert.Equal(shouldHaveNext, actual.MoveNext()); - Assert.Equal(expected.Current, actual.Current); - if (!shouldHaveNext) - { - break; - } + break; } - expected.Dispose(); - actual.Dispose(); } + expected.Dispose(); + actual.Dispose(); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.cs index a210067..73706dc 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/EnumeratorExtensionsTests.cs @@ -1,6 +1,5 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class EnumeratorExtensionsTests { - public partial class EnumeratorExtensionsTests - { - } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractConverterMetadata.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractConverterMetadata.cs index 0c8d78d..0dd204d 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractConverterMetadata.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractConverterMetadata.cs @@ -5,436 +5,431 @@ using MGR.CommandLineParser.Extensibility.Converters; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class ExtractConverterMetadata { - public class ExtractConverterMetadata - { - public int OriginalProperty { get; set; } + public int OriginalProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [Converter(typeof(Int32Converter))] + [Converter(typeof(Int32Converter))] #pragma warning restore CS0618 // Type or member is obsolete - public int CustomConverterProperty { get; set; } + public int CustomConverterProperty { get; set; } #if NET7_0_OR_GREATER - [Converter] - public int CustomGenericConverterProperty { get; set; } + [Converter] + public int CustomGenericConverterProperty { get; set; } #endif #pragma warning disable CS0618 // Type or member is obsolete - [Converter(typeof(GuidConverter))] + [Converter(typeof(GuidConverter))] #pragma warning restore CS0618 // Type or member is obsolete - public int WrongCustomConverterProperty { get; set; } + public int WrongCustomConverterProperty { get; set; } - public List OriginalListProperty { get; set; } + public List OriginalListProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [Converter(typeof(Int32Converter))] + [Converter(typeof(Int32Converter))] #pragma warning restore CS0618 // Type or member is obsolete - public List CustomListConverterProperty { get; set; } + public List CustomListConverterProperty { get; set; } - public Dictionary OriginalDictionaryProperty { get; set; } + public Dictionary OriginalDictionaryProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] + [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] #pragma warning restore CS0618 // Type or member is obsolete - public Dictionary CustomDictionaryConverterProperty { get; set; } + public Dictionary CustomDictionaryConverterProperty { get; set; } - [ConverterKeyValue] - public Dictionary CustomDictionaryConverterGenericProperty { get; set; } + [ConverterKeyValue] + public Dictionary CustomDictionaryConverterGenericProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [ConverterKeyValue(typeof(GuidConverter))] + [ConverterKeyValue(typeof(GuidConverter))] #pragma warning restore CS0618 // Type or member is obsolete - public Dictionary CustomValueOnlyDictionaryConverterProperty { get; set; } + public Dictionary CustomValueOnlyDictionaryConverterProperty { get; set; } - [ConverterKeyValue] - public Dictionary CustomValueOnlyDictionaryConverterGenericProperty { get; set; } + [ConverterKeyValue] + public Dictionary CustomValueOnlyDictionaryConverterGenericProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [ConverterKeyValue(typeof(GuidConverter))] + [ConverterKeyValue(typeof(GuidConverter))] #pragma warning restore CS0618 // Type or member is obsolete - public List CustomDictionaryConverterWithListProperty { get; set; } + public List CustomDictionaryConverterWithListProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] + [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] #pragma warning restore CS0618 // Type or member is obsolete - public Dictionary CustomDictionaryWithWrongKeyConverterProperty { get; set; } + public Dictionary CustomDictionaryWithWrongKeyConverterProperty { get; set; } #pragma warning disable CS0618 // Type or member is obsolete - [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] + [ConverterKeyValue(typeof(GuidConverter), typeof(Int32Converter))] #pragma warning restore CS0618 // Type or member is obsolete - public Dictionary CustomDictionaryWithWrongValueConverterProperty { get; set; } - - public Dictionary OriginalDictionaryWithWrongKeyConverterProperty { get; set; } - public Dictionary OriginalDictionaryWithWrongValueConverterProperty { get; set; } - - [Fact] - public void OriginalTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void OriginalNoConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter()}; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoConverterFound(propertyName, commandName, typeof(int)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void CustomConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + public Dictionary CustomDictionaryWithWrongValueConverterProperty { get; set; } + + public Dictionary OriginalDictionaryWithWrongKeyConverterProperty { get; set; } + public Dictionary OriginalDictionaryWithWrongValueConverterProperty { get; set; } + + [Fact] + public void OriginalTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void OriginalNoConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter()}; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoConverterFound(propertyName, commandName, typeof(int)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void CustomConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } #if NET7_0_OR_GREATER - [Fact] - public void CustomGenericConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomGenericConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomDictionaryGenericConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterGenericProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter(), new GuidConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomValueOnlyDictionaryGenericConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomValueOnlyDictionaryConverterGenericProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter(), new Int32Converter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } + [Fact] + public void CustomGenericConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomGenericConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomDictionaryGenericConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterGenericProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter(), new GuidConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomValueOnlyDictionaryGenericConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomValueOnlyDictionaryConverterGenericProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter(), new Int32Converter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } #endif - [Fact] - public void WrongCustomConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => WrongCustomConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyName, commandName, typeof(int), typeof(Guid)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void OriginalListTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalListProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomListConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomListConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void OriginalDictionaryTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalDictionaryProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter(), new GuidConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomDictionaryConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter(), new GuidConverter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomValueOnlyDictionaryConverterTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomValueOnlyDictionaryConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter(), new Int32Converter() }; - - // Act - var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); - - // Assert - Assert.NotNull(actual); - Assert.IsType(actual); - } - - [Fact] - public void CustomDictionaryConverterWithListException() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterWithListProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new StringConverter(), new GuidConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(propertyName, "MyCommand"); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void CustomDictionaryWithWrongKeyConverterException() - { - // Arrange - var propertyName = - TypeHelpers.ExtractPropertyName(() => CustomDictionaryWithWrongKeyConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter(), new GuidConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractKeyConverterIsNotValid(propertyName, commandName, typeof(string), typeof(int)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void CustomDictionaryWithWrongValueConverterException() - { - // Arrange - var propertyName = - TypeHelpers.ExtractPropertyName(() => CustomDictionaryWithWrongValueConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter(), new GuidConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractValueConverterIsNotValid(propertyName, commandName, typeof(string), typeof(Guid)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void OriginalDictionaryWithoutKeyConverterException() - { - // Arrange - var propertyName = - TypeHelpers.ExtractPropertyName(() => OriginalDictionaryWithWrongKeyConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter(), new GuidConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoKeyConverterFound(propertyName, commandName, typeof(string)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void OriginalDictionaryWithoutValueConverterException() - { - // Arrange - var propertyName = - TypeHelpers.ExtractPropertyName(() => OriginalDictionaryWithWrongValueConverterProperty); - var propertyInfo = GetType().GetProperty(propertyName); - var commandName = "MyCommand"; - var converters = new List { new Int32Converter(), new GuidConverter() }; - var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoValueConverterFound(propertyName, commandName, typeof(string)); - - // Act - var actualException = - Assert.Throws( - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.Message); - } - - [Fact] - public void NullPropertyInfoException() - { - // Arrange - PropertyInfo propertyInfo = null; - var converters = new List { new Int32Converter(), new GuidConverter() }; - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - Assert.Throws( - // ReSharper disable once ExpressionIsAlwaysNull - () => propertyInfo.ExtractConverter(converters, null, null)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } - - [Fact] - public void NullOptionNameException() - { - // Arrange - var propertyInfo = GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); - var converters = new List { new Int32Converter(), new GuidConverter() }; - string optionName = null; - string commandName = null; - var expectedExceptionMessage = nameof(optionName); - - // Act - var actualException = - Assert.Throws( - // ReSharper disable ExpressionIsAlwaysNull - () => propertyInfo.ExtractConverter(converters, optionName, commandName)); - // ReSharper restore ExpressionIsAlwaysNull - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } - - [Fact] - public void NullMetadataException() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); - var propertyInfo = GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); - var converters = new List { new Int32Converter(), new GuidConverter() }; - string commandName = null; - var expectedExceptionMessage = nameof(commandName); - - // Act - var actualException = - Assert.Throws( - // ReSharper disable once ExpressionIsAlwaysNull - () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + [Fact] + public void WrongCustomConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => WrongCustomConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserSpecifiedConverterNotValid(propertyName, commandName, typeof(int), typeof(Guid)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void OriginalListTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalListProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomListConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomListConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void OriginalDictionaryTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalDictionaryProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter(), new GuidConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomDictionaryConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter(), new GuidConverter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomValueOnlyDictionaryConverterTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomValueOnlyDictionaryConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter(), new Int32Converter() }; + + // Act + var actual = propertyInfo.ExtractConverter(converters, propertyName, commandName); + + // Assert + Assert.NotNull(actual); + Assert.IsType(actual); + } + + [Fact] + public void CustomDictionaryConverterWithListException() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomDictionaryConverterWithListProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new StringConverter(), new GuidConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractConverterKeyValueConverterIsForIDictionaryProperty(propertyName, "MyCommand"); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void CustomDictionaryWithWrongKeyConverterException() + { + // Arrange + var propertyName = + TypeHelpers.ExtractPropertyName(() => CustomDictionaryWithWrongKeyConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter(), new GuidConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractKeyConverterIsNotValid(propertyName, commandName, typeof(string), typeof(int)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void CustomDictionaryWithWrongValueConverterException() + { + // Arrange + var propertyName = + TypeHelpers.ExtractPropertyName(() => CustomDictionaryWithWrongValueConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter(), new GuidConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserExtractValueConverterIsNotValid(propertyName, commandName, typeof(string), typeof(Guid)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void OriginalDictionaryWithoutKeyConverterException() + { + // Arrange + var propertyName = + TypeHelpers.ExtractPropertyName(() => OriginalDictionaryWithWrongKeyConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter(), new GuidConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoKeyConverterFound(propertyName, commandName, typeof(string)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void OriginalDictionaryWithoutValueConverterException() + { + // Arrange + var propertyName = + TypeHelpers.ExtractPropertyName(() => OriginalDictionaryWithWrongValueConverterProperty); + var propertyInfo = GetType().GetProperty(propertyName); + var commandName = "MyCommand"; + var converters = new List { new Int32Converter(), new GuidConverter() }; + var expectedExceptionMessage = Constants.ExceptionMessages.ParserNoValueConverterFound(propertyName, commandName, typeof(string)); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.Message); + } + + [Fact] + public void NullPropertyInfoException() + { + // Arrange + PropertyInfo propertyInfo = null; + var converters = new List { new Int32Converter(), new GuidConverter() }; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, null, null)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); + } + + [Fact] + public void NullOptionNameException() + { + // Arrange + var propertyInfo = GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); + var converters = new List { new Int32Converter(), new GuidConverter() }; + string optionName = null; + string commandName = null; + var expectedExceptionMessage = nameof(optionName); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, optionName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); + } + + [Fact] + public void NullMetadataException() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); + var propertyInfo = GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); + var converters = new List { new Int32Converter(), new GuidConverter() }; + string commandName = null; + var expectedExceptionMessage = nameof(commandName); + + // Act + var actualException = + Assert.Throws( + () => propertyInfo.ExtractConverter(converters, propertyName, commandName)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractDefaultValue.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractDefaultValue.cs index 35cc63e..ef8d1d8 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractDefaultValue.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractDefaultValue.cs @@ -5,108 +5,102 @@ using System.Reflection; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class ExtractDefaultValue { - public class ExtractDefaultValue + private const string GuidValue = "0DCC5598-E071-47ED-9BC1-5E4C3E923A49"; + public int OriginalProperty { get; set; } + + [Display(Name = "CustomName")] + [DefaultValue(42)] + public int CustomIntProperty { get; set; } + + [DefaultValue("Test")] + public string CustomStringProperty { get; set; } + + [DefaultValue(GuidValue)] + public Guid CustomGuidProperty { get; set; } + + [DefaultValue("Test|Test2")] + public List CustomStringListProperty { get; set; } + + [Fact] + public void OriginalTest() + { + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); + + // Act + var actual = propertyInfo.ExtractDefaultValue(_ => _); + + // Assert + Assert.Null(actual); + } + + [Fact] + public void CustomIntTypeTest() + { + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomIntProperty)); + var expected = 42; + + // Act + var actual = propertyInfo.ExtractDefaultValue(_ => _); + + // Assert + Assert.IsType(actual); + Assert.Equal(expected, actual); + } + + [Fact] + public void CustomStringTypeTest() + { + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomStringProperty)); + var expected = "Test"; + + // Act + var actual = propertyInfo.ExtractDefaultValue(_ => _); + + // Assert + Assert.IsType(actual); + Assert.Equal(expected, actual); + } + + [Fact] + public void CustomGuidTypeTest() { - private const string GuidValue = "0DCC5598-E071-47ED-9BC1-5E4C3E923A49"; - public int OriginalProperty { get; set; } - - [Display(Name = "CustomName")] - [DefaultValue(42)] - public int CustomIntProperty { get; set; } - - [DefaultValue("Test")] - public string CustomStringProperty { get; set; } - - [DefaultValue(GuidValue)] - public Guid CustomGuidProperty { get; set; } - - [DefaultValue("Test|Test2")] - public List CustomStringListProperty { get; set; } - - [Fact] - public void OriginalTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => OriginalProperty)); - - // Act - // ReSharper disable once AssignNullToNotNullAttribute - var actual = propertyInfo.ExtractDefaultValue(_ => _); - - // Assert - Assert.Null(actual); - } - - [Fact] - public void CustomIntTypeTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomIntProperty)); - var expected = 42; - - // Act - // ReSharper disable once AssignNullToNotNullAttribute - var actual = propertyInfo.ExtractDefaultValue(_ => _); - - // Assert - Assert.IsType(actual); - Assert.Equal(expected, actual); - } - - [Fact] - public void CustomStringTypeTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomStringProperty)); - var expected = "Test"; - - // Act - // ReSharper disable once AssignNullToNotNullAttribute - var actual = propertyInfo.ExtractDefaultValue(_ => _); - - // Assert - Assert.IsType(actual); - Assert.Equal(expected, actual); - } - - [Fact] - public void CustomGuidTypeTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomGuidProperty)); - var expected = new Guid(GuidValue); - - // Act - // ReSharper disable once AssignNullToNotNullAttribute - var actual = propertyInfo.ExtractDefaultValue(value => Guid.Parse(value.ToString())); - - // Assert - Assert.IsType(actual); - Assert.Equal(expected, actual); - } - - [Fact] - public void CustomStringListTest() - { - // Arrange - var expectedName = TypeHelpers.ExtractPropertyName(() => CustomStringListProperty); - var propertyInfo = GetType().GetProperty(expectedName); - - // Act - // ReSharper disable once AssignNullToNotNullAttribute - var actual = propertyInfo.ExtractDefaultValue(_ => _); - - // Assert - Assert.Null(actual); - } + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomGuidProperty)); + var expected = new Guid(GuidValue); + + // Act + var actual = propertyInfo.ExtractDefaultValue(value => Guid.Parse(value.ToString())); + + // Assert + Assert.IsType(actual); + Assert.Equal(expected, actual); + } + + [Fact] + public void CustomStringListTest() + { + // Arrange + var expectedName = TypeHelpers.ExtractPropertyName(() => CustomStringListProperty); + var propertyInfo = GetType().GetProperty(expectedName); + + // Act + var actual = propertyInfo.ExtractDefaultValue(_ => _); + + // Assert + Assert.Null(actual); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractIsRequiredMetadata.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractIsRequiredMetadata.cs index dfe802b..c3de97a 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractIsRequiredMetadata.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractIsRequiredMetadata.cs @@ -3,60 +3,58 @@ using System.Reflection; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class ExtractIsRequiredMetadata { - public class ExtractIsRequiredMetadata + public int WritableProperty { get; set; } + + [Required] + public int WritableIgnoredProperty { get; set; } + + [Fact] + public void WritableTest() + { + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); + + // Act + var actual = propertyInfo.ExtractIsRequiredMetadata(); + + // Assert + Assert.False(actual); + } + + [Fact] + public void NonWritableTest() { - public int WritableProperty { get; set; } - - [Required] - public int WritableIgnoredProperty { get; set; } - - [Fact] - public void WritableTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); - - // Act - var actual = propertyInfo.ExtractIsRequiredMetadata(); - - // Assert - Assert.False(actual); - } - - [Fact] - public void NonWritableTest() - { - // Arrange - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableIgnoredProperty)); - - // Act - var actual = propertyInfo.ExtractIsRequiredMetadata(); - - // Assert - Assert.True(actual); - } - - [Fact] - public void NullPropertyInfoException() - { - // Arrange - PropertyInfo propertyInfo = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => propertyInfo.ExtractIsRequiredMetadata()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableIgnoredProperty)); + + // Act + var actual = propertyInfo.ExtractIsRequiredMetadata(); + + // Assert + Assert.True(actual); + } + + [Fact] + public void NullPropertyInfoException() + { + // Arrange + PropertyInfo propertyInfo = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws(() => propertyInfo.ExtractIsRequiredMetadata()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractOptionDisplayInfoMetadata.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractOptionDisplayInfoMetadata.cs index e8d8e7b..6f29509 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractOptionDisplayInfoMetadata.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ExtractOptionDisplayInfoMetadata.cs @@ -5,132 +5,130 @@ using MGR.CommandLineParser.Extensibility.ClassBased; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class ExtractOptionDisplayInfoMetadata { - public class ExtractOptionDisplayInfoMetadata + public int OriginalProperty { get; set; } + + [Display(Name = "CustomName")] + public int CustomNameProperty { get; set; } + + [Display(ShortName = "csnp")] + public int CustomShortNameProperty { get; set; } + + [Display(Name = "CustomName", ShortName = "csnp")] + public int CustomNameAndShortNameProperty { get; set; } + + [Display(Name = "CustomName", ShortName = "csnp", Description = "My custom description")] + public int CustomNameAndShortNameDescriptionProperty { get; set; } + + [Fact] + public void OriginalTest() + { + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); + var expected = "original-property"; + var propertyInfo = GetType().GetProperty(propertyName); + + // Act + var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); + + // Assert + Assert.Equal(expected, actual.Name); + Assert.Equal(string.Empty, actual.ShortName); + Assert.True(string.IsNullOrEmpty(actual.Description)); + } + + [Fact] + public void CustomNameTest() + { + // Arrange + var expectedName = "CustomName"; + var expectedShortName = expectedName; + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameProperty)); + + // Act + var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); + + // Assert + Assert.Equal(expectedName, actual.Name); + Assert.Equal(expectedShortName, actual.ShortName); + Assert.True(string.IsNullOrEmpty(actual.Description)); + } + + [Fact] + public void CustomShortNameTest() { - public int OriginalProperty { get; set; } - - [Display(Name = "CustomName")] - public int CustomNameProperty { get; set; } - - [Display(ShortName = "csnp")] - public int CustomShortNameProperty { get; set; } - - [Display(Name = "CustomName", ShortName = "csnp")] - public int CustomNameAndShortNameProperty { get; set; } - - [Display(Name = "CustomName", ShortName = "csnp", Description = "My custom description")] - public int CustomNameAndShortNameDescriptionProperty { get; set; } - - [Fact] - public void OriginalTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => OriginalProperty); - var expected = "original-property"; - var propertyInfo = GetType().GetProperty(propertyName); - - // Act - var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); - - // Assert - Assert.Equal(expected, actual.Name); - Assert.Equal(string.Empty, actual.ShortName); - Assert.True(string.IsNullOrEmpty(actual.Description)); - } - - [Fact] - public void CustomNameTest() - { - // Arrange - var expectedName = "CustomName"; - var expectedShortName = expectedName; - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameProperty)); - - // Act - var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); - - // Assert - Assert.Equal(expectedName, actual.Name); - Assert.Equal(expectedShortName, actual.ShortName); - Assert.True(string.IsNullOrEmpty(actual.Description)); - } - - [Fact] - public void CustomShortNameTest() - { - // Arrange - var propertyName = TypeHelpers.ExtractPropertyName(() => CustomShortNameProperty); - var expectedName = "custom-short-name-property"; - var expectedShortName = "csnp"; - var propertyInfo = GetType().GetProperty(propertyName); - - // Act - var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); - - // Assert - Assert.Equal(expectedName, actual.Name); - Assert.Equal(expectedShortName, actual.ShortName); - Assert.True(string.IsNullOrEmpty(actual.Description)); - } - - [Fact] - public void CustomNameAndShortNameTest() - { - // Arrange - var expectedName = "CustomName"; - var expectedShortName = "csnp"; - var propertyInfo = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameAndShortNameProperty)); - - // Act - var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); - - // Assert - Assert.Equal(expectedName, actual.Name); - Assert.Equal(expectedShortName, actual.ShortName); - Assert.True(string.IsNullOrEmpty(actual.Description)); - } - - [Fact] - public void CustomNameShortNameAndDescriptionTest() - { - // Arrange - var expectedName = "CustomName"; - var expectedShortName = "csnp"; - var expectedDescription = "My custom description"; - var propertyInfo = - GetType() - .GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameAndShortNameDescriptionProperty)); - - // Act - var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); - - // Assert - Assert.Equal(expectedName, actual.Name); - Assert.Equal(expectedShortName, actual.ShortName); - Assert.Equal(expectedDescription, actual.Description); - } - - [Fact] - public void NullPropertyInfoException() - { - // Arrange - PropertyInfo propertyInfo = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => propertyInfo.ExtractOptionDisplayInfoMetadata(new List())); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var propertyName = TypeHelpers.ExtractPropertyName(() => CustomShortNameProperty); + var expectedName = "custom-short-name-property"; + var expectedShortName = "csnp"; + var propertyInfo = GetType().GetProperty(propertyName); + + // Act + var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); + + // Assert + Assert.Equal(expectedName, actual.Name); + Assert.Equal(expectedShortName, actual.ShortName); + Assert.True(string.IsNullOrEmpty(actual.Description)); + } + + [Fact] + public void CustomNameAndShortNameTest() + { + // Arrange + var expectedName = "CustomName"; + var expectedShortName = "csnp"; + var propertyInfo = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameAndShortNameProperty)); + + // Act + var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); + + // Assert + Assert.Equal(expectedName, actual.Name); + Assert.Equal(expectedShortName, actual.ShortName); + Assert.True(string.IsNullOrEmpty(actual.Description)); + } + + [Fact] + public void CustomNameShortNameAndDescriptionTest() + { + // Arrange + var expectedName = "CustomName"; + var expectedShortName = "csnp"; + var expectedDescription = "My custom description"; + var propertyInfo = + GetType() + .GetProperty(TypeHelpers.ExtractPropertyName(() => CustomNameAndShortNameDescriptionProperty)); + + // Act + var actual = propertyInfo.ExtractOptionDisplayInfoMetadata(new List()); + + // Assert + Assert.Equal(expectedName, actual.Name); + Assert.Equal(expectedShortName, actual.ShortName); + Assert.Equal(expectedDescription, actual.Description); + } + + [Fact] + public void NullPropertyInfoException() + { + // Arrange + PropertyInfo propertyInfo = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws(() => propertyInfo.ExtractOptionDisplayInfoMetadata(new List())); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.IsValidOptionProperty.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.IsValidOptionProperty.cs index 019de7e..2afd812 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.IsValidOptionProperty.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.IsValidOptionProperty.cs @@ -3,77 +3,75 @@ using System.Reflection; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class IsValidOptionProperty { - public class IsValidOptionProperty + public int WritableProperty { get; set; } + + public int NonWritableProperty => 0; + + public List NonWritableMultiValueProperty => new List(); + + [Fact] + public void WritableTest() { - public int WritableProperty { get; set; } - - public int NonWritableProperty => 0; - - public List NonWritableMultiValueProperty => new List(); - - [Fact] - public void WritableTest() - { - // Arrange - var propertyToTest = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); - var expected = true; - - // Act - var actual = propertyToTest.IsValidOptionProperty(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NonWritableTest() - { - // Arrange - var propertyToTest = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => NonWritableProperty)); - var expected = false; - - // Act - var actual = propertyToTest.IsValidOptionProperty(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NonWritableMultiValueTest() - { - // Arrange - var propertyToTest = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => NonWritableMultiValueProperty)); - var expected = true; - - // Act - var actual = propertyToTest.IsValidOptionProperty(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullPropertyInfoException() - { - // Arrange - PropertyInfo testedProperty = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedProperty.IsValidOptionProperty()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var propertyToTest = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); + var expected = true; + + // Act + var actual = propertyToTest.IsValidOptionProperty(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NonWritableTest() + { + // Arrange + var propertyToTest = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => NonWritableProperty)); + var expected = false; + + // Act + var actual = propertyToTest.IsValidOptionProperty(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NonWritableMultiValueTest() + { + // Arrange + var propertyToTest = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => NonWritableMultiValueProperty)); + var expected = true; + + // Act + var actual = propertyToTest.IsValidOptionProperty(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullPropertyInfoException() + { + // Arrange + PropertyInfo testedProperty = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedProperty.IsValidOptionProperty()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ShouldBeIgnored.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ShouldBeIgnored.cs index da7739f..3c1e478 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ShouldBeIgnored.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.ShouldBeIgnored.cs @@ -3,61 +3,59 @@ using MGR.CommandLineParser.Command; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests + public class ShouldBeIgnored { - public class ShouldBeIgnored + public int WritableProperty { get; set; } + + [IgnoreOptionProperty] + public int WritableIgnoredProperty { get; set; } + + [Fact] + public void WritableTest() + { + // Arrange + var propertyToTest = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); + var expected = false; + + // Act + var actual = propertyToTest.ShouldBeIgnored(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NonWritableTest() { - public int WritableProperty { get; set; } - - [IgnoreOptionProperty] - public int WritableIgnoredProperty { get; set; } - - [Fact] - public void WritableTest() - { - // Arrange - var propertyToTest = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableProperty)); - var expected = false; - - // Act - var actual = propertyToTest.ShouldBeIgnored(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NonWritableTest() - { - // Arrange - var propertyToTest = - GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableIgnoredProperty)); - var expected = true; - - // Act - var actual = propertyToTest.ShouldBeIgnored(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullPropertyInfoException() - { - // Arrange - PropertyInfo testedProperty = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedProperty.ShouldBeIgnored()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var propertyToTest = + GetType().GetProperty(TypeHelpers.ExtractPropertyName(() => WritableIgnoredProperty)); + var expected = true; + + // Act + var actual = propertyToTest.ShouldBeIgnored(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullPropertyInfoException() + { + // Arrange + PropertyInfo testedProperty = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedProperty.ShouldBeIgnored()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.cs index 76159a9..e7f6798 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/PropertyInfoExtensionsTests.cs @@ -1,7 +1,6 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class PropertyInfoExtensionsTests { - public partial class PropertyInfoExtensionsTests - { - private static readonly string SourceParameterName = "source"; - } + private static readonly string SourceParameterName = "source"; } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.AsKebabCase.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.AsKebabCase.cs index 6f07310..125bb34 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.AsKebabCase.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.AsKebabCase.cs @@ -1,29 +1,28 @@ using System; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class StringExtensionsTests { - public partial class StringExtensionsTests + public class AsKebabCase { - public class AsKebabCase + [Theory] + [InlineData("", "")] + [InlineData("Word", "word")] + [InlineData("SingleWord", "single-word")] + [InlineData("KC", "kc")] + [InlineData("MSBuild", "msbuild")] + [InlineData("RunMSBuild", "run-msbuild")] + public void AsKebabCaseReturnsTheRightValue(string source, string expected) { - [Theory] - [InlineData("", "")] - [InlineData("Word", "word")] - [InlineData("SingleWord", "single-word")] - [InlineData("KC", "kc")] - [InlineData("MSBuild", "msbuild")] - [InlineData("RunMSBuild", "run-msbuild")] - public void AsKebabCaseReturnsTheRightValue(string source, string expected) - { - // Arrange + // Arrange - // Act - var actual = source.AsKebabCase(); + // Act + var actual = source.AsKebabCase(); - // Assert - Assert.Equal(expected, actual); - } + // Assert + Assert.Equal(expected, actual); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.cs index 10e1d0d..edf7c90 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/StringExtensionsTests.cs @@ -1,6 +1,5 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class StringExtensionsTests { - public partial class StringExtensionsTests - { - } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetCollectionType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetCollectionType.cs index abb6b81..70dbc25 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetCollectionType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetCollectionType.cs @@ -2,98 +2,94 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class GetCollectionType { - public class GetCollectionType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + var expected = typeof (ICollection); + + // Act + var actual = testedType.GetCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ICollectionIntTest() + { + // Arrange + var testedType = typeof (ICollection); + var expected = typeof (ICollection); + + // Act + var actual = testedType.GetCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() + { + // Arrange + var testedType = typeof (Tuple); + Type expected = null; + + // Act + var actual = testedType.GetCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (ICollection>); + + // Act + var actual = testedType.GetCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringInt() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - var expected = typeof (ICollection); - - // Act - var actual = testedType.GetCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void ICollectionIntTest() - { - // Arrange - var testedType = typeof (ICollection); - var expected = typeof (ICollection); - - // Act - var actual = testedType.GetCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - Type expected = null; - - // Act - var actual = testedType.GetCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (ICollection>); - - // Act - var actual = testedType.GetCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringInt() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = typeof (ICollection>); - - // Act - var actual = testedType.GetCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.GetCollectionType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (IDictionary); + var expected = typeof (ICollection>); + + // Act + var actual = testedType.GetCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.GetCollectionType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetDictionaryType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetDictionaryType.cs index 157a9d2..8b18c70 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetDictionaryType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetDictionaryType.cs @@ -2,98 +2,94 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class GetDictionaryType { - public class GetDictionaryType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + Type expected = null; + + // Act + var actual = testedType.GetDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ICollectionIntTest() + { + // Arrange + var testedType = typeof (ICollection); + Type expected = null; + + // Act + var actual = testedType.GetDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() + { + // Arrange + var testedType = typeof (Tuple); + Type expected = null; + + // Act + var actual = testedType.GetDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (IDictionary); + + // Act + var actual = testedType.GetDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringInt() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - Type expected = null; - - // Act - var actual = testedType.GetDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void ICollectionIntTest() - { - // Arrange - var testedType = typeof (ICollection); - Type expected = null; - - // Act - var actual = testedType.GetDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - Type expected = null; - - // Act - var actual = testedType.GetDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (IDictionary); - - // Act - var actual = testedType.GetDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringInt() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = typeof (IDictionary); - - // Act - var actual = testedType.GetDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.GetDictionaryType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (IDictionary); + var expected = typeof (IDictionary); + + // Act + var actual = testedType.GetDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.GetDictionaryType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingCollectionType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingCollectionType.cs index e26f05f..6d0fb05 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingCollectionType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingCollectionType.cs @@ -2,84 +2,81 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class GetUnderlyingCollectionType { - public class GetUnderlyingCollectionType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + var expected = typeof (int); + + // Act + var actual = testedType.GetUnderlyingCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ICollectionIntTest() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - var expected = typeof (int); - - // Act - var actual = testedType.GetUnderlyingCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void ICollectionIntTest() - { - // Arrange - var testedType = typeof (ICollection); - var expected = typeof (int); - - // Act - var actual = testedType.GetUnderlyingCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - Type expected = null; - - // Act - var actual = testedType.GetUnderlyingCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (KeyValuePair); - - // Act - var actual = testedType.GetUnderlyingCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => testedType.GetUnderlyingCollectionType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (ICollection); + var expected = typeof (int); + + // Act + var actual = testedType.GetUnderlyingCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() + { + // Arrange + var testedType = typeof (Tuple); + Type expected = null; + + // Act + var actual = testedType.GetUnderlyingCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (KeyValuePair); + + // Act + var actual = testedType.GetUnderlyingCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws(() => testedType.GetUnderlyingCollectionType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingDictionaryType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingDictionaryType.cs index 435d71f..9ba4782 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingDictionaryType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingDictionaryType.cs @@ -2,113 +2,109 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class GetUnderlyingDictionaryType { - public class GetUnderlyingDictionaryType + [Fact] + public void DictionaryStringIntKeyTest() { - [Fact] - public void DictionaryStringIntKeyTest() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (string); - - // Act - var actual = testedType.GetUnderlyingDictionaryType(true); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringIntKeyTest() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = typeof (string); - - // Act - var actual = testedType.GetUnderlyingDictionaryType(true); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringIntValueTest() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (int); - - // Act - var actual = testedType.GetUnderlyingDictionaryType(false); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringIntValueTest() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = typeof (int); - - // Act - var actual = testedType.GetUnderlyingDictionaryType(false); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleIntKeyTest() - { - // Arrange - var testedType = typeof (Tuple); - Type expected = null; - - // Act - var actual = testedType.GetUnderlyingDictionaryType(true); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleIntValueTest() - { - // Arrange - var testedType = typeof (Tuple); - Type expected = null; - - // Act - var actual = testedType.GetUnderlyingDictionaryType(false); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - var actualException = - // ReSharper disable once ExpressionIsAlwaysNull - Assert.Throws(() => testedType.GetUnderlyingDictionaryType(true)); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (string); + + // Act + var actual = testedType.GetUnderlyingDictionaryType(true); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringIntKeyTest() + { + // Arrange + var testedType = typeof (IDictionary); + var expected = typeof (string); + + // Act + var actual = testedType.GetUnderlyingDictionaryType(true); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringIntValueTest() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (int); + + // Act + var actual = testedType.GetUnderlyingDictionaryType(false); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringIntValueTest() + { + // Arrange + var testedType = typeof (IDictionary); + var expected = typeof (int); + + // Act + var actual = testedType.GetUnderlyingDictionaryType(false); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleIntKeyTest() + { + // Arrange + var testedType = typeof (Tuple); + Type expected = null; + + // Act + var actual = testedType.GetUnderlyingDictionaryType(true); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleIntValueTest() + { + // Arrange + var testedType = typeof (Tuple); + Type expected = null; + + // Act + var actual = testedType.GetUnderlyingDictionaryType(false); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = + Assert.Throws(() => testedType.GetUnderlyingDictionaryType(true)); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingGenericType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingGenericType.cs index 1276a18..9b2cff4 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingGenericType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.GetUnderlyingGenericType.cs @@ -2,82 +2,80 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class GetUnderlyingGenericType { - public class GetUnderlyingGenericType + [Fact] + public void TestNonGenericType() + { + // Arrange + var testedType = typeof (int); + + // Act + var actualType = testedType.GetUnderlyingGenericType(); + + // Assert + Assert.Null(actualType); + } + + [Fact] + public void TestGenericListType() { - [Fact] - public void TestNonGenericType() - { - // Arrange - var testedType = typeof (int); - - // Act - var actualType = testedType.GetUnderlyingGenericType(); - - // Assert - Assert.Null(actualType); - } - - [Fact] - public void TestGenericListType() - { - // Arrange - var testedType = typeof (List); - var expected = typeof (int); - - // Act - var actual = testedType.GetUnderlyingGenericType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestFirstDictionaryType() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (string); - - // Act - var actual = testedType.GetUnderlyingGenericType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TestSecondDictionaryType() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = typeof (int); - var index = 1; - - // Act - var actual = testedType.GetUnderlyingGenericType(index); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.GetUnderlyingGenericType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (List); + var expected = typeof (int); + + // Act + var actual = testedType.GetUnderlyingGenericType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestFirstDictionaryType() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (string); + + // Act + var actual = testedType.GetUnderlyingGenericType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TestSecondDictionaryType() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = typeof (int); + var index = 1; + + // Act + var actual = testedType.GetUnderlyingGenericType(index); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.GetUnderlyingGenericType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsCollectionType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsCollectionType.cs index d8e42c4..6eaebcf 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsCollectionType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsCollectionType.cs @@ -2,83 +2,80 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class IsCollectionType { - public class IsCollectionType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + var expected = true; + + // Act + var actual = testedType.IsCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ICollectionIntTest() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - var expected = true; - - // Act - var actual = testedType.IsCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void ICollectionIntTest() - { - // Arrange - var testedType = typeof (ICollection); - var expected = true; - - // Act - var actual = testedType.IsCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - var expected = false; - - // Act - var actual = testedType.IsCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = false; - - // Act - var actual = testedType.IsCollectionType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.IsCollectionType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (ICollection); + var expected = true; + + // Act + var actual = testedType.IsCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() + { + // Arrange + var testedType = typeof (Tuple); + var expected = false; + + // Act + var actual = testedType.IsCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = false; + + // Act + var actual = testedType.IsCollectionType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.IsCollectionType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsDictionaryType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsDictionaryType.cs index a338efb..c57f241 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsDictionaryType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsDictionaryType.cs @@ -2,98 +2,94 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class IsDictionaryType { - public class IsDictionaryType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + var expected = false; + + // Act + var actual = testedType.IsDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void ICollectionIntTest() + { + // Arrange + var testedType = typeof (ICollection); + var expected = false; + + // Act + var actual = testedType.IsDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() + { + // Arrange + var testedType = typeof (Tuple); + var expected = false; + + // Act + var actual = testedType.IsDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = true; + + // Act + var actual = testedType.IsDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringInt() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - var expected = false; - - // Act - var actual = testedType.IsDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void ICollectionIntTest() - { - // Arrange - var testedType = typeof (ICollection); - var expected = false; - - // Act - var actual = testedType.IsDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - var expected = false; - - // Act - var actual = testedType.IsDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = true; - - // Act - var actual = testedType.IsDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringInt() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = true; - - // Act - var actual = testedType.IsDictionaryType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.IsDictionaryType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (IDictionary); + var expected = true; + + // Act + var actual = testedType.IsDictionaryType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.IsDictionaryType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsMultiValuedType.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsMultiValuedType.cs index 56456d1..9653f4e 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsMultiValuedType.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.IsMultiValuedType.cs @@ -2,83 +2,80 @@ using System.Collections.Generic; using Xunit; -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests + public class IsMultiValuedType { - public class IsMultiValuedType + [Fact] + public void ListIntTest() + { + // Arrange + var testedType = typeof (List); + var expected = true; + + // Act + var actual = testedType.IsMultiValuedType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void TupleInt() { - [Fact] - public void ListIntTest() - { - // Arrange - var testedType = typeof (List); - var expected = true; - - // Act - var actual = testedType.IsMultiValuedType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void TupleInt() - { - // Arrange - var testedType = typeof (Tuple); - var expected = false; - - // Act - var actual = testedType.IsMultiValuedType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void DictionaryStringInt() - { - // Arrange - var testedType = typeof (Dictionary); - var expected = true; - - // Act - var actual = testedType.IsMultiValuedType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - // ReSharper disable once InconsistentNaming - public void IDictionaryStringInt() - { - // Arrange - var testedType = typeof (IDictionary); - var expected = true; - - // Act - var actual = testedType.IsMultiValuedType(); - - // Assert - Assert.Equal(expected, actual); - } - - [Fact] - public void NullTypeException() - { - // Arrange - Type testedType = null; - var expectedExceptionMessage = SourceParameterName; - - // Act - // ReSharper disable once ExpressionIsAlwaysNull - var actualException = Assert.Throws(() => testedType.IsMultiValuedType()); - - // Assert - Assert.Equal(expectedExceptionMessage, actualException.ParamName); - } + // Arrange + var testedType = typeof (Tuple); + var expected = false; + + // Act + var actual = testedType.IsMultiValuedType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void DictionaryStringInt() + { + // Arrange + var testedType = typeof (Dictionary); + var expected = true; + + // Act + var actual = testedType.IsMultiValuedType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void IDictionaryStringInt() + { + // Arrange + var testedType = typeof (IDictionary); + var expected = true; + + // Act + var actual = testedType.IsMultiValuedType(); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public void NullTypeException() + { + // Arrange + Type testedType = null; + var expectedExceptionMessage = SourceParameterName; + + // Act + var actualException = Assert.Throws(() => testedType.IsMultiValuedType()); + + // Assert + Assert.Equal(expectedExceptionMessage, actualException.ParamName); } } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.cs b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.cs index a21cdc7..db60401 100644 --- a/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.cs +++ b/tests/MGR.CommandLineParser.UnitTests/Extensions/TypeExtensionsTests.cs @@ -1,7 +1,6 @@ -namespace MGR.CommandLineParser.UnitTests.Extensions +namespace MGR.CommandLineParser.UnitTests.Extensions; + +public partial class TypeExtensionsTests { - public partial class TypeExtensionsTests - { - private static readonly string SourceParameterName = "source"; - } + private static readonly string SourceParameterName = "source"; } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/FakeConsole.cs b/tests/MGR.CommandLineParser.UnitTests/FakeConsole.cs index b81fbe9..6b961e6 100644 --- a/tests/MGR.CommandLineParser.UnitTests/FakeConsole.cs +++ b/tests/MGR.CommandLineParser.UnitTests/FakeConsole.cs @@ -3,103 +3,102 @@ using System.Text; using MGR.CommandLineParser.Extensibility; -namespace MGR.CommandLineParser.UnitTests +namespace MGR.CommandLineParser.UnitTests; + +public class FakeConsole : IConsole { - public class FakeConsole : IConsole + private readonly List _messages = new List(); + private Message _currentMessage; + public abstract class Message :IEquatable { - private readonly List _messages = new List(); - private Message _currentMessage; - public abstract class Message :IEquatable + private readonly StringBuilder _sb = new StringBuilder(); + + internal void Add(string value) { - private readonly StringBuilder _sb = new StringBuilder(); + _sb.Append(value); + } - internal void Add(string value) + public override string ToString() => _sb.ToString(); + + public bool Equals(Message other) + { + if (ReferenceEquals(null, other)) { - _sb.Append(value); + return false; } - public override string ToString() => _sb.ToString(); - - public bool Equals(Message other) + if (ReferenceEquals(this, other)) { - if (ReferenceEquals(null, other)) - { - return false; - } + return true; + } - if (ReferenceEquals(this, other)) - { - return true; - } + return GetType() == other.GetType() && Equals(_sb, other._sb); + } - return GetType() == other.GetType() && Equals(_sb, other._sb); + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; } - public override bool Equals(object obj) + if (ReferenceEquals(this, obj)) { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((Message) obj); + return true; } - public override int GetHashCode() => (_sb != null ? _sb.GetHashCode() : 0); - } - public class ErrorMessage : Message - { + if (obj.GetType() != GetType()) + { + return false; + } + return Equals((Message) obj); } - public class InformationMessage : Message - { - } - public class WarningMessage : Message - { + public override int GetHashCode() => (_sb != null ? _sb.GetHashCode() : 0); + } + public class ErrorMessage : Message + { - } - - public void Write(string format, params object[] args) + } + public class InformationMessage : Message + { + + } + public class WarningMessage : Message + { + + } + + public void Write(string format, params object[] args) + { + if (!(_currentMessage is InformationMessage)) { - if (!(_currentMessage is InformationMessage)) - { - _currentMessage = new InformationMessage(); - _messages.Add(_currentMessage); - } - _currentMessage.Add(string.Format(format, args)); + _currentMessage = new InformationMessage(); + _messages.Add(_currentMessage); } + _currentMessage.Add(string.Format(format, args)); + } - public void WriteError(string format, params object[] args) + public void WriteError(string format, params object[] args) + { + if (!(_currentMessage is ErrorMessage)) { - if (!(_currentMessage is ErrorMessage)) - { - _currentMessage = new ErrorMessage(); - _messages.Add(_currentMessage); - } - _currentMessage.Add(string.Format(format, args)); + _currentMessage = new ErrorMessage(); + _messages.Add(_currentMessage); } + _currentMessage.Add(string.Format(format, args)); + } - public void WriteWarning(string format, params object[] args) + public void WriteWarning(string format, params object[] args) + { + if (!(_currentMessage is WarningMessage)) { - if (!(_currentMessage is WarningMessage)) - { - _currentMessage = new WarningMessage(); - _messages.Add(_currentMessage); - } - _currentMessage.Add(string.Format(format, args)); + _currentMessage = new WarningMessage(); + _messages.Add(_currentMessage); } - - internal List Messages => _messages; + _currentMessage.Add(string.Format(format, args)); } + + internal List Messages => _messages; } diff --git a/tests/MGR.CommandLineParser.UnitTests/LangageSwitcher.cs b/tests/MGR.CommandLineParser.UnitTests/LangageSwitcher.cs index 9308489..b186370 100644 --- a/tests/MGR.CommandLineParser.UnitTests/LangageSwitcher.cs +++ b/tests/MGR.CommandLineParser.UnitTests/LangageSwitcher.cs @@ -2,47 +2,46 @@ using System.Globalization; using System.Threading; -namespace MGR.CommandLineParser.UnitTests +namespace MGR.CommandLineParser.UnitTests; + +internal sealed class LangageSwitcher : IDisposable { - internal sealed class LangageSwitcher : IDisposable + private readonly CultureInfo _previousCulture; + private readonly CultureInfo _previousUICulture; + + private LangageSwitcher() + { + _previousUICulture = Thread.CurrentThread.CurrentUICulture; + _previousCulture = Thread.CurrentThread.CurrentCulture; + } + + internal LangageSwitcher(CultureInfo culture, CultureInfo uiCulture) + : this() + { + Thread.CurrentThread.CurrentUICulture = culture; + Thread.CurrentThread.CurrentCulture = uiCulture; + } + + internal LangageSwitcher(string culture, string uiCulture) + : this(new CultureInfo(culture), new CultureInfo(uiCulture)) + { + } + + internal LangageSwitcher(CultureInfo culture) + : this() + { + Thread.CurrentThread.CurrentUICulture = culture; + Thread.CurrentThread.CurrentCulture = culture; + } + + internal LangageSwitcher(string culture) + : this(new CultureInfo(culture)) + { + } + + public void Dispose() { - private readonly CultureInfo _previousCulture; - private readonly CultureInfo _previousUICulture; - - private LangageSwitcher() - { - _previousUICulture = Thread.CurrentThread.CurrentUICulture; - _previousCulture = Thread.CurrentThread.CurrentCulture; - } - - internal LangageSwitcher(CultureInfo culture, CultureInfo uiCulture) - : this() - { - Thread.CurrentThread.CurrentUICulture = culture; - Thread.CurrentThread.CurrentCulture = uiCulture; - } - - internal LangageSwitcher(string culture, string uiCulture) - : this(new CultureInfo(culture), new CultureInfo(uiCulture)) - { - } - - internal LangageSwitcher(CultureInfo culture) - : this() - { - Thread.CurrentThread.CurrentUICulture = culture; - Thread.CurrentThread.CurrentCulture = culture; - } - - internal LangageSwitcher(string culture) - : this(new CultureInfo(culture)) - { - } - - public void Dispose() - { - Thread.CurrentThread.CurrentUICulture = _previousUICulture; - Thread.CurrentThread.CurrentCulture = _previousCulture; - } + Thread.CurrentThread.CurrentUICulture = _previousUICulture; + Thread.CurrentThread.CurrentCulture = _previousCulture; } } \ No newline at end of file diff --git a/tests/MGR.CommandLineParser.UnitTests/MGR.CommandLineParser.UnitTests.csproj b/tests/MGR.CommandLineParser.UnitTests/MGR.CommandLineParser.UnitTests.csproj index c530913..6cf84c5 100644 --- a/tests/MGR.CommandLineParser.UnitTests/MGR.CommandLineParser.UnitTests.csproj +++ b/tests/MGR.CommandLineParser.UnitTests/MGR.CommandLineParser.UnitTests.csproj @@ -1,25 +1,26 @@  - - - net8.0;net48 - - false - false - + + + net8.0;net48 + + false + false + latest + - - - - - - - - + + + + + + + + - - - - + + + + diff --git a/tests/MGR.CommandLineParser.UnitTests/TypeHelpers.cs b/tests/MGR.CommandLineParser.UnitTests/TypeHelpers.cs index a5b868b..d295718 100644 --- a/tests/MGR.CommandLineParser.UnitTests/TypeHelpers.cs +++ b/tests/MGR.CommandLineParser.UnitTests/TypeHelpers.cs @@ -2,35 +2,34 @@ using System.Linq.Expressions; using System.Reflection; -namespace MGR.CommandLineParser.UnitTests +namespace MGR.CommandLineParser.UnitTests; + +public static class TypeHelpers { - public static class TypeHelpers - { - public static string ExtractPropertyName(Expression> propertyExpression) - => ExtractPropertyName(propertyExpression.Body as MemberExpression); + public static string ExtractPropertyName(Expression> propertyExpression) + => ExtractPropertyName(propertyExpression.Body as MemberExpression); - public static string ExtractPropertyName(Expression> propertyExpression) - => ExtractPropertyName(propertyExpression.Body as MemberExpression); + public static string ExtractPropertyName(Expression> propertyExpression) + => ExtractPropertyName(propertyExpression.Body as MemberExpression); - public static string ExtractPropertyName(Expression> propertyExpression) - => ExtractPropertyName(propertyExpression.Body as MemberExpression); + public static string ExtractPropertyName(Expression> propertyExpression) + => ExtractPropertyName(propertyExpression.Body as MemberExpression); - private static string ExtractPropertyName(MemberExpression memberExpression) + private static string ExtractPropertyName(MemberExpression memberExpression) + { + if (memberExpression == null) + { + throw new ArgumentException(); + } + var propertyInfo = memberExpression.Member as PropertyInfo; + if (propertyInfo == null) + { + throw new ArgumentException(); + } + if (propertyInfo.GetGetMethod(true).IsStatic) { - if (memberExpression == null) - { - throw new ArgumentException(); - } - var propertyInfo = memberExpression.Member as PropertyInfo; - if (propertyInfo == null) - { - throw new ArgumentException(); - } - if (propertyInfo.GetGetMethod(true).IsStatic) - { - throw new ArgumentException(); - } - return memberExpression.Member.Name; + throw new ArgumentException(); } + return memberExpression.Member.Name; } } \ No newline at end of file