-
Notifications
You must be signed in to change notification settings - Fork 399
add GetRequiredValue to avoid null checks for required options #2564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -826,6 +826,33 @@ public void Commands_can_have_default_argument_values() | |
GetValue(result, argument) | ||
.Should() | ||
.Be("default"); | ||
|
||
result.GetRequiredValue(argument) | ||
.Should() | ||
.Be("default"); | ||
} | ||
|
||
[Fact] | ||
public void GetRequiredValue_throws_when_argument_without_default_value_was_not_provided() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
{ | ||
Argument<int> argument = new("the-arg"); | ||
Option<bool> option = new("--option"); | ||
|
||
Command command = new("command") | ||
{ | ||
argument, | ||
option | ||
}; | ||
|
||
ParseResult result = command.Parse("command --option"); | ||
|
||
result.Invoking(result => result.GetRequiredValue(argument)) | ||
.Should() | ||
.Throw<InvalidOperationException>(); | ||
|
||
result.Invoking(result => result.GetRequiredValue<int>(argument.Name)) | ||
.Should() | ||
.Throw<InvalidOperationException>(); | ||
} | ||
|
||
[Fact] | ||
|
@@ -925,6 +952,11 @@ public void Command_default_argument_value_does_not_override_parsed_value() | |
.Name | ||
.Should() | ||
.Be("the-directory"); | ||
|
||
result.GetRequiredValue(argument) | ||
.Name | ||
.Should() | ||
.Be("the-directory"); | ||
} | ||
|
||
[Fact] | ||
|
@@ -1160,6 +1192,10 @@ public void Arguments_can_match_subcommands() | |
GetValue(result, argument) | ||
.Should() | ||
.BeEquivalentSequenceTo("one", "two", "three", "subcommand", "four"); | ||
|
||
result.GetRequiredValue(argument) | ||
.Should() | ||
.BeEquivalentSequenceTo("one", "two", "three", "subcommand", "four"); | ||
} | ||
|
||
[Theory] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,6 +122,22 @@ public IEnumerable<ParseError> Errors | |
return Argument<T>.CreateDefaultValue(); | ||
} | ||
|
||
/// <inheritdoc cref="ParseResult.GetRequiredValue{T}(Argument{T})"/> | ||
public T GetRequiredValue<T>(Argument<T> argument) | ||
=> GetResult(argument) switch | ||
{ | ||
ArgumentResult argumentResult => argumentResult.GetValueOrDefault<T>(), | ||
null => throw new InvalidOperationException($"{argument.Name} is required but was not provided."), | ||
}; | ||
|
||
/// <inheritdoc cref="ParseResult.GetRequiredValue{T}(Option{T})"/> | ||
public T GetRequiredValue<T>(Option<T> option) | ||
=> GetResult(option) switch | ||
{ | ||
OptionResult optionResult => optionResult.GetValueOrDefault<T>(), | ||
jonsequitur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
null => throw new InvalidOperationException($"{option.Name} is required but was not provided."), | ||
}; | ||
|
||
/// <summary> | ||
/// Gets the value for a symbol having the specified name anywhere in the parse tree. | ||
/// </summary> | ||
|
@@ -147,6 +163,20 @@ public IEnumerable<ParseError> Errors | |
return Argument<T>.CreateDefaultValue(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the value for a symbol having the specified name anywhere in the parse tree. | ||
/// </summary> | ||
/// <param name="name">The name of the symbol for which to find a result.</param> | ||
/// <returns>An argument result if the argument was matched by the parser or has a default value; otherwise, <c>null</c>.</returns> | ||
public T GetRequiredValue<T>(string name) | ||
=> GetResult(name) switch | ||
{ | ||
OptionResult optionResult => optionResult.GetValueOrDefault<T>(), | ||
ArgumentResult argumentResult => argumentResult.GetValueOrDefault<T>(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this can still return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The only scenario I can come up with is the user defining There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My memory was that |
||
SymbolResult _ => throw new InvalidOperationException($"{name} is not an option or argument."), | ||
_ => throw new InvalidOperationException($"{name} is required but was not provided."), | ||
}; | ||
|
||
internal virtual bool UseDefaultValueFor(ArgumentResult argumentResult) => false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we also testing
Option.GetRequiredValue
for these cases?