diff --git a/src/CommandLine/Core/TypeConverter.cs b/src/CommandLine/Core/TypeConverter.cs index ad2b7d81..2feb54ca 100644 --- a/src/CommandLine/Core/TypeConverter.cs +++ b/src/CommandLine/Core/TypeConverter.cs @@ -49,6 +49,19 @@ private static Maybe ChangeTypeScalar(string value, Type conversionType, return result.ToMaybe(); } + private static object ConvertString(string value, Type type, CultureInfo conversionCulture) + { + try + { + return Convert.ChangeType(value, type, conversionCulture); + } + catch (InvalidCastException) + { + // Required for converting from string to TimeSpan because Convert.ChangeType can't + return System.ComponentModel.TypeDescriptor.GetConverter(type).ConvertFrom(null, conversionCulture, value); + } + } + private static Result ChangeTypeScalarImpl(string value, Type conversionType, CultureInfo conversionCulture, bool ignoreValueCase) { Func changeType = () => @@ -71,10 +84,9 @@ private static Result ChangeTypeScalarImpl(string value, Type () => #if !SKIP_FSHARP isFsOption - ? FSharpOptionHelper.Some(type, Convert.ChangeType(value, type, conversionCulture)) : + ? FSharpOptionHelper.Some(type, ConvertString(value, type, conversionCulture)) : #endif - Convert.ChangeType(value, type, conversionCulture); - + ConvertString(value, type, conversionCulture); #if !SKIP_FSHARP Func empty = () => isFsOption ? FSharpOptionHelper.None(type) : null; #else diff --git a/tests/CommandLine.Tests/CommandLine.Tests.csproj b/tests/CommandLine.Tests/CommandLine.Tests.csproj index eb6e691e..cabb761d 100644 --- a/tests/CommandLine.Tests/CommandLine.Tests.csproj +++ b/tests/CommandLine.Tests/CommandLine.Tests.csproj @@ -95,6 +95,7 @@ + diff --git a/tests/CommandLine.Tests/Fakes/Options_With_TimeSpan.cs b/tests/CommandLine.Tests/Fakes/Options_With_TimeSpan.cs new file mode 100644 index 00000000..0e88896d --- /dev/null +++ b/tests/CommandLine.Tests/Fakes/Options_With_TimeSpan.cs @@ -0,0 +1,12 @@ +// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information. + +using System; + +namespace CommandLine.Tests.Fakes +{ + public class Options_With_TimeSpan + { + [Option('d', "duration")] + public TimeSpan Duration { get; set; } + } +} diff --git a/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs b/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs index 7d7544e6..7a49b39b 100644 --- a/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs +++ b/tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs @@ -1023,6 +1023,22 @@ public void Parse_Guid(string[] arguments, Options_With_Guid expected) // Teardown } + [Fact] + public void Parse_TimeSpan() + { + // Fixture setup + var expectedResult = new Options_With_TimeSpan { Duration = TimeSpan.FromMinutes(42) }; + + // Exercize system + var result = InvokeBuild( + new[] { "--duration=00:42:00" }); + + // Verify outcome + expectedResult.ShouldBeEquivalentTo(((Parsed)result).Value); + + // Teardown + } + public static IEnumerable RequiredValueStringData { get diff --git a/tests/CommandLine.Tests/Unit/ParserTests.cs b/tests/CommandLine.Tests/Unit/ParserTests.cs index 5ecd085c..43b44e27 100644 --- a/tests/CommandLine.Tests/Unit/ParserTests.cs +++ b/tests/CommandLine.Tests/Unit/ParserTests.cs @@ -366,7 +366,7 @@ public void Implicit_help_screen_in_verb_scenario() var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -397,7 +397,7 @@ public void Double_dash_help_dispalys_verbs_index_in_verbs_scenario() var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -452,7 +452,7 @@ public void Errors_of_type_MutuallyExclusiveSetError_are_properly_formatted() var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -501,7 +501,7 @@ public void Properly_formatted_help_screen_is_displayed_when_usage_is_defined_in var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -541,7 +541,7 @@ public void Properly_formatted_help_screen_is_displayed_when_there_is_a_hidden_v var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -571,7 +571,7 @@ public void Properly_formatted_help_screen_is_displayed_when_there_is_a_hidden_v var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -639,7 +639,7 @@ public void Specific_verb_help_screen_should_be_displayed_regardless_other_argum var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); @@ -709,7 +709,7 @@ public void Properly_formatted_help_screen_excludes_help_as_unknown_option() var lines = result.ToNotEmptyLines().TrimStringArray(); #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit"); diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index e041026a..90ca41b5 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -390,7 +390,7 @@ public void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_fo #if !PLATFORM_DOTNET lines[0].Should().StartWithEquivalent("CommandLine"); - lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala"); + lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors"); #else // Takes the name of the xUnit test program lines[0].Should().StartWithEquivalent("xUnit");