Skip to content

Commit 0746536

Browse files
KathleenDollardmhutch
authored andcommitted
Clean up pipeline/subsystem tests
1 parent 83934e0 commit 0746536

File tree

5 files changed

+129
-92
lines changed

5 files changed

+129
-92
lines changed

src/System.CommandLine.Subsystems.Tests/PipelineTests.cs

Lines changed: 86 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,87 +3,78 @@
33

44
using FluentAssertions;
55
using System.CommandLine.Parsing;
6-
using System.Reflection;
76
using Xunit;
87

98
namespace System.CommandLine.Subsystems.Tests
109
{
1110
public class PipelineTests
1211
{
13-
14-
private static readonly string? version = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly())
15-
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
16-
?.InformationalVersion;
17-
12+
private static Pipeline GetTestPipeline(VersionSubsystem versionSubsystem)
13+
=> new()
14+
{
15+
Version = versionSubsystem
16+
};
17+
private static CliConfiguration GetNewTestConfiguration()
18+
=> new(new CliRootCommand { new CliOption<bool>("-x") }); // Add option expected by test data
19+
20+
private static ConsoleHack GetNewTestConsole()
21+
=> new ConsoleHack().RedirectToBuffer(true);
22+
23+
//private static (Pipeline pipeline, CliConfiguration configuration, ConsoleHack consoleHack) StandardObjects(VersionSubsystem versionSubsystem)
24+
//{
25+
// var configuration = new CliConfiguration(new CliRootCommand { new CliOption<bool>("-x") });
26+
// var pipeline = new Pipeline
27+
// {
28+
// Version = versionSubsystem
29+
// };
30+
// var consoleHack = new ConsoleHack().RedirectToBuffer(true);
31+
// return (pipeline, configuration, consoleHack);
32+
//}
1833

1934
[Theory]
20-
[InlineData("-v", true)]
21-
[InlineData("--version", true)]
22-
[InlineData("-x", false)]
23-
[InlineData("", false)]
24-
[InlineData(null, false)]
35+
[ClassData(typeof(TestData.Version))]
2536
public void Subsystem_runs_in_pipeline_only_when_requested(string input, bool shouldRun)
2637
{
27-
var configuration = new CliConfiguration(new CliRootCommand { });
28-
var pipeline = new Pipeline
29-
{
30-
Version = new VersionSubsystem()
31-
};
32-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
38+
var pipeline = GetTestPipeline(new VersionSubsystem());
39+
var console = GetNewTestConsole();
3340

34-
var exit = pipeline.Execute(configuration, input, consoleHack);
41+
var exit = pipeline.Execute(GetNewTestConfiguration(), input, console);
3542

3643
exit.ExitCode.Should().Be(0);
3744
exit.Handled.Should().Be(shouldRun);
3845
if (shouldRun)
3946
{
40-
consoleHack.GetBuffer().Trim().Should().Be(version);
47+
console.GetBuffer().Trim().Should().Be(TestData.AssemblyVersionString);
4148
}
4249
}
4350

4451
[Theory]
45-
[InlineData("-v", true)]
46-
[InlineData("--version", true)]
47-
[InlineData("-x", false)]
48-
[InlineData("", false)]
49-
[InlineData(null, false)]
52+
[ClassData(typeof(TestData.Version))]
5053
public void Subsystem_runs_with_explicit_parse_only_when_requested(string input, bool shouldRun)
5154
{
52-
var configuration = new CliConfiguration(new CliRootCommand { });
53-
var pipeline = new Pipeline
54-
{
55-
Version = new VersionSubsystem()
56-
};
57-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
55+
var pipeline = GetTestPipeline(new VersionSubsystem());
56+
var console = GetNewTestConsole();
5857

59-
var result = pipeline.Parse(configuration, input);
60-
var exit = pipeline.Execute(result, input, consoleHack);
58+
var result = pipeline.Parse(GetNewTestConfiguration(), input);
59+
var exit = pipeline.Execute(result, input, console);
6160

6261
exit.ExitCode.Should().Be(0);
6362
exit.Handled.Should().Be(shouldRun);
6463
if (shouldRun)
6564
{
66-
consoleHack.GetBuffer().Trim().Should().Be(version);
65+
console.GetBuffer().Trim().Should().Be(TestData.AssemblyVersionString);
6766
}
6867
}
6968

7069
[Theory]
71-
[InlineData("-v", true)]
72-
[InlineData("--version", true)]
73-
[InlineData("-x", false)]
74-
[InlineData("", false)]
75-
[InlineData(null, false)]
70+
[ClassData(typeof(TestData.Version))]
7671
public void Subsystem_runs_initialize_and_teardown_when_requested(string input, bool shouldRun)
7772
{
78-
var configuration = new CliConfiguration(new CliRootCommand { });
79-
AlternateSubsystems.VersionWithInitializeAndTeardown versionSubsystem = new AlternateSubsystems.VersionWithInitializeAndTeardown();
80-
var pipeline = new Pipeline
81-
{
82-
Version = versionSubsystem
83-
};
84-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
73+
var versionSubsystem = new AlternateSubsystems.VersionWithInitializeAndTeardown();
74+
var pipeline = GetTestPipeline(versionSubsystem);
75+
var console = GetNewTestConsole();
8576

86-
var exit = pipeline.Execute(configuration, input, consoleHack);
77+
var exit = pipeline.Execute(GetNewTestConfiguration(), input, console);
8778

8879
exit.ExitCode.Should().Be(0);
8980
exit.Handled.Should().Be(shouldRun);
@@ -94,56 +85,72 @@ public void Subsystem_runs_initialize_and_teardown_when_requested(string input,
9485

9586

9687
[Theory]
97-
[InlineData("-v", true)]
98-
[InlineData("--version", true)]
99-
[InlineData("-x", false)]
100-
[InlineData("", false)]
101-
[InlineData(null, false)]
102-
public void Subsystem_can_be_used_without_runner(string input, bool shouldRun)
88+
[ClassData(typeof(TestData.Version))]
89+
public void Subsystem_works_without_pipeline(string input, bool shouldRun)
10390
{
104-
var configuration = new CliConfiguration(new CliRootCommand { });
10591
var versionSubsystem = new VersionSubsystem();
106-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
107-
108-
Subsystem.Initialize(versionSubsystem, configuration);
109-
// TODO: I do not know why anyone would do this, but I do not see a reason to work to block it. See style2 below
110-
var parseResult = CliParser.Parse(configuration.RootCommand, input, configuration);
92+
// TODO: Ensure an efficient conversion as people may copy this code
93+
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly();
94+
var console = GetNewTestConsole();
95+
var configuration = GetNewTestConfiguration();
96+
97+
Subsystem.Initialize(versionSubsystem, configuration, args);
98+
// This approach might be taken if someone is using a subsystem just for initialization
99+
var parseResult = CliParser.Parse(configuration.RootCommand, args, configuration);
111100
bool value = parseResult.GetValue<bool>("--version");
112101

102+
parseResult.Errors.Should().BeEmpty();
113103
value.Should().Be(shouldRun);
114-
if (shouldRun)
104+
if (shouldRun)
115105
{
116106
// TODO: Add an execute overload to avoid checking activated twice
117-
var exit = Subsystem.Execute(versionSubsystem, parseResult, input, consoleHack);
107+
var exit = Subsystem.Execute(versionSubsystem, parseResult, input, console);
118108
exit.Should().NotBeNull();
119109
exit.ExitCode.Should().Be(0);
120110
exit.Handled.Should().BeTrue();
121-
consoleHack.GetBuffer().Trim().Should().Be(version);
111+
console.GetBuffer().Trim().Should().Be(TestData.AssemblyVersionString);
122112
}
123113
}
124114

125115
[Theory]
126-
[InlineData("-v", true)]
127-
[InlineData("--version", true)]
128-
[InlineData("-x", false)]
129-
[InlineData("", false)]
130-
[InlineData(null, false)]
131-
public void Subsystem_can_be_used_without_runner_style2(string input, bool shouldRun)
116+
[ClassData(typeof(TestData.Version))]
117+
public void Subsystem_works_without_pipeline_style2(string input, bool shouldRun)
132118
{
133-
var configuration = new CliConfiguration(new CliRootCommand { });
134119
var versionSubsystem = new VersionSubsystem();
135-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
120+
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly();
121+
var console = GetNewTestConsole();
122+
var configuration = GetNewTestConfiguration();
136123
var expectedVersion = shouldRun
137-
? version
124+
? TestData.AssemblyVersionString
138125
: "";
139126

140-
Subsystem.Initialize(versionSubsystem, configuration);
141-
var parseResult = CliParser.Parse(configuration.RootCommand, input, configuration);
142-
var exit = Subsystem.ExecuteIfNeeded(versionSubsystem, parseResult, input, consoleHack);
127+
// Someone might use this approach if they wanted to do something with the ParseResult
128+
Subsystem.Initialize(versionSubsystem, configuration, args);
129+
var parseResult = CliParser.Parse(configuration.RootCommand, args, configuration);
130+
var exit = Subsystem.ExecuteIfNeeded(versionSubsystem, parseResult, input, console);
143131

144132
exit.ExitCode.Should().Be(0);
145133
exit.Handled.Should().Be(shouldRun);
146-
consoleHack.GetBuffer().Trim().Should().Be(expectedVersion);
134+
console.GetBuffer().Trim().Should().Be(expectedVersion);
135+
}
136+
137+
138+
[Theory]
139+
[InlineData("-xy", false)]
140+
[InlineData("--versionx", false)]
141+
public void Subsystem_runs_when_requested_even_when_there_are_errors(string input, bool shouldRun)
142+
{
143+
var versionSubsystem = new VersionSubsystem();
144+
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly();
145+
var configuration = GetNewTestConfiguration();
146+
147+
Subsystem.Initialize(versionSubsystem, configuration, args);
148+
// This approach might be taken if someone is using a subsystem just for initialization
149+
var parseResult = CliParser.Parse(configuration.RootCommand, args, configuration);
150+
bool value = parseResult.GetValue<bool>("--version");
151+
152+
parseResult.Errors.Should().NotBeEmpty();
153+
value.Should().Be(shouldRun);
147154
}
148155

149156
[Fact]
@@ -171,9 +178,8 @@ public void Normal_pipeline_contains_no_subsystems()
171178
public void Subsystems_can_access_each_others_data()
172179
{
173180
// TODO: Explore a mechanism that doesn't require the reference to retrieve data, this shows that it is awkward
174-
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
175181
var symbol = new CliOption<bool>("-x");
176-
182+
var console = GetNewTestConsole();
177183
var pipeline = new StandardPipeline
178184
{
179185
Version = new AlternateSubsystems.VersionThatUsesHelpData(symbol)
@@ -183,9 +189,10 @@ public void Subsystems_can_access_each_others_data()
183189
{
184190
symbol.With(pipeline.Help.Description, "Testing")
185191
};
186-
pipeline.Execute(new CliConfiguration(rootCommand), "-v", consoleHack);
187-
consoleHack.GetBuffer().Trim().Should().Be($"Testing");
188-
}
189192

193+
pipeline.Execute(new CliConfiguration(rootCommand), "-v", console);
194+
195+
console.GetBuffer().Trim().Should().Be($"Testing");
196+
}
190197
}
191198
}

src/System.CommandLine.Subsystems.Tests/System.CommandLine.Subsystems.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<Compile Include="AlternateSubsystems.cs" />
3333
<Compile Include="Constants.cs" />
3434
<Compile Include="PipelineTests.cs" />
35+
<Compile Include="TestData.cs" />
3536
<Compile Include="VersionFunctionalTests.cs" />
3637
<Compile Include="VersionSubsystemTests.cs" />
3738
</ItemGroup>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Collections;
5+
using System.Reflection;
6+
7+
namespace System.CommandLine.Subsystems.Tests;
8+
9+
internal class TestData
10+
{
11+
internal static readonly string? AssemblyVersionString = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly())
12+
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
13+
?.InformationalVersion;
14+
15+
internal class Version : IEnumerable<object[]>
16+
{
17+
// This data only works if the CLI has a --version with a -v alias and also has a -x option
18+
private readonly List<object[]> _data =
19+
[
20+
["--version", true],
21+
["-v", true],
22+
["-vx", true],
23+
["-xv", true],
24+
["-x", false],
25+
[null, false],
26+
["", false],
27+
];
28+
29+
public IEnumerator<object[]> GetEnumerator() => _data.GetEnumerator();
30+
31+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
32+
}
33+
}

src/System.CommandLine.Subsystems.Tests/VersionSubsystemTests.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System.Reflection;
54
using FluentAssertions;
65
using Xunit;
76
using System.CommandLine.Parsing;
87

98
namespace System.CommandLine.Subsystems.Tests
109
{
11-
1210
public class VersionSubsystemTests
1311
{
1412
[Fact]
1513
public void When_version_subsystem_is_used_the_version_option_is_added_to_the_root()
1614
{
1715
var rootCommand = new CliRootCommand
18-
{
19-
new CliOption<bool>("-x")
20-
};
16+
{
17+
new CliOption<bool>("-x") // add option that is expected for the test data used here
18+
};
2119
var configuration = new CliConfiguration(rootCommand);
2220
var pipeline = new Pipeline
2321
{
@@ -32,20 +30,18 @@ public void When_version_subsystem_is_used_the_version_option_is_added_to_the_ro
3230
.Count(x => x.Name == "--version")
3331
.Should()
3432
.Be(1);
35-
3633
}
3734

3835
[Theory]
39-
[InlineData("--version", true)]
40-
[InlineData("-v", true)]
41-
[InlineData("-x", false)]
42-
[InlineData("", false)]
36+
[ClassData(typeof(TestData.Version))]
4337
public void Version_is_activated_only_when_requested(string input, bool result)
4438
{
45-
CliRootCommand rootCommand = new();
39+
CliRootCommand rootCommand = [new CliOption<bool>("-x")]; // add random option as empty CLIs are rare
4640
var configuration = new CliConfiguration(rootCommand);
4741
var versionSubsystem = new VersionSubsystem();
48-
Subsystem.Initialize(versionSubsystem, configuration);
42+
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly();
43+
44+
Subsystem.Initialize(versionSubsystem, configuration, args);
4945

5046
var parseResult = CliParser.Parse(rootCommand, input, configuration);
5147
var isActive = Subsystem.GetIsActivated(versionSubsystem, parseResult);

src/System.CommandLine.Subsystems/CompletionSubsystem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace System.CommandLine;
99
public class CompletionSubsystem : CliSubsystem
1010
{
1111
public CompletionSubsystem(IAnnotationProvider? annotationProvider = null)
12-
: base(CompletionAnnotations.Prefix, annotationProvider, SubsystemKind.Completion)
12+
: base(CompletionAnnotations.Prefix, SubsystemKind.Completion, annotationProvider)
1313
{ }
1414

1515
// TODO: Figure out trigger for completions

0 commit comments

Comments
 (0)