Improve tests

This commit is contained in:
Tyrrrz
2020-10-23 21:18:57 +03:00
parent b120138de3
commit 14ad9d5738
6 changed files with 100 additions and 22 deletions

View File

@@ -275,11 +275,8 @@ namespace CliFx.Analyzers
private static void CheckCommandType(SymbolAnalysisContext context)
{
// Named type: MyCommand
if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol))
return;
// Only classes
if (namedTypeSymbol.TypeKind != TypeKind.Class)
if (!(context.Symbol is INamedTypeSymbol namedTypeSymbol) ||
namedTypeSymbol.TypeKind != TypeKind.Class)
return;
// Implements ICommand?

View File

@@ -913,7 +913,7 @@ namespace CliFx.Tests
}
[Fact]
public async Task Argument_value_can_be_bound_to_an_enum_type_by_name()
public async Task Argument_value_can_be_bound_to_enum_type_by_name()
{
// Arrange
var (console, stdOut, _) = VirtualConsole.CreateBuffered();
@@ -941,7 +941,7 @@ namespace CliFx.Tests
}
[Fact]
public async Task Argument_value_can_be_bound_to_an_enum_type_by_id()
public async Task Argument_value_can_be_bound_to_enum_type_by_id()
{
// Arrange
var (console, stdOut, _) = VirtualConsole.CreateBuffered();
@@ -1318,6 +1318,54 @@ namespace CliFx.Tests
});
}
[Fact]
public async Task Argument_value_can_only_be_bound_if_the_target_type_is_supported()
{
// Arrange
var (console, _, stdErr) = VirtualConsole.CreateBuffered();
var application = new CliApplicationBuilder()
.AddCommand<UnsupportedArgumentTypesCommand>()
.UseConsole(console)
.Build();
// Act
var exitCode = await application.RunAsync(new[]
{
"cmd", "--custom"
});
// Assert
exitCode.Should().NotBe(0);
stdErr.GetString().Should().NotBeNullOrWhiteSpace();
_output.WriteLine(stdErr.GetString());
}
[Fact]
public async Task Argument_value_can_only_be_bound_if_the_provided_value_can_be_converted_to_the_target_type()
{
// Arrange
var (console, _, stdErr) = VirtualConsole.CreateBuffered();
var application = new CliApplicationBuilder()
.AddCommand<SupportedArgumentTypesCommand>()
.UseConsole(console)
.Build();
// Act
var exitCode = await application.RunAsync(new[]
{
"cmd", "--int", "foo"
});
// Assert
exitCode.Should().NotBe(0);
stdErr.GetString().Should().NotBeNullOrWhiteSpace();
_output.WriteLine(stdErr.GetString());
}
[Fact]
public async Task Argument_value_can_only_be_bound_to_non_nullable_type_if_it_is_set()
{
@@ -1365,5 +1413,29 @@ namespace CliFx.Tests
_output.WriteLine(stdErr.GetString());
}
[Fact]
public async Task Argument_values_can_only_be_bound_to_a_type_that_implements_IEnumerable_and_can_be_converted_from_an_array()
{
// Arrange
var (console, _, stdErr) = VirtualConsole.CreateBuffered();
var application = new CliApplicationBuilder()
.AddCommand<UnsupportedArgumentTypesCommand>()
.UseConsole(console)
.Build();
// Act
var exitCode = await application.RunAsync(new[]
{
"cmd", "--custom-enumerable"
});
// Assert
exitCode.Should().NotBe(0);
stdErr.GetString().Should().NotBeNullOrWhiteSpace();
_output.WriteLine(stdErr.GetString());
}
}
}

View File

@@ -8,11 +8,11 @@ namespace CliFx.Tests.Commands
[Command("cmd")]
public partial class UnsupportedArgumentTypesCommand : SelfSerializeCommandBase
{
[CommandOption("str-non-initializable")]
public CustomType? StringNonInitializable { get; set; }
[CommandOption("custom")]
public CustomType? CustomNonConvertible { get; set; }
[CommandOption("str-enumerable-non-initializable")]
public CustomEnumerable<string>? StringEnumerableNonInitializable { get; set; }
[CommandOption("custom-enumerable")]
public CustomEnumerable<string>? CustomEnumerableNonConvertible { get; set; }
}
public partial class UnsupportedArgumentTypesCommand

View File

@@ -165,9 +165,9 @@ namespace CliFx
/// </summary>
public CliApplication Build()
{
_title ??= TryGetDefaultTitle() ?? "App";
_executableName ??= TryGetDefaultExecutableName() ?? "app";
_versionText ??= TryGetDefaultVersionText() ?? "v1.0";
_title ??= GetDefaultTitle();
_executableName ??= GetDefaultExecutableName();
_versionText ??= GetDefaultVersionText();
_console ??= new SystemConsole();
_typeActivator ??= new DefaultTypeActivator();
@@ -185,23 +185,29 @@ namespace CliFx
// Entry assembly is null in tests
private static Assembly? EntryAssembly => LazyEntryAssembly.Value;
private static string? TryGetDefaultTitle() => EntryAssembly?.GetName().Name;
private static string GetDefaultTitle() => EntryAssembly?.GetName().Name?? "App";
private static string? TryGetDefaultExecutableName()
private static string GetDefaultExecutableName()
{
var entryAssemblyLocation = EntryAssembly?.Location;
// The assembly can be an executable or a dll, depending on how it was packaged
var isDll = string.Equals(Path.GetExtension(entryAssemblyLocation), ".dll", StringComparison.OrdinalIgnoreCase);
var isDll = string.Equals(
Path.GetExtension(entryAssemblyLocation),
".dll",
StringComparison.OrdinalIgnoreCase
);
return isDll
var name = isDll
? "dotnet " + Path.GetFileName(entryAssemblyLocation)
: Path.GetFileNameWithoutExtension(entryAssemblyLocation);
return name ?? "app";
}
private static string? TryGetDefaultVersionText() =>
private static string GetDefaultVersionText() =>
EntryAssembly != null
? $"v{EntryAssembly.GetName().Version.ToSemanticString()}"
: null;
: "v1.0";
}
}

View File

@@ -1,5 +1,6 @@
using System;
using CliFx.Exceptions;
using CliFx.Internal.Extensions;
namespace CliFx
{
@@ -13,7 +14,7 @@ namespace CliFx
{
try
{
return Activator.CreateInstance(type);
return type.CreateInstance();
}
catch (Exception ex)
{

View File

@@ -8,7 +8,9 @@ namespace CliFx.Internal.Extensions
{
internal static class TypeExtensions
{
public static T CreateInstance<T>(this Type type) => (T) Activator.CreateInstance(type);
public static object CreateInstance(this Type type) => Activator.CreateInstance(type);
public static T CreateInstance<T>(this Type type) => (T) type.CreateInstance();
public static bool Implements(this Type type, Type interfaceType) => type.GetInterfaces().Contains(interfaceType);