Skip to content

Commit c8ed98b

Browse files
committed
Merge branch 'develop' of https://github.com/tkouba/commandline into tkouba-develop
# Conflicts: # src/CommandLine/BaseAttribute.cs # src/CommandLine/CommandLine.csproj # tests/CommandLine.Tests.Properties/CommandLine.Tests.Properties.csproj # tests/CommandLine.Tests/CommandLine.Tests.csproj Fix failed tests by seting HelpText default to string.empty
2 parents e9340b0 + 0881d1b commit c8ed98b

File tree

4 files changed

+146
-12
lines changed

4 files changed

+146
-12
lines changed

src/CommandLine/BaseAttribute.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ public abstract class BaseAttribute : Attribute
1212
private int min;
1313
private int max;
1414
private object @default;
15-
private string helpText;
15+
private Infrastructure.LocalizableAttributeProperty helpText;
1616
private string metaValue;
17+
private Type resourceType;
1718

1819
/// <summary>
1920
/// Initializes a new instance of the <see cref="CommandLine.BaseAttribute"/> class.
@@ -22,8 +23,9 @@ protected internal BaseAttribute()
2223
{
2324
min = -1;
2425
max = -1;
25-
helpText = string.Empty;
26+
helpText = new Infrastructure.LocalizableAttributeProperty(nameof(HelpText));
2627
metaValue = string.Empty;
28+
resourceType = null;
2729
}
2830

2931
/// <summary>
@@ -90,11 +92,8 @@ public object Default
9092
/// </summary>
9193
public string HelpText
9294
{
93-
get { return helpText; }
94-
set
95-
{
96-
helpText = value ?? throw new ArgumentNullException("value");
97-
}
95+
get => helpText.Value??string.Empty;
96+
set => helpText.Value = value ?? throw new ArgumentNullException("value");
9897
}
9998

10099
/// <summary>
@@ -105,7 +104,12 @@ public string MetaValue
105104
get { return metaValue; }
106105
set
107106
{
108-
metaValue = value ?? throw new ArgumentNullException("value");
107+
if (value == null)
108+
{
109+
throw new ArgumentNullException("value");
110+
}
111+
112+
metaValue = value;
109113
}
110114
}
111115

@@ -117,5 +121,18 @@ public bool Hidden
117121
get;
118122
set;
119123
}
124+
125+
/// <summary>
126+
/// Gets or sets the <see cref="System.Type"/> that contains the resources for <see cref="HelpText"/>.
127+
/// </summary>
128+
public Type ResourceType
129+
{
130+
get { return resourceType; }
131+
set
132+
{
133+
resourceType =
134+
helpText.ResourceType = value;
135+
}
136+
}
120137
}
121138
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
7+
namespace CommandLine.Infrastructure
8+
{
9+
internal class LocalizableAttributeProperty
10+
{
11+
private string _propertyName;
12+
private string _value;
13+
private Type _type;
14+
private PropertyInfo _localizationPropertyInfo;
15+
16+
public LocalizableAttributeProperty(string propertyName)
17+
{
18+
_propertyName = propertyName;
19+
}
20+
21+
public string Value
22+
{
23+
get { return GetLocalizedValue(); }
24+
set
25+
{
26+
_localizationPropertyInfo = null;
27+
_value = value;
28+
}
29+
}
30+
31+
public Type ResourceType
32+
{
33+
set
34+
{
35+
_localizationPropertyInfo = null;
36+
_type = value;
37+
}
38+
}
39+
40+
private string GetLocalizedValue()
41+
{
42+
if (String.IsNullOrEmpty(_value) || _type == null)
43+
return _value;
44+
if (_localizationPropertyInfo == null)
45+
{
46+
// Static class IsAbstract
47+
if (!_type.IsVisible)
48+
throw new ArgumentException("Invalid resource type", _propertyName);
49+
PropertyInfo propertyInfo = _type.GetProperty(_value, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static);
50+
if (propertyInfo == null || !propertyInfo.CanRead || propertyInfo.PropertyType != typeof(string))
51+
throw new ArgumentException("Invalid resource property name", _propertyName);
52+
_localizationPropertyInfo = propertyInfo;
53+
}
54+
return (string)_localizationPropertyInfo.GetValue(null, null);
55+
}
56+
}
57+
58+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace CommandLine.Tests.Fakes
8+
{
9+
public static class StaticResource
10+
{
11+
public static string HelpText { get { return "Localized HelpText"; } }
12+
}
13+
14+
public class NonStaticResource
15+
{
16+
public static string HelpText { get { return "Localized HelpText"; } }
17+
public static string WriteOnlyText { set { value?.ToString(); } }
18+
private static string PrivateHelpText { get { return "Localized HelpText"; } }
19+
}
20+
21+
public class NonStaticResource_WithNonStaticProperty
22+
{
23+
public string HelpText { get { return "Localized HelpText"; } }
24+
}
25+
26+
internal class InternalResource
27+
{
28+
public static string HelpText { get { return "Localized HelpText"; } }
29+
}
30+
31+
}

tests/CommandLine.Tests/Unit/BaseAttributeTests.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
4-
using System.Reflection;
5-
using System.Text;
6-
using System.Threading.Tasks;
73
using Xunit;
84

95
namespace CommandLine.Tests.Unit
@@ -20,12 +16,44 @@ public static void Default(object defaultValue)
2016
Assert.Equal(defaultValue, baseAttribute.Default);
2117
}
2218

19+
[Theory]
20+
[InlineData("", null, "")]
21+
[InlineData("", typeof(Fakes.StaticResource), "")]
22+
[InlineData("Help text", null, "Help text")]
23+
[InlineData("HelpText", typeof(Fakes.StaticResource), "Localized HelpText")]
24+
[InlineData("HelpText", typeof(Fakes.NonStaticResource), "Localized HelpText")]
25+
public static void HelpText(string helpText, Type resourceType, string expected)
26+
{
27+
TestBaseAttribute baseAttribute = new TestBaseAttribute();
28+
baseAttribute.HelpText = helpText;
29+
baseAttribute.ResourceType = resourceType;
30+
31+
Assert.Equal(expected, baseAttribute.HelpText);
32+
}
33+
34+
[Theory]
35+
[InlineData("HelpText", typeof(Fakes.NonStaticResource_WithNonStaticProperty))]
36+
[InlineData("WriteOnlyText", typeof(Fakes.NonStaticResource))]
37+
[InlineData("PrivateOnlyText", typeof(Fakes.NonStaticResource))]
38+
[InlineData("HelpText", typeof(Fakes.InternalResource))]
39+
public void ThrowsHelpText(string helpText, Type resourceType)
40+
{
41+
TestBaseAttribute baseAttribute = new TestBaseAttribute();
42+
baseAttribute.HelpText = helpText;
43+
baseAttribute.ResourceType = resourceType;
44+
45+
// Verify exception
46+
Assert.Throws<ArgumentException>(() => baseAttribute.HelpText.ToString());
47+
}
48+
49+
2350
private class TestBaseAttribute : BaseAttribute
2451
{
2552
public TestBaseAttribute()
2653
{
2754
// Do nothing
2855
}
2956
}
57+
3058
}
3159
}

0 commit comments

Comments
 (0)