Skip to content

Commit 6b064a3

Browse files
committed
Add string extension tests and test value names to CONSTANT_CASE
1 parent 9126267 commit 6b064a3

File tree

4 files changed

+106
-15
lines changed

4 files changed

+106
-15
lines changed

src/CommandLineUtils/Attributes/OptionAttribute.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,14 @@ internal CommandOption Configure(CommandLineApplication app, PropertyInfo prop)
7979
{
8080
LongName = longName,
8181
ShortName = longName.Substring(0, 1),
82-
ValueName = prop.Name,
82+
ValueName = prop.Name.ToConstantCase(),
8383
};
8484

8585
option.Template = $"-{option.ShortName}|--{option.LongName}";
8686

8787
if (option.OptionType != CommandOptionType.NoValue)
8888
{
89-
option.Template += $" <{option.ValueName.ToUpperInvariant()}>";
89+
option.Template += $" <{option.ValueName.ToConstantCase()}>";
9090
}
9191
}
9292

src/CommandLineUtils/Internal/StringExtensions.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,55 @@ public static string ToKebabCase(this string str)
5656
}
5757
return sb.ToString();
5858
}
59+
60+
public static string ToConstantCase(this string str)
61+
{
62+
if (string.IsNullOrEmpty(str))
63+
{
64+
return str;
65+
}
66+
67+
var sb = new StringBuilder();
68+
var i = 0;
69+
var addUnderscore = false;
70+
71+
for (; i < str.Length; i++)
72+
{
73+
var ch = str[i];
74+
if (char.IsLetterOrDigit(ch))
75+
{
76+
addUnderscore = !char.IsUpper(ch);
77+
sb.Append(char.ToUpperInvariant(ch));
78+
i++;
79+
break;
80+
}
81+
}
82+
83+
for (; i < str.Length; i++)
84+
{
85+
var ch = str[i];
86+
if (char.IsUpper(ch))
87+
{
88+
if (addUnderscore)
89+
{
90+
addUnderscore = false;
91+
sb.Append('_');
92+
}
93+
94+
sb.Append(char.ToUpperInvariant(ch));
95+
}
96+
else if (char.IsLetterOrDigit(ch))
97+
{
98+
addUnderscore = true;
99+
sb.Append(char.ToUpperInvariant(ch));
100+
}
101+
else
102+
{
103+
addUnderscore = false;
104+
sb.Append('_');
105+
}
106+
}
107+
return sb.ToString();
108+
}
59109
}
60110
}

test/CommandLineUtils.Tests/ReflectionAppBuilderTests.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -324,23 +324,23 @@ public void BindsToStaticPropertiesWithSetterMethod()
324324
}
325325

326326
[Theory]
327-
[InlineData("Option123", "o", "option123")]
328-
[InlineData("dWORD", "d", "d-word")]
329-
[InlineData("MSBuild", "m", "msbuild")]
330-
[InlineData("NoEdit", "n", "no-edit")]
331-
[InlineData("SetUpstreamBranch", "s", "set-upstream-branch")]
332-
[InlineData("lowerCaseFirst", "l", "lower-case-first")]
333-
[InlineData("_field", "f", "field")]
334-
[InlineData("__field", "f", "field")]
335-
[InlineData("___field", "f", "field")]
336-
[InlineData("m_field", "m", "m-field")]
337-
[InlineData("m_Field", "m", "m-field")]
338-
public void ItDeterminesShortAndLongOptionNames(string propName, string shortName, string longName)
327+
[InlineData("Option123", "o", "option123", "OPTION123")]
328+
[InlineData("dWORD", "d", "d-word", "D_WORD")]
329+
[InlineData("MSBuild", "m", "msbuild", "MSBUILD")]
330+
[InlineData("NoEdit", "n", "no-edit", "NO_EDIT")]
331+
[InlineData("SetUpstreamBranch", "s", "set-upstream-branch", "SET_UPSTREAM_BRANCH")]
332+
[InlineData("lowerCaseFirst", "l", "lower-case-first", "LOWER_CASE_FIRST")]
333+
[InlineData("_field", "f", "field", "FIELD")]
334+
[InlineData("__field", "f", "field", "FIELD")]
335+
[InlineData("___field", "f", "field", "FIELD")]
336+
[InlineData("m_field", "m", "m-field", "M_FIELD")]
337+
[InlineData("m_Field", "m", "m-field", "M_FIELD")]
338+
public void ItDeterminesShortAndLongOptionNames(string propName, string shortName, string longName, string valueName)
339339
{
340340
var option = CreateOption(typeof(int), propName);
341341
Assert.Equal(longName, option.LongName);
342342
Assert.Equal(shortName, option.ShortName);
343-
Assert.Equal(propName, option.ValueName);
343+
Assert.Equal(valueName, option.ValueName);
344344
}
345345

346346
private CommandOption CreateOption(Type propType, string propName)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) Nate McMaster.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Xunit;
5+
6+
namespace McMaster.Extensions.CommandLineUtils.Tests
7+
{
8+
public class StringExtensionsTests
9+
{
10+
[Theory]
11+
[InlineData(null, null)]
12+
[InlineData("", "")]
13+
[InlineData("Option123", "option123")]
14+
[InlineData("dWORD", "d-word")]
15+
[InlineData("MSBuild", "msbuild")]
16+
[InlineData("NoEdit", "no-edit")]
17+
[InlineData("SetUpstreamBranch", "set-upstream-branch")]
18+
[InlineData("lowerCaseFirst", "lower-case-first")]
19+
[InlineData("_field", "field")]
20+
[InlineData("__field", "field")]
21+
[InlineData("___field", "field")]
22+
[InlineData("m_field", "m-field")]
23+
[InlineData("m_Field", "m-field")]
24+
public void ToKebabCase(string input, string expected)
25+
{
26+
Assert.Equal(expected, input.ToKebabCase());
27+
}
28+
29+
[Theory]
30+
[InlineData(null, null)]
31+
[InlineData("", "")]
32+
[InlineData("NoEdit", "NO_EDIT")]
33+
[InlineData("word", "WORD")]
34+
[InlineData("_field", "FIELD")]
35+
[InlineData("MSBuildTask", "MSBUILD_TASK")]
36+
public void ToConstantCase(string input, string expected)
37+
{
38+
Assert.Equal(expected, input.ToConstantCase());
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)