Skip to content

Commit b703454

Browse files
committed
Fix dotnet#1715 with the ability to revert the old behavior
1 parent a15545b commit b703454

File tree

5 files changed

+66
-12
lines changed

5 files changed

+66
-12
lines changed

src/BenchmarkDotNet/Reports/SummaryStyle.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ public class SummaryStyle : IEquatable<SummaryStyle>
2626

2727
public RatioStyle RatioStyle { get; }
2828

29+
public bool OldBehaviorForBenchmarkName { get; }
30+
2931
public SummaryStyle([CanBeNull] CultureInfo cultureInfo, bool printUnitsInHeader, SizeUnit sizeUnit, TimeUnit timeUnit, bool printUnitsInContent = true,
30-
bool printZeroValuesInContent = false, int maxParameterColumnWidth = DefaultMaxParameterColumnWidth, RatioStyle ratioStyle = RatioStyle.Value)
32+
bool printZeroValuesInContent = false, int maxParameterColumnWidth = DefaultMaxParameterColumnWidth, RatioStyle ratioStyle = RatioStyle.Value,
33+
bool oldBehaviorForBenchmarkName = false)
3134
{
3235
if (maxParameterColumnWidth < DefaultMaxParameterColumnWidth)
3336
throw new ArgumentOutOfRangeException(nameof(maxParameterColumnWidth), $"{DefaultMaxParameterColumnWidth} is the minimum.");
@@ -41,6 +44,7 @@ public SummaryStyle([CanBeNull] CultureInfo cultureInfo, bool printUnitsInHeader
4144
MaxParameterColumnWidth = maxParameterColumnWidth;
4245
RatioStyle = ratioStyle;
4346
CodeSizeUnit = SizeUnit.B;
47+
OldBehaviorForBenchmarkName = oldBehaviorForBenchmarkName;
4448
}
4549

4650
public SummaryStyle WithTimeUnit(TimeUnit timeUnit)
@@ -61,6 +65,9 @@ public SummaryStyle WithCultureInfo(CultureInfo cultureInfo)
6165
public SummaryStyle WithRatioStyle(RatioStyle ratioStyle)
6266
=> new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth, ratioStyle);
6367

68+
public SummaryStyle WithOldBehaviorForBenchmarkName(bool oldBehaviorForBenchmarkName)
69+
=> new SummaryStyle(CultureInfo, PrintUnitsInHeader, SizeUnit, TimeUnit, PrintUnitsInContent, PrintZeroValuesInContent, MaxParameterColumnWidth, RatioStyle, oldBehaviorForBenchmarkName);
70+
6471
public bool Equals(SummaryStyle other)
6572
{
6673
if (ReferenceEquals(null, other))
@@ -75,7 +82,8 @@ public bool Equals(SummaryStyle other)
7582
&& Equals(CodeSizeUnit, other.CodeSizeUnit)
7683
&& Equals(TimeUnit, other.TimeUnit)
7784
&& MaxParameterColumnWidth == other.MaxParameterColumnWidth
78-
&& RatioStyle == other.RatioStyle;
85+
&& RatioStyle == other.RatioStyle
86+
&& OldBehaviorForBenchmarkName == other.OldBehaviorForBenchmarkName;
7987
}
8088

8189
public override bool Equals(object obj) => obj is SummaryStyle summary && Equals(summary);
@@ -92,6 +100,7 @@ public override int GetHashCode()
92100
hashCode = (hashCode * 397) ^ (TimeUnit != null ? TimeUnit.GetHashCode() : 0);
93101
hashCode = (hashCode * 397) ^ MaxParameterColumnWidth;
94102
hashCode = (hashCode * 397) ^ RatioStyle.GetHashCode();
103+
hashCode = (hashCode * 397) ^ OldBehaviorForBenchmarkName.GetHashCode();
95104
return hashCode;
96105
}
97106
}

src/BenchmarkDotNet/Running/BenchmarkConverter.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private static BenchmarkRunInfo MethodsToBenchmarksWithFullConfig(Type type, Met
5151
var iterationSetupMethods = GetAttributedMethods<IterationSetupAttribute>(allMethods, "IterationSetup");
5252
var iterationCleanupMethods = GetAttributedMethods<IterationCleanupAttribute>(allMethods, "IterationCleanup");
5353

54-
var targets = GetTargets(benchmarkMethods, type, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods).ToArray();
54+
var targets = GetTargets(benchmarkMethods, type, globalSetupMethods, globalCleanupMethods, iterationSetupMethods, iterationCleanupMethods, configPerType.SummaryStyle.OldBehaviorForBenchmarkName).ToArray();
5555

5656
var parameterDefinitions = GetParameterDefinitions(type);
5757
var parameterInstancesList = parameterDefinitions.Expand(configPerType.SummaryStyle);
@@ -115,7 +115,8 @@ private static IEnumerable<Descriptor> GetTargets(
115115
Tuple<MethodInfo, TargetedAttribute>[] globalSetupMethods,
116116
Tuple<MethodInfo, TargetedAttribute>[] globalCleanupMethods,
117117
Tuple<MethodInfo, TargetedAttribute>[] iterationSetupMethods,
118-
Tuple<MethodInfo, TargetedAttribute>[] iterationCleanupMethods)
118+
Tuple<MethodInfo, TargetedAttribute>[] iterationCleanupMethods,
119+
bool oldBehaviorForBenchmarkName)
119120
{
120121
return targetMethods
121122
.Select(methodInfo => CreateDescriptor(type,
@@ -125,7 +126,8 @@ private static IEnumerable<Descriptor> GetTargets(
125126
GetTargetedMatchingMethod(methodInfo, iterationSetupMethods),
126127
GetTargetedMatchingMethod(methodInfo, iterationCleanupMethods),
127128
methodInfo.ResolveAttribute<BenchmarkAttribute>(),
128-
targetMethods));
129+
targetMethods,
130+
oldBehaviorForBenchmarkName));
129131
}
130132

131133
private static MethodInfo GetTargetedMatchingMethod(MethodInfo benchmarkMethod, Tuple<MethodInfo, TargetedAttribute>[] methods)
@@ -152,7 +154,8 @@ private static Descriptor CreateDescriptor(
152154
MethodInfo iterationSetupMethod,
153155
MethodInfo iterationCleanupMethod,
154156
BenchmarkAttribute attr,
155-
MethodInfo[] targetMethods)
157+
MethodInfo[] targetMethods,
158+
bool oldBehaviorForBenchmarkName)
156159
{
157160
var target = new Descriptor(
158161
type,
@@ -165,7 +168,8 @@ private static Descriptor CreateDescriptor(
165168
baseline: attr.Baseline,
166169
categories: GetCategories(methodInfo),
167170
operationsPerInvoke: attr.OperationsPerInvoke,
168-
methodIndex: Array.IndexOf(targetMethods, methodInfo));
171+
methodIndex: Array.IndexOf(targetMethods, methodInfo),
172+
oldBehaviorForBenchmarkName: oldBehaviorForBenchmarkName);
169173
AssertMethodHasCorrectSignature("Benchmark", methodInfo);
170174
AssertMethodIsAccessible("Benchmark", methodInfo);
171175
AssertMethodIsNotGeneric("Benchmark", methodInfo);

src/BenchmarkDotNet/Running/ClassicBenchmarkConverter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ public static BenchmarkRunInfo[] SourceToBenchmarks(string source, IConfig confi
114114
return BenchmarkCase.Create(
115115
new Descriptor(target.Type, target.WorkloadMethod, target.GlobalSetupMethod, target.GlobalCleanupMethod,
116116
target.IterationSetupMethod, target.IterationCleanupMethod,
117-
target.WorkloadMethodDisplayInfo, benchmarkContent, target.Baseline, target.Categories, target.OperationsPerInvoke),
117+
target.WorkloadMethodDisplayInfo, benchmarkContent, target.Baseline, target.Categories, target.OperationsPerInvoke,
118+
oldBehaviorForBenchmarkName: config?.SummaryStyle?.OldBehaviorForBenchmarkName ?? false),
118119
b.Job,
119120
b.Parameters,
120121
b.Config);

src/BenchmarkDotNet/Running/Descriptor.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public Descriptor(
4141
bool baseline = false,
4242
string[] categories = null,
4343
int operationsPerInvoke = 1,
44-
int methodIndex = 0)
44+
int methodIndex = 0,
45+
bool oldBehaviorForBenchmarkName = false)
4546
{
4647
Type = type;
4748
WorkloadMethod = workloadMethod;
@@ -51,16 +52,19 @@ public Descriptor(
5152
IterationCleanupMethod = iterationCleanupMethod;
5253
OperationsPerInvoke = operationsPerInvoke;
5354
AdditionalLogic = additionalLogic ?? string.Empty;
54-
WorkloadMethodDisplayInfo = FormatDescription(description) ?? workloadMethod?.Name ?? "Untitled";
55+
WorkloadMethodDisplayInfo = FormatDescription(description, oldBehaviorForBenchmarkName) ?? workloadMethod?.Name ?? "Untitled";
5556
Baseline = baseline;
5657
Categories = categories ?? Array.Empty<string>();
5758
MethodIndex = methodIndex;
5859
}
5960

6061
public override string ToString() => DisplayInfo;
6162

62-
private static string FormatDescription([CanBeNull] string description)
63+
private static string FormatDescription([CanBeNull] string description, bool oldBehaviorForBenchmarkName)
6364
{
65+
if (!oldBehaviorForBenchmarkName)
66+
return description;
67+
6468
var specialSymbols = new[] { ' ', '\'', '[', ']' };
6569
return description != null && specialSymbols.Any(description.Contains)
6670
? "'" + description + "'"

tests/BenchmarkDotNet.Tests/Running/BenchmarkConverterTests.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using BenchmarkDotNet.Configs;
55
using BenchmarkDotNet.Environments;
66
using BenchmarkDotNet.Jobs;
7+
using BenchmarkDotNet.Reports;
78
using BenchmarkDotNet.Running;
89
using Perfolizer.Mathematics.OutlierDetection;
910
using Xunit;
@@ -278,5 +279,40 @@ public class PrivateIterationCleanup
278279
[IterationCleanup] private void X() { }
279280
[Benchmark] public void A() { }
280281
}
282+
283+
[Fact]
284+
public void BenchmarkNameWithSpecialCharactersIsNotEscapedByDefault()
285+
{
286+
var info = BenchmarkConverter.TypeToBenchmarks(typeof(BenchmarkNamesWithSpecialCharacters));
287+
288+
Assert.Equal("with space", info.BenchmarksCases[0].Descriptor.WorkloadMethodDisplayInfo);
289+
Assert.Equal("na\'me", info.BenchmarksCases[1].Descriptor.WorkloadMethodDisplayInfo);
290+
Assert.Equal("[name]", info.BenchmarksCases[2].Descriptor.WorkloadMethodDisplayInfo);
291+
}
292+
293+
[Fact]
294+
public void OldBenchmarkNameBehaviorCanBeEnabledWithSummaryStyle()
295+
{
296+
var config = DefaultConfig.Instance.WithSummaryStyle(
297+
SummaryStyle.Default.WithOldBehaviorForBenchmarkName(true));
298+
299+
var info = BenchmarkConverter.TypeToBenchmarks(typeof(BenchmarkNamesWithSpecialCharacters), config);
300+
301+
Assert.Equal("'with space'", info.BenchmarksCases[0].Descriptor.WorkloadMethodDisplayInfo);
302+
Assert.Equal("'na\'me'", info.BenchmarksCases[1].Descriptor.WorkloadMethodDisplayInfo);
303+
Assert.Equal("'[name]'", info.BenchmarksCases[2].Descriptor.WorkloadMethodDisplayInfo);
304+
}
305+
306+
public sealed class BenchmarkNamesWithSpecialCharacters
307+
{
308+
[Benchmark(Description = "with space")]
309+
public void A() { }
310+
311+
[Benchmark(Description = "na\'me")]
312+
public void B() { }
313+
314+
[Benchmark(Description = "[name]")]
315+
public void C() { }
316+
}
281317
}
282-
}
318+
}

0 commit comments

Comments
 (0)