Refactor a bit

This commit is contained in:
Alexey Golub
2020-05-05 22:23:27 +03:00
parent c58629e999
commit cbb72b16ae
7 changed files with 82 additions and 23 deletions

View File

@@ -3,11 +3,16 @@ using System.IO;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
using Xunit.Abstractions;
namespace CliFx.Tests
{
public partial class ErrorReportingSpecs
{
private readonly ITestOutputHelper _output;
public ErrorReportingSpecs(ITestOutputHelper output) => _output = output;
[Fact]
public async Task Command_may_throw_a_generic_exception_which_exits_and_prints_error_message_and_stack_trace()
{
@@ -33,6 +38,8 @@ namespace CliFx.Tests
"System.Exception:",
"Kaput", "at",
"CliFx.Tests");
_output.WriteLine(stdErrData);
}
[Fact]
@@ -57,6 +64,8 @@ namespace CliFx.Tests
// Assert
exitCode.Should().Be(69);
stdErrData.Should().Be("Kaput");
_output.WriteLine(stdErrData);
}
[Fact]
@@ -81,6 +90,8 @@ namespace CliFx.Tests
// Assert
exitCode.Should().NotBe(0);
stdErrData.Should().NotBeEmpty();
_output.WriteLine(stdErrData);
}
[Fact]
@@ -114,6 +125,9 @@ namespace CliFx.Tests
"sub",
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
_output.WriteLine(stdErrData);
}
[Fact]
@@ -146,6 +160,9 @@ namespace CliFx.Tests
"sub",
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
_output.WriteLine(stdErrData);
}
[Fact]
@@ -173,6 +190,8 @@ namespace CliFx.Tests
"System.Exception:",
"Kaput", "at",
"CliFx.Tests");
_output.WriteLine(stdErrData);
}
[Fact]
@@ -200,7 +219,8 @@ namespace CliFx.Tests
exitCode.Should().NotBe(0);
stdErrData.Should().ContainAll(
"Can't find a command that matches the following arguments:",
"not-a-valid-command");
"not-a-valid-command"
);
stdOutData.Should().ContainAll(
"Usage",
"[command]",
@@ -208,7 +228,11 @@ namespace CliFx.Tests
"-h|--help", "Shows help text.",
"Commands",
"inv",
"You can run", "to show help on a specific command.");
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
_output.WriteLine(stdErrData);
}
}
}

View File

@@ -2,11 +2,16 @@
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
using Xunit.Abstractions;
namespace CliFx.Tests
{
public partial class HelpTextSpecs
{
private readonly ITestOutputHelper _output;
public HelpTextSpecs(ITestOutputHelper output) => _output = output;
[Fact]
public async Task Version_information_can_be_requested_by_providing_the_version_option_without_other_arguments()
{
@@ -29,6 +34,8 @@ namespace CliFx.Tests
// Assert
exitCode.Should().Be(0);
stdOutData.Should().Be("v6.9");
_output.WriteLine(stdOutData);
}
[Fact]
@@ -68,6 +75,8 @@ namespace CliFx.Tests
"cmd", "NamedCommand description.",
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -104,6 +113,8 @@ namespace CliFx.Tests
"sub", "SubCommand description.",
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -137,6 +148,8 @@ namespace CliFx.Tests
"-e|--option-e", "OptionE description.",
"-h|--help", "Shows help text."
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -167,6 +180,8 @@ namespace CliFx.Tests
"cmd", "NamedCommand description.",
"You can run", "to show help on a specific command."
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -190,6 +205,8 @@ namespace CliFx.Tests
"Usage",
"cmd-with-params", "<first>", "<parameterb>", "<third list...>", "[options]"
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -217,6 +234,8 @@ namespace CliFx.Tests
"* -g|--option-g",
"-h|--option-h"
);
_output.WriteLine(stdOutData);
}
[Fact]
@@ -241,6 +260,8 @@ namespace CliFx.Tests
"* -a|--option-a", "Environment variable:", "ENV_OPT_A",
"-b|--option-b", "Environment variable:", "ENV_OPT_B"
);
_output.WriteLine(stdOutData);
}
}
}

View File

@@ -51,7 +51,6 @@
<ProjectReference Include="..\CliFx.Analyzers\CliFx.Analyzers.csproj" ReferenceOutputAssembly="true" IncludeAssets="CliFx.Analyzers.dll" />
</ItemGroup>
<Target Name="CopyAnalyzerToPackage">
<ItemGroup>
<TfmSpecificPackageFile Include="$(OutDir)/CliFx.Analyzers.dll" PackagePath="analyzers/dotnet/cs" BuildAction="none" />

View File

@@ -39,10 +39,14 @@ namespace CliFx.Domain
!string.IsNullOrWhiteSpace(Name) &&
string.Equals(Name, name, StringComparison.OrdinalIgnoreCase);
public bool MatchesShortName(char shortName) =>
public bool MatchesShortName(char? shortName) =>
ShortName != null &&
ShortName == shortName;
public bool MatchesNameOrShortName(string? name, char? shortName) =>
MatchesName(name) ||
MatchesShortName(shortName);
public bool MatchesNameOrShortName(string alias) =>
MatchesName(alias) ||
alias.Length == 1 && MatchesShortName(alias.Single());

View File

@@ -40,6 +40,21 @@ namespace CliFx.Domain
public bool MatchesName(string? name) => string.Equals(name, Name, StringComparison.OrdinalIgnoreCase);
public IReadOnlyList<CommandOptionSchema> GetBuiltInOptions()
{
var result = new List<CommandOptionSchema>(2);
var helpOption = CommandOptionSchema.HelpOption;
var versionOption = CommandOptionSchema.VersionOption;
result.Add(helpOption);
if (IsDefault)
result.Add(versionOption);
return result;
}
private void InjectParameters(ICommand command, IReadOnlyList<CommandUnboundArgumentInput> parameterInputs)
{
// All inputs must be bound

View File

@@ -212,12 +212,8 @@ namespace CliFx.Domain
var options = command.Options
.OrderByDescending(o => o.IsRequired)
.ToList();
// Add built-in options
options.Add(CommandOptionSchema.HelpOption);
if (command.IsDefault)
options.Add(CommandOptionSchema.VersionOption);
.Concat(command.GetBuiltInOptions())
.ToArray();
foreach (var option in options)
{

View File

@@ -217,7 +217,7 @@ If that's not possible, consider converting the parameter into an option, to avo
{
var message = $@"
Command '{command.Type.FullName}' is invalid because it contains one or more options without a name:
{string.Join(Environment.NewLine, invalidOptions.Select(p => p.Property.Name))}
{string.Join(Environment.NewLine, invalidOptions.Select(o => o.Property.Name))}
Options must have either a name or a short name or both, because that's what identifies them.
@@ -232,7 +232,7 @@ To fix this, ensure all options have their names or short names set to some valu
{
var message = $@"
Command '{command.Type.FullName}' is invalid because it contains one or more options whose names are too short:
{string.Join(Environment.NewLine, invalidOptions.Select(p => $"{p.Property.Name} ('{p.DisplayName}')"))}
{string.Join(Environment.NewLine, invalidOptions.Select(o => $"{o.Property.Name} ('{o.DisplayName}')"))}
Option names must be at least 2 characters long to avoid confusion with short names.
If you intended to set the short name instead, use the corresponding attribute overload.
@@ -249,7 +249,7 @@ To fix this, ensure all option names are at least 2 characters long.";
{
var message = $@"
Command '{command.Type.FullName}' is invalid because it contains {invalidOptions.Count} options with the same name ('{name}'):
{string.Join(Environment.NewLine, invalidOptions.Select(p => p.Property.Name))}
{string.Join(Environment.NewLine, invalidOptions.Select(o => o.Property.Name))}
Options must have unique names, because that's what identifies them.
Names are not case-sensitive.
@@ -266,7 +266,7 @@ To fix this, ensure that all options have different names.";
{
var message = $@"
Command '{command.Type.FullName}' is invalid because it contains {invalidOptions.Count} options with the same short name ('{shortName}'):
{string.Join(Environment.NewLine, invalidOptions.Select(p => p.Property.Name))}
{string.Join(Environment.NewLine, invalidOptions.Select(o => o.Property.Name))}
Options must have unique short names, because that's what identifies them.
Short names are case-sensitive (i.e. 'a' and 'A' are different short names).
@@ -283,7 +283,7 @@ To fix this, ensure that all options have different short names.";
{
var message = $@"
Command '{command.Type.FullName}' is invalid because it contains {invalidOptions.Count} options with the same fallback environment variable name ('{environmentVariableName}'):
{string.Join(Environment.NewLine, invalidOptions.Select(p => p.Property.Name))}
{string.Join(Environment.NewLine, invalidOptions.Select(o => o.Property.Name))}
Options cannot share the same environment variable as a fallback.
Environment variable names are not case-sensitive.