diff --git a/src/System.CommandLine.Tests/Binding/TypeConversionTests.cs b/src/System.CommandLine.Tests/Binding/TypeConversionTests.cs index 454942a873..efbe793a8f 100644 --- a/src/System.CommandLine.Tests/Binding/TypeConversionTests.cs +++ b/src/System.CommandLine.Tests/Binding/TypeConversionTests.cs @@ -27,6 +27,21 @@ protected T GetValue(Argument argument, string commandLine) return result.GetValue(argument); } + [Fact] + public void Option_argument_of_DirectoryInfo_can_be_bound_without_custom_conversion_logic() + { + var option = new Option("--dir"); + + var dir = new DirectoryInfo(Path.Combine(Directory.GetCurrentDirectory(), "temp")); + + var result = new RootCommand { option }.Parse($"--dir {dir.FullName}"); + + result.GetValue(option) + .FullName + .Should() + .Be(dir.FullName); + } + [Fact] public void Option_argument_of_FileInfo_can_be_bound_without_custom_conversion_logic() { @@ -34,7 +49,9 @@ public void Option_argument_of_FileInfo_can_be_bound_without_custom_conversion_l var file = new FileInfo(Path.Combine(new DirectoryInfo("temp").FullName, "the-file.txt")); - GetValue(option, $"--file {file.FullName}") + var result = new RootCommand { option }.Parse($"--file {file.FullName}"); + + result.GetValue(option) .Name .Should() .Be("the-file.txt"); @@ -107,6 +124,20 @@ public void Argument_of_array_of_FileInfo_can_be_called_without_custom_conversio .BeEquivalentTo("file1.txt", "file2.txt"); } + [Fact] // https://github.com/dotnet/command-line-api/issues/2574 + public void Option_argument_of_Uri_can_be_bound_without_custom_conversion_logic() + { + var option = new Option("--file"); + + var uri = new Uri("https://example.com"); + + var result = new RootCommand { option }.Parse($"--file {uri}"); + + result.GetValue(option) + .Should() + .Be(uri); + } + [Fact] public void Argument_defaults_arity_to_One_for_non_IEnumerable_types() { @@ -419,44 +450,6 @@ public void A_default_value_of_a_non_string_type_can_be_specified() .Be(123); } - [Fact] - public void A_default_value_with_a_custom_constructor_can_be_specified_for_an_option_argument() - { - var directoryInfo = new DirectoryInfo(Directory.GetCurrentDirectory()); - - var option = new Option("-x") { DefaultValueFactory = (_) => directoryInfo }; - - var command = new Command("something") - { - option - }; - - var result = command.Parse("something"); - - result.GetValue(option).Should().Be(directoryInfo); - } - - [Fact] - public void A_default_value_with_a_custom_constructor_can_be_specified_for_a_command_argument() - { - var directoryInfo = new DirectoryInfo(Directory.GetCurrentDirectory()); - - var argument = new Argument("the-arg") { DefaultValueFactory = (_) => directoryInfo }; - - var command = new Command("something") - { - argument - }; - - var result = command.Parse("something"); - - result.Errors.Should().BeEmpty(); - - var value = result.GetValue(argument); - - value.Should().Be(directoryInfo); - } - [Fact] public void Specifying_an_option_argument_overrides_the_default_value() { @@ -474,7 +467,6 @@ public void Specifying_an_option_argument_overrides_the_default_value() value.Should().Be(456); } - [Fact] public void Values_can_be_correctly_converted_to_DateTime_without_the_parser_specifying_a_custom_converter() { diff --git a/src/System.CommandLine/Binding/ArgumentConverter.StringConverters.cs b/src/System.CommandLine/Binding/ArgumentConverter.StringConverters.cs index 4a48afbb34..52e1575987 100644 --- a/src/System.CommandLine/Binding/ArgumentConverter.StringConverters.cs +++ b/src/System.CommandLine/Binding/ArgumentConverter.StringConverters.cs @@ -286,5 +286,17 @@ private static Dictionary StringConverters value = default; return false; }, + + [typeof(Uri)] = (string input, out object? value) => + { + if (Uri.TryCreate(input, UriKind.Absolute, out var uri)) + { + value = uri; + return true; + } + + value = default; + return false; + }, }; } \ No newline at end of file