Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a0e9cb7

Browse files
authored
Merge pull request #356 from anthonylangsworth/missing_author_NullReference
Fix for missing author null reference (#332)
2 parents 9ff3c90 + 13d8b58 commit a0e9cb7

File tree

7 files changed

+181
-3
lines changed

7 files changed

+181
-3
lines changed

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ artifacts/*
3939
.vs/*
4040
*.xproj.user
4141
*.nuget.targets
42-
*.lock.json
42+
*.lock.json
43+
*.nuget.props
44+

‎src/CommandLine/Error.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public abstract class TokenError : Error, IEquatable<TokenError>
157157
{
158158
private readonly string token;
159159

160+
/// <summary>
161+
/// Initializes a new instance of the <see cref="CommandLine.TokenError"/> class.
162+
/// </summary>
163+
/// <param name="tag">Error type.</param>
164+
/// <param name="token">Problematic token.</param>
160165
protected internal TokenError(ErrorType tag, string token)
161166
: base(tag)
162167
{
@@ -232,6 +237,12 @@ public abstract class NamedError : Error, IEquatable<NamedError>
232237
{
233238
private readonly NameInfo nameInfo;
234239

240+
/// <summary>
241+
/// Initializes a new instance of the <see cref="CommandLine.NamedError"/> class.
242+
/// </summary>
243+
/// <param name="tag">Error type.</param>
244+
/// <param name="nameInfo">Problematic name.</param>
245+
235246
protected internal NamedError(ErrorType tag, NameInfo nameInfo)
236247
: base(tag)
237248
{

‎src/CommandLine/Infrastructure/ReflectionHelper.cs‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,57 @@
11
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
22

33
using System;
4+
using System.Collections.Generic;
45
using System.Linq;
56
using System.Reflection;
7+
using System.Runtime.Remoting.Messaging;
68
using CommandLine.Core;
79
using CSharpx;
810

911
namespace CommandLine.Infrastructure
1012
{
1113
static class ReflectionHelper
1214
{
15+
/// <summary>
16+
/// Per thread assembly attribute overrides for testing.
17+
/// </summary>
18+
[ThreadStatic] private static IDictionary<Type, Attribute> _overrides;
19+
20+
/// <summary>
21+
/// Assembly attribute overrides for testing.
22+
/// </summary>
23+
/// <remarks>
24+
/// The implementation will fail if two or more attributes of the same type
25+
/// are included in <paramref name="overrides"/>.
26+
/// </remarks>
27+
/// <param name="overrides">
28+
/// Attributes that replace the existing assembly attributes or null,
29+
/// to clear any testing attributes.
30+
/// </param>
31+
public static void SetAttributeOverride(IEnumerable<Attribute> overrides)
32+
{
33+
if (overrides != null)
34+
{
35+
_overrides = overrides.ToDictionary(attr => attr.GetType(), attr => attr);
36+
}
37+
else
38+
{
39+
_overrides = null;
40+
}
41+
}
42+
1343
public static Maybe<TAttribute> GetAttribute<TAttribute>()
1444
where TAttribute : Attribute
1545
{
46+
// Test support
47+
if (_overrides != null)
48+
{
49+
return
50+
_overrides.ContainsKey(typeof(TAttribute)) ?
51+
Maybe.Just((TAttribute)_overrides[typeof(TAttribute)]) :
52+
Maybe.Nothing< TAttribute>();
53+
}
54+
1655
var assembly = GetExecutingOrEntryAssembly();
1756

1857
#if NET40

‎src/CommandLine/Text/CopyrightInfo.cs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information.
22

33
using System;
4+
using System.Dynamic;
45
using System.Globalization;
56
using System.Reflection;
67
using System.Text;
@@ -24,6 +25,17 @@ public class CopyrightInfo
2425
private readonly string author;
2526
private readonly int builderSize;
2627

28+
/// <summary>
29+
/// An empty object used for initialization.
30+
/// </summary>
31+
public static CopyrightInfo Empty
32+
{
33+
get
34+
{
35+
return new CopyrightInfo("author", 1);
36+
}
37+
}
38+
2739
/// <summary>
2840
/// Initializes a new instance of the <see cref="CommandLine.Text.CopyrightInfo"/> class
2941
/// specifying author and year.

‎src/CommandLine/Text/HeadingInfo.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ public HeadingInfo(string programName, string version = null)
3333
this.version = version;
3434
}
3535

36+
/// <summary>
37+
/// An empty object used for initialization.
38+
/// </summary>
39+
public static HeadingInfo Empty
40+
{
41+
get
42+
{
43+
return new HeadingInfo("");
44+
}
45+
}
46+
3647
/// <summary>
3748
/// Gets the default heading instance.
3849
/// The title is retrieved from <see cref="AssemblyTitleAttribute"/>,

‎src/CommandLine/Text/HelpText.cs‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,23 @@ public static HelpText AutoBuild<T>(
212212
{
213213
var auto = new HelpText
214214
{
215-
Heading = HeadingInfo.Default,
216-
Copyright = CopyrightInfo.Default,
215+
Heading = HeadingInfo.Empty,
216+
Copyright = CopyrightInfo.Empty,
217217
AdditionalNewLineAfterOption = true,
218218
AddDashesToOption = !verbsIndex,
219219
MaximumDisplayWidth = maxDisplayWidth
220220
};
221221

222+
try
223+
{
224+
auto.Heading = HeadingInfo.Default;
225+
auto.Copyright = CopyrightInfo.Default;
226+
}
227+
catch (Exception)
228+
{
229+
auto = onError(auto);
230+
}
231+
222232
var errors = Enumerable.Empty<Error>();
223233

224234
if (onError != null && parserResult.Tag == ParserResultType.NotParsed)

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

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
using System.Collections.Generic;
55
using System.Globalization;
66
using System.Linq;
7+
using System.Reflection;
78
using CommandLine.Core;
9+
using CommandLine.Infrastructure;
810
using CommandLine.Tests.Fakes;
11+
using CommandLine.Tests.Unit.Infrastructure;
912
using CommandLine.Text;
1013
using FluentAssertions;
1114
using Xunit;
@@ -564,5 +567,95 @@ public void Default_set_to_sequence_should_be_properly_printed()
564567
// Teardown
565568
}
566569
#endif
570+
571+
[Fact]
572+
public void AutoBuild_when_no_assembly_attributes()
573+
{
574+
try
575+
{
576+
string expectedCopyright = "Copyright (C) 1 author";
577+
578+
ReflectionHelper.SetAttributeOverride(new Attribute[0]);
579+
580+
ParserResult<Simple_Options> fakeResult = new NotParsed<Simple_Options>(
581+
TypeInfo.Create(typeof (Simple_Options)), new Error[0]);
582+
bool onErrorCalled = false;
583+
HelpText actualResult = HelpText.AutoBuild(fakeResult, ht =>
584+
{
585+
onErrorCalled = true;
586+
return ht;
587+
}, ex => ex);
588+
589+
onErrorCalled.Should().BeTrue();
590+
actualResult.Copyright.Should().Be(expectedCopyright);
591+
}
592+
finally
593+
{
594+
ReflectionHelper.SetAttributeOverride(null);
595+
}
596+
}
597+
598+
[Fact]
599+
public void AutoBuild_with_assembly_title_and_version_attributes_only()
600+
{
601+
try
602+
{
603+
string expectedTitle = "Title";
604+
string expectedVersion = "1.2.3.4";
605+
606+
ReflectionHelper.SetAttributeOverride(new Attribute[]
607+
{
608+
new AssemblyTitleAttribute(expectedTitle),
609+
new AssemblyInformationalVersionAttribute(expectedVersion)
610+
});
611+
612+
ParserResult<Simple_Options> fakeResult = new NotParsed<Simple_Options>(
613+
TypeInfo.Create(typeof (Simple_Options)), new Error[0]);
614+
bool onErrorCalled = false;
615+
HelpText actualResult = HelpText.AutoBuild(fakeResult, ht =>
616+
{
617+
onErrorCalled = true;
618+
return ht;
619+
}, ex => ex);
620+
621+
onErrorCalled.Should().BeTrue();
622+
actualResult.Heading.Should().Be(string.Format("{0} {1}", expectedTitle, expectedVersion));
623+
}
624+
finally
625+
{
626+
ReflectionHelper.SetAttributeOverride(null);
627+
}
628+
}
629+
630+
631+
[Fact]
632+
public void AutoBuild_with_assembly_company_attribute_only()
633+
{
634+
try
635+
{
636+
string expectedCompany = "Company";
637+
638+
ReflectionHelper.SetAttributeOverride(new Attribute[]
639+
{
640+
new AssemblyCompanyAttribute(expectedCompany)
641+
});
642+
643+
ParserResult<Simple_Options> fakeResult = new NotParsed<Simple_Options>(
644+
TypeInfo.Create(typeof (Simple_Options)), new Error[0]);
645+
bool onErrorCalled = false;
646+
HelpText actualResult = HelpText.AutoBuild(fakeResult, ht =>
647+
{
648+
onErrorCalled = true;
649+
return ht;
650+
}, ex => ex);
651+
652+
onErrorCalled.Should().BeFalse(); // Other attributes have fallback logic
653+
actualResult.Copyright.Should().Be(string.Format("Copyright (C) {0} {1}", DateTime.Now.Year, expectedCompany));
654+
}
655+
finally
656+
{
657+
ReflectionHelper.SetAttributeOverride(null);
658+
}
659+
}
567660
}
568661
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /