Skip to content

Commit 6026408

Browse files
KathleenDollardmhutch
authored andcommitted
Add Pipeline tests
1 parent 44c0504 commit 6026408

File tree

6 files changed

+251
-15
lines changed

6 files changed

+251
-15
lines changed

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace System.CommandLine.Subsystems.Tests
77
{
88
internal class AlternateSubsystems
99
{
10-
internal class Version : VersionSubsystem
10+
internal class AlternateVersion : VersionSubsystem
1111
{
1212
protected override CliExit Execute(PipelineContext pipelineContext)
1313
{
@@ -39,5 +39,31 @@ protected override CliExit Execute(PipelineContext pipelineContext)
3939
}
4040
}
4141

42+
internal class VersionWithInitializeAndTeardown : VersionSubsystem
43+
{
44+
internal bool InitializationWasRun;
45+
internal bool ExecutionWasRun;
46+
internal bool TeardownWasRun;
47+
48+
protected override CliConfiguration Initialize(CliConfiguration configuration)
49+
{
50+
// marker hack needed because ConsoleHack not available in initialization
51+
InitializationWasRun = true;
52+
return base.Initialize(configuration);
53+
}
54+
55+
protected override CliExit Execute(PipelineContext pipelineContext)
56+
{
57+
ExecutionWasRun = true;
58+
return base.Execute(pipelineContext);
59+
}
60+
61+
protected override CliExit TearDown(CliExit cliExit)
62+
{
63+
TeardownWasRun = true;
64+
return base.TearDown(cliExit);
65+
}
66+
}
67+
4268
}
4369
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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.Reflection;
5+
6+
namespace System.CommandLine.Subsystems.Tests
7+
{
8+
internal class Constants
9+
{
10+
11+
internal static readonly string? version = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly())
12+
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
13+
?.InformationalVersion;
14+
15+
internal static readonly string newLine = Environment.NewLine;
16+
17+
18+
}
19+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
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 FluentAssertions;
5+
using System.CommandLine.Parsing;
6+
using System.Reflection;
7+
using Xunit;
8+
9+
namespace System.CommandLine.Subsystems.Tests
10+
{
11+
public class PipelineTests
12+
{
13+
14+
private static readonly string? version = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly())
15+
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
16+
?.InformationalVersion;
17+
18+
19+
[Theory]
20+
[InlineData("-v", true)]
21+
[InlineData("--version", true)]
22+
[InlineData("-x", false)]
23+
[InlineData("", false)]
24+
[InlineData(null, false)]
25+
public void Subsystem_runs_in_pipeline_only_when_requested(string input, bool shouldRun)
26+
{
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);
33+
34+
var exit = pipeline.Execute(configuration, input, consoleHack);
35+
36+
exit.ExitCode.Should().Be(0);
37+
exit.Handled.Should().Be(shouldRun);
38+
if (shouldRun)
39+
{
40+
consoleHack.GetBuffer().Trim().Should().Be(version);
41+
}
42+
}
43+
44+
[Theory]
45+
[InlineData("-v", true)]
46+
[InlineData("--version", true)]
47+
[InlineData("-x", false)]
48+
[InlineData("", false)]
49+
[InlineData(null, false)]
50+
public void Subsystem_runs_with_explicit_parse_only_when_requested(string input, bool shouldRun)
51+
{
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);
58+
59+
var result = pipeline.Parse(configuration, input);
60+
var exit = pipeline.Execute(result, input, consoleHack);
61+
62+
exit.ExitCode.Should().Be(0);
63+
exit.Handled.Should().Be(shouldRun);
64+
if (shouldRun)
65+
{
66+
consoleHack.GetBuffer().Trim().Should().Be(version);
67+
}
68+
}
69+
70+
[Theory]
71+
[InlineData("-v", true)]
72+
[InlineData("--version", true)]
73+
[InlineData("-x", false)]
74+
[InlineData("", false)]
75+
[InlineData(null, false)]
76+
public void Subsystem_runs_initialize_and_teardown_when_requested(string input, bool shouldRun)
77+
{
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);
85+
86+
var exit = pipeline.Execute(configuration, input, consoleHack);
87+
88+
exit.ExitCode.Should().Be(0);
89+
exit.Handled.Should().Be(shouldRun);
90+
versionSubsystem.InitializationWasRun.Should().BeTrue();
91+
versionSubsystem.ExecutionWasRun.Should().Be(shouldRun);
92+
versionSubsystem.TeardownWasRun.Should().BeTrue();
93+
}
94+
95+
96+
[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)
103+
{
104+
var configuration = new CliConfiguration(new CliRootCommand { });
105+
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);
111+
bool value = parseResult.GetValue<bool>("--version");
112+
113+
value.Should().Be(shouldRun);
114+
if (shouldRun)
115+
{
116+
// TODO: Add an execute overload to avoid checking activated twice
117+
var exit = Subsystem.Execute(versionSubsystem, parseResult, input, consoleHack);
118+
exit.Should().NotBeNull();
119+
exit.ExitCode.Should().Be(0);
120+
exit.Handled.Should().BeTrue();
121+
consoleHack.GetBuffer().Trim().Should().Be(version);
122+
}
123+
}
124+
125+
[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)
132+
{
133+
var configuration = new CliConfiguration(new CliRootCommand { });
134+
var versionSubsystem = new VersionSubsystem();
135+
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
136+
var expectedVersion = shouldRun
137+
? version
138+
: "";
139+
140+
Subsystem.Initialize(versionSubsystem, configuration);
141+
var parseResult = CliParser.Parse(configuration.RootCommand, input, configuration);
142+
var exit = Subsystem.ExecuteIfNeeded(versionSubsystem, parseResult, input, consoleHack);
143+
144+
exit.ExitCode.Should().Be(0);
145+
exit.Handled.Should().Be(shouldRun);
146+
consoleHack.GetBuffer().Trim().Should().Be(expectedVersion);
147+
}
148+
149+
[Fact]
150+
public void Standard_pipeline_contains_expected_subsystems()
151+
{
152+
var pipeline = new StandardPipeline();
153+
pipeline.Version.Should().BeOfType<VersionSubsystem>();
154+
pipeline.Help.Should().BeOfType<HelpSubsystem>();
155+
pipeline.ErrorReporting.Should().BeOfType<ErrorReportingSubsystem>();
156+
pipeline.Completion.Should().BeOfType<CompletionSubsystem>();
157+
}
158+
159+
[Fact]
160+
public void Normal_pipeline_contains_no_subsystems()
161+
{
162+
var pipeline = new Pipeline();
163+
pipeline.Version.Should().BeNull();
164+
pipeline.Help.Should().BeNull();
165+
pipeline.ErrorReporting.Should().BeNull();
166+
pipeline.Completion.Should().BeNull();
167+
}
168+
169+
170+
[Fact]
171+
public void Subsystems_can_access_each_others_data()
172+
{
173+
// 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);
175+
var symbol = new CliOption<bool>("-x");
176+
177+
var pipeline = new StandardPipeline
178+
{
179+
Version = new AlternateSubsystems.VersionThatUsesHelpData(symbol)
180+
};
181+
if (pipeline.Help is null) throw new InvalidOperationException();
182+
var rootCommand = new CliRootCommand
183+
{
184+
symbol.With(pipeline.Help.Description, "Testing")
185+
};
186+
pipeline.Execute(new CliConfiguration(rootCommand), "-v", consoleHack);
187+
consoleHack.GetBuffer().Trim().Should().Be($"Testing");
188+
}
189+
190+
}
191+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
<Compile Include="..\System.CommandLine.Suggest\DotnetMuxer.cs" Link="Utility\DotnetMuxer.cs" />
2626
<Compile Include="..\System.CommandLine\Properties\Resources.Designer.cs" Link="Properties\Resources.Designer.cs" />
2727
<Compile Include="AlternateSubsystems.cs" />
28+
<Compile Include="Constants.cs" />
29+
<Compile Include="PipelineTests.cs" />
2830
<Compile Include="VersionFunctionalTests.cs" />
2931
<Compile Include="VersionSubsystemTests.cs" />
3032
</ItemGroup>

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

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,9 @@
88

99
namespace System.CommandLine.Subsystems.Tests
1010
{
11+
1112
public class VersionSubsystemTests
1213
{
13-
private static readonly string? version = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly())
14-
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
15-
?.InformationalVersion;
16-
17-
private readonly string newLine = Environment.NewLine;
18-
19-
2014
[Fact]
2115
public void When_version_subsystem_is_used_the_version_option_is_added_to_the_root()
2216
{
@@ -65,7 +59,7 @@ public void Outputs_assembly_version()
6559
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
6660
var versionSubsystem = new VersionSubsystem();
6761
Subsystem.Execute(versionSubsystem, new PipelineContext(null, "", null, consoleHack));
68-
consoleHack.GetBuffer().Trim().Should().Be(version);
62+
consoleHack.GetBuffer().Trim().Should().Be(Constants.version);
6963
}
7064

7165
[Fact]
@@ -89,7 +83,7 @@ public void Outputs_assembly_version_when_specified_version_set_to_null()
8983
SpecificVersion = null
9084
};
9185
Subsystem.Execute(versionSubsystem, new PipelineContext(null, "", null, consoleHack));
92-
consoleHack.GetBuffer().Trim().Should().Be(version);
86+
consoleHack.GetBuffer().Trim().Should().Be(Constants.version);
9387
}
9488

9589
[Fact]
@@ -101,7 +95,7 @@ public void Console_output_can_be_tested()
10195
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
10296
var versionSubsystem = new VersionSubsystem();
10397
Subsystem.Execute(versionSubsystem, new PipelineContext(null, "", null, consoleHack));
104-
consoleHack.GetBuffer().Trim().Should().Be(version);
98+
consoleHack.GetBuffer().Trim().Should().Be(Constants.version);
10599
}
106100

107101
[Fact]
@@ -110,10 +104,10 @@ public void Custom_version_subsystem_can_be_used()
110104
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
111105
var pipeline = new Pipeline
112106
{
113-
Version = new AlternateSubsystems.Version()
107+
Version = new AlternateSubsystems.AlternateVersion()
114108
};
115109
pipeline.Execute(new CliConfiguration(new CliRootCommand()), "-v", consoleHack);
116-
consoleHack.GetBuffer().Trim().Should().Be($"***{version}***");
110+
consoleHack.GetBuffer().Trim().Should().Be($"***{Constants.version}***");
117111
}
118112

119113
[Fact]
@@ -122,10 +116,10 @@ public void Custom_version_subsystem_can_replace_standard()
122116
var consoleHack = new ConsoleHack().RedirectToBuffer(true);
123117
var pipeline = new StandardPipeline
124118
{
125-
Version = new AlternateSubsystems.Version()
119+
Version = new AlternateSubsystems.AlternateVersion()
126120
};
127121
pipeline.Execute(new CliConfiguration(new CliRootCommand()), "-v", consoleHack);
128-
consoleHack.GetBuffer().Trim().Should().Be($"***{version}***");
122+
consoleHack.GetBuffer().Trim().Should().Be($"***{Constants.version}***");
129123
}
130124
}
131125
}

src/System.CommandLine.Subsystems/Subsystems/Subsystem.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public static bool GetIsActivated(CliSubsystem subsystem, ParseResult parseResul
1717
public static CliExit ExecuteIfNeeded(CliSubsystem subsystem, ParseResult parseResult, string rawInput, ConsoleHack? consoleHack = null)
1818
=> new(subsystem.ExecuteIfNeeded(new PipelineContext(parseResult, rawInput, null,consoleHack)));
1919

20+
public static CliExit Execute(CliSubsystem subsystem, ParseResult parseResult, string rawInput, ConsoleHack? consoleHack = null)
21+
=> subsystem.Execute(new PipelineContext(parseResult, rawInput, null, consoleHack));
22+
23+
2024
internal static PipelineContext ExecuteIfNeeded(CliSubsystem subsystem, ParseResult parseResult, string rawInput, ConsoleHack? consoleHack, PipelineContext? pipelineContext = null)
2125
=> subsystem.ExecuteIfNeeded(pipelineContext ?? new PipelineContext(parseResult, rawInput, null,consoleHack));
2226

0 commit comments

Comments
 (0)