Refactor tests

This commit is contained in:
Alexey Golub
2019-08-25 17:27:17 +03:00
parent cd3892bf83
commit 43a304bb26
36 changed files with 441 additions and 441 deletions

View File

@@ -1,15 +0,0 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests
{
public partial class CliApplicationBuilderTests
{
[Command]
private class TestCommand : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -1,12 +1,13 @@
using System; using System;
using System.IO; using System.IO;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests namespace CliFx.Tests
{ {
[TestFixture] [TestFixture]
public partial class CliApplicationBuilderTests public class CliApplicationBuilderTests
{ {
// Make sure all builder methods work // Make sure all builder methods work
[Test] [Test]
@@ -17,10 +18,10 @@ namespace CliFx.Tests
// Act // Act
builder builder
.AddCommand(typeof(TestCommand)) .AddCommand(typeof(EchoCommand))
.AddCommandsFrom(typeof(TestCommand).Assembly) .AddCommandsFrom(typeof(EchoCommand).Assembly)
.AddCommands(new[] {typeof(TestCommand)}) .AddCommands(new[] {typeof(EchoCommand)})
.AddCommandsFrom(new[] {typeof(TestCommand).Assembly}) .AddCommandsFrom(new[] {typeof(EchoCommand).Assembly})
.AddCommandsFromThisAssembly() .AddCommandsFromThisAssembly()
.AllowDebugMode() .AllowDebugMode()
.AllowPreviewMode() .AllowPreviewMode()

View File

@@ -1,53 +0,0 @@
using System;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Exceptions;
using CliFx.Services;
namespace CliFx.Tests
{
public partial class CliApplicationTests
{
[Command]
private class DefaultCommand : ICommand
{
public Task ExecuteAsync(IConsole console)
{
console.Output.WriteLine("DefaultCommand executed.");
return Task.CompletedTask;
}
}
[Command("cmd")]
private class NamedCommand : ICommand
{
public Task ExecuteAsync(IConsole console)
{
console.Output.WriteLine("NamedCommand executed.");
return Task.CompletedTask;
}
}
}
// Negative
public partial class CliApplicationTests
{
[Command("faulty1")]
private class FaultyCommand1 : ICommand
{
public Task ExecuteAsync(IConsole console) => throw new CommandException(150);
}
[Command("faulty2")]
private class FaultyCommand2 : ICommand
{
public Task ExecuteAsync(IConsole console) => throw new CommandException("FaultyCommand2 error message.", 150);
}
[Command("faulty3")]
private class FaultyCommand3 : ICommand
{
public Task ExecuteAsync(IConsole console) => throw new Exception("FaultyCommand3 error message.");
}
}
}

View File

@@ -3,38 +3,39 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests namespace CliFx.Tests
{ {
[TestFixture] [TestFixture]
public partial class CliApplicationTests public class CliApplicationTests
{ {
private const string TestVersionText = "v1.0"; private const string TestVersionText = "v1.0";
private static IEnumerable<TestCaseData> GetTestCases_RunAsync() private static IEnumerable<TestCaseData> GetTestCases_RunAsync()
{ {
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoDefaultCommand)},
new string[0], new[] {"-m", "foo bar"},
"DefaultCommand executed." "foo bar"
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"cmd"}, new[] {"echo", "-m", "foo bar"},
"NamedCommand executed." "foo bar"
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoDefaultCommand)},
new[] {"--version"}, new[] {"--version"},
TestVersionText TestVersionText
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"--version"}, new[] {"--version"},
TestVersionText TestVersionText
); );
@@ -43,78 +44,68 @@ namespace CliFx.Tests
private static IEnumerable<TestCaseData> GetTestCases_RunAsync_Smoke() private static IEnumerable<TestCaseData> GetTestCases_RunAsync_Smoke()
{ {
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoDefaultCommand)},
new string[0]
);
yield return new TestCaseData(
new[] {typeof(DefaultCommand)},
new[] {"-h"} new[] {"-h"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoDefaultCommand)},
new[] {"--help"} new[] {"--help"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoDefaultCommand)},
new[] {"--version"} new[] {"--version"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new string[0] new string[0]
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"-h"} new[] {"-h"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"--help"} new[] {"--help"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"--version"} new[] {"--version"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NamedCommand)}, new[] {typeof(EchoCommand)},
new[] {"cmd", "-h"} new[] {"echo", "-h"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand1)}, new[] {typeof(ExceptionCommand)},
new[] {"faulty1", "-h"} new[] {"exc", "-h"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand2)}, new[] {typeof(CommandExceptionCommand)},
new[] {"faulty2", "-h"} new[] {"exc", "-h"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand3)}, new[] {typeof(EchoDefaultCommand)},
new[] {"faulty3", "-h"}
);
yield return new TestCaseData(
new[] {typeof(DefaultCommand)},
new[] {"[preview]"} new[] {"[preview]"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand1)}, new[] {typeof(ExceptionCommand)},
new[] {"faulty1", "[preview]"} new[] {"exc", "[preview]"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand1)}, new[] {typeof(EchoCommand)},
new[] {"faulty1", "[preview]", "-o", "value"} new[] {"echo", "[preview]", "-o", "value"}
); );
} }
@@ -126,23 +117,23 @@ namespace CliFx.Tests
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(DefaultCommand)}, new[] {typeof(EchoCommand)},
new[] {"non-existing"} new[] {"non-existing"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand1)}, new[] {typeof(ExceptionCommand)},
new[] {"faulty1"} new[] {"exc"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand2)}, new[] {typeof(CommandExceptionCommand)},
new[] {"faulty2"} new[] {"exc"}
); );
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(FaultyCommand3)}, new[] {typeof(CommandExceptionCommand)},
new[] {"faulty3"} new[] {"exc", "-c", "666"}
); );
} }

View File

@@ -1,15 +0,0 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.Services
{
public partial class CommandFactoryTests
{
[Command]
private class TestCommand : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -3,20 +3,21 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class CommandFactoryTests public class CommandFactoryTests
{ {
private static CommandSchema GetCommandSchema(Type commandType) => private static CommandSchema GetCommandSchema(Type commandType) =>
new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single(); new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single();
private static IEnumerable<TestCaseData> GetTestCases_CreateCommand() private static IEnumerable<TestCaseData> GetTestCases_CreateCommand()
{ {
yield return new TestCaseData(GetCommandSchema(typeof(TestCommand))); yield return new TestCaseData(GetCommandSchema(typeof(EchoCommand)));
} }
[Test] [Test]

View File

@@ -1,24 +0,0 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.Services
{
public partial class CommandInitializerTests
{
[Command]
private class TestCommand : ICommand
{
[CommandOption("int", 'i', IsRequired = true)]
public int Option1 { get; set; } = 24;
[CommandOption("str", 's')]
public string Option2 { get; set; } = "foo bar";
[CommandOption('S')]
public bool Option3 { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -4,13 +4,14 @@ using System.Linq;
using CliFx.Exceptions; using CliFx.Exceptions;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class CommandInitializerTests public class CommandInitializerTests
{ {
private static CommandSchema GetCommandSchema(Type commandType) => private static CommandSchema GetCommandSchema(Type commandType) =>
new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single(); new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single();
@@ -18,63 +19,89 @@ namespace CliFx.Tests.Services
private static IEnumerable<TestCaseData> GetTestCases_InitializeCommand() private static IEnumerable<TestCaseData> GetTestCases_InitializeCommand()
{ {
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new DivideCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(DivideCommand)),
new CommandInput(new[] new CommandInput("div", new[]
{ {
new CommandOptionInput("int", "13") new CommandOptionInput("dividend", "13"),
new CommandOptionInput("divisor", "8")
}), }),
new TestCommand {Option1 = 13} new DivideCommand {Dividend = 13, Divisor = 8}
); );
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new DivideCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(DivideCommand)),
new CommandInput(new[] new CommandInput("div", new[]
{ {
new CommandOptionInput("int", "13"), new CommandOptionInput("dividend", "13"),
new CommandOptionInput("str", "hello world") new CommandOptionInput("d", "8")
}), }),
new TestCommand {Option1 = 13, Option2 = "hello world"} new DivideCommand {Dividend = 13, Divisor = 8}
); );
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new DivideCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(DivideCommand)),
new CommandInput(new[] new CommandInput("div", new[]
{ {
new CommandOptionInput("i", "13") new CommandOptionInput("D", "13"),
new CommandOptionInput("d", "8")
}), }),
new TestCommand {Option1 = 13} new DivideCommand {Dividend = 13, Divisor = 8}
); );
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new ConcatCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(ConcatCommand)),
new CommandInput(new[] new CommandInput("concat", new[]
{ {
new CommandOptionInput("i", "13"), new CommandOptionInput("i", new[] {"foo", " ", "bar"})
new CommandOptionInput("s", "hello world"),
new CommandOptionInput("S")
}), }),
new TestCommand {Option1 = 13, Option2 = "hello world", Option3 = true} new ConcatCommand {Inputs = new[] {"foo", " ", "bar"}}
);
yield return new TestCaseData(
new ConcatCommand(),
GetCommandSchema(typeof(ConcatCommand)),
new CommandInput("concat", new[]
{
new CommandOptionInput("i", new[] {"foo", "bar"}),
new CommandOptionInput("s", " ")
}),
new ConcatCommand {Inputs = new[] {"foo", "bar"}, Separator = " "}
); );
} }
private static IEnumerable<TestCaseData> GetTestCases_InitializeCommand_Negative() private static IEnumerable<TestCaseData> GetTestCases_InitializeCommand_Negative()
{ {
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new DivideCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(DivideCommand)),
CommandInput.Empty new CommandInput("div")
); );
yield return new TestCaseData( yield return new TestCaseData(
new TestCommand(), new DivideCommand(),
GetCommandSchema(typeof(TestCommand)), GetCommandSchema(typeof(DivideCommand)),
new CommandInput(new[] new CommandInput("div", new[]
{ {
new CommandOptionInput("str", "hello world") new CommandOptionInput("D", "13")
})
);
yield return new TestCaseData(
new ConcatCommand(),
GetCommandSchema(typeof(ConcatCommand)),
new CommandInput("concat")
);
yield return new TestCaseData(
new ConcatCommand(),
GetCommandSchema(typeof(ConcatCommand)),
new CommandInput("concat", new[]
{
new CommandOptionInput("s", "_")
}) })
); );
} }

View File

@@ -1,63 +0,0 @@
using System;
namespace CliFx.Tests.Services
{
public partial class CommandOptionInputConverterTests
{
private enum TestEnum
{
Value1,
Value2,
Value3
}
private class TestStringConstructable
{
public string Value { get; }
public TestStringConstructable(string value)
{
Value = value;
}
}
private class TestStringParseable
{
public string Value { get; }
private TestStringParseable(string value)
{
Value = value;
}
public static TestStringParseable Parse(string value) => new TestStringParseable(value);
}
private class TestStringParseableWithFormatProvider
{
public string Value { get; }
private TestStringParseableWithFormatProvider(string value)
{
Value = value;
}
public static TestStringParseableWithFormatProvider Parse(string value, IFormatProvider formatProvider) =>
new TestStringParseableWithFormatProvider(value + " " + formatProvider);
}
}
// Negative
public partial class CommandOptionInputConverterTests
{
private class NonStringParseable
{
public int Value { get; }
public NonStringParseable(int value)
{
Value = value;
}
}
}
}

View File

@@ -5,13 +5,14 @@ using System.Globalization;
using CliFx.Exceptions; using CliFx.Exceptions;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCustomTypes;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class CommandOptionInputConverterTests public class CommandOptionInputConverterTests
{ {
private static IEnumerable<TestCaseData> GetTestCases_ConvertOptionInput() private static IEnumerable<TestCaseData> GetTestCases_ConvertOptionInput()
{ {
@@ -271,7 +272,7 @@ namespace CliFx.Tests.Services
yield return new TestCaseData( yield return new TestCaseData(
new CommandOptionInput("option", "123"), new CommandOptionInput("option", "123"),
typeof(NonStringParseable) typeof(TestNonStringParseable)
); );
} }

View File

@@ -1,90 +0,0 @@
using System;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.Services
{
public partial class CommandSchemaResolverTests
{
[Command("cmd", Description = "NormalCommand1 description.")]
private class NormalCommand1 : ICommand
{
[CommandOption("option-a", 'a')]
public int OptionA { get; set; }
[CommandOption('A')]
public int AlmostOptionA { get; set; }
[CommandOption("option-b", IsRequired = true)]
public string OptionB { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command(Description = "NormalCommand2 description.")]
private class NormalCommand2 : ICommand
{
[CommandOption("option-c", Description = "OptionC description.")]
public bool OptionC { get; set; }
[CommandOption("option-d", 'd')]
public DateTimeOffset OptionD { get; set; }
public string NotAnOption { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
// Negative
public partial class CommandSchemaResolverTests
{
[Command("conflict")]
private class ConflictingCommand1 : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command("conflict")]
private class ConflictingCommand2 : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command]
private class InvalidCommand1
{
}
// No attribute
private class InvalidCommand2 : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command]
private class InvalidCommand3 : ICommand
{
[CommandOption("conflict")]
public string ConflictingOption1 { get; set; }
[CommandOption("conflict")]
public string ConflictingOption2 { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command]
private class InvalidCommand4 : ICommand
{
[CommandOption('c')]
public string ConflictingOption1 { get; set; }
[CommandOption('c')]
public string ConflictingOption2 { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -3,37 +3,49 @@ using System.Collections.Generic;
using CliFx.Exceptions; using CliFx.Exceptions;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class CommandSchemaResolverTests public class CommandSchemaResolverTests
{ {
private static IEnumerable<TestCaseData> GetTestCases_GetCommandSchemas() private static IEnumerable<TestCaseData> GetTestCases_GetCommandSchemas()
{ {
yield return new TestCaseData( yield return new TestCaseData(
new[] {typeof(NormalCommand1), typeof(NormalCommand2)}, new[] {typeof(DivideCommand), typeof(ConcatCommand)},
new[] new[]
{ {
new CommandSchema(typeof(NormalCommand1), "cmd", "NormalCommand1 description.", new CommandSchema(typeof(DivideCommand), "div", "Divide one number by another.",
new[] new[]
{ {
new CommandOptionSchema(typeof(NormalCommand1).GetProperty(nameof(NormalCommand1.OptionA)), new CommandOptionSchema(typeof(DivideCommand).GetProperty(nameof(DivideCommand.Dividend)),
"option-a", 'a', false, null), "dividend", 'D', true, "The number to divide."),
new CommandOptionSchema(typeof(NormalCommand1).GetProperty(nameof(NormalCommand1.AlmostOptionA)), new CommandOptionSchema(typeof(DivideCommand).GetProperty(nameof(DivideCommand.Divisor)),
null, 'A', false, null), "divisor", 'd', true, "The number to divide by.")
new CommandOptionSchema(typeof(NormalCommand1).GetProperty(nameof(NormalCommand1.OptionB)),
"option-b", null, true, null)
}), }),
new CommandSchema(typeof(NormalCommand2), null, "NormalCommand2 description.", new CommandSchema(typeof(ConcatCommand), "concat", "Concatenate strings.",
new[] new[]
{ {
new CommandOptionSchema(typeof(NormalCommand2).GetProperty(nameof(NormalCommand2.OptionC)), new CommandOptionSchema(typeof(ConcatCommand).GetProperty(nameof(ConcatCommand.Inputs)),
"option-c", null, false, "OptionC description."), null, 'i', true, "Input strings."),
new CommandOptionSchema(typeof(NormalCommand2).GetProperty(nameof(NormalCommand2.OptionD)), new CommandOptionSchema(typeof(ConcatCommand).GetProperty(nameof(ConcatCommand.Separator)),
"option-d", 'd', false, null) null, 's', false, "String separator.")
})
}
);
yield return new TestCaseData(
new[] {typeof(EchoDefaultCommand)},
new[]
{
new CommandSchema(typeof(EchoDefaultCommand), null, null,
new[]
{
new CommandOptionSchema(typeof(EchoDefaultCommand).GetProperty(nameof(EchoDefaultCommand.Message)),
"message", 'm', true, null)
}) })
} }
); );
@@ -48,27 +60,27 @@ namespace CliFx.Tests.Services
yield return new TestCaseData(new object[] yield return new TestCaseData(new object[]
{ {
new[] {typeof(ConflictingCommand1), typeof(ConflictingCommand2)} new[] {typeof(NonImplementedCommand)}
}); });
yield return new TestCaseData(new object[] yield return new TestCaseData(new object[]
{ {
new[] {typeof(InvalidCommand1)} new[] {typeof(NonAnnotatedCommand)}
});
yield return new TestCaseData(new object[]
{
new[] {typeof(DuplicateOptionNamesCommand)}
}); });
yield return new TestCaseData(new object[] yield return new TestCaseData(new object[]
{ {
new[] {typeof(InvalidCommand2)} new[] {typeof(DuplicateOptionShortNamesCommand)}
}); });
yield return new TestCaseData(new object[] yield return new TestCaseData(new object[]
{ {
new[] {typeof(InvalidCommand3)} new[] {typeof(ExceptionCommand), typeof(CommandExceptionCommand)}
});
yield return new TestCaseData(new object[]
{
new[] {typeof(InvalidCommand4)}
}); });
} }

View File

@@ -1,15 +0,0 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.Services
{
public partial class DelegateCommandFactoryTests
{
[Command]
private class TestCommand : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -3,13 +3,14 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class DelegateCommandFactoryTests public class DelegateCommandFactoryTests
{ {
private static CommandSchema GetCommandSchema(Type commandType) => private static CommandSchema GetCommandSchema(Type commandType) =>
new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single(); new CommandSchemaResolver().GetCommandSchemas(new[] {commandType}).Single();
@@ -18,7 +19,7 @@ namespace CliFx.Tests.Services
{ {
yield return new TestCaseData( yield return new TestCaseData(
new Func<CommandSchema, ICommand>(schema => (ICommand) Activator.CreateInstance(schema.Type)), new Func<CommandSchema, ICommand>(schema => (ICommand) Activator.CreateInstance(schema.Type)),
GetCommandSchema(typeof(TestCommand)) GetCommandSchema(typeof(EchoCommand))
); );
} }

View File

@@ -1,42 +0,0 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.Services
{
public partial class HelpTextRendererTests
{
[Command(Description = "DefaultCommand description.")]
private class DefaultCommand : ICommand
{
[CommandOption("option-a", 'a', Description = "OptionA description.")]
public string OptionA { get; set; }
[CommandOption("option-b", 'b', Description = "OptionB description.")]
public string OptionB { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command("cmd", Description = "NamedCommand description.")]
private class NamedCommand : ICommand
{
[CommandOption("option-c", 'c', Description = "OptionC description.")]
public string OptionC { get; set; }
[CommandOption("option-d", 'd', Description = "OptionD description.")]
public string OptionD { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
[Command("cmd sub", Description = "NamedSubCommand description.")]
private class NamedSubCommand : ICommand
{
[CommandOption("option-e", 'e', Description = "OptionE description.")]
public string OptionE { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -4,13 +4,14 @@ using System.IO;
using System.Linq; using System.Linq;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using CliFx.Tests.TestCommands;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
namespace CliFx.Tests.Services namespace CliFx.Tests.Services
{ {
[TestFixture] [TestFixture]
public partial class HelpTextRendererTests public class HelpTextRendererTests
{ {
private static HelpTextSource CreateHelpTextSource(IReadOnlyList<Type> availableCommandTypes, Type targetCommandType) private static HelpTextSource CreateHelpTextSource(IReadOnlyList<Type> availableCommandTypes, Type targetCommandType)
{ {
@@ -27,11 +28,13 @@ namespace CliFx.Tests.Services
{ {
yield return new TestCaseData( yield return new TestCaseData(
CreateHelpTextSource( CreateHelpTextSource(
new[] {typeof(DefaultCommand), typeof(NamedCommand), typeof(NamedSubCommand)}, new[] {typeof(HelpDefaultCommand), typeof(HelpNamedCommand), typeof(HelpSubCommand)},
typeof(DefaultCommand)), typeof(HelpDefaultCommand)),
new[] new[]
{ {
"Description",
"HelpDefaultCommand description.",
"Usage", "Usage",
"[command]", "[options]", "[command]", "[options]",
"Options", "Options",
@@ -40,20 +43,20 @@ namespace CliFx.Tests.Services
"-h|--help", "Shows help text.", "-h|--help", "Shows help text.",
"--version", "Shows version information.", "--version", "Shows version information.",
"Commands", "Commands",
"cmd", "NamedCommand description.", "cmd", "HelpNamedCommand description.",
"You can run", "to show help on a specific command." "You can run", "to show help on a specific command."
} }
); );
yield return new TestCaseData( yield return new TestCaseData(
CreateHelpTextSource( CreateHelpTextSource(
new[] {typeof(DefaultCommand), typeof(NamedCommand), typeof(NamedSubCommand)}, new[] {typeof(HelpDefaultCommand), typeof(HelpNamedCommand), typeof(HelpSubCommand)},
typeof(NamedCommand)), typeof(HelpNamedCommand)),
new[] new[]
{ {
"Description", "Description",
"NamedCommand description.", "HelpNamedCommand description.",
"Usage", "Usage",
"cmd", "[command]", "[options]", "cmd", "[command]", "[options]",
"Options", "Options",
@@ -61,20 +64,20 @@ namespace CliFx.Tests.Services
"-d|--option-d", "OptionD description.", "-d|--option-d", "OptionD description.",
"-h|--help", "Shows help text.", "-h|--help", "Shows help text.",
"Commands", "Commands",
"sub", "NamedSubCommand description.", "sub", "HelpSubCommand description.",
"You can run", "to show help on a specific command." "You can run", "to show help on a specific command."
} }
); );
yield return new TestCaseData( yield return new TestCaseData(
CreateHelpTextSource( CreateHelpTextSource(
new[] {typeof(DefaultCommand), typeof(NamedCommand), typeof(NamedSubCommand)}, new[] {typeof(HelpDefaultCommand), typeof(HelpNamedCommand), typeof(HelpSubCommand)},
typeof(NamedSubCommand)), typeof(HelpSubCommand)),
new[] new[]
{ {
"Description", "Description",
"NamedSubCommand description.", "HelpSubCommand description.",
"Usage", "Usage",
"cmd sub", "[options]", "cmd sub", "[options]",
"Options", "Options",

View File

@@ -0,0 +1,19 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Exceptions;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("exc")]
public class CommandExceptionCommand : ICommand
{
[CommandOption("code", 'c')]
public int ExitCode { get; set; } = 1337;
[CommandOption("msg", 'm')]
public string Message { get; set; }
public Task ExecuteAsync(IConsole console) => throw new CommandException(Message, ExitCode);
}
}

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("concat", Description = "Concatenate strings.")]
public class ConcatCommand : ICommand
{
[CommandOption('i', IsRequired = true, Description = "Input strings.")]
public IReadOnlyList<string> Inputs { get; set; }
[CommandOption('s', Description = "String separator.")]
public string Separator { get; set; } = "";
public Task ExecuteAsync(IConsole console)
{
console.Output.WriteLine(string.Join(Separator, Inputs));
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,25 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("div", Description = "Divide one number by another.")]
public class DivideCommand : ICommand
{
[CommandOption("dividend", 'D', IsRequired = true, Description = "The number to divide.")]
public double Dividend { get; set; }
[CommandOption("divisor", 'd', IsRequired = true, Description = "The number to divide by.")]
public double Divisor { get; set; }
// This property should be ignored by resolver
public bool NotAnOption { get; set; }
public Task ExecuteAsync(IConsole console)
{
console.Output.WriteLine(Dividend / Divisor);
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command]
public class DuplicateOptionNamesCommand : ICommand
{
[CommandOption("fruits")]
public string Apples { get; set; }
[CommandOption("fruits")]
public string Oranges { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command]
public class DuplicateOptionShortNamesCommand : ICommand
{
[CommandOption('f')]
public string Apples { get; set; }
[CommandOption('f')]
public string Oranges { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,19 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("echo")]
public class EchoCommand : ICommand
{
[CommandOption("message", 'm', IsRequired = true)]
public string Message { get; set; }
public Task ExecuteAsync(IConsole console)
{
console.Output.WriteLine(Message);
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,9 @@
using CliFx.Attributes;
namespace CliFx.Tests.TestCommands
{
[Command]
public class EchoDefaultCommand : EchoCommand
{
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("exc")]
public class ExceptionCommand : ICommand
{
[CommandOption("msg", 'm')]
public string Message { get; set; }
public Task ExecuteAsync(IConsole console) => throw new Exception(Message);
}
}

View File

@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command(Description = "HelpDefaultCommand description.")]
public class HelpDefaultCommand : ICommand
{
[CommandOption("option-a", 'a', Description = "OptionA description.")]
public string OptionA { get; set; }
[CommandOption("option-b", 'b', Description = "OptionB description.")]
public string OptionB { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("cmd", Description = "HelpNamedCommand description.")]
public class HelpNamedCommand : ICommand
{
[CommandOption("option-c", 'c', Description = "OptionC description.")]
public string OptionC { get; set; }
[CommandOption("option-d", 'd', Description = "OptionD description.")]
public string OptionD { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,15 @@
using System.Threading.Tasks;
using CliFx.Attributes;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
[Command("cmd sub", Description = "HelpSubCommand description.")]
public class HelpSubCommand : ICommand
{
[CommandOption("option-e", 'e', Description = "OptionE description.")]
public string OptionE { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
using CliFx.Services;
namespace CliFx.Tests.TestCommands
{
public class NonAnnotatedCommand : ICommand
{
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}

View File

@@ -0,0 +1,9 @@
using CliFx.Attributes;
namespace CliFx.Tests.TestCommands
{
[Command]
public class NonImplementedCommand
{
}
}

View File

@@ -0,0 +1,9 @@
namespace CliFx.Tests.TestCustomTypes
{
public enum TestEnum
{
Value1,
Value2,
Value3
}
}

View File

@@ -0,0 +1,12 @@
namespace CliFx.Tests.TestCustomTypes
{
public class TestNonStringParseable
{
public int Value { get; }
public TestNonStringParseable(int value)
{
Value = value;
}
}
}

View File

@@ -0,0 +1,12 @@
namespace CliFx.Tests.TestCustomTypes
{
public class TestStringConstructable
{
public string Value { get; }
public TestStringConstructable(string value)
{
Value = value;
}
}
}

View File

@@ -0,0 +1,14 @@
namespace CliFx.Tests.TestCustomTypes
{
public class TestStringParseable
{
public string Value { get; }
private TestStringParseable(string value)
{
Value = value;
}
public static TestStringParseable Parse(string value) => new TestStringParseable(value);
}
}

View File

@@ -0,0 +1,17 @@
using System;
namespace CliFx.Tests.TestCustomTypes
{
public class TestStringParseableWithFormatProvider
{
public string Value { get; }
private TestStringParseableWithFormatProvider(string value)
{
Value = value;
}
public static TestStringParseableWithFormatProvider Parse(string value, IFormatProvider formatProvider) =>
new TestStringParseableWithFormatProvider(value + " " + formatProvider);
}
}

View File

@@ -129,7 +129,7 @@ namespace CliFx
// Keep track whether there was an error in the input // Keep track whether there was an error in the input
var isError = false; var isError = false;
// If target command isn't defined, find its parent // If target command isn't defined, find its contextual replacement
if (targetCommandSchema == null) if (targetCommandSchema == null)
{ {
// If command was specified, inform the user that it's not defined // If command was specified, inform the user that it's not defined

View File

@@ -1,5 +1,4 @@
using System; using CliFx.Models;
using CliFx.Models;
namespace CliFx.Services namespace CliFx.Services
{ {