Skip to content

Commit 4fa8ddf

Browse files
authored
Merge pull request #358 from anthonylangsworth/type_conversion
Fix for invalid cast when specifying true or false for int option (#339)
2 parents ae88004 + 8b31892 commit 4fa8ddf

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ artifacts/*
4141
*.nuget.targets
4242
*.lock.json
4343
*.nuget.props
44+
*.DotSettings.user
4445

‎src/CommandLine/Core/TypeConverter.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ private static Result<object, Exception> ChangeTypeScalarImpl(string value, Type
8484
return(value==null)?empty():withValue();
8585
};
8686

87-
returnvalue.IsBooleanString()
87+
returnvalue.IsBooleanString()&&conversionType==typeof(bool)
8888
?value.ToBoolean():conversionType.GetTypeInfo().IsEnum
8989
?value.ToEnum(conversionType,ignoreValueCase):safeChangeType();
9090
};

‎tests/CommandLine.Tests/CommandLine.Tests.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
<SubType>Code</SubType>
113113
</Compile>
114114
<CompileInclude="Unit\Core\TokenTests.cs" />
115+
<CompileInclude="Unit\Core\TypeConverterTests.cs" />
115116
<CompileInclude="Unit\Infrastructure\FSharpOptionHelperTests.cs" />
116117
<CompileInclude="Unit\Core\ReflectionExtensions.cs" />
117118
<CompileInclude="Unit\ParserResultExtensionsTests.cs" />
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
usingSystem;
2+
usingSystem.CodeDom;
3+
usingSystem.Collections.Generic;
4+
usingSystem.Dynamic;
5+
usingSystem.Globalization;
6+
usingSystem.Linq;
7+
usingSystem.Text;
8+
usingSystem.Threading.Tasks;
9+
usingCommandLine.Core;
10+
usingCSharpx;
11+
usingFluentAssertions;
12+
usingXunit;
13+
14+
namespaceCommandLine.Tests.Unit.Core
15+
{
16+
publicclassTypeConverterTests
17+
{
18+
enumTestEnum
19+
{
20+
ValueA=1,
21+
ValueB=2
22+
}
23+
24+
[Theory]
25+
[MemberData("ChangeType_scalars_source")]
26+
publicvoidChangeType_scalars(stringtestValue,TypedestinationType,boolexpectFail,objectexpectedResult)
27+
{
28+
Maybe<object>result=TypeConverter.ChangeType(new[]{testValue},destinationType,true,CultureInfo.InvariantCulture,true);
29+
30+
if(expectFail)
31+
{
32+
result.MatchNothing().Should().BeTrue("should fail parsing");
33+
}
34+
else
35+
{
36+
objectmatchedValue;
37+
38+
result.MatchJust(outmatchedValue).Should().BeTrue("should parse successfully");
39+
Assert.Equal(matchedValue,expectedResult);
40+
}
41+
}
42+
43+
publicstaticIEnumerable<object[]>ChangeType_scalars_source
44+
{
45+
get
46+
{
47+
returnnew[]
48+
{
49+
newobject[]{"1",typeof(int),false,1},
50+
newobject[]{"0",typeof(int),false,0},
51+
newobject[]{"-1",typeof(int),false,-1},
52+
newobject[]{"abcd",typeof(int),true,null},
53+
newobject[]{"1.0",typeof(int),true,null},
54+
newobject[]{int.MaxValue.ToString(),typeof(int),false,int.MaxValue},
55+
newobject[]{int.MinValue.ToString(),typeof(int),false,int.MinValue},
56+
newobject[]{((long)int.MaxValue+1).ToString(),typeof(int),true,null},
57+
newobject[]{((long)int.MinValue-1).ToString(),typeof(int),true,null},
58+
59+
newobject[]{"1",typeof(uint),false,(uint)1},
60+
newobject[]{"0",typeof(uint),false,(uint)0},
61+
newobject[]{"-1",typeof(uint),true,null},
62+
newobject[]{uint.MaxValue.ToString(),typeof(uint),false,uint.MaxValue},
63+
newobject[]{uint.MinValue.ToString(),typeof(uint),false,uint.MinValue},
64+
newobject[]{((long)uint.MaxValue+1).ToString(),typeof(uint),true,null},
65+
newobject[]{((long)uint.MinValue-1).ToString(),typeof(uint),true,null},
66+
67+
newobject[]{"true",typeof(bool),false,true},
68+
newobject[]{"True",typeof(bool),false,true},
69+
newobject[]{"TRUE",typeof(bool),false,true},
70+
newobject[]{"false",typeof(bool),false,false},
71+
newobject[]{"False",typeof(bool),false,false},
72+
newobject[]{"FALSE",typeof(bool),false,false},
73+
newobject[]{"abcd",typeof(bool),true,null},
74+
newobject[]{"0",typeof(bool),true,null},
75+
newobject[]{"1",typeof(bool),true,null},
76+
77+
newobject[]{"1.0",typeof(float),false,1.0f},
78+
newobject[]{"0.0",typeof(float),false,0.0f},
79+
newobject[]{"-1.0",typeof(float),false,-1.0f},
80+
newobject[]{"abcd",typeof(float),true,null},
81+
82+
newobject[]{"1.0",typeof(double),false,1.0},
83+
newobject[]{"0.0",typeof(double),false,0.0},
84+
newobject[]{"-1.0",typeof(double),false,-1.0},
85+
newobject[]{"abcd",typeof(double),true,null},
86+
87+
newobject[]{"1.0",typeof(decimal),false,1.0m},
88+
newobject[]{"0.0",typeof(decimal),false,0.0m},
89+
newobject[]{"-1.0",typeof(decimal),false,-1.0m},
90+
newobject[]{"-1.123456",typeof(decimal),false,-1.123456m},
91+
newobject[]{"abcd",typeof(decimal),true,null},
92+
93+
newobject[]{"",typeof(string),false,""},
94+
newobject[]{"abcd",typeof(string),false,"abcd"},
95+
96+
newobject[]{"ValueA",typeof(TestEnum),false,TestEnum.ValueA},
97+
newobject[]{"VALUEA",typeof(TestEnum),false,TestEnum.ValueA},
98+
newobject[]{"ValueB",typeof(TestEnum),false,TestEnum.ValueB},
99+
newobject[]{((int)TestEnum.ValueA).ToString(),typeof(TestEnum),false,TestEnum.ValueA},
100+
newobject[]{((int)TestEnum.ValueB).ToString(),typeof(TestEnum),false,TestEnum.ValueB},
101+
newobject[]{((int)TestEnum.ValueB+1).ToString(),typeof(TestEnum),true,null},
102+
newobject[]{((int)TestEnum.ValueA-1).ToString(),typeof(TestEnum),true,null},
103+
104+
// Failed before #339
105+
newobject[]{"false",typeof(int),true,0},
106+
newobject[]{"true",typeof(int),true,0}
107+
};
108+
}
109+
}
110+
}
111+
}

0 commit comments

Comments
(0)