Skip to content

Commit

Permalink
fix #1711 (#1716)
Browse files Browse the repository at this point in the history
* fix #1711

* fix for net462 build
  • Loading branch information
jonsequitur authored Apr 21, 2022
1 parent dd44dd0 commit 689dff5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 28 deletions.
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

0 comments on commit 689dff5

Please sign in to comment.