Skip to content

Commit d633699

Browse files
committed
refactor: improve readability and maintainability organization options
1 parent 3aff795 commit d633699

File tree

11 files changed

+278
-174
lines changed

11 files changed

+278
-174
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//"compare", "-f", "console", "-b", "../tests/test-data/report-02/Benchmark-report-full.json", "-t", "../tests/test-data/report-01/Benchmark-report-full.json", "-tm", "4%", "-ta", "5%"
1414
//"compare", "-f", "console", "-b", "../tests/test-data/report-01/Benchmark-report-full.json", "-t", "../tests/test-data/report-04/Benchmark-report-full.json"
1515
//"compare", "-f", "markdown", "-b", "../tests/test-data/report-01/Benchmark-report-full.json", "-t", "../tests/test-data/report-02/Benchmark-report-full.json", "-tm", "12ns", "-ta", "5%"
16-
"compare", "-f", "console", "-f", "markdown", "-b", "../tests/test-data/report-12", "-t", "../tests/test-data/report-11"
16+
"compare", "-f", "CONSOLE", "-f", "markdown", "-b", "../tests/test-data/report-12", "-t", "../tests/test-data/report-11"
1717
],
1818
"cwd": "${workspaceFolder}/src",
1919
"console": "internalConsole",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.CommandLine;
2+
3+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
4+
5+
public sealed class AllocationThresholdOption : Option<string>
6+
{
7+
public AllocationThresholdOption()
8+
: base("--threshold-allocation", "-ta")
9+
{
10+
Description = "Throw an error when the allocation threshold is met. Examples: 5%, 10b, 10kb, 100mb, 1gb.";
11+
}
12+
}

src/Options/BaselineOption.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.CommandLine;
2+
3+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
4+
5+
public sealed class BaselineOption : Option<string>
6+
{
7+
public BaselineOption()
8+
: base("--baseline", "-b")
9+
{
10+
Description = "Path to the folder or file with Baseline report.";
11+
Required = true;
12+
}
13+
}

src/Options/FormatsOption.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.CommandLine;
4+
using System.Linq;
5+
6+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
7+
8+
public sealed class FormatsOption : Option<string[]>
9+
{
10+
private static readonly HashSet<string> _allowedValues = new(StringComparer.OrdinalIgnoreCase) { "console", "markdown", "json", "hit-txt" };
11+
12+
public FormatsOption()
13+
: base("--format", "-f")
14+
{
15+
Description = "Output format for the report.";
16+
DefaultValueFactory = _ => ["console"];
17+
18+
Validators.Add(static result =>
19+
{
20+
var values = result.Tokens
21+
.Select(token => token.Value)
22+
.Where(value => !string.IsNullOrWhiteSpace(value))
23+
.ToArray();
24+
if(values != null)
25+
{
26+
foreach(var value in values)
27+
{
28+
if(!_allowedValues.Contains(value))
29+
{
30+
result.AddError($"Invalid format '{value}'. Allowed values: {string.Join(", ", _allowedValues)}");
31+
}
32+
}
33+
}
34+
});
35+
}
36+
}

src/Options/MeanThresholdOption.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.CommandLine;
2+
3+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
4+
5+
public sealed class MeanThresholdOption : Option<string>
6+
{
7+
public MeanThresholdOption()
8+
: base("--threshold-mean", "-tm")
9+
{
10+
Description = "Throw an error when the mean threshold is met. Examples: 5%, 10ms, 10μs, 100ns, 1s.";
11+
}
12+
}

src/Options/OutputOption.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.CommandLine;
2+
3+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
4+
5+
public sealed class OutputOption : Option<string>
6+
{
7+
public OutputOption()
8+
: base("--output", "-o")
9+
{
10+
Description = "Output directory to export the diff report. Default is current directory.";
11+
DefaultValueFactory = _ => "./BenchmarkReporter";
12+
}
13+
}

src/Options/TargetOption.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.CommandLine;
2+
3+
namespace PowerUtils.BenchmarkDotnet.Reporter.Options;
4+
5+
public sealed class TargetOption : Option<string>
6+
{
7+
public TargetOption()
8+
: base("--target", "-t")
9+
{
10+
Description = "Path to the folder or file with target reports.";
11+
Required = true;
12+
}
13+
}

src/ToolCommands.cs

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
using System;
22
using System.CommandLine;
3-
using System.Linq;
43
using Microsoft.Extensions.DependencyInjection;
54
using PowerUtils.BenchmarkDotnet.Reporter.Commands;
5+
using PowerUtils.BenchmarkDotnet.Reporter.Options;
66

77
namespace PowerUtils.BenchmarkDotnet.Reporter;
88

99
public sealed class ToolCommands : RootCommand
1010
{
1111
public ToolCommands(IServiceProvider provider)
1212
{
13-
var baseline = _createBaselineOption();
14-
var target = _createTargetOption();
13+
var baseline = new BaselineOption();
14+
var target = new TargetOption();
1515

16-
var meanThreshold = _createMeanThresholdOption();
17-
var allocationThreshold = _createAllocationThresholdOption();
16+
var meanThreshold = new MeanThresholdOption();
17+
var allocationThreshold = new AllocationThresholdOption();
1818

19-
var formats = _createFormatsOption();
20-
var output = _createOutputOption();
19+
var formats = new FormatsOption();
20+
var output = new OutputOption();
2121

2222
var compareCommand = new Command(
2323
"compare",
@@ -43,65 +43,4 @@ public ToolCommands(IServiceProvider provider)
4343

4444
Subcommands.Add(compareCommand);
4545
}
46-
47-
48-
private static Option<string> _createBaselineOption()
49-
=> new("--baseline", "-b")
50-
{
51-
Description = "Path to the folder or file with Baseline report.",
52-
Required = true
53-
};
54-
55-
private static Option<string> _createTargetOption()
56-
=> new("--target", "-t")
57-
{
58-
Description = "Path to the folder or file with target reports.",
59-
Required = true
60-
};
61-
62-
private static Option<string> _createMeanThresholdOption()
63-
=> new("--threshold-mean", "-tm")
64-
{
65-
Description = "Throw an error when the mean threshold is met. Examples: 5%, 10ms, 10μs, 100ns, 1s."
66-
};
67-
68-
private static Option<string> _createAllocationThresholdOption()
69-
=> new("--threshold-allocation", "-ta")
70-
{
71-
Description = "Throw an error when the allocation threshold is met. Examples: 5%, 10b, 10kb, 100mb, 1gb."
72-
};
73-
74-
private static Option<string[]> _createFormatsOption()
75-
{
76-
var option = new Option<string[]>("--format", "-f")
77-
{
78-
Description = "Output format for the report.",
79-
DefaultValueFactory = _ => ["console"]
80-
};
81-
82-
option.Validators.Add(result =>
83-
{
84-
var allowedValues = new[] { "console", "markdown", "json", "hit-txt" };
85-
var values = result.GetValue(option);
86-
if(values != null)
87-
{
88-
foreach(var value in values)
89-
{
90-
if(!allowedValues.Contains(value))
91-
{
92-
result.AddError($"Invalid format '{value}'. Allowed values: {string.Join(", ", allowedValues)}");
93-
}
94-
}
95-
}
96-
});
97-
98-
return option;
99-
}
100-
101-
private static Option<string> _createOutputOption()
102-
=> new("--output", "-o")
103-
{
104-
Description = "Output directory to export the diff report. Default is current directory.",
105-
DefaultValueFactory = _ => "./BenchmarkReporter"
106-
};
10746
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using System.Linq;
3+
using PowerUtils.BenchmarkDotnet.Reporter.Commands;
4+
5+
namespace PowerUtils.BenchmarkDotnet.Reporter.Tests.Options;
6+
7+
public sealed class FormatOptionTests
8+
{
9+
private readonly IServiceProvider _provider;
10+
11+
public FormatOptionTests()
12+
{
13+
_provider = Substitute.For<IServiceProvider>();
14+
var command = Substitute.For<IComparerCommand>();
15+
16+
_provider
17+
.GetService(typeof(IComparerCommand))
18+
.Returns(command);
19+
}
20+
21+
[Fact]
22+
public void CompareCommand_ShouldHave_FormatsOption()
23+
{
24+
// Arrange & Act
25+
var toolCommands = new ToolCommands(_provider);
26+
27+
28+
// Assert
29+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
30+
var formatsOption = compareCommand.Options.Single(o => o.Name == "--format");
31+
32+
formatsOption.ValueType.ShouldBe(typeof(string[]));
33+
formatsOption.Aliases.Count.ShouldBe(1);
34+
formatsOption.Aliases.ShouldContain("-f");
35+
formatsOption.Description.ShouldBe("Output format for the report.");
36+
}
37+
38+
[Theory]
39+
[InlineData("markdown", true)]
40+
[InlineData("jSOn", true)]
41+
[InlineData("HIT-TXT", true)]
42+
[InlineData("console", true)]
43+
[InlineData("invalid-format", false)]
44+
public void Test_Validation_Format_Option(string format, bool isValid)
45+
{
46+
// Arrange
47+
var command = "compare";
48+
var option = "--format";
49+
50+
var toolCommands = new ToolCommands(_provider);
51+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == command);
52+
var formatsOption = compareCommand.Options.Single(o => o.Name == option);
53+
var validation = formatsOption.Validators.Single();
54+
55+
56+
// Act
57+
var parseResult = toolCommands.Parse($"{command} {option} {format}");
58+
var firstOptionResult = parseResult.GetResult(formatsOption);
59+
60+
// Assert
61+
firstOptionResult?.Errors.Count().ShouldBe(isValid ? 0 : 1);
62+
}
63+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using System.Linq;
3+
using PowerUtils.BenchmarkDotnet.Reporter.Commands;
4+
5+
namespace PowerUtils.BenchmarkDotnet.Reporter.Tests.Options;
6+
7+
public sealed class OptionsTests
8+
{
9+
private readonly IServiceProvider _provider;
10+
11+
public OptionsTests()
12+
{
13+
_provider = Substitute.For<IServiceProvider>();
14+
var command = Substitute.For<IComparerCommand>();
15+
16+
_provider
17+
.GetService(typeof(IComparerCommand))
18+
.Returns(command);
19+
}
20+
21+
[Fact]
22+
public void CompareCommand_ShouldHave_BaselineOption()
23+
{
24+
// Arrange & Act
25+
var toolCommands = new ToolCommands(_provider);
26+
27+
28+
// Assert
29+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
30+
var baselineOption = compareCommand.Options.Single(o => o.Name == "--baseline");
31+
32+
baselineOption.ValueType.ShouldBe(typeof(string));
33+
baselineOption.Aliases.Count.ShouldBe(1);
34+
baselineOption.Aliases.ShouldContain("-b");
35+
baselineOption.Required.ShouldBeTrue();
36+
baselineOption.Description.ShouldBe("Path to the folder or file with Baseline report.");
37+
}
38+
39+
[Fact]
40+
public void CompareCommand_ShouldHave_TargetOption()
41+
{
42+
// Arrange & Act
43+
var toolCommands = new ToolCommands(_provider);
44+
45+
46+
// Assert
47+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
48+
var targetOption = compareCommand.Options.Single(o => o.Name == "--target");
49+
50+
targetOption.ValueType.ShouldBe(typeof(string));
51+
targetOption.Aliases.Count.ShouldBe(1);
52+
targetOption.Aliases.ShouldContain("-t");
53+
targetOption.Required.ShouldBeTrue();
54+
targetOption.Description.ShouldBe("Path to the folder or file with target reports.");
55+
}
56+
57+
[Fact]
58+
public void CompareCommand_ShouldHave_ThresholdMeanOption()
59+
{
60+
// Arrange & Act
61+
var toolCommands = new ToolCommands(_provider);
62+
63+
64+
// Assert
65+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
66+
var meanThresholdOption = compareCommand.Options.Single(o => o.Name == "--threshold-mean");
67+
68+
meanThresholdOption.ValueType.ShouldBe(typeof(string));
69+
meanThresholdOption.Aliases.Count.ShouldBe(1);
70+
meanThresholdOption.Aliases.ShouldContain("-tm");
71+
meanThresholdOption.Description.ShouldBe("Throw an error when the mean threshold is met. Examples: 5%, 10ms, 10μs, 100ns, 1s.");
72+
}
73+
74+
[Fact]
75+
public void CompareCommand_ShouldHave_ThresholdAllocationOption()
76+
{
77+
// Arrange & Act
78+
var toolCommands = new ToolCommands(_provider);
79+
80+
81+
// Assert
82+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
83+
var allocationThresholdOption = compareCommand.Options.Single(o => o.Name == "--threshold-allocation");
84+
85+
allocationThresholdOption.ValueType.ShouldBe(typeof(string));
86+
allocationThresholdOption.Aliases.Count.ShouldBe(1);
87+
allocationThresholdOption.Aliases.ShouldContain("-ta");
88+
allocationThresholdOption.Description.ShouldBe("Throw an error when the allocation threshold is met. Examples: 5%, 10b, 10kb, 100mb, 1gb.");
89+
}
90+
91+
[Fact]
92+
public void CompareCommand_ShouldHave_OutputOption()
93+
{
94+
// Arrange & Act
95+
var toolCommands = new ToolCommands(_provider);
96+
97+
98+
// Assert
99+
var compareCommand = toolCommands.Subcommands.Single(c => c.Name == "compare");
100+
var outputOption = compareCommand.Options.Single(o => o.Name == "--output");
101+
102+
outputOption.ValueType.ShouldBe(typeof(string));
103+
outputOption.Aliases.Count.ShouldBe(1);
104+
outputOption.Aliases.ShouldContain("-o");
105+
outputOption.Description.ShouldBe("Output directory to export the diff report. Default is current directory.");
106+
}
107+
}

0 commit comments

Comments
 (0)