Skip to content

Commit 93cdf61

Browse files
authored
Merge pull request #205 from 0xced/TimeSpan
Add support for TimeSpan and other classes with a TypeConverter
2 parents 6b5c039 + 3fcfa9a commit 93cdf61

File tree

6 files changed

+53
-12
lines changed

6 files changed

+53
-12
lines changed

src/CommandLine/Core/TypeConverter.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ private static Maybe<object> ChangeTypeScalar(string value, Type conversionType,
4949
return result.ToMaybe();
5050
}
5151

52+
private static object ConvertString(string value, Type type, CultureInfo conversionCulture)
53+
{
54+
try
55+
{
56+
return Convert.ChangeType(value, type, conversionCulture);
57+
}
58+
catch (InvalidCastException)
59+
{
60+
// Required for converting from string to TimeSpan because Convert.ChangeType can't
61+
return System.ComponentModel.TypeDescriptor.GetConverter(type).ConvertFrom(null, conversionCulture, value);
62+
}
63+
}
64+
5265
private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type conversionType, CultureInfo conversionCulture, bool ignoreValueCase)
5366
{
5467
Func<object> changeType = () =>
@@ -71,10 +84,9 @@ private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type
7184
() =>
7285
#if !SKIP_FSHARP
7386
isFsOption
74-
? FSharpOptionHelper.Some(type, Convert.ChangeType(value, type, conversionCulture)) :
87+
? FSharpOptionHelper.Some(type, ConvertString(value, type, conversionCulture)) :
7588
#endif
76-
Convert.ChangeType(value, type, conversionCulture);
77-
89+
ConvertString(value, type, conversionCulture);
7890
#if !SKIP_FSHARP
7991
Func<object> empty = () => isFsOption ? FSharpOptionHelper.None(type) : null;
8092
#else

tests/CommandLine.Tests/CommandLine.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
<Compile Include="Fakes\Options_With_Two_Options_Having_Required_Set_To_True.cs" />
9696
<Compile Include="Fakes\Options_With_Required_Set_To_True.cs" />
9797
<Compile Include="Fakes\Options_With_Required_Set_To_True_Within_Same_Set.cs" />
98+
<Compile Include="Fakes\Options_With_TimeSpan.cs" />
9899
<Compile Include="Fakes\Help_Fakes.cs" />
99100
<Compile Include="Fakes\IInterface_With_Two_Scalar_Options.cs" />
100101
<Compile Include="Fakes\Immutable_Verb_Fakes.cs" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
2+
3+
using System;
4+
5+
namespace CommandLine.Tests.Fakes
6+
{
7+
public class Options_With_TimeSpan
8+
{
9+
[Option('d', "duration")]
10+
public TimeSpan Duration { get; set; }
11+
}
12+
}

tests/CommandLine.Tests/Unit/Core/InstanceBuilderTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,22 @@ public void Parse_Guid(string[] arguments, Options_With_Guid expected)
10231023
// Teardown
10241024
}
10251025

1026+
[Fact]
1027+
public void Parse_TimeSpan()
1028+
{
1029+
// Fixture setup
1030+
var expectedResult = new Options_With_TimeSpan { Duration = TimeSpan.FromMinutes(42) };
1031+
1032+
// Exercize system
1033+
var result = InvokeBuild<Options_With_TimeSpan>(
1034+
new[] { "--duration=00:42:00" });
1035+
1036+
// Verify outcome
1037+
expectedResult.ShouldBeEquivalentTo(((Parsed<Options_With_TimeSpan>)result).Value);
1038+
1039+
// Teardown
1040+
}
1041+
10261042
public static IEnumerable<object> RequiredValueStringData
10271043
{
10281044
get

tests/CommandLine.Tests/Unit/ParserTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ public void Implicit_help_screen_in_verb_scenario()
366366
var lines = result.ToNotEmptyLines().TrimStringArray();
367367
#if !PLATFORM_DOTNET
368368
lines[0].Should().StartWithEquivalent("CommandLine");
369-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
369+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
370370
#else
371371
// Takes the name of the xUnit test program
372372
lines[0].Should().StartWithEquivalent("xUnit");
@@ -397,7 +397,7 @@ public void Double_dash_help_dispalys_verbs_index_in_verbs_scenario()
397397
var lines = result.ToNotEmptyLines().TrimStringArray();
398398
#if !PLATFORM_DOTNET
399399
lines[0].Should().StartWithEquivalent("CommandLine");
400-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
400+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
401401
#else
402402
// Takes the name of the xUnit test program
403403
lines[0].Should().StartWithEquivalent("xUnit");
@@ -452,7 +452,7 @@ public void Errors_of_type_MutuallyExclusiveSetError_are_properly_formatted()
452452
var lines = result.ToNotEmptyLines().TrimStringArray();
453453
#if !PLATFORM_DOTNET
454454
lines[0].Should().StartWithEquivalent("CommandLine");
455-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
455+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
456456
#else
457457
// Takes the name of the xUnit test program
458458
lines[0].Should().StartWithEquivalent("xUnit");
@@ -501,7 +501,7 @@ public void Properly_formatted_help_screen_is_displayed_when_usage_is_defined_in
501501
var lines = result.ToNotEmptyLines().TrimStringArray();
502502
#if !PLATFORM_DOTNET
503503
lines[0].Should().StartWithEquivalent("CommandLine");
504-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
504+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
505505
#else
506506
// Takes the name of the xUnit test program
507507
lines[0].Should().StartWithEquivalent("xUnit");
@@ -541,7 +541,7 @@ public void Properly_formatted_help_screen_is_displayed_when_there_is_a_hidden_v
541541
var lines = result.ToNotEmptyLines().TrimStringArray();
542542
#if !PLATFORM_DOTNET
543543
lines[0].Should().StartWithEquivalent("CommandLine");
544-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
544+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
545545
#else
546546
// Takes the name of the xUnit test program
547547
lines[0].Should().StartWithEquivalent("xUnit");
@@ -571,7 +571,7 @@ public void Properly_formatted_help_screen_is_displayed_when_there_is_a_hidden_v
571571
var lines = result.ToNotEmptyLines().TrimStringArray();
572572
#if !PLATFORM_DOTNET
573573
lines[0].Should().StartWithEquivalent("CommandLine");
574-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
574+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
575575
#else
576576
// Takes the name of the xUnit test program
577577
lines[0].Should().StartWithEquivalent("xUnit");
@@ -639,7 +639,7 @@ public void Specific_verb_help_screen_should_be_displayed_regardless_other_argum
639639
var lines = result.ToNotEmptyLines().TrimStringArray();
640640
#if !PLATFORM_DOTNET
641641
lines[0].Should().StartWithEquivalent("CommandLine");
642-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
642+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
643643
#else
644644
// Takes the name of the xUnit test program
645645
lines[0].Should().StartWithEquivalent("xUnit");
@@ -709,7 +709,7 @@ public void Properly_formatted_help_screen_excludes_help_as_unknown_option()
709709
var lines = result.ToNotEmptyLines().TrimStringArray();
710710
#if !PLATFORM_DOTNET
711711
lines[0].Should().StartWithEquivalent("CommandLine");
712-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
712+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
713713
#else
714714
// Takes the name of the xUnit test program
715715
lines[0].Should().StartWithEquivalent("xUnit");

tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ public void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_fo
390390

391391
#if !PLATFORM_DOTNET
392392
lines[0].Should().StartWithEquivalent("CommandLine");
393-
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2015 Giacomo Stelluti Scala");
393+
lines[1].ShouldBeEquivalentTo("Copyright (c) 2005 - 2018 Giacomo Stelluti Scala & Contributors");
394394
#else
395395
// Takes the name of the xUnit test program
396396
lines[0].Should().StartWithEquivalent("xUnit");

0 commit comments

Comments
 (0)