Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CommandLineParser.Tests/Command/MultipleCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class MultipleCommandTests
[InlineData(new string[] { "cmd1", "-x", "8" }, false)]
[InlineData(new string[] { "cmd2", "-x", "8" }, false)]
[InlineData(new string[] { }, false)]
public void NonRequiredCommandShouldNotSetResultInErrorStateWhenRequiredOptionsAreMissing(string[] args, bool hasErrors)
public void NonRequiredCommandShouldNotSetResultInErrorStateWhenRequiredOptionsAreMissing(string[] args, bool _)
{
var parser = new CommandLineParser<object>();

Expand All @@ -26,7 +26,7 @@ public void NonRequiredCommandShouldNotSetResultInErrorStateWhenRequiredOptionsA

var result = parser.Parse(args);

Assert.False(result.HasErrors);
result.AssertNoErrors();
}

private class MultipleCOmmandTestsOptions
Expand Down
31 changes: 22 additions & 9 deletions CommandLineParser.Tests/Command/SubCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ namespace MatthiWare.CommandLine.Tests.Command
{
public class SubCommandTests
{
[Fact]
public void TestSubCommandWorksCorrectly()
[Theory]
[InlineData(true)]
[InlineData(false)]
public void TestSubCommandWorksCorrectlyInModel(bool autoExecute)
{
var lock1 = new ManualResetEventSlim();
var lock2 = new ManualResetEventSlim();

var containerResolver = new CustomInstantiator(lock1, lock2);
var containerResolver = new CustomInstantiator(lock1, lock2, autoExecute);

var parser = new CommandLineParser<MainModel>(containerResolver);

var result = parser.Parse(new[] { "main", "-b", "something", "sub", "-i", "15", "-n", "-1" });

Assert.False(result.HasErrors);
result.AssertNoErrors();

if (!autoExecute)
result.ExecuteCommands();

Assert.True(lock1.Wait(1000), "MainCommand didn't execute in time.");
Assert.True(lock2.Wait(1000), "SubCommand didn't execute in time.");
Expand All @@ -32,19 +37,21 @@ private class CustomInstantiator : IContainerResolver
{
private readonly ManualResetEventSlim lock1;
private readonly ManualResetEventSlim lock2;
private readonly bool autoExecute;

public CustomInstantiator(ManualResetEventSlim lock1, ManualResetEventSlim lock2)
public CustomInstantiator(ManualResetEventSlim lock1, ManualResetEventSlim lock2, bool autoExecute)
{
this.lock1 = lock1;
this.lock2 = lock2;
this.autoExecute = autoExecute;
}

public T Resolve<T>()
{
if (typeof(T) == typeof(MainCommand))
return (T)Activator.CreateInstance(typeof(T), lock1);
return (T)Activator.CreateInstance(typeof(T), lock1, autoExecute);
else if (typeof(T) == typeof(SubCommand))
return (T)Activator.CreateInstance(typeof(T), lock2);
return (T)Activator.CreateInstance(typeof(T), lock2, autoExecute);
else
return default;
}
Expand All @@ -54,16 +61,19 @@ public T Resolve<T>()
public class MainCommand : Command<MainModel, SubModel>
{
private readonly ManualResetEventSlim locker;
private readonly bool autoExecute;

public MainCommand(ManualResetEventSlim locker)
public MainCommand(ManualResetEventSlim locker, bool autoExecute)
{
this.locker = locker;
this.autoExecute = autoExecute;
}

public override void OnConfigure(ICommandConfigurationBuilder<SubModel> builder)
{
builder
.Name("main")
.AutoExecute(autoExecute)
.Required();
}

Expand All @@ -78,16 +88,19 @@ public override void OnExecute(MainModel options, SubModel commandOptions)
public class SubCommand : Command<MainModel, SubSubModel>
{
private readonly ManualResetEventSlim locker;
private readonly bool autoExecute;

public SubCommand(ManualResetEventSlim locker)
public SubCommand(ManualResetEventSlim locker, bool autoExecute)
{
this.locker = locker;
this.autoExecute = autoExecute;
}

public override void OnConfigure(ICommandConfigurationBuilder<SubSubModel> builder)
{
builder
.Name("sub")
.AutoExecute(autoExecute)
.Required();
}

Expand Down
25 changes: 9 additions & 16 deletions CommandLineParser.Tests/CommandLineParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Linq;
using System.Threading;

using MatthiWare.CommandLine;
using MatthiWare.CommandLine.Abstractions;
using MatthiWare.CommandLine.Abstractions.Command;
using MatthiWare.CommandLine.Abstractions.Models;
Expand Down Expand Up @@ -59,7 +58,7 @@ public void CommandLineParserUsesContainerCorrectly()

var result = parser.Parse(new[] { "app.exe", "my" });

Assert.False(result.HasErrors);
result.AssertNoErrors();

commandMock.VerifyAll();
containerMock.VerifyAll();
Expand Down Expand Up @@ -148,7 +147,7 @@ public void CommandLineParserUsesArgumentFactoryCorrectly()

var result = parser.Parse(new[] { "app.exe", "-m" });

Assert.False(result.HasErrors);
result.AssertNoErrors();

resolverMock.VerifyAll();
argResolverFactory.Verify();
Expand All @@ -168,7 +167,7 @@ public void ParseTests()

Assert.NotNull(parsed);

Assert.False(parsed.HasErrors);
parsed.AssertNoErrors();

Assert.Equal("test", parsed.Result.Option1);
}
Expand Down Expand Up @@ -222,9 +221,7 @@ public void ParseWithDefaults(string[] args, string result1, string result2, str

var parsed = parser.Parse(args);

Assert.NotNull(parsed);

Assert.False(parsed.HasErrors);
parsed.AssertNoErrors();

Assert.Equal(result1, parsed.Result.Option1);
Assert.Equal(result2, parsed.Result.Option2);
Expand All @@ -246,7 +243,7 @@ public void ParseWithCustomParserInAttributeConfiguredModelTests()

var result = parser.Parse(new[] { "app.exe", "-p", "sample" });

Assert.False(result.HasErrors);
result.AssertNoErrors();

Assert.Same(obj, result.Result.Param);
}
Expand Down Expand Up @@ -278,9 +275,7 @@ public void ParseWithCommandTests()

var parsed = parser.Parse(new string[] { "app.exe", "-o", "test", "add", "-m", "my message" });

Assert.False(parsed.HasErrors);

Assert.NotNull(parsed);
parsed.AssertNoErrors();

Assert.Equal("test", parsed.Result.Option1);

Expand Down Expand Up @@ -318,7 +313,7 @@ public void ParseCommandTests(string[] args, string result1, string result2)

var result = parser.Parse(args);

Assert.False(result.HasErrors);
result.AssertNoErrors();

Assert.Equal(result1, result.Result.Message);

Expand All @@ -335,16 +330,14 @@ public void BoolResolverSpecialCaseParsesCorrectly(string[] args, bool expected)
{
var parser = new CommandLineParser<Options>();

//parser.Configure(opt => opt.Option1)
// .Name("o", "opt")
// .Default("Default message");

parser.Configure(opt => opt.Option2)
.Name("x", "xsomething")
.Required();

var result = parser.Parse(args);

result.AssertNoErrors();

Assert.Equal(expected, result.Result.Option2);
}

Expand Down
6 changes: 1 addition & 5 deletions CommandLineParser.Tests/CustomerReportedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ public void AutoPrintUsageAndErrorsShouldNotPrintWhenEverythingIsFIne(string ver

var parsed = parser.Parse(items.ToArray());

if (parsed.HasErrors)
{
foreach (var err in parsed.Errors)
throw err;
}
parsed.AssertNoErrors();

void AddItemToArray(string item)
{
Expand Down
4 changes: 2 additions & 2 deletions CommandLineParser.Tests/Parsing/ParserResultTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void TestMergeResultOfCommandResultWorks()

mockCmdResult.VerifyGet(x => x.HasErrors);

Assert.False(result.HasErrors);
result.AssertNoErrors();
}

[Fact]
Expand All @@ -58,7 +58,7 @@ public void TestMergeResultOfResultWorks()

result.MergeResult(obj);

Assert.False(result.HasErrors);
result.AssertNoErrors();

Assert.Empty(result.Errors);

Expand Down
6 changes: 1 addition & 5 deletions CommandLineParser.Tests/Usage/HelpDisplayCommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using MatthiWare.CommandLine;
using MatthiWare.CommandLine.Abstractions;
using MatthiWare.CommandLine.Abstractions;
using MatthiWare.CommandLine.Abstractions.Command;
using MatthiWare.CommandLine.Abstractions.Usage;
using MatthiWare.CommandLine.Core.Attributes;
Expand Down
11 changes: 11 additions & 0 deletions CommandLineParser.Tests/XUnitExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq.Expressions;
using MatthiWare.CommandLine.Abstractions.Parsing;

namespace MatthiWare.CommandLine.Tests
{
Expand All @@ -9,5 +10,15 @@ public static LambdaExpression CreateLambda<TSource, TProperty>(Expression<Func<
{
return expression;
}

public static void AssertNoErrors<T>(this IParserResult<T> result)
{
if (result == null)
throw new NullReferenceException("Parsing result was null");

foreach (var err in result.Errors)
throw err;
}

}
}
5 changes: 5 additions & 0 deletions CommandLineParser/Abstractions/Command/ICommandBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace MatthiWare.CommandLine.Abstractions.Command
{
/// <summary>
/// Generic command builder
/// </summary>
/// <typeparam name="TOption"></typeparam>
public interface ICommandBuilder<TOption>
{
/// <summary>
Expand Down Expand Up @@ -36,6 +40,7 @@ public interface ICommandBuilder<TOption>
/// <summary>
/// Configures the execution of the command
/// </summary>
/// <param name="action">The execution action</param>
/// <param name="required">True or false</param>
/// <returns><see cref="ICommandBuilder{TOption}"/></returns>
ICommandBuilder<TOption> OnExecuting(Action<TOption> action);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace MatthiWare.CommandLine.Abstractions.Command
{
/// <summary>
/// Command builder
/// </summary>
public interface ICommandConfigurationBuilder
{
/// <summary>
Expand All @@ -22,5 +25,12 @@ public interface ICommandConfigurationBuilder
/// <param name="name">Command name</param>
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
ICommandConfigurationBuilder Name(string name);

/// <summary>
/// Configures if the command should auto execute
/// </summary>
/// <param name="autoExecute">True for automated execution, false for manual</param>
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
ICommandConfigurationBuilder AutoExecute(bool autoExecute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

namespace MatthiWare.CommandLine.Abstractions.Command
{
/// <summary>
/// Builder for a generic command
/// </summary>
/// <typeparam name="TSource"></typeparam>
public interface ICommandConfigurationBuilder<TSource>
: ICommandConfigurationBuilder
where TSource : class
Expand All @@ -19,21 +23,28 @@ public interface ICommandConfigurationBuilder<TSource>
/// Configures if the command is required
/// </summary>
/// <param name="required">True or false</param>
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
/// <returns><see cref="ICommandConfigurationBuilder{TSource}"/></returns>
new ICommandConfigurationBuilder<TSource> Required(bool required = true);

/// <summary>
/// Configures the description text for the command
/// </summary>
/// <param name="required">True or false</param>
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
/// <param name="description">The description</param>
/// <returns><see cref="ICommandConfigurationBuilder{TSource}"/></returns>
new ICommandConfigurationBuilder<TSource> Description(string description);

/// <summary>
/// Configures the command name
/// </summary>
/// <param name="name">Command name</param>
/// <returns><see cref="ICommandConfigurationBuilder"/></returns>
/// <returns><see cref="ICommandConfigurationBuilder{TSource}"/></returns>
new ICommandConfigurationBuilder<TSource> Name(string name);

/// <summary>
/// Configures if the command should auto execute
/// </summary>
/// <param name="autoExecute">True for automated execution, false for manual</param>
/// <returns><see cref="ICommandConfigurationBuilder{TSource}"/></returns>
new ICommandConfigurationBuilder<TSource> AutoExecute(bool autoExecute);
}
}
Loading