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
55 changes: 39 additions & 16 deletions src/System.CommandLine.Tests/ParserTests.MultipleArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;
using System.CommandLine.Parsing;
using System.CommandLine.Tests.Utility;
using System.Threading.Tasks;
using System.Linq;
using FluentAssertions;
using FluentAssertions.Execution;
using Xunit;
Expand Down Expand Up @@ -149,17 +150,12 @@ public void Multiple_arguments_of_unspecified_type_are_parsed_correctly()
public void When_multiple_arguments_are_defined_but_not_provided_then_option_parses_correctly()
{
var option = new Option<string>("-e");
var command = new Command("the-command") { option };

command.AddArgument(new Argument<string>
{
Name = "arg1",
});

command.AddArgument(new Argument<string>
var command = new Command("the-command")
{
Name = "arg2",
});
option,
new Argument<string>(),
new Argument<string>()
};

var result = command.Parse("-e foo");

Expand All @@ -168,9 +164,8 @@ public void When_multiple_arguments_are_defined_but_not_provided_then_option_par
optionResult.Should().Be("foo");
}


[Fact]
public void tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_next_multiple_arity_argument()
public void Tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_next_multiple_arity_argument()
{
var ints = new Argument<int[]>();
var strings = new Argument<string[]>();
Expand All @@ -197,7 +192,7 @@ public void tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_n
}

[Fact]
public void tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_next_single_arity_argument()
public void Tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_next_single_arity_argument()
{
var ints = new Argument<int[]>();
var strings = new Argument<string>();
Expand Down Expand Up @@ -232,11 +227,11 @@ public void tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_n
[Fact]
public void Unsatisfied_subsequent_argument_with_min_arity_0_parses_as_default_value()
{
var arg1 = new Argument<string>("arg1")
var arg1 = new Argument<string>
{
Arity = ArgumentArity.ExactlyOne
};
var arg2 = new Argument<string>("arg2")
var arg2 = new Argument<string>
{
Arity = ArgumentArity.ZeroOrOne,
};
Expand Down Expand Up @@ -290,6 +285,34 @@ public void When_subsequent_argument_with_ZeroOrOne_arity_is_not_provided_then_p

result.GetValueForArgument(argument1).Should().Be("one");
}

[Theory] // https://github.com/dotnet/command-line-api/issues/1711
[InlineData("")]
[InlineData("a")]
[InlineData("a b")]
[InlineData("a b c")]
public void When_there_are_not_enough_tokens_for_all_arguments_then_the_correct_number_of_errors_is_reported(
string providedArgs)
{
var command = new Command("command")
{
new Argument<string>(),
new Argument<string>(),
new Argument<string>(),
new Argument<string>()
};

var result = new Parser(command).Parse(providedArgs);

var numberOfMissingArgs =
result
.Errors
.Count(e => e.Message == LocalizationResources.Instance.RequiredArgumentMissing(result.CommandResult));

numberOfMissingArgs
.Should()
.Be(4 - providedArgs.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length);
}
}
}
}
4 changes: 1 addition & 3 deletions src/System.CommandLine.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
namespace System.CommandLine.Tests
{
public partial class ParserTests
{public partial class RootCommandAndArg0
{
}
{
private readonly ITestOutputHelper _output;

public ParserTests(ITestOutputHelper output)
Expand Down
19 changes: 11 additions & 8 deletions src/System.CommandLine/Parsing/ParseResultVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,21 +291,24 @@ private void ValidateAndConvertArgumentResults(IReadOnlyList<Argument> arguments
_symbolResults.TryAdd(nextArgumentResult.Symbol, nextArgumentResult);
}

var argumentResult = _argumentResults[i];
if (commandArgumentResultCount >= _argumentResults.Count)
{
var argumentResult = _argumentResults[i];

ValidateAndConvertArgumentResult(argumentResult);
ValidateAndConvertArgumentResult(argumentResult);

if (argumentResult.PassedOnTokens is { } &&
i == arguments.Count - 1)
{
_unparsedTokens ??= new List<Token>();
_unparsedTokens.AddRange(argumentResult.PassedOnTokens);
if (argumentResult.PassedOnTokens is { } &&
i == arguments.Count - 1)
{
_unparsedTokens ??= new List<Token>();
_unparsedTokens.AddRange(argumentResult.PassedOnTokens);
}
}
}

if (_argumentResults.Count > arguments.Count)
{
for (var i = arguments.Count; i < _argumentResults.Count; i++)
for (var i = arguments.Count; i < _argumentResults.Count - 1; i++)
{
var result = _argumentResults[i];

Expand Down
2 changes: 1 addition & 1 deletion src/System.CommandLine/Parsing/SymbolResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal static Token Token(this SymbolResult symbolResult)
return symbolResult switch
{
CommandResult commandResult => commandResult.Token,
OptionResult optionResult => optionResult.Token is null ? CreateImplicitToken(optionResult.Option) : optionResult.Token,
OptionResult optionResult => optionResult.Token ?? CreateImplicitToken(optionResult.Option),
_ => throw new ArgumentOutOfRangeException(nameof(symbolResult))
};

Expand Down