mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 02:25:28 +08:00 
			
		
		
		
	Move Spectre.Console.Cli to it's own package
This commit is contained in:
		
				
					committed by
					
						
						Patrik Svensson
					
				
			
			
				
	
			
			
			
						parent
						
							b600832e00
						
					
				
				
					commit
					36ca22ffac
				
			@@ -1,18 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests;
 | 
			
		||||
 | 
			
		||||
public static class Constants
 | 
			
		||||
{
 | 
			
		||||
    public static string[] VersionCommand { get; } =
 | 
			
		||||
        new[]
 | 
			
		||||
        {
 | 
			
		||||
                CliConstants.Commands.Branch,
 | 
			
		||||
                CliConstants.Commands.Version,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    public static string[] XmlDocCommand { get; } =
 | 
			
		||||
        new[]
 | 
			
		||||
        {
 | 
			
		||||
                CliConstants.Commands.Branch,
 | 
			
		||||
                CliConstants.Commands.XmlDoc,
 | 
			
		||||
        };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
using SystemConsole = System.Console;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public abstract class AnimalCommand<TSettings> : Command<TSettings>
 | 
			
		||||
    where TSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    protected void DumpSettings(CommandContext context, TSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        if (context == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(context));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (settings == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(settings));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var properties = settings.GetType().GetProperties();
 | 
			
		||||
        foreach (var group in properties.GroupBy(x => x.DeclaringType).Reverse())
 | 
			
		||||
        {
 | 
			
		||||
            SystemConsole.WriteLine();
 | 
			
		||||
            SystemConsole.ForegroundColor = ConsoleColor.Yellow;
 | 
			
		||||
            SystemConsole.WriteLine(group.Key.FullName);
 | 
			
		||||
            SystemConsole.ResetColor();
 | 
			
		||||
 | 
			
		||||
            foreach (var property in group)
 | 
			
		||||
            {
 | 
			
		||||
                SystemConsole.WriteLine($"  {property.Name} = {property.GetValue(settings)}");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (context.Remaining.Raw.Count > 0)
 | 
			
		||||
        {
 | 
			
		||||
            SystemConsole.WriteLine();
 | 
			
		||||
            SystemConsole.ForegroundColor = ConsoleColor.Yellow;
 | 
			
		||||
            SystemConsole.WriteLine("Remaining:");
 | 
			
		||||
            SystemConsole.ResetColor();
 | 
			
		||||
            SystemConsole.WriteLine(string.Join(", ", context.Remaining));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SystemConsole.WriteLine();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class CatCommand : AnimalCommand<CatSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, CatSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        DumpSettings(context, settings);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[Description("The dog command.")]
 | 
			
		||||
public class DogCommand : AnimalCommand<DogSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override ValidationResult Validate(CommandContext context, DogSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        if (context is null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.ArgumentNullException(nameof(context));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (settings is null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new System.ArgumentNullException(nameof(settings));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (settings.Age > 100 && !context.Remaining.Raw.Contains("zombie"))
 | 
			
		||||
        {
 | 
			
		||||
            return ValidationResult.Error("Dog is too old...");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return base.Validate(context, settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override int Execute(CommandContext context, DogSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        DumpSettings(context, settings);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class DumpRemainingCommand : Command<EmptyCommandSettings>
 | 
			
		||||
{
 | 
			
		||||
    private readonly IAnsiConsole _console;
 | 
			
		||||
 | 
			
		||||
    public DumpRemainingCommand(IAnsiConsole console)
 | 
			
		||||
    {
 | 
			
		||||
        _console = console;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override int Execute([NotNull] CommandContext context, [NotNull] EmptyCommandSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        if (context.Remaining.Raw.Count > 0)
 | 
			
		||||
        {
 | 
			
		||||
            _console.WriteLine("# Raw");
 | 
			
		||||
            foreach (var item in context.Remaining.Raw)
 | 
			
		||||
            {
 | 
			
		||||
                _console.WriteLine(item);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (context.Remaining.Parsed.Count > 0)
 | 
			
		||||
        {
 | 
			
		||||
            _console.WriteLine("# Parsed");
 | 
			
		||||
            foreach (var item in context.Remaining.Parsed)
 | 
			
		||||
            {
 | 
			
		||||
                _console.WriteLine(string.Format("{0}={1}", item.Key, string.Join(",", item.Select(x => x))));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class EmptyCommand : Command<EmptyCommandSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, EmptyCommandSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class GenericCommand<TSettings> : Command<TSettings>
 | 
			
		||||
    where TSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, TSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[Description("The giraffe command.")]
 | 
			
		||||
public sealed class GiraffeCommand : Command<GiraffeSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, GiraffeSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class HiddenOptionsCommand : Command<HiddenOptionSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, HiddenOptionSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[Description("The horse command.")]
 | 
			
		||||
public class HorseCommand : AnimalCommand<MammalSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, MammalSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        DumpSettings(context, settings);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class InvalidCommand : Command<InvalidSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, InvalidSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[Description("The lion command.")]
 | 
			
		||||
public class LionCommand : AnimalCommand<LionSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, LionSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class NoDescriptionCommand : Command<EmptyCommandSettings>
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("-f|--foo <VALUE>")]
 | 
			
		||||
    public int Foo { get; set; }
 | 
			
		||||
 | 
			
		||||
    public override int Execute([NotNull] CommandContext context, [NotNull] EmptyCommandSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class OptionVectorCommand : Command<OptionVectorSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, OptionVectorSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class ThrowingCommand : Command<ThrowingCommandSettings>
 | 
			
		||||
{
 | 
			
		||||
    public override int Execute(CommandContext context, ThrowingCommandSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        throw new InvalidOperationException("W00t?");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public sealed class ThrowingCommandSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class CatAgilityConverter : TypeConverter
 | 
			
		||||
{
 | 
			
		||||
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
 | 
			
		||||
    {
 | 
			
		||||
        if (value is string stringValue)
 | 
			
		||||
        {
 | 
			
		||||
            return stringValue.Length;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return base.ConvertFrom(context, culture, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class StringToIntegerConverter : TypeConverter
 | 
			
		||||
{
 | 
			
		||||
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
 | 
			
		||||
    {
 | 
			
		||||
        if (value is string stringValue)
 | 
			
		||||
        {
 | 
			
		||||
            return int.Parse(stringValue, CultureInfo.InvariantCulture);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return base.ConvertFrom(context, culture, value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public abstract class AnimalSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("-a|--alive|--not-dead")]
 | 
			
		||||
    [Description("Indicates whether or not the animal is alive.")]
 | 
			
		||||
    public bool IsAlive { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(1, "[LEGS]")]
 | 
			
		||||
    [Description("The number of legs.")]
 | 
			
		||||
    [EvenNumberValidator("Animals must have an even number of legs.")]
 | 
			
		||||
    [PositiveNumberValidator("Number of legs must be greater than 0.")]
 | 
			
		||||
    public int Legs { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class ArgumentOrderSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "[QUX]")]
 | 
			
		||||
    public int Qux { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(3, "<CORGI>")]
 | 
			
		||||
    public int Corgi { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(1, "<BAR>")]
 | 
			
		||||
    public int Bar { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(2, "<BAZ>")]
 | 
			
		||||
    public int Baz { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(0, "<FOO>")]
 | 
			
		||||
    public int Foo { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class ArgumentVectorSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<Foos>")]
 | 
			
		||||
    public string[] Foo { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class BarCommandSettings : FooCommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<CORGI>")]
 | 
			
		||||
    [Description("The corgi value.")]
 | 
			
		||||
    public string Corgi { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class CatSettings : MammalSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("--agility <VALUE>")]
 | 
			
		||||
    [TypeConverter(typeof(CatAgilityConverter))]
 | 
			
		||||
    [DefaultValue(10)]
 | 
			
		||||
    [Description("The agility between 0 and 100.")]
 | 
			
		||||
    [PositiveNumberValidator("Agility cannot be negative.")]
 | 
			
		||||
    public int Agility { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class DogSettings : MammalSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<AGE>")]
 | 
			
		||||
    public int Age { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandOption("-g|--good-boy")]
 | 
			
		||||
    public bool GoodBoy { get; set; }
 | 
			
		||||
 | 
			
		||||
    public override ValidationResult Validate()
 | 
			
		||||
    {
 | 
			
		||||
        if (Name == "Tiger")
 | 
			
		||||
        {
 | 
			
		||||
            return ValidationResult.Error("Tiger is not a dog name!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ValidationResult.Success();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class EmptySettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class FooCommandSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "[QUX]")]
 | 
			
		||||
    [Description("The qux value.")]
 | 
			
		||||
    public string Qux { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class GiraffeSettings : MammalSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<LENGTH>")]
 | 
			
		||||
    [Description("The option description.")]
 | 
			
		||||
    public int Length { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class HiddenOptionSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<FOO>")]
 | 
			
		||||
    [Description("Dummy argument FOO")]
 | 
			
		||||
    public int Foo { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandOption("--bar", IsHidden = true)]
 | 
			
		||||
    [Description("You should not be able to read this unless you used the 'cli explain' command with the '--hidden' option")]
 | 
			
		||||
    public int Bar { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandOption("--baz")]
 | 
			
		||||
    [Description("Dummy option BAZ")]
 | 
			
		||||
    public int Baz { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class InvalidSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("-f|--foo [BAR]")]
 | 
			
		||||
    public string Value { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class LionSettings : CatSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<TEETH>")]
 | 
			
		||||
    [Description("The number of teeth the lion has.")]
 | 
			
		||||
    public int Teeth { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandOption("-c <CHILDREN>")]
 | 
			
		||||
    [Description("The number of children the lion has.")]
 | 
			
		||||
    public int Children { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class MammalSettings : AnimalSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("-n|-p|--name|--pet-name <VALUE>")]
 | 
			
		||||
    public string Name { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class MultipleArgumentVectorSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<Foos>")]
 | 
			
		||||
    public string[] Foo { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(0, "<Bars>")]
 | 
			
		||||
    public string[] Bar { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class MultipleArgumentVectorSpecifiedFirstSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(1, "[Bar]")]
 | 
			
		||||
    public string Bar { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandArgument(0, "<Foos>")]
 | 
			
		||||
    public string[] Foo { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public class OptionVectorSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("--foo")]
 | 
			
		||||
    public string[] Foo { get; set; }
 | 
			
		||||
 | 
			
		||||
    [CommandOption("--bar")]
 | 
			
		||||
    public int[] Bar { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class OptionalArgumentWithDefaultValueSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "[GREETING]")]
 | 
			
		||||
    [DefaultValue("Hello World")]
 | 
			
		||||
    public string Greeting { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public sealed class OptionalArgumentWithPropertyInitializerSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "[NAMES]")]
 | 
			
		||||
    public string[] Names { get; set; } = Array.Empty<string>();
 | 
			
		||||
 | 
			
		||||
    [CommandOption("-c")]
 | 
			
		||||
    public int Count { get; set; } = 1;
 | 
			
		||||
 | 
			
		||||
    [CommandOption("-v")]
 | 
			
		||||
    public int Value { get; set; } = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public sealed class OptionalArgumentWithDefaultValueAndTypeConverterSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "[GREETING]")]
 | 
			
		||||
    [DefaultValue("5")]
 | 
			
		||||
    [TypeConverter(typeof(StringToIntegerConverter))]
 | 
			
		||||
    public int Greeting { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public sealed class RequiredArgumentWithDefaultValueSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandArgument(0, "<GREETING>")]
 | 
			
		||||
    [DefaultValue("Hello World")]
 | 
			
		||||
    public string Greeting { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
public sealed class StringOptionSettings : CommandSettings
 | 
			
		||||
{
 | 
			
		||||
    [CommandOption("-f|--foo")]
 | 
			
		||||
    public string Foo { get; set; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
 | 
			
		||||
public sealed class EvenNumberValidatorAttribute : ParameterValidationAttribute
 | 
			
		||||
{
 | 
			
		||||
    public EvenNumberValidatorAttribute(string errorMessage)
 | 
			
		||||
        : base(errorMessage)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override ValidationResult Validate(CommandParameterContext context)
 | 
			
		||||
    {
 | 
			
		||||
        if (context.Value is int integer)
 | 
			
		||||
        {
 | 
			
		||||
            if (integer % 2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                return ValidationResult.Success();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return ValidationResult.Error($"Number is not even ({context.Parameter.PropertyName}).");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new InvalidOperationException($"Parameter is not a number ({context.Parameter.PropertyName}).");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Data;
 | 
			
		||||
 | 
			
		||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
 | 
			
		||||
public sealed class PositiveNumberValidatorAttribute : ParameterValidationAttribute
 | 
			
		||||
{
 | 
			
		||||
    public PositiveNumberValidatorAttribute(string errorMessage)
 | 
			
		||||
        : base(errorMessage)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override ValidationResult Validate(CommandParameterContext context)
 | 
			
		||||
    {
 | 
			
		||||
        if (context.Value is int integer)
 | 
			
		||||
        {
 | 
			
		||||
            if (integer > 0)
 | 
			
		||||
            {
 | 
			
		||||
                return ValidationResult.Success();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return ValidationResult.Error($"Number is not greater than 0 ({context.Parameter.PropertyName}).");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new InvalidOperationException($"Parameter is not a number ({context.Parameter.PropertyName}).");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,5 @@
 | 
			
		||||
global using System;
 | 
			
		||||
global using System.Collections.Generic;
 | 
			
		||||
global using System.ComponentModel;
 | 
			
		||||
global using System.Diagnostics;
 | 
			
		||||
global using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
global using System.Globalization;
 | 
			
		||||
global using System.IO;
 | 
			
		||||
global using System.Linq;
 | 
			
		||||
@@ -13,8 +10,6 @@ global using System.Threading;
 | 
			
		||||
global using System.Threading.Tasks;
 | 
			
		||||
global using Shouldly;
 | 
			
		||||
global using Spectre.Console.Advanced;
 | 
			
		||||
global using Spectre.Console.Cli;
 | 
			
		||||
global using Spectre.Console.Cli.Unsafe;
 | 
			
		||||
global using Spectre.Console.Rendering;
 | 
			
		||||
global using Spectre.Console.Testing;
 | 
			
		||||
global using Spectre.Console.Tests.Data;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,13 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <AdditionalFiles Include="..\..\src\stylecop.json" Link="Properties/stylecop.json" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('Windows'))">net6.0;net5.0;net48</TargetFrameworks>
 | 
			
		||||
    <TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('Windows'))">net6.0;net5.0</TargetFrameworks>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <AdditionalFiles Include="..\..\src\stylecop.json" Link="Properties/stylecop.json" />
 | 
			
		||||
    <None Remove="Data\starwars.flf" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <EmbeddedResource Include="Data\starwars.flf" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
@@ -34,6 +28,7 @@
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\..\src\Spectre.Console.Cli\Spectre.Console.Cli.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Spectre.Console.Testing\Spectre.Console.Testing.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,88 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli.Annotations;
 | 
			
		||||
 | 
			
		||||
[ExpectationPath("Cli/Arguments")]
 | 
			
		||||
public sealed partial class CommandArgumentAttributeTests
 | 
			
		||||
{
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class ArgumentCannotContainOptions
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandArgument(0, "--foo <BAR>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("ArgumentCannotContainOptions")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class MultipleValuesAreNotSupported
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandArgument(0, "<FOO> <BAR>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("MultipleValuesAreNotSupported")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class ValuesMustHaveName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandArgument(0, "<>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("ValuesMustHaveName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class Fixture
 | 
			
		||||
    {
 | 
			
		||||
        public static string Run<TSettings>(params string[] args)
 | 
			
		||||
            where TSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            using (var writer = new TestConsole())
 | 
			
		||||
            {
 | 
			
		||||
                var app = new CommandApp();
 | 
			
		||||
                app.Configure(c => c.ConfigureConsole(writer));
 | 
			
		||||
                app.Configure(c => c.AddCommand<GenericCommand<TSettings>>("foo"));
 | 
			
		||||
                app.Run(args);
 | 
			
		||||
 | 
			
		||||
                return writer.Output
 | 
			
		||||
                    .NormalizeLineEndings()
 | 
			
		||||
                    .TrimLines()
 | 
			
		||||
                    .Trim();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli.Annotations;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandArgumentAttributeTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Not_Contain_Options()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = Record.Exception(() => new CommandArgumentAttribute(0, "--foo <BAR>"));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBe(null);
 | 
			
		||||
        result.ShouldBeOfType<CommandTemplateException>().And(exception =>
 | 
			
		||||
            exception.Message.ShouldBe("Arguments can not contain options."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("<FOO> <BAR>")]
 | 
			
		||||
    [InlineData("[FOO] [BAR]")]
 | 
			
		||||
    [InlineData("[FOO] <BAR>")]
 | 
			
		||||
    [InlineData("<FOO> [BAR]")]
 | 
			
		||||
    public void Should_Not_Contain_Multiple_Value_Names(string template)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = Record.Exception(() => new CommandArgumentAttribute(0, template));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBe(null);
 | 
			
		||||
        result.ShouldBeOfType<CommandTemplateException>().And(exception =>
 | 
			
		||||
            exception.Message.ShouldBe("Multiple values are not supported."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("<>")]
 | 
			
		||||
    [InlineData("[]")]
 | 
			
		||||
    public void Should_Not_Contain_Empty_Value_Name(string template)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = Record.Exception(() => new CommandArgumentAttribute(0, template));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBe(null);
 | 
			
		||||
        result.ShouldBeOfType<CommandTemplateException>().And(exception =>
 | 
			
		||||
            exception.Message.ShouldBe("Values without name are not allowed."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("<FOO>", true)]
 | 
			
		||||
    [InlineData("[FOO]", false)]
 | 
			
		||||
    public void Should_Parse_Valid_Options(string template, bool required)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandArgumentAttribute(0, template);
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ValueName.ShouldBe("FOO");
 | 
			
		||||
        result.IsRequired.ShouldBe(required);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,240 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli.Annotations;
 | 
			
		||||
 | 
			
		||||
[ExpectationPath("Cli/Arguments")]
 | 
			
		||||
public sealed partial class CommandOptionAttributeTests
 | 
			
		||||
{
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class UnexpectedCharacter
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("<FOO> $ <BAR>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("UnexpectedCharacter")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Encountered unexpected character '$'.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class UnterminatedValueName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--foo|-f <BAR")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("UnterminatedValueName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Encountered unterminated value name 'BAR'.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class OptionsMustHaveName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--foo|-")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("OptionsMustHaveName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Options without name are not allowed.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class OptionNamesCannotStartWithDigit
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--1foo")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("OptionNamesCannotStartWithDigit")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Option names cannot start with a digit.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class InvalidCharacterInOptionName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--f$oo")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("InvalidCharacterInOptionName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Encountered invalid character '$' in option name.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class LongOptionMustHaveMoreThanOneCharacter
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--f")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("LongOptionMustHaveMoreThanOneCharacter")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Long option names must consist of more than one character.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class ShortOptionMustOnlyBeOneCharacter
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--foo|-bar")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("ShortOptionMustOnlyBeOneCharacter")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Short option names can not be longer than one character.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class MultipleOptionValuesAreNotSupported
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("-f|--foo <FOO> <BAR>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("MultipleOptionValuesAreNotSupported")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Multiple option values are not supported.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class InvalidCharacterInValueName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("-f|--foo <F$OO>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("InvalidCharacterInValueName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("Encountered invalid character '$' in value name.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    public sealed class MissingLongAndShortName
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class Settings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("<FOO>")]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("MissingLongAndShortName")]
 | 
			
		||||
        public Task Should_Return_Correct_Text()
 | 
			
		||||
        {
 | 
			
		||||
            // Given, When
 | 
			
		||||
            var result = Fixture.Run<Settings>();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Exception.Message.ShouldBe("No long or short name for option has been specified.");
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class Fixture
 | 
			
		||||
    {
 | 
			
		||||
        public static CommandAppFailure Run<TSettings>(params string[] args)
 | 
			
		||||
            where TSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(c =>
 | 
			
		||||
            {
 | 
			
		||||
                c.AddCommand<GenericCommand<TSettings>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return app.RunAndCatch<CommandTemplateException>(args);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,212 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli.Annotations;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandOptionAttributeTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Parse_Short_Name_Correctly()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = new CommandOptionAttribute("-o|--option <VALUE>");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShortNames.ShouldContain("o");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Parse_Long_Name_Correctly()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = new CommandOptionAttribute("-o|--option <VALUE>");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.LongNames.ShouldContain("option");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("<VALUE>")]
 | 
			
		||||
    public void Should_Parse_Value_Correctly(string value)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = new CommandOptionAttribute($"-o|--option {value}");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ValueName.ShouldBe("VALUE");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Parse_Only_Short_Name()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = new CommandOptionAttribute("-o");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShortNames.ShouldContain("o");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Parse_Only_Long_Name()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = new CommandOptionAttribute("--option");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.LongNames.ShouldContain("option");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("")]
 | 
			
		||||
    [InlineData("<VALUE>")]
 | 
			
		||||
    public void Should_Throw_If_Template_Is_Empty(string value)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = Record.Exception(() => new CommandOptionAttribute(value));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
            e.Message.ShouldBe("No long or short name for option has been specified."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("--bar|-foo")]
 | 
			
		||||
    [InlineData("--bar|-f-b")]
 | 
			
		||||
    public void Should_Throw_If_Short_Name_Is_Invalid(string value)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = Record.Exception(() => new CommandOptionAttribute(value));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
            e.Message.ShouldBe("Short option names can not be longer than one character."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("--o")]
 | 
			
		||||
    public void Should_Throw_If_Long_Name_Is_Invalid(string value)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = Record.Exception(() => new CommandOptionAttribute(value));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
            e.Message.ShouldBe("Long option names must consist of more than one character."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("-")]
 | 
			
		||||
    [InlineData("--")]
 | 
			
		||||
    public void Should_Throw_If_Option_Have_No_Name(string template)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var option = Record.Exception(() => new CommandOptionAttribute(template));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        option.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
            e.Message.ShouldBe("Options without name are not allowed."));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("--foo|-foo[b", '[')]
 | 
			
		||||
    [InlineData("--foo|-f€b", '€')]
 | 
			
		||||
    [InlineData("--foo|-foo@b", '@')]
 | 
			
		||||
    public void Should_Throw_If_Option_Contains_Invalid_Name(string template, char invalid)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = Record.Exception(() => new CommandOptionAttribute(template));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
        {
 | 
			
		||||
            e.Message.ShouldBe($"Encountered invalid character '{invalid}' in option name.");
 | 
			
		||||
            e.Template.ShouldBe(template);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("--foo <HELLO-WORLD>", "HELLO-WORLD")]
 | 
			
		||||
    [InlineData("--foo <HELLO_WORLD>", "HELLO_WORLD")]
 | 
			
		||||
    public void Should_Accept_Dash_And_Underscore_In_Value_Name(string template, string name)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute(template);
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ValueName.ShouldBe(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("--foo|-1")]
 | 
			
		||||
    public void Should_Throw_If_First_Letter_Of_An_Option_Name_Is_A_Digit(string template)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = Record.Exception(() => new CommandOptionAttribute(template));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldBeOfType<CommandTemplateException>().And(e =>
 | 
			
		||||
        {
 | 
			
		||||
            e.Message.ShouldBe("Option names cannot start with a digit.");
 | 
			
		||||
            e.Template.ShouldBe(template);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Multiple_Short_Options_Are_Supported()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute("-f|-b");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShortNames.Count.ShouldBe(2);
 | 
			
		||||
        result.ShortNames.ShouldContain("f");
 | 
			
		||||
        result.ShortNames.ShouldContain("b");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Multiple_Long_Options_Are_Supported()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute("--foo|--bar");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.LongNames.Count.ShouldBe(2);
 | 
			
		||||
        result.LongNames.ShouldContain("foo");
 | 
			
		||||
        result.LongNames.ShouldContain("bar");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("-f|--foo <BAR>")]
 | 
			
		||||
    [InlineData("--foo|-f <BAR>")]
 | 
			
		||||
    [InlineData("<BAR> --foo|-f")]
 | 
			
		||||
    [InlineData("<BAR> -f|--foo")]
 | 
			
		||||
    [InlineData("-f <BAR> --foo")]
 | 
			
		||||
    [InlineData("--foo <BAR> -f")]
 | 
			
		||||
    public void Template_Parts_Can_Appear_In_Any_Order(string template)
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute(template);
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.LongNames.ShouldContain("foo");
 | 
			
		||||
        result.ShortNames.ShouldContain("f");
 | 
			
		||||
        result.ValueName.ShouldBe("BAR");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Is_Not_Hidden_From_Help_By_Default()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute("--foo");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.IsHidden.ShouldBeFalse();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Can_Indicate_That_It_Must_Be_Hidden_From_Help_Text()
 | 
			
		||||
    {
 | 
			
		||||
        // Given, When
 | 
			
		||||
        var result = new CommandOptionAttribute("--foo") { IsHidden = true };
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.IsHidden.ShouldBeTrue();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,104 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public class NullableSettings : CommandSettings
 | 
			
		||||
    {
 | 
			
		||||
        public NullableSettings(bool? detailed, string[] extra)
 | 
			
		||||
        {
 | 
			
		||||
            Detailed = detailed;
 | 
			
		||||
            Extra = extra;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [CommandOption("-d")]
 | 
			
		||||
        public bool? Detailed { get; }
 | 
			
		||||
 | 
			
		||||
        [CommandArgument(0, "[extra]")]
 | 
			
		||||
        public string[] Extra { get; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NullableWithInitSettings : CommandSettings
 | 
			
		||||
    {
 | 
			
		||||
        [CommandOption("-d")]
 | 
			
		||||
        public bool? Detailed { get; init; }
 | 
			
		||||
 | 
			
		||||
        [CommandArgument(0, "[extra]")]
 | 
			
		||||
        public string[] Extra { get; init; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NullableCommand : Command<NullableSettings>
 | 
			
		||||
    {
 | 
			
		||||
        public override int Execute(CommandContext context, NullableSettings settings) => 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NullableWithInitCommand : Command<NullableWithInitSettings>
 | 
			
		||||
    {
 | 
			
		||||
        public override int Execute(CommandContext context, NullableWithInitSettings settings) => 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Populate_Nullable_Objects_In_Settings()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var fixture = new CommandAppTester();
 | 
			
		||||
        fixture.Configure(configurator =>
 | 
			
		||||
        {
 | 
			
		||||
            configurator.SetApplicationName("myapp");
 | 
			
		||||
            configurator.AddCommand<NullableCommand>("null");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = fixture.Run("null");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Settings.ShouldBeOfType<NullableSettings>().And(settings =>
 | 
			
		||||
        {
 | 
			
		||||
            settings.Detailed.ShouldBeNull();
 | 
			
		||||
            settings.Extra.ShouldBeNull();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Populate_Nullable_Objects_With_Init_In_Settings()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var fixture = new CommandAppTester();
 | 
			
		||||
        fixture.Configure(configurator =>
 | 
			
		||||
        {
 | 
			
		||||
            configurator.SetApplicationName("myapp");
 | 
			
		||||
            configurator.AddCommand<NullableWithInitCommand>("null");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = fixture.Run("null");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Settings.ShouldBeOfType<NullableWithInitSettings>().And(settings =>
 | 
			
		||||
        {
 | 
			
		||||
            settings.Detailed.ShouldBeNull();
 | 
			
		||||
            settings.Extra.ShouldBeNull();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Populate_Regular_Settings()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var fixture = new CommandAppTester();
 | 
			
		||||
        fixture.Configure(configurator =>
 | 
			
		||||
        {
 | 
			
		||||
            configurator.SetApplicationName("myapp");
 | 
			
		||||
            configurator.AddCommand<NullableCommand>("null");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = fixture.Run("null", "-d", "true", "first-item");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Settings.ShouldBeOfType<NullableSettings>().And(settings =>
 | 
			
		||||
        {
 | 
			
		||||
            settings.Detailed.ShouldBe(true);
 | 
			
		||||
            settings.Extra.ShouldBe(new[] { "first-item" });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Exception_Handling
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Not_Propagate_Runtime_Exceptions_If_Not_Explicitly_Told_To_Do_So()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "animal", "4", "dog", "101", "--name", "Rufus" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(-1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Not_Propagate_Exceptions_If_Not_Explicitly_Told_To_Do_So()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<ThrowingCommand>("throw");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "throw" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(-1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Handle_Exceptions_If_ExceptionHandler_Is_Set_Using_Action()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var exceptionHandled = false;
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<ThrowingCommand>("throw");
 | 
			
		||||
                config.SetExceptionHandler(_ =>
 | 
			
		||||
                {
 | 
			
		||||
                    exceptionHandled = true;
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "throw" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(-1);
 | 
			
		||||
            exceptionHandled.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Handle_Exceptions_If_ExceptionHandler_Is_Set_Using_Function()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var exceptionHandled = false;
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<ThrowingCommand>("throw");
 | 
			
		||||
                config.SetExceptionHandler(_ =>
 | 
			
		||||
                {
 | 
			
		||||
                    exceptionHandled = true;
 | 
			
		||||
                    return -99;
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "throw" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(-99);
 | 
			
		||||
            exceptionHandled.ShouldBeTrue();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,214 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class FlagValues
 | 
			
		||||
    {
 | 
			
		||||
        [SuppressMessage("Performance", "CA1812", Justification = "It's OK")]
 | 
			
		||||
        private sealed class FlagSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--serve [PORT]")]
 | 
			
		||||
            public FlagValue<int> Serve { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [SuppressMessage("Performance", "CA1812", Justification = "It's OK")]
 | 
			
		||||
        private sealed class FlagSettingsWithNullableValueType : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--serve [PORT]")]
 | 
			
		||||
            public FlagValue<int?> Serve { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [SuppressMessage("Performance", "CA1812", Justification = "It's OK")]
 | 
			
		||||
        private sealed class FlagSettingsWithOptionalOptionButNoFlagValue : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--serve [PORT]")]
 | 
			
		||||
            public int Serve { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [SuppressMessage("Performance", "CA1812", Justification = "It's OK")]
 | 
			
		||||
        private sealed class FlagSettingsWithDefaultValue : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--serve [PORT]")]
 | 
			
		||||
            [DefaultValue(987)]
 | 
			
		||||
            public FlagValue<int> Serve { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Command_Option_Value_Is_Optional_But_Type_Is_Not_A_Flag_Value()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettingsWithOptionalOptionButNoFlagValue>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "foo", "--serve", "123" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
            {
 | 
			
		||||
                ex.Message.ShouldBe("The option 'serve' has an optional value but does not implement IFlagValue.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Set_Flag_And_Value_If_Both_Were_Provided()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettings>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo", "--serve", "123", });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<FlagSettings>().And(flag =>
 | 
			
		||||
            {
 | 
			
		||||
                flag.Serve.IsSet.ShouldBeTrue();
 | 
			
		||||
                flag.Serve.Value.ShouldBe(123);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Only_Set_Flag_If_No_Value_Was_Provided()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettings>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo", "--serve" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<FlagSettings>().And(flag =>
 | 
			
		||||
            {
 | 
			
		||||
                flag.Serve.IsSet.ShouldBeTrue();
 | 
			
		||||
                flag.Serve.Value.ShouldBe(0);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Set_Value_To_Default_Value_If_None_Was_Explicitly_Set()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettingsWithDefaultValue>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo", "--serve" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<FlagSettingsWithDefaultValue>().And(flag =>
 | 
			
		||||
            {
 | 
			
		||||
                flag.Serve.IsSet.ShouldBeTrue();
 | 
			
		||||
                flag.Serve.Value.ShouldBe(987);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Create_Unset_Instance_If_Flag_Was_Not_Set()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettings>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<FlagSettings>().And(flag =>
 | 
			
		||||
            {
 | 
			
		||||
                flag.Serve.IsSet.ShouldBeFalse();
 | 
			
		||||
                flag.Serve.Value.ShouldBe(0);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Create_Unset_Instance_With_Null_For_Nullable_Value_Type_If_Flag_Was_Not_Set()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<FlagSettingsWithNullableValueType>>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<FlagSettingsWithNullableValueType>().And(flag =>
 | 
			
		||||
            {
 | 
			
		||||
                flag.Serve.IsSet.ShouldBeFalse();
 | 
			
		||||
                flag.Serve.Value.ShouldBeNull();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("Foo", true, "Set=True, Value=Foo")]
 | 
			
		||||
        [InlineData("Bar", false, "Set=False, Value=Bar")]
 | 
			
		||||
        public void Should_Return_Correct_String_Representation_From_ToString(
 | 
			
		||||
            string value,
 | 
			
		||||
            bool isSet,
 | 
			
		||||
            string expected)
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var flag = new FlagValue<string>
 | 
			
		||||
            {
 | 
			
		||||
                Value = value,
 | 
			
		||||
                IsSet = isSet,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = flag.ToString();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData(true, "Set=True")]
 | 
			
		||||
        [InlineData(false, "Set=False")]
 | 
			
		||||
        public void Should_Return_Correct_String_Representation_From_ToString_If_Value_Is_Not_Set(
 | 
			
		||||
            bool isSet,
 | 
			
		||||
            string expected)
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var flag = new FlagValue<string>
 | 
			
		||||
            {
 | 
			
		||||
                IsSet = isSet,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = flag.ToString();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,293 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    [ExpectationPath("Cli/Help")]
 | 
			
		||||
    public class Help
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Root")]
 | 
			
		||||
        public Task Should_Output_Root_Correctly()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                configurator.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                configurator.AddCommand<GiraffeCommand>("giraffe");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Hidden_Commands")]
 | 
			
		||||
        public Task Should_Skip_Hidden_Commands()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                configurator.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                configurator.AddCommand<GiraffeCommand>("giraffe")
 | 
			
		||||
                    .WithExample(new[] { "giraffe", "123" })
 | 
			
		||||
                    .IsHidden();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Command")]
 | 
			
		||||
        public Task Should_Output_Command_Correctly()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddBranch<CatSettings>("cat", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SetDescription("Contains settings for a cat.");
 | 
			
		||||
                    animal.AddCommand<LionCommand>("lion");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("cat", "--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Leaf")]
 | 
			
		||||
        public Task Should_Output_Leaf_Correctly()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddBranch<CatSettings>("cat", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SetDescription("Contains settings for a cat.");
 | 
			
		||||
                    animal.AddCommand<LionCommand>("lion");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("cat", "lion", "--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Default")]
 | 
			
		||||
        public Task Should_Output_Default_Command_Correctly()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<LionCommand>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("RootExamples")]
 | 
			
		||||
        public Task Should_Output_Root_Examples_Defined_On_Root()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddExample(new[] { "dog", "--name", "Rufus", "--age", "12", "--good-boy" });
 | 
			
		||||
                configurator.AddExample(new[] { "horse", "--name", "Brutus" });
 | 
			
		||||
                configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                configurator.AddCommand<HorseCommand>("horse");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("RootExamples_Children")]
 | 
			
		||||
        public Task Should_Output_Root_Examples_Defined_On_Direct_Children_If_Root_Have_No_Examples()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddCommand<DogCommand>("dog")
 | 
			
		||||
                    .WithExample(new[] { "dog", "--name", "Rufus", "--age", "12", "--good-boy" });
 | 
			
		||||
                configurator.AddCommand<HorseCommand>("horse")
 | 
			
		||||
                    .WithExample(new[] { "horse", "--name", "Brutus" });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("RootExamples_Leafs")]
 | 
			
		||||
        public Task Should_Output_Root_Examples_Defined_On_Leaves_If_No_Other_Examples_Are_Found()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SetDescription("The animal command.");
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog")
 | 
			
		||||
                        .WithExample(new[] { "animal", "dog", "--name", "Rufus", "--age", "12", "--good-boy" });
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse")
 | 
			
		||||
                        .WithExample(new[] { "animal", "horse", "--name", "Brutus" });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("CommandExamples")]
 | 
			
		||||
        public Task Should_Only_Output_Command_Examples_Defined_On_Command()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SetDescription("The animal command.");
 | 
			
		||||
                    animal.AddExample(new[] { "animal", "--help" });
 | 
			
		||||
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog")
 | 
			
		||||
                        .WithExample(new[] { "animal", "dog", "--name", "Rufus", "--age", "12", "--good-boy" });
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse")
 | 
			
		||||
                        .WithExample(new[] { "animal", "horse", "--name", "Brutus" });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("animal", "--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("DefaultExamples")]
 | 
			
		||||
        public Task Should_Output_Root_Examples_If_Default_Command_Is_Specified()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<LionCommand>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddExample(new[] { "12", "-c", "3" });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("NoDescription")]
 | 
			
		||||
        public Task Should_Not_Show_Truncated_Command_Table_If_Commands_Are_Missing_Description()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddCommand<NoDescriptionCommand>("bar");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("ArgumentOrder")]
 | 
			
		||||
        public Task Should_List_Arguments_In_Correct_Order()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<GenericCommand<ArgumentOrderSettings>>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Hidden_Command_Options")]
 | 
			
		||||
        public Task Should_Not_Show_Hidden_Command_Options()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<GenericCommand<HiddenOptionSettings>>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("--help");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,90 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Injection
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class FakeDependency
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class InjectSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            public FakeDependency Fake { get; set; }
 | 
			
		||||
 | 
			
		||||
            [CommandOption("--name <NAME>")]
 | 
			
		||||
            public string Name { get; }
 | 
			
		||||
 | 
			
		||||
            [CommandOption("--age <AGE>")]
 | 
			
		||||
            public int Age { get; set; }
 | 
			
		||||
 | 
			
		||||
            public InjectSettings(FakeDependency fake, string name)
 | 
			
		||||
            {
 | 
			
		||||
                Fake = fake;
 | 
			
		||||
                Name = "Hello " + name;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Inject_Parameters()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            var dependency = new FakeDependency();
 | 
			
		||||
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<InjectSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.Settings.Registrar.RegisterInstance(dependency);
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--name", "foo",
 | 
			
		||||
                "--age", "35",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<InjectSettings>().And(injected =>
 | 
			
		||||
            {
 | 
			
		||||
                injected.ShouldNotBeNull();
 | 
			
		||||
                injected.Fake.ShouldBeSameAs(dependency);
 | 
			
		||||
                injected.Name.ShouldBe("Hello foo");
 | 
			
		||||
                injected.Age.ShouldBe(35);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Inject_Dependency_Using_A_Given_Registrar()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var dependency = new FakeDependency();
 | 
			
		||||
            var registrar = new FakeTypeRegistrar { TypeResolverFactory = FakeTypeResolver.Factory };
 | 
			
		||||
            registrar.RegisterInstance(typeof(FakeDependency), dependency);
 | 
			
		||||
            var app = new CommandAppTester(registrar);
 | 
			
		||||
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<InjectSettings>>();
 | 
			
		||||
            app.Configure(config => config.PropagateExceptions());
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--name", "foo",
 | 
			
		||||
                "--age", "35",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<InjectSettings>().And(injected =>
 | 
			
		||||
            {
 | 
			
		||||
                injected.ShouldNotBeNull();
 | 
			
		||||
                injected.Fake.ShouldBeSameAs(dependency);
 | 
			
		||||
                injected.Name.ShouldBe("Hello foo");
 | 
			
		||||
                injected.Age.ShouldBe(35);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,316 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Pairs
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class AmbiguousSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            [PairDeconstructor(typeof(StringIntDeconstructor))]
 | 
			
		||||
            [TypeConverter(typeof(CatAgilityConverter))]
 | 
			
		||||
            public ILookup<string, string> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class NotDeconstructableSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            [PairDeconstructor(typeof(StringIntDeconstructor))]
 | 
			
		||||
            public string Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class DefaultPairDeconstructorSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            public IDictionary<string, int> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class DefaultPairDeconstructorEnumValueSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            public IDictionary<string, DayOfWeek> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class LookupSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            [PairDeconstructor(typeof(StringIntDeconstructor))]
 | 
			
		||||
            public ILookup<string, string> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class DictionarySettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            [PairDeconstructor(typeof(StringIntDeconstructor))]
 | 
			
		||||
            public IDictionary<string, string> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class ReadOnlyDictionarySettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("--var <VALUE>")]
 | 
			
		||||
            [PairDeconstructor(typeof(StringIntDeconstructor))]
 | 
			
		||||
            public IReadOnlyDictionary<string, string> Values { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class StringIntDeconstructor : PairDeconstructor<string, string>
 | 
			
		||||
        {
 | 
			
		||||
            protected override (string Key, string Value) Deconstruct(string value)
 | 
			
		||||
            {
 | 
			
		||||
                if (value == null)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new ArgumentNullException(nameof(value));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var parts = value.Split(new[] { '=' });
 | 
			
		||||
                if (parts.Length != 2)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new InvalidOperationException("Could not parse pair");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return (parts[0], parts[1]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Option_Has_Pair_Deconstructor_And_Type_Converter()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp<GenericCommand<AmbiguousSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "foo=qux",
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
            {
 | 
			
		||||
                ex.Message.ShouldBe("The option 'var' is both marked as pair deconstructable and convertable.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Option_Has_Pair_Deconstructor_But_Type_Is_Not_Deconstructable()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp<GenericCommand<NotDeconstructableSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "foo=qux",
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
            {
 | 
			
		||||
                ex.Message.ShouldBe("The option 'var' is marked as pair deconstructable, but the underlying type does not support that.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_Pairs_To_Pair_Deconstructable_Collection_Using_Default_Deconstructort()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<DefaultPairDeconstructorSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=1",
 | 
			
		||||
                "--var", "foo=3",
 | 
			
		||||
                "--var", "bar=4",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DefaultPairDeconstructorSettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(2);
 | 
			
		||||
                pair.Values["foo"].ShouldBe(3);
 | 
			
		||||
                pair.Values["bar"].ShouldBe(4);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_Pairs_With_Enum_Value_To_Pair_Deconstructable_Collection_Using_Default_Deconstructor()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<DefaultPairDeconstructorEnumValueSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=Monday",
 | 
			
		||||
                "--var", "bar=Tuesday",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DefaultPairDeconstructorEnumValueSettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(2);
 | 
			
		||||
                pair.Values["foo"].ShouldBe(DayOfWeek.Monday);
 | 
			
		||||
                pair.Values["bar"].ShouldBe(DayOfWeek.Tuesday);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Theory]
 | 
			
		||||
        [InlineData("foo=1=2", "Error: The value 'foo=1=2' is not in a correct format")]
 | 
			
		||||
        [InlineData("foo=1=2=3", "Error: The value 'foo=1=2=3' is not in a correct format")]
 | 
			
		||||
        public void Should_Throw_If_Value_Is_Not_In_A_Valid_Format_Using_Default_Deconstructor(
 | 
			
		||||
            string input, string expected)
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<DefaultPairDeconstructorSettings>>();
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", input,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(-1);
 | 
			
		||||
            result.Output.ShouldBe(expected);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_Lookup_Values()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<LookupSettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "foo=qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<LookupSettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(1);
 | 
			
		||||
                pair.Values["foo"].ToList().Count.ShouldBe(2);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_Dictionary_Values()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<DictionarySettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "baz=qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DictionarySettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(2);
 | 
			
		||||
                pair.Values["foo"].ShouldBe("bar");
 | 
			
		||||
                pair.Values["baz"].ShouldBe("qux");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_Latest_Value_Of_Same_Key_When_Mapping_To_Dictionary()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<DictionarySettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "foo=qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DictionarySettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(1);
 | 
			
		||||
                pair.Values["foo"].ShouldBe("qux");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Map_ReadOnly_Dictionary_Values()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<ReadOnlyDictionarySettings>>();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "--var", "foo=bar",
 | 
			
		||||
                "--var", "baz=qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<ReadOnlyDictionarySettings>().And(pair =>
 | 
			
		||||
            {
 | 
			
		||||
                pair.Values.ShouldNotBeNull();
 | 
			
		||||
                pair.Values.Count.ShouldBe(2);
 | 
			
		||||
                pair.Values["foo"].ShouldBe("bar");
 | 
			
		||||
                pair.Values["baz"].ShouldBe("qux");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,666 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    [ExpectationPath("Cli/Parsing")]
 | 
			
		||||
    public sealed class Parsing
 | 
			
		||||
    {
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("UnknownCommand")]
 | 
			
		||||
        public sealed class UnknownCommand
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_When_Command_Is_Unknown()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(config =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("cat", "14");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Unknown_Command_When_Current_Command_Has_No_Arguments()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<EmptyCommand>("empty");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("empty", "other");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_3")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_When_Command_Followed_By_Argument_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(config =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.AddBranch<CommandSettings>("dog", a =>
 | 
			
		||||
                    {
 | 
			
		||||
                        a.AddCommand<CatCommand>("cat");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "bat", "14");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_4")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_When_Root_Command_Followed_By_Argument_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(config =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.AddCommand<CatCommand>("cat");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("bat", "14");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_5")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_And_No_Arguments_When_Root_Command_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.WithDefaultCommand<GenericCommand<EmptyCommandSettings>>();
 | 
			
		||||
                fixture.Configure(config =>
 | 
			
		||||
                {
 | 
			
		||||
                    config.AddCommand<GenericCommand<EmptyCommandSettings>>("cat");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("bat");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_6")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_And_No_Arguments_When_Command_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.WithDefaultCommand<GenericCommand<EmptyCommandSettings>>();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddBranch<CommandSettings>("dog", a =>
 | 
			
		||||
                    {
 | 
			
		||||
                        a.AddCommand<CatCommand>("cat");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "bat");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_7")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_When_Root_Command_After_Argument_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.WithDefaultCommand<GenericCommand<FooCommandSettings>>();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<GenericCommand<BarCommandSettings>>("bar");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("qux", "bat");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_8")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_With_Suggestion_When_Command_After_Argument_Is_Unknown_And_Distance_Is_Small()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddBranch<FooCommandSettings>("foo", a =>
 | 
			
		||||
                    {
 | 
			
		||||
                        a.AddCommand<GenericCommand<BarCommandSettings>>("bar");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("foo", "qux", "bat");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("CannotAssignValueToFlag")]
 | 
			
		||||
        public sealed class CannotAssignValueToFlag
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Long_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "--alive", "foo");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Short_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "-a", "foo");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("NoValueForOption")]
 | 
			
		||||
        public sealed class NoValueForOption
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Long_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "--name");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Short_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "-n");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("NoMatchingArgument")]
 | 
			
		||||
        public sealed class NoMatchingArgument
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<GiraffeCommand>("giraffe");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("giraffe", "foo", "bar", "baz");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("UnexpectedOption")]
 | 
			
		||||
        public sealed class UnexpectedOption
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Long_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("--foo");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Short_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("-f");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("UnknownOption")]
 | 
			
		||||
        public sealed class UnknownOption
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Long_Option_If_Strict_Mode_Is_Enabled()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.UseStrictParsing();
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "--unknown");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Short_Option_If_Strict_Mode_Is_Enabled()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.UseStrictParsing();
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "-u");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("UnterminatedQuote")]
 | 
			
		||||
        public sealed class UnterminatedQuote
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("--name", "\"Rufus");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("OptionWithoutName")]
 | 
			
		||||
        public sealed class OptionWithoutName
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Short_Option()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", "-", " ");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_2")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Missing_Long_Option_Value_With_Equality_Separator()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"--foo=");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_3")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Missing_Long_Option_Value_With_Colon_Separator()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"--foo:");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_4")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Missing_Short_Option_Value_With_Equality_Separator()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"-f=");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_5")]
 | 
			
		||||
            public Task Should_Return_Correct_Text_For_Missing_Short_Option_Value_With_Colon_Separator()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"-f:");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("InvalidShortOptionName")]
 | 
			
		||||
        public sealed class InvalidShortOptionName
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"-f0o");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("LongOptionNameIsOneCharacter")]
 | 
			
		||||
        public sealed class LongOptionNameIsOneCharacter
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"--f");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("LongOptionNameIsMissing")]
 | 
			
		||||
        public sealed class LongOptionNameIsMissing
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"-- ");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("LongOptionNameStartWithDigit")]
 | 
			
		||||
        public sealed class LongOptionNameStartWithDigit
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"--1foo");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [UsesVerify]
 | 
			
		||||
        [ExpectationPath("LongOptionNameContainSymbol")]
 | 
			
		||||
        public sealed class LongOptionNameContainSymbol
 | 
			
		||||
        {
 | 
			
		||||
            [Fact]
 | 
			
		||||
            [Expectation("Test_1")]
 | 
			
		||||
            public Task Should_Return_Correct_Text()
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", $"--f€oo");
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                return Verifier.Verify(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [Theory]
 | 
			
		||||
            [InlineData("--f-oo")]
 | 
			
		||||
            [InlineData("--f-o-o")]
 | 
			
		||||
            [InlineData("--f_oo")]
 | 
			
		||||
            [InlineData("--f_o_o")]
 | 
			
		||||
            public void Should_Allow_Special_Symbols_In_Name(string option)
 | 
			
		||||
            {
 | 
			
		||||
                // Given
 | 
			
		||||
                var fixture = new Fixture();
 | 
			
		||||
                fixture.Configure(configurator =>
 | 
			
		||||
                {
 | 
			
		||||
                    configurator.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // When
 | 
			
		||||
                var result = fixture.Run("dog", option);
 | 
			
		||||
 | 
			
		||||
                // Then
 | 
			
		||||
                result.ShouldBe("Error: Command 'dog' is missing required argument 'AGE'.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Quoted_Strings")]
 | 
			
		||||
        public Task Should_Parse_Quoted_Strings_Correctly()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new Fixture();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.AddCommand<DumpRemainingCommand>("foo");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run("foo", "--", "/c", "\"set && pause\"");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal sealed class Fixture
 | 
			
		||||
    {
 | 
			
		||||
        private Action<CommandApp> _appConfiguration = _ => { };
 | 
			
		||||
        private Action<IConfigurator> _configuration;
 | 
			
		||||
 | 
			
		||||
        public void WithDefaultCommand<T>()
 | 
			
		||||
            where T : class, ICommand
 | 
			
		||||
        {
 | 
			
		||||
            _appConfiguration = (app) => app.SetDefaultCommand<T>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Configure(Action<IConfigurator> action)
 | 
			
		||||
        {
 | 
			
		||||
            _configuration = action;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Run(params string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            using (var console = new TestConsole())
 | 
			
		||||
            {
 | 
			
		||||
                var app = new CommandApp();
 | 
			
		||||
                _appConfiguration?.Invoke(app);
 | 
			
		||||
 | 
			
		||||
                app.Configure(_configuration);
 | 
			
		||||
                app.Configure(c => c.ConfigureConsole(console));
 | 
			
		||||
                app.Run(args);
 | 
			
		||||
 | 
			
		||||
                return console.Output
 | 
			
		||||
                    .NormalizeLineEndings()
 | 
			
		||||
                    .TrimLines()
 | 
			
		||||
                    .Trim();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Remaining
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Register_Remaining_Parsed_Arguments_With_Context()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "4", "dog", "12", "--",
 | 
			
		||||
                "--foo", "bar", "--foo", "baz",
 | 
			
		||||
                "-bar", "\"baz\"", "qux",
 | 
			
		||||
                "foo bar baz qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Context.Remaining.Parsed.Count.ShouldBe(4);
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("foo", values: new[] { "bar", "baz" });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("b", values: new[] { (string)null });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("a", values: new[] { (string)null });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("r", values: new[] { (string)null });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Register_Remaining_Raw_Arguments_With_Context()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "4", "dog", "12", "--",
 | 
			
		||||
                "--foo", "bar", "-bar", "\"baz\"", "qux",
 | 
			
		||||
                "foo bar baz qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Context.Remaining.Raw.Count.ShouldBe(6);
 | 
			
		||||
            result.Context.Remaining.Raw[0].ShouldBe("--foo");
 | 
			
		||||
            result.Context.Remaining.Raw[1].ShouldBe("bar");
 | 
			
		||||
            result.Context.Remaining.Raw[2].ShouldBe("-bar");
 | 
			
		||||
            result.Context.Remaining.Raw[3].ShouldBe("baz");
 | 
			
		||||
            result.Context.Remaining.Raw[4].ShouldBe("qux");
 | 
			
		||||
            result.Context.Remaining.Raw[5].ShouldBe("foo bar baz qux");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandApptests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Treat_Commands_As_Case_Sensitive_If_Specified()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.CaseSensitivity(CaseSensitivity.Commands);
 | 
			
		||||
            config.AddCommand<GenericCommand<StringOptionSettings>>("command");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "Command", "--foo", "bar",
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBeNull();
 | 
			
		||||
        result.ShouldBeOfType<CommandParseException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("Unknown command 'Command'.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Treat_Long_Options_As_Case_Sensitive_If_Specified()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.CaseSensitivity(CaseSensitivity.LongOptions);
 | 
			
		||||
            config.AddCommand<GenericCommand<StringOptionSettings>>("command");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "command", "--Foo", "bar",
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBeNull();
 | 
			
		||||
        result.ShouldBeOfType<CommandParseException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("Unknown option 'Foo'.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Treat_Short_Options_As_Case_Sensitive()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<GenericCommand<StringOptionSettings>>("command");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "command", "-F", "bar",
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldNotBeNull();
 | 
			
		||||
        result.ShouldBeOfType<CommandParseException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("Unknown option 'F'.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Suppress_Case_Sensitivity_If_Specified()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.CaseSensitivity(CaseSensitivity.None);
 | 
			
		||||
            config.AddCommand<GenericCommand<StringOptionSettings>>("command");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "Command", "--Foo", "bar",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<StringOptionSettings>().And(vec =>
 | 
			
		||||
        {
 | 
			
		||||
            vec.Foo.ShouldBe("bar");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Apply_Case_Sensitivity_For_Everything_By_Default()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var defaultSensitivity = CaseSensitivity.None;
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            defaultSensitivity = config.Settings.CaseSensitivity;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        defaultSensitivity.ShouldBe(CaseSensitivity.All);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class TypeConverters
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Bind_Using_Custom_Type_Converter_If_Specified()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<CatCommand>("cat");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                    "cat", "--name", "Tiger",
 | 
			
		||||
                    "--agility", "FOOBAR",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<CatSettings>().And(cat =>
 | 
			
		||||
            {
 | 
			
		||||
                cat.Agility.ShouldBe(6);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,291 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class SafetyOff
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Can_Mix_Safe_And_Unsafe_Configurators()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SafetyOff().AddBranch("mammal", typeof(MammalSettings), mammal =>
 | 
			
		||||
                    {
 | 
			
		||||
                        mammal.AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
                        mammal.AddCommand("horse", typeof(HorseCommand));
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "--alive", "mammal", "--name",
 | 
			
		||||
                "Rufus", "dog", "12", "--good-boy",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Age.ShouldBe(12);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
                dog.IsAlive.ShouldBe(true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Can_Turn_Safety_On_After_Turning_It_Off_For_Branch()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
 | 
			
		||||
                config.SafetyOff().AddBranch("animal", typeof(AnimalSettings), animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SafetyOn<AnimalSettings>()
 | 
			
		||||
                        .AddBranch<MammalSettings>("mammal", mammal =>
 | 
			
		||||
                    {
 | 
			
		||||
                        mammal.SafetyOff().AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
                        mammal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "--alive", "mammal", "--name",
 | 
			
		||||
                "Rufus", "dog", "12", "--good-boy",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Age.ShouldBe(12);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
                dog.IsAlive.ShouldBe(true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Trying_To_Convert_Unsafe_Branch_Configurator_To_Safe_Version_With_Wrong_Type()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
 | 
			
		||||
                config.SafetyOff().AddBranch("animal", typeof(AnimalSettings), animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.SafetyOn<MammalSettings>().AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>();
 | 
			
		||||
            result.Message.ShouldBe("Configurator cannot be converted to a safe configurator of type 'MammalSettings'.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_1()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
 | 
			
		||||
                config.SafetyOff().AddBranch("animal", typeof(AnimalSettings), animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddBranch("mammal", typeof(MammalSettings), mammal =>
 | 
			
		||||
                    {
 | 
			
		||||
                        mammal.AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
                        mammal.AddCommand("horse", typeof(HorseCommand));
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "--alive", "mammal", "--name",
 | 
			
		||||
                "Rufus", "dog", "12", "--good-boy",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Age.ShouldBe(12);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
                dog.IsAlive.ShouldBe(true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_2()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.SafetyOff().AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "dog", "12", "4", "--good-boy",
 | 
			
		||||
                "--name", "Rufus", "--alive",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Legs.ShouldBe(12);
 | 
			
		||||
                dog.Age.ShouldBe(4);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
                dog.IsAlive.ShouldBe(true);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_3()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.SafetyOff().AddBranch("animal", typeof(AnimalSettings), animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
                    animal.AddCommand("horse", typeof(HorseCommand));
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "dog", "12", "--good-boy",
 | 
			
		||||
                "--name", "Rufus",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Age.ShouldBe(12);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
                dog.IsAlive.ShouldBe(false);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_4()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.SafetyOff().AddBranch("animal", typeof(AnimalSettings), animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand("dog", typeof(DogCommand));
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "4", "dog", "12",
 | 
			
		||||
                "--good-boy", "--name", "Rufus",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
            {
 | 
			
		||||
                dog.Legs.ShouldBe(4);
 | 
			
		||||
                dog.Age.ShouldBe(12);
 | 
			
		||||
                dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
                dog.IsAlive.ShouldBe(false);
 | 
			
		||||
                dog.Name.ShouldBe("Rufus");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_5()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.SafetyOff().AddCommand("multi", typeof(OptionVectorCommand));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "multi", "--foo", "a", "--foo", "b", "--bar", "1", "--foo", "c", "--bar", "2",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<OptionVectorSettings>().And(vec =>
 | 
			
		||||
            {
 | 
			
		||||
                vec.Foo.Length.ShouldBe(3);
 | 
			
		||||
                vec.Foo.ShouldBe(new[] { "a", "b", "c" });
 | 
			
		||||
                vec.Bar.Length.ShouldBe(2);
 | 
			
		||||
                vec.Bar.ShouldBe(new[] { 1, 2 });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Pass_Case_6()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<ArgumentVectorSettings>>("multi");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "multi", "a", "b", "c",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<ArgumentVectorSettings>().And(vec =>
 | 
			
		||||
            {
 | 
			
		||||
                vec.Foo.Length.ShouldBe(3);
 | 
			
		||||
                vec.Foo.ShouldBe(new[] { "a", "b", "c" });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Validation
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Attribute_Validation_Fails()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "animal", "3", "dog", "7", "--name", "Rufus" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandRuntimeException>().And(e =>
 | 
			
		||||
            {
 | 
			
		||||
                e.Message.ShouldBe("Animals must have an even number of legs.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Settings_Validation_Fails()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "animal", "4", "dog", "7", "--name", "Tiger" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandRuntimeException>().And(e =>
 | 
			
		||||
            {
 | 
			
		||||
                e.Message.ShouldBe("Tiger is not a dog name!");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_Command_Validation_Fails()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "animal", "4", "dog", "101", "--name", "Rufus" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandRuntimeException>().And(e =>
 | 
			
		||||
            {
 | 
			
		||||
                e.Message.ShouldBe("Dog is too old...");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,88 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class ValueProviders
 | 
			
		||||
    {
 | 
			
		||||
        public sealed class ValueProviderSettings : CommandSettings
 | 
			
		||||
        {
 | 
			
		||||
            [CommandOption("-f|--foo <VALUE>")]
 | 
			
		||||
            [IntegerValueProvider(32)]
 | 
			
		||||
            [TypeConverter(typeof(HexConverter))]
 | 
			
		||||
            public string Foo { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class IntegerValueProvider : ParameterValueProviderAttribute
 | 
			
		||||
        {
 | 
			
		||||
            private readonly int _value;
 | 
			
		||||
 | 
			
		||||
            public IntegerValueProvider(int value)
 | 
			
		||||
            {
 | 
			
		||||
                _value = value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override bool TryGetValue(CommandParameterContext context, out object result)
 | 
			
		||||
            {
 | 
			
		||||
                if (context.Value == null)
 | 
			
		||||
                {
 | 
			
		||||
                    result = _value;
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                result = null;
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public sealed class HexConverter : TypeConverter
 | 
			
		||||
        {
 | 
			
		||||
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
 | 
			
		||||
            {
 | 
			
		||||
                if (value is int integer)
 | 
			
		||||
                {
 | 
			
		||||
                    return integer.ToString("X");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return value is string stringValue && int.TryParse(stringValue, out var intValue)
 | 
			
		||||
                    ? intValue.ToString("X")
 | 
			
		||||
                    : base.ConvertFrom(context, culture, value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Use_Provided_Value_If_No_Value_Was_Specified()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<ValueProviderSettings>>();
 | 
			
		||||
            app.Configure(config => config.PropagateExceptions());
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Settings.ShouldBeOfType<ValueProviderSettings>().And(settings =>
 | 
			
		||||
            {
 | 
			
		||||
                settings.Foo.ShouldBe("20"); // 32 is 0x20
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Not_Override_Value_If_Value_Was_Specified()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.SetDefaultCommand<GenericCommand<ValueProviderSettings>>();
 | 
			
		||||
            app.Configure(config => config.PropagateExceptions());
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run("--foo", "12");
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Settings.ShouldBeOfType<ValueProviderSettings>().And(settings =>
 | 
			
		||||
            {
 | 
			
		||||
                settings.Foo.ShouldBe("C"); // 12 is 0xC
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,104 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Vectors
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_A_Single_Command_Has_Multiple_Argument_Vectors()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<MultipleArgumentVectorSettings>>("multi");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "multi", "a", "b", "c" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
            {
 | 
			
		||||
                ex.Message.ShouldBe("The command 'multi' specifies more than one vector argument.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Throw_If_An_Argument_Vector_Is_Not_Specified_Last()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<MultipleArgumentVectorSpecifiedFirstSettings>>("multi");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = Record.Exception(() => app.Run(new[] { "multi", "a", "b", "c" }));
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
            {
 | 
			
		||||
                ex.Message.ShouldBe("The command 'multi' specifies an argument vector that is not the last argument.");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Assign_Values_To_Argument_Vector()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<GenericCommand<ArgumentVectorSettings>>("multi");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "multi", "a", "b", "c",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<ArgumentVectorSettings>().And(vec =>
 | 
			
		||||
            {
 | 
			
		||||
                vec.Foo.Length.ShouldBe(3);
 | 
			
		||||
                vec.Foo[0].ShouldBe("a");
 | 
			
		||||
                vec.Foo[1].ShouldBe("b");
 | 
			
		||||
                vec.Foo[2].ShouldBe("c");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Assign_Values_To_Option_Vector()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddCommand<OptionVectorCommand>("cmd");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "cmd", "--foo", "red",
 | 
			
		||||
                "--bar", "4", "--foo", "blue",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ExitCode.ShouldBe(0);
 | 
			
		||||
            result.Settings.ShouldBeOfType<OptionVectorSettings>().And(vec =>
 | 
			
		||||
            {
 | 
			
		||||
                vec.Foo.ShouldBe(new string[] { "red", "blue" });
 | 
			
		||||
                vec.Bar.ShouldBe(new int[] { 4 });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    public sealed class Version
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Output_The_Version_To_The_Console()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddBranch<MammalSettings>("mammal", mammal =>
 | 
			
		||||
                    {
 | 
			
		||||
                        mammal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                        mammal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.VersionCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Output.ShouldStartWith("Spectre.Cli version ");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,148 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    [UsesVerify]
 | 
			
		||||
    [ExpectationPath("Cli/Xml")]
 | 
			
		||||
    public sealed class Xml
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_1")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Case_1()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddBranch<MammalSettings>("mammal", mammal =>
 | 
			
		||||
                    {
 | 
			
		||||
                        mammal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                        mammal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_2")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Case_2()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_3")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Case_3()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_4")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Case_4()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_5")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Case_5()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<OptionVectorCommand>("cmd");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Test_6")]
 | 
			
		||||
        public Task Should_Dump_Correct_Model_For_Model_With_Default_Command()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<DogCommand>();
 | 
			
		||||
            fixture.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.AddCommand<HorseCommand>("horse");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Hidden_Command_Options")]
 | 
			
		||||
        public Task Should_Not_Dump_Hidden_Options_On_A_Command()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<HiddenOptionsCommand>();
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run(Constants.XmlDocCommand);
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,812 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed partial class CommandAppTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_1()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddBranch<MammalSettings>("mammal", mammal =>
 | 
			
		||||
                {
 | 
			
		||||
                    mammal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                    mammal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "--alive", "mammal", "--name",
 | 
			
		||||
            "Rufus", "dog", "12", "--good-boy",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
            dog.Name.ShouldBe("Rufus");
 | 
			
		||||
            dog.IsAlive.ShouldBe(true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_2()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<DogCommand>("dog");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "dog", "12", "4", "--good-boy",
 | 
			
		||||
            "--name", "Rufus", "--alive",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.Legs.ShouldBe(12);
 | 
			
		||||
            dog.Age.ShouldBe(4);
 | 
			
		||||
            dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
            dog.Name.ShouldBe("Rufus");
 | 
			
		||||
            dog.IsAlive.ShouldBe(true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_3()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "dog", "12", "--good-boy",
 | 
			
		||||
            "--name", "Rufus",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
            dog.Name.ShouldBe("Rufus");
 | 
			
		||||
            dog.IsAlive.ShouldBe(false);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_4()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12", "--good-boy",
 | 
			
		||||
            "--name", "Rufus",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.Legs.ShouldBe(4);
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
            dog.IsAlive.ShouldBe(false);
 | 
			
		||||
            dog.Name.ShouldBe("Rufus");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_5()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<OptionVectorCommand>("multi");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "multi", "--foo", "a", "--foo", "b",
 | 
			
		||||
            "--bar", "1", "--foo", "c", "--bar", "2",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<OptionVectorSettings>().And(vec =>
 | 
			
		||||
        {
 | 
			
		||||
            vec.Foo.Length.ShouldBe(3);
 | 
			
		||||
            vec.Foo.ShouldBe(new[] { "a", "b", "c" });
 | 
			
		||||
            vec.Bar.Length.ShouldBe(2);
 | 
			
		||||
            vec.Bar.ShouldBe(new[] { 1, 2 });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Case_6()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<GenericCommand<ArgumentVectorSettings>>("multi");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "multi", "a", "b", "c",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<ArgumentVectorSettings>().And(vec =>
 | 
			
		||||
        {
 | 
			
		||||
            vec.Foo.Length.ShouldBe(3);
 | 
			
		||||
            vec.Foo.ShouldBe(new[] { "a", "b", "c" });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Be_Able_To_Use_Command_Alias()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<OptionVectorCommand>("multi").WithAlias("multiple");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "multiple", "--foo", "a",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<OptionVectorSettings>().And(vec =>
 | 
			
		||||
        {
 | 
			
		||||
            vec.Foo.Length.ShouldBe(1);
 | 
			
		||||
            vec.Foo.ShouldBe(new[] { "a" });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Assign_Default_Value_To_Optional_Argument()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<GenericCommand<OptionalArgumentWithDefaultValueSettings>>();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(Array.Empty<string>());
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<OptionalArgumentWithDefaultValueSettings>().And(settings =>
 | 
			
		||||
        {
 | 
			
		||||
            settings.Greeting.ShouldBe("Hello World");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Assign_Property_Initializer_To_Optional_Argument()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<GenericCommand<OptionalArgumentWithPropertyInitializerSettings>>();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(Array.Empty<string>());
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings
 | 
			
		||||
            .ShouldBeOfType<OptionalArgumentWithPropertyInitializerSettings>()
 | 
			
		||||
            .And(settings => settings.Count.ShouldBe(1))
 | 
			
		||||
            .And(settings => settings.Value.ShouldBe(0))
 | 
			
		||||
            .And(settings => settings.Names.ShouldNotBeNull())
 | 
			
		||||
            .And(settings => settings.Names.ShouldNotBeNull())
 | 
			
		||||
            .And(settings => settings.Names.ShouldBeEmpty());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Overwrite_Property_Initializer_With_Argument_Value()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<GenericCommand<OptionalArgumentWithPropertyInitializerSettings>>();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run("-c", "0", "-v", "50", "ABBA", "Herreys");
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings
 | 
			
		||||
            .ShouldBeOfType<OptionalArgumentWithPropertyInitializerSettings>()
 | 
			
		||||
            .And(settings => settings.Count.ShouldBe(0))
 | 
			
		||||
            .And(settings => settings.Value.ShouldBe(50))
 | 
			
		||||
            .And(settings => settings.Names.ShouldContain("ABBA"))
 | 
			
		||||
            .And(settings => settings.Names.ShouldContain("Herreys"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Assign_Default_Value_To_Optional_Argument_Using_Converter_If_Necessary()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<GenericCommand<OptionalArgumentWithDefaultValueAndTypeConverterSettings>>();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(Array.Empty<string>());
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<OptionalArgumentWithDefaultValueAndTypeConverterSettings>().And(settings =>
 | 
			
		||||
        {
 | 
			
		||||
            settings.Greeting.ShouldBe(5);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Throw_If_Required_Argument_Have_Default_Value()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<GenericCommand<RequiredArgumentWithDefaultValueSettings>>();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(Array.Empty<string>()));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("The required argument 'GREETING' cannot have a default value.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Throw_If_Alias_Conflicts_With_Another_Command()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<DogCommand>("dog").WithAlias("cat");
 | 
			
		||||
            config.AddCommand<CatCommand>("cat");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(new[] { "dog", "4", "12" }));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldBeOfType<CommandConfigurationException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("The alias 'cat' for 'dog' conflicts with another command.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Register_Commands_When_Configuring_Application()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var registrar = new FakeTypeRegistrar();
 | 
			
		||||
        var app = new CommandApp(registrar);
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<GenericCommand<FooCommandSettings>>("foo");
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(GenericCommand<FooCommandSettings>)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(DogCommand)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(HorseCommand)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations[typeof(GenericCommand<FooCommandSettings>)].ShouldContain(typeof(GenericCommand<FooCommandSettings>));
 | 
			
		||||
        registrar.Registrations[typeof(DogCommand)].ShouldContain(typeof(DogCommand));
 | 
			
		||||
        registrar.Registrations[typeof(HorseCommand)].ShouldContain(typeof(HorseCommand));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Register_Default_Command_When_Configuring_Application()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var registrar = new FakeTypeRegistrar();
 | 
			
		||||
        var app = new CommandApp<DogCommand>(registrar);
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "12", "4",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(DogCommand)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations[typeof(DogCommand)].ShouldContain(typeof(DogCommand));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Can_Register_Default_Command_Settings_When_Configuring_Application()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var registrar = new FakeTypeRegistrar();
 | 
			
		||||
        registrar.Register(typeof(DogSettings), typeof(DogSettings));
 | 
			
		||||
        var app = new CommandApp<DogCommand>(registrar);
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "12", "4",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(DogSettings)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations[typeof(DogSettings)].Count.ShouldBe(1);
 | 
			
		||||
        registrar.Registrations[typeof(DogSettings)].ShouldContain(typeof(DogSettings));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Can_Register_Command_Settings_When_Configuring_Application()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var registrar = new FakeTypeRegistrar();
 | 
			
		||||
        registrar.Register(typeof(DogSettings), typeof(DogSettings));
 | 
			
		||||
        registrar.Register(typeof(MammalSettings), typeof(MammalSettings));
 | 
			
		||||
        var app = new CommandApp(registrar);
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                animal.AddCommand<HorseCommand>("horse");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(DogSettings)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations[typeof(DogSettings)].Count.ShouldBe(1);
 | 
			
		||||
        registrar.Registrations[typeof(DogSettings)].ShouldContain(typeof(DogSettings));
 | 
			
		||||
        registrar.Registrations.ContainsKey(typeof(MammalSettings)).ShouldBeTrue();
 | 
			
		||||
        registrar.Registrations[typeof(MammalSettings)].Count.ShouldBe(1);
 | 
			
		||||
        registrar.Registrations[typeof(MammalSettings)].ShouldContain(typeof(MammalSettings));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Theory]
 | 
			
		||||
    [InlineData("true", true)]
 | 
			
		||||
    [InlineData("True", true)]
 | 
			
		||||
    [InlineData("false", false)]
 | 
			
		||||
    [InlineData("False", false)]
 | 
			
		||||
    public void Should_Accept_Explicit_Boolan_Flag(string value, bool expected)
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddCommand<DogCommand>("dog");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "dog", "12", "4", "--alive", value,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.IsAlive.ShouldBe(expected);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Throw_When_Encountering_Unknown_Option_In_Strict_Mode()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandApp();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.AddCommand<DogCommand>("dog");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = Record.Exception(() => app.Run(new[] { "dog", "--foo" }));
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ShouldBeOfType<CommandParseException>().And(ex =>
 | 
			
		||||
        {
 | 
			
		||||
            ex.Message.ShouldBe("Unknown option 'foo'.");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Add_Unknown_Option_To_Remaining_Arguments_In_Relaxed_Mode()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
            "--foo", "bar",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Context.ShouldNotBeNull();
 | 
			
		||||
        result.Context.Remaining.Parsed.Count.ShouldBe(1);
 | 
			
		||||
        result.Context.ShouldHaveRemainingArgument("foo", values: new[] { "bar" });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Add_Unknown_Option_To_Remaining_Arguments_In_Strict_Mode()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.UseStrictParsing();
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
            "--",
 | 
			
		||||
            "--foo", "bar",
 | 
			
		||||
            "-f", "baz",
 | 
			
		||||
            "qux",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Context.ShouldNotBeNull();
 | 
			
		||||
        result.Context.Remaining.Parsed.Count.ShouldBe(2);
 | 
			
		||||
        result.Context.ShouldHaveRemainingArgument("foo", values: new[] { "bar" });
 | 
			
		||||
        result.Context.ShouldHaveRemainingArgument("f", values: new[] { "baz" });
 | 
			
		||||
        result.Context.Remaining.Raw.Count.ShouldBe(5);
 | 
			
		||||
        result.Context.Remaining.Raw.ShouldBe(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "--foo", "bar",
 | 
			
		||||
            "-f", "baz",
 | 
			
		||||
            "qux",
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Add_Unknown_Boolean_Option_To_Remaining_Arguments_In_Relaxed_Mode()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12", "--foo",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Context.ShouldNotBeNull();
 | 
			
		||||
        result.Context.Remaining.Parsed.Count.ShouldBe(1);
 | 
			
		||||
        result.Context.ShouldHaveRemainingArgument("foo", values: new[] { (string)null });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Be_Able_To_Set_The_Default_Command()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.SetDefaultCommand<DogCommand>();
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "4", "12", "--good-boy", "--name", "Rufus",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.ExitCode.ShouldBe(0);
 | 
			
		||||
        result.Settings.ShouldBeOfType<DogSettings>().And(dog =>
 | 
			
		||||
        {
 | 
			
		||||
            dog.Legs.ShouldBe(4);
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.GoodBoy.ShouldBe(true);
 | 
			
		||||
            dog.Name.ShouldBe("Rufus");
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Set_Command_Name_In_Context()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Context.ShouldNotBeNull();
 | 
			
		||||
        result.Context.Name.ShouldBe("dog");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Command_Data_In_Context()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
        var app = new CommandAppTester();
 | 
			
		||||
        app.Configure(config =>
 | 
			
		||||
        {
 | 
			
		||||
            config.PropagateExceptions();
 | 
			
		||||
            config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
            {
 | 
			
		||||
                animal.AddCommand<DogCommand>("dog").WithData(123);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // When
 | 
			
		||||
        var result = app.Run(new[]
 | 
			
		||||
        {
 | 
			
		||||
            "animal", "4", "dog", "12",
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Then
 | 
			
		||||
        result.Context.ShouldNotBeNull();
 | 
			
		||||
        result.Context.Data.ShouldBe(123);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public sealed class Delegate_Commands
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Execute_Delegate_Command_At_Root_Level()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var dog = default(DogSettings);
 | 
			
		||||
            var data = 0;
 | 
			
		||||
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddDelegate<DogSettings>(
 | 
			
		||||
                    "foo", (context, settings) =>
 | 
			
		||||
                    {
 | 
			
		||||
                        dog = settings;
 | 
			
		||||
                        data = (int)context.Data;
 | 
			
		||||
                        return 1;
 | 
			
		||||
                    }).WithData(2);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo", "4", "12" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBe(1);
 | 
			
		||||
            dog.ShouldNotBeNull();
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.Legs.ShouldBe(4);
 | 
			
		||||
            data.ShouldBe(2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Execute_Nested_Delegate_Command()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var dog = default(DogSettings);
 | 
			
		||||
            var data = 0;
 | 
			
		||||
 | 
			
		||||
            var app = new CommandApp();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("foo", foo =>
 | 
			
		||||
                {
 | 
			
		||||
                    foo.AddDelegate<DogSettings>(
 | 
			
		||||
                        "bar", (context, settings) =>
 | 
			
		||||
                        {
 | 
			
		||||
                            dog = settings;
 | 
			
		||||
                            data = (int)context.Data;
 | 
			
		||||
                            return 1;
 | 
			
		||||
                        }).WithData(2);
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[] { "foo", "4", "bar", "12" });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.ShouldBe(1);
 | 
			
		||||
            dog.ShouldNotBeNull();
 | 
			
		||||
            dog.Age.ShouldBe(12);
 | 
			
		||||
            dog.Legs.ShouldBe(4);
 | 
			
		||||
            data.ShouldBe(2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public sealed class Remaining_Arguments
 | 
			
		||||
    {
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Register_Remaining_Parsed_Arguments_With_Context()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "4", "dog", "12", "--",
 | 
			
		||||
                "--foo", "bar", "--foo", "baz",
 | 
			
		||||
                "-bar", "\"baz\"", "qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Context.Remaining.Parsed.Count.ShouldBe(4);
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("foo", values: new[] { "bar", "baz" });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("b", values: new[] { (string)null });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("a", values: new[] { (string)null });
 | 
			
		||||
            result.Context.ShouldHaveRemainingArgument("r", values: new[] { (string)null });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Should_Register_Remaining_Raw_Arguments_With_Context()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var app = new CommandAppTester();
 | 
			
		||||
            app.Configure(config =>
 | 
			
		||||
            {
 | 
			
		||||
                config.PropagateExceptions();
 | 
			
		||||
                config.AddBranch<AnimalSettings>("animal", animal =>
 | 
			
		||||
                {
 | 
			
		||||
                    animal.AddCommand<DogCommand>("dog");
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = app.Run(new[]
 | 
			
		||||
            {
 | 
			
		||||
                "animal", "4", "dog", "12", "--",
 | 
			
		||||
                "--foo", "bar", "-bar", "\"baz\"", "qux",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            result.Context.Remaining.Raw.Count.ShouldBe(5);
 | 
			
		||||
            result.Context.Remaining.Raw[0].ShouldBe("--foo");
 | 
			
		||||
            result.Context.Remaining.Raw[1].ShouldBe("bar");
 | 
			
		||||
            result.Context.Remaining.Raw[2].ShouldBe("-bar");
 | 
			
		||||
            result.Context.Remaining.Raw[3].ShouldBe("baz");
 | 
			
		||||
            result.Context.Remaining.Raw[4].ShouldBe("qux");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests.Unit.Cli;
 | 
			
		||||
 | 
			
		||||
public sealed class DefaultTypeRegistrarTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public void Should_Pass_Base_Registrar_Tests()
 | 
			
		||||
    {
 | 
			
		||||
        var harness = new TypeRegistrarBaseTests(() => new DefaultTypeRegistrar());
 | 
			
		||||
        harness.RunAllTests();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -14,7 +14,7 @@ public sealed class MultiSelectionPromptTests
 | 
			
		||||
                return x.X == y.X && x.Y == y.Y;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public int GetHashCode([DisallowNull] CustomItem obj)
 | 
			
		||||
            public int GetHashCode(CustomItem obj)
 | 
			
		||||
            {
 | 
			
		||||
                throw new NotSupportedException();
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@ namespace Spectre.Console.Tests.Unit;
 | 
			
		||||
public sealed class SelectionPromptTests
 | 
			
		||||
{
 | 
			
		||||
    [Fact]
 | 
			
		||||
    [GitHubIssue(608)]
 | 
			
		||||
    public void Should_Not_Throw_When_Selecting_An_Item_With_Escaped_Markup()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
 
 | 
			
		||||
@@ -227,7 +227,6 @@ public sealed class TextPromptTests
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    [Expectation("NoSuffix")]
 | 
			
		||||
    [GitHubIssue(413)]
 | 
			
		||||
    public Task Should_Not_Append_Questionmark_Or_Colon_If_No_Choices_Are_Set()
 | 
			
		||||
    {
 | 
			
		||||
        // Given
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Cli;
 | 
			
		||||
 | 
			
		||||
public static class CommandContextExtensions
 | 
			
		||||
{
 | 
			
		||||
    public static void ShouldHaveRemainingArgument(this CommandContext context, string name, string[] values)
 | 
			
		||||
    {
 | 
			
		||||
        if (context == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(context));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (values == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(values));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        context.Remaining.Parsed.Contains(name).ShouldBeTrue();
 | 
			
		||||
        context.Remaining.Parsed[name].Count().ShouldBe(values.Length);
 | 
			
		||||
 | 
			
		||||
        foreach (var value in values)
 | 
			
		||||
        {
 | 
			
		||||
            context.Remaining.Parsed[name].ShouldContain(value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
namespace Spectre.Console;
 | 
			
		||||
 | 
			
		||||
public static class ShouldlyExtensions
 | 
			
		||||
{
 | 
			
		||||
    [DebuggerStepThrough]
 | 
			
		||||
    public static T And<T>(this T item, Action<T> action)
 | 
			
		||||
    {
 | 
			
		||||
        if (action == null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(action));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        action(item);
 | 
			
		||||
        return item;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Testing;
 | 
			
		||||
 | 
			
		||||
public sealed class FakeTypeRegistrar : ITypeRegistrar
 | 
			
		||||
{
 | 
			
		||||
    public Dictionary<Type, List<Type>> Registrations { get; }
 | 
			
		||||
    public Dictionary<Type, List<object>> Instances { get; }
 | 
			
		||||
    public Func<Dictionary<Type, List<Type>>, Dictionary<Type, List<object>>, ITypeResolver> TypeResolverFactory { get; set; }
 | 
			
		||||
 | 
			
		||||
    public FakeTypeRegistrar()
 | 
			
		||||
    {
 | 
			
		||||
        Registrations = new Dictionary<Type, List<Type>>();
 | 
			
		||||
        Instances = new Dictionary<Type, List<object>>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Register(Type service, Type implementation)
 | 
			
		||||
    {
 | 
			
		||||
        if (!Registrations.ContainsKey(service))
 | 
			
		||||
        {
 | 
			
		||||
            Registrations.Add(service, new List<Type> { implementation });
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            Registrations[service].Add(implementation);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void RegisterInstance(Type service, object implementation)
 | 
			
		||||
    {
 | 
			
		||||
        if (!Instances.ContainsKey(service))
 | 
			
		||||
        {
 | 
			
		||||
            Instances.Add(service, new List<object> { implementation });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void RegisterLazy(Type service, Func<object> factory)
 | 
			
		||||
    {
 | 
			
		||||
        if (factory is null)
 | 
			
		||||
        {
 | 
			
		||||
            throw new ArgumentNullException(nameof(factory));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!Instances.ContainsKey(service))
 | 
			
		||||
        {
 | 
			
		||||
            Instances.Add(service, new List<object> { factory() });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ITypeResolver Build()
 | 
			
		||||
    {
 | 
			
		||||
        return TypeResolverFactory?.Invoke(Registrations, Instances);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Testing;
 | 
			
		||||
 | 
			
		||||
public sealed class FakeTypeResolver : ITypeResolver
 | 
			
		||||
{
 | 
			
		||||
    private readonly Dictionary<Type, List<Type>> _registrations;
 | 
			
		||||
    private readonly Dictionary<Type, List<object>> _instances;
 | 
			
		||||
 | 
			
		||||
    public FakeTypeResolver(
 | 
			
		||||
        Dictionary<Type, List<Type>> registrations,
 | 
			
		||||
        Dictionary<Type, List<object>> instances)
 | 
			
		||||
    {
 | 
			
		||||
        _registrations = registrations ?? throw new ArgumentNullException(nameof(registrations));
 | 
			
		||||
        _instances = instances ?? throw new ArgumentNullException(nameof(instances));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Func<Dictionary<Type, List<Type>>, Dictionary<Type, List<object>>, ITypeResolver> Factory =>
 | 
			
		||||
        (r, i) => new FakeTypeResolver(r, i);
 | 
			
		||||
 | 
			
		||||
    public object Resolve(Type type)
 | 
			
		||||
    {
 | 
			
		||||
        if (_instances.TryGetValue(type, out var instances))
 | 
			
		||||
        {
 | 
			
		||||
            return instances.FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (_registrations.TryGetValue(type, out var registrations))
 | 
			
		||||
        {
 | 
			
		||||
            return registrations.Count == 0
 | 
			
		||||
                ? null
 | 
			
		||||
                : Activator.CreateInstance(type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
namespace Spectre.Console.Tests;
 | 
			
		||||
 | 
			
		||||
[AttributeUsage(AttributeTargets.Method)]
 | 
			
		||||
public sealed class GitHubIssueAttribute : Attribute
 | 
			
		||||
{
 | 
			
		||||
    public int IssueId { get; }
 | 
			
		||||
 | 
			
		||||
    public GitHubIssueAttribute(int issueId)
 | 
			
		||||
    {
 | 
			
		||||
        IssueId = issueId;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user