mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Cleanup
This commit is contained in:
@@ -223,56 +223,6 @@ public class NamedChildCommand : ICommand
|
||||
stdErr.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
// Regression test for #117
|
||||
[Fact]
|
||||
public async Task Help_text_lists_parameters_in_specified_order()
|
||||
{
|
||||
// Arrange
|
||||
var commandType = DynamicCommandBuilder.Compile(
|
||||
// language=cs
|
||||
@"
|
||||
public abstract class CommandBase : ICommand
|
||||
{
|
||||
[CommandParameter(0)]
|
||||
public string Foo { get; set; }
|
||||
|
||||
public abstract ValueTask ExecuteAsync(IConsole console);
|
||||
}
|
||||
|
||||
[Command]
|
||||
public class Command : CommandBase
|
||||
{
|
||||
[CommandParameter(1)]
|
||||
public string Bar { get; set; }
|
||||
|
||||
[CommandParameter(2)]
|
||||
public IReadOnlyList<string> Baz { get; set; }
|
||||
|
||||
public override ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
");
|
||||
|
||||
var application = new CliApplicationBuilder()
|
||||
.AddCommand(commandType)
|
||||
.UseConsole(FakeConsole)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
var stdOut = FakeConsole.ReadOutputString();
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
stdOut.Should().ContainAllInOrder(
|
||||
"USAGE",
|
||||
"<foo>", "<bar>", "<baz...>"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Help_text_shows_application_metadata()
|
||||
{
|
||||
@@ -421,6 +371,57 @@ public class Command : ICommand
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/Tyrrrz/CliFx/issues/117
|
||||
[Fact]
|
||||
public async Task Help_text_shows_usage_format_which_lists_all_parameters_in_specified_order()
|
||||
{
|
||||
// Arrange
|
||||
var commandType = DynamicCommandBuilder.Compile(
|
||||
// language=cs
|
||||
@"
|
||||
// Base members appear last in reflection order
|
||||
public abstract class CommandBase : ICommand
|
||||
{
|
||||
[CommandParameter(0)]
|
||||
public string Foo { get; set; }
|
||||
|
||||
public abstract ValueTask ExecuteAsync(IConsole console);
|
||||
}
|
||||
|
||||
[Command]
|
||||
public class Command : CommandBase
|
||||
{
|
||||
[CommandParameter(2)]
|
||||
public IReadOnlyList<string> Baz { get; set; }
|
||||
|
||||
[CommandParameter(1)]
|
||||
public string Bar { get; set; }
|
||||
|
||||
public override ValueTask ExecuteAsync(IConsole console) => default;
|
||||
}
|
||||
");
|
||||
|
||||
var application = new CliApplicationBuilder()
|
||||
.AddCommand(commandType)
|
||||
.UseConsole(FakeConsole)
|
||||
.Build();
|
||||
|
||||
// Act
|
||||
var exitCode = await application.RunAsync(
|
||||
new[] { "--help" },
|
||||
new Dictionary<string, string>()
|
||||
);
|
||||
|
||||
var stdOut = FakeConsole.ReadOutputString();
|
||||
|
||||
// Assert
|
||||
exitCode.Should().Be(0);
|
||||
stdOut.Should().ContainAllInOrder(
|
||||
"USAGE",
|
||||
"<foo>", "<bar>", "<baz...>"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Help_text_shows_usage_format_which_lists_all_required_options()
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ public abstract class BindingValidator<T> : IBindingValidator
|
||||
/// You can use the utility methods <see cref="Ok"/> and <see cref="Error"/> to
|
||||
/// create an appropriate result.
|
||||
/// </remarks>
|
||||
public abstract BindingValidationError? Validate(T value);
|
||||
public abstract BindingValidationError? Validate(T? value);
|
||||
|
||||
BindingValidationError? IBindingValidator.Validate(object? value) => Validate((T) value!);
|
||||
BindingValidationError? IBindingValidator.Validate(object? value) => Validate((T?) value);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ internal class HelpConsoleFormatter : ConsoleFormatter
|
||||
Write(' ');
|
||||
|
||||
// Parameters
|
||||
foreach (var parameter in _context.CommandSchema.Parameters)
|
||||
foreach (var parameter in _context.CommandSchema.Parameters.OrderBy(p => p.Order))
|
||||
{
|
||||
Write(ConsoleColor.DarkCyan, parameter.Property.IsScalar()
|
||||
? $"<{parameter.Name}>"
|
||||
|
||||
@@ -16,8 +16,8 @@ internal partial class ApplicationSchema
|
||||
|
||||
public IReadOnlyList<string> GetCommandNames() => Commands
|
||||
.Select(c => c.Name)
|
||||
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||||
.ToArray()!;
|
||||
.WhereNotNullOrWhiteSpace()
|
||||
.ToArray();
|
||||
|
||||
public CommandSchema? TryFindDefaultCommand() =>
|
||||
Commands.FirstOrDefault(c => c.IsDefault);
|
||||
|
||||
@@ -89,13 +89,12 @@ internal partial class CommandSchema
|
||||
|
||||
var parameterSchemas = type.GetProperties()
|
||||
.Select(ParameterSchema.TryResolve)
|
||||
.Where(p => p is not null)
|
||||
.OrderBy(p => p!.Order)
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
var optionSchemas = type.GetProperties()
|
||||
.Select(OptionSchema.TryResolve)
|
||||
.Where(o => o is not null)
|
||||
.WhereNotNull()
|
||||
.Concat(implicitOptionSchemas)
|
||||
.ToArray();
|
||||
|
||||
@@ -103,8 +102,8 @@ internal partial class CommandSchema
|
||||
type,
|
||||
name,
|
||||
description,
|
||||
parameterSchemas!,
|
||||
optionSchemas!
|
||||
parameterSchemas,
|
||||
optionSchemas
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,25 @@ namespace CliFx.Utils.Extensions;
|
||||
|
||||
internal static class CollectionExtensions
|
||||
{
|
||||
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> source)
|
||||
where T : class
|
||||
{
|
||||
foreach (var i in source)
|
||||
{
|
||||
if (i is not null)
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> WhereNotNullOrWhiteSpace(this IEnumerable<string?> source)
|
||||
{
|
||||
foreach (var i in source)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(i))
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveRange<T>(this ICollection<T> source, IEnumerable<T> items)
|
||||
{
|
||||
foreach (var item in items)
|
||||
@@ -17,5 +36,5 @@ internal static class CollectionExtensions
|
||||
IEqualityComparer<TKey> comparer) =>
|
||||
dictionary
|
||||
.Cast<DictionaryEntry>()
|
||||
.ToDictionary(entry => (TKey) entry.Key, entry => (TValue) entry.Value, comparer)!;
|
||||
.ToDictionary(entry => (TKey) entry.Key, entry => (TValue) entry.Value, comparer);
|
||||
}
|
||||
Reference in New Issue
Block a user