Skip to content
Commits on Source (2)
......@@ -20,7 +20,7 @@ namespace TBureck.Terminal.Commands
this.Description = "Lists all available commands";
}
public void Execute(IInput input, IOutput output)
public override int Execute(IInput input, IOutput output)
{
output.WriteLine("Available commands:");
......@@ -29,6 +29,8 @@ namespace TBureck.Terminal.Commands
}
output.WriteLine($"\t{this.Name}\t\t\t{this.Description}");
return 0;
}
}
}
\ No newline at end of file
......@@ -11,14 +11,14 @@ namespace TBureck.Terminal.IO
private readonly IList<string> _unparsedArgs;
public IDictionary<string, string> Arguments { get; }
public IDictionary<string, string> Options { get; }
public IDictionary<string, object> Options { get; }
private InputDefinition InputDefinition { get; set; }
private ArgsInput(IList<string> args)
{
this.Arguments = new Dictionary<string, string>();
this.Options = new Dictionary<string, string>();
this.Options = new Dictionary<string, object>();
this._unparsedArgs = args;
}
......@@ -86,7 +86,11 @@ namespace TBureck.Terminal.IO
private bool ParseOption(InputOption option, string possibleValue)
{
if (option.AcceptsValue) {
this.Options[option.Name] = possibleValue;
if (option.IsValueMultiple) {
this.ParseMultipleValueOption(option, possibleValue);
} else {
this.ParseSingleValueOption(option, possibleValue);
}
return true;
}
......@@ -95,6 +99,21 @@ namespace TBureck.Terminal.IO
return false;
}
private void ParseSingleValueOption(InputOption option, string value)
{
this.Options[option.Name] = value;
}
private void ParseMultipleValueOption(InputOption option, string value)
{
if (false == this.Options.ContainsKey(option.Name)) {
this.Options[option.Name] = new List<string>();
}
IList<string> optionValues = (IList<string>) this.Options[option.Name];
optionValues.Add(value);
}
public static ArgsInput Of(IList<string> args)
{
return new ArgsInput(args);
......
......@@ -7,6 +7,6 @@ namespace TBureck.Terminal.IO
{
IDictionary<string, string> Arguments { get; }
IDictionary<string, string> Options { get; }
IDictionary<string, object> Options { get; }
}
}
\ No newline at end of file
......@@ -51,9 +51,11 @@ namespace TBureck.Terminal.IO
private InputOptionMode Mode { get; }
public bool AcceptsValue => this.Mode == InputOptionMode.ValueOptional || this.Mode == InputOptionMode.ValueRequired;
public bool IsValueRequired => this.Mode == InputOptionMode.ValueRequired;
public bool AcceptsValue => this.Mode != InputOptionMode.NoValue;
public bool IsValueRequired => this.Mode == InputOptionMode.ValueRequired || this.Mode == InputOptionMode.MultipleValues;
public bool IsValueOptional => this.Mode == InputOptionMode.ValueOptional;
public bool IsValueMultiple => this.Mode == InputOptionMode.MultipleValues;
private bool AcceptsDefaultValue => this.AcceptsValue && false == this.IsValueMultiple;
public string Description { get; }
......@@ -62,7 +64,7 @@ namespace TBureck.Terminal.IO
get => this._default;
private set
{
if (value != null && this.AcceptsValue == false) {
if (value != null && this.AcceptsDefaultValue == false) {
throw new ArgumentException("Must not define a default value for an option that does not accept a value.");
}
......@@ -98,6 +100,10 @@ namespace TBureck.Terminal.IO
sb.Append("]");
if (this.IsValueMultiple) {
sb.Append("...");
}
return sb.ToString();
}
}
......
......@@ -5,6 +5,7 @@ namespace TBureck.Terminal.IO
{
NoValue,
MultipleValues,
ValueOptional,
ValueRequired
}
......
......@@ -154,6 +154,39 @@ namespace TBureck.Tests.Terminal.IO
Assert.Equal(testOptionValue, argsInput.Options["file"]);
}
[Fact]
public void OptionWithMultipleValues_ResultsInEnumerableValue()
{
const string testOption = "--file";
const string testOptionValue1 = "filename.txt";
const string testOptionValue2 = "readme.txt";
List<string> args = new List<string> {
testOption,
testOptionValue1,
testOption,
testOptionValue2
};
InputDefinition inputDefinition = new InputDefinition();
inputDefinition.AddOption(InputOption.Of("file", mode: InputOptionMode.MultipleValues));
ArgsInput argsInput = ArgsInput.Of(args);
argsInput.Bind(inputDefinition);
Assert.Empty(argsInput.Arguments);
Assert.Single(argsInput.Options);
Assert.True(argsInput.Options.ContainsKey("file"));
IEnumerable<string> optionValues = argsInput.Options["file"] as IEnumerable<string>;
Assert.NotNull(optionValues);
Assert.Collection(
optionValues,
v => Assert.Equal(testOptionValue1, v),
v => Assert.Equal(testOptionValue2, v)
);
}
[Fact]
public void GivenNonExistingArgument_ThrowsArgumentException()
{
......
......@@ -51,21 +51,25 @@ namespace TBureck.Tests.Terminal.IO
Assert.False(option.AcceptsValue);
Assert.False(option.IsValueRequired);
Assert.False(option.IsValueOptional);
Assert.False(option.IsValueMultiple);
option = InputOption.Of("foo", "f", InputOptionMode.NoValue);
Assert.False(option.AcceptsValue);
Assert.False(option.IsValueRequired);
option = InputOption.Of("foo", "f", InputOptionMode.ValueRequired);
Assert.True(option.AcceptsValue);
Assert.True(option.IsValueRequired);
Assert.False(option.IsValueOptional);
Assert.False(option.IsValueMultiple);
option = InputOption.Of("foo", "f", InputOptionMode.ValueRequired);
option = InputOption.Of("foo", "f", InputOptionMode.MultipleValues);
Assert.True(option.AcceptsValue);
Assert.True(option.IsValueRequired);
Assert.False(option.IsValueOptional);
Assert.True(option.IsValueMultiple);
option = InputOption.Of("foo", "f", InputOptionMode.ValueOptional);
Assert.True(option.AcceptsValue);
Assert.False(option.IsValueRequired);
Assert.True(option.IsValueOptional);
Assert.False(option.IsValueMultiple);
}
[Fact]
......@@ -98,6 +102,16 @@ namespace TBureck.Tests.Terminal.IO
});
}
[Fact]
public void InputOptionWithMultipleValues_ProhibitDefaultValue()
{
Assert.Throws<ArgumentException>(() => {
const string @default = "foobar";
InputOption.Of("foo", mode: InputOptionMode.MultipleValues, @default: @default);
});
}
[Fact]
public void InputOptionNameMustNotBeEmpty()
{
......@@ -128,6 +142,9 @@ namespace TBureck.Tests.Terminal.IO
option = InputOption.Of("foo", "f", InputOptionMode.ValueRequired);
Assert.Equal("[-f|--foo FOO]", option.Synopsis);
option = InputOption.Of("foo", "f", InputOptionMode.MultipleValues);
Assert.Equal("[-f|--foo FOO]...", option.Synopsis);
option = InputOption.Of("foo", "f", InputOptionMode.ValueOptional);
Assert.Equal("[-f|--foo [FOO]]", option.Synopsis);
}
......