Skip to content

Commit 0b347be

Browse files
Add unit tests for PublishedBinaryCli command functionality
- Introduced a new test class `PublishedBinaryCliTests` to validate the command-line interface of the Cognitive Code Analysis Console App. - Implemented tests for help output, configuration file generation with and without specified paths, and default configuration source reporting during analysis. - Ensured proper setup and teardown of temporary directories for test isolation and resource management. - Aimed to enhance test coverage and reliability of the command-line features in the application.
1 parent 49f3e7d commit 0b347be

1 file changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/// <copyright company="Florian Krämer">
2+
/// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
/// </copyright>
4+
5+
using System.Diagnostics;
6+
using System.Runtime.InteropServices;
7+
using CognitiveCodeAnalysis.Configuration;
8+
9+
namespace CognitiveCodeAnalysisConsoleApp.Tests.Commands;
10+
11+
[TestFixture]
12+
public class PublishedBinaryCliTests
13+
{
14+
private static string _publishDirectory = null!;
15+
private static string _executablePath = null!;
16+
private string _workingDirectory = null!;
17+
18+
[OneTimeSetUp]
19+
public void OneTimeSetUp()
20+
{
21+
_publishDirectory = Path.Combine(Path.GetTempPath(), $"cca-published-{Guid.NewGuid():N}");
22+
PublishConsoleApp(_publishDirectory);
23+
24+
string executableName = OperatingSystem.IsWindows()
25+
? "CognitiveCodeAnalysisConsoleApp.exe"
26+
: "CognitiveCodeAnalysisConsoleApp";
27+
_executablePath = Path.Combine(_publishDirectory, executableName);
28+
29+
Assert.That(File.Exists(_executablePath), Is.True, $"Expected published executable at {_executablePath}");
30+
}
31+
32+
[OneTimeTearDown]
33+
public void OneTimeTearDown()
34+
{
35+
if (Directory.Exists(_publishDirectory))
36+
{
37+
Directory.Delete(_publishDirectory, recursive: true);
38+
}
39+
}
40+
41+
[SetUp]
42+
public void SetUp()
43+
{
44+
_workingDirectory = Path.Combine(Path.GetTempPath(), $"cca-binary-run-{Guid.NewGuid():N}");
45+
Directory.CreateDirectory(_workingDirectory);
46+
}
47+
48+
[TearDown]
49+
public void TearDown()
50+
{
51+
if (Directory.Exists(_workingDirectory))
52+
{
53+
Directory.Delete(_workingDirectory, recursive: true);
54+
}
55+
}
56+
57+
[Test]
58+
public void Help_IncludesGenerateConfigOption()
59+
{
60+
(int exitCode, string output) = RunExecutable(_workingDirectory, "--help");
61+
62+
Assert.That(exitCode, Is.EqualTo(0));
63+
Assert.That(output, Does.Contain("--generate-config"));
64+
Assert.That(output, Does.Contain("[PATH]"));
65+
Assert.That(output, Does.Not.Contain("Could not find color or style"));
66+
}
67+
68+
[Test]
69+
public void GenerateConfig_WithoutPath_WritesFileToWorkingDirectory()
70+
{
71+
(int exitCode, _) = RunExecutable(_workingDirectory, "--generate-config");
72+
73+
string expectedPath = Path.Combine(_workingDirectory, ConfigurationResolver.DefaultFileName);
74+
75+
Assert.That(exitCode, Is.EqualTo(0));
76+
Assert.That(File.Exists(expectedPath), Is.True);
77+
}
78+
79+
[Test]
80+
public void GenerateConfig_WithPath_WritesFileToTargetDirectory()
81+
{
82+
var targetDirectory = Path.Combine(_workingDirectory, "config-output");
83+
84+
(int exitCode, _) = RunExecutable(_workingDirectory, "--generate-config", targetDirectory);
85+
86+
string expectedPath = Path.Combine(targetDirectory, ConfigurationResolver.DefaultFileName);
87+
88+
Assert.That(exitCode, Is.EqualTo(0));
89+
Assert.That(File.Exists(expectedPath), Is.True);
90+
}
91+
92+
[Test]
93+
public void Analyze_WithoutConfig_PrintsDefaultConfigSource()
94+
{
95+
File.WriteAllText(
96+
Path.Combine(_workingDirectory, "Sample.cs"),
97+
"""
98+
namespace Samples;
99+
100+
public class Sample
101+
{
102+
public void M() { }
103+
}
104+
"""
105+
);
106+
107+
(int exitCode, string output) = RunExecutable(_workingDirectory, _workingDirectory, "-f", "ConsoleText");
108+
109+
Assert.That(exitCode, Is.EqualTo(0));
110+
Assert.That(output, Does.Contain("Config: Default"));
111+
}
112+
113+
private (int ExitCode, string Output) RunExecutable(string workingDirectory, params string[] args)
114+
{
115+
var process = new Process
116+
{
117+
StartInfo = new ProcessStartInfo
118+
{
119+
FileName = _executablePath,
120+
WorkingDirectory = workingDirectory,
121+
RedirectStandardOutput = true,
122+
RedirectStandardError = true,
123+
UseShellExecute = false,
124+
},
125+
};
126+
127+
foreach (string arg in args)
128+
{
129+
process.StartInfo.ArgumentList.Add(arg);
130+
}
131+
132+
process.Start();
133+
string stdout = process.StandardOutput.ReadToEnd();
134+
string stderr = process.StandardError.ReadToEnd();
135+
process.WaitForExit(TimeSpan.FromMinutes(2));
136+
137+
return (process.ExitCode, stdout + stderr);
138+
}
139+
140+
private static void PublishConsoleApp(string outputDirectory)
141+
{
142+
string solutionRoot = FindSolutionRoot();
143+
string consoleProject = Path.Combine(
144+
solutionRoot,
145+
"CognitiveCodeAnalysisConsoleApp",
146+
"CognitiveCodeAnalysisConsoleApp.csproj"
147+
);
148+
149+
var process = new Process
150+
{
151+
StartInfo = new ProcessStartInfo
152+
{
153+
FileName = "dotnet",
154+
WorkingDirectory = solutionRoot,
155+
RedirectStandardOutput = true,
156+
RedirectStandardError = true,
157+
UseShellExecute = false,
158+
},
159+
};
160+
161+
process.StartInfo.ArgumentList.Add("publish");
162+
process.StartInfo.ArgumentList.Add(consoleProject);
163+
process.StartInfo.ArgumentList.Add("-c");
164+
process.StartInfo.ArgumentList.Add("Release");
165+
process.StartInfo.ArgumentList.Add("-r");
166+
process.StartInfo.ArgumentList.Add(RuntimeInformation.RuntimeIdentifier);
167+
process.StartInfo.ArgumentList.Add("--self-contained");
168+
process.StartInfo.ArgumentList.Add("true");
169+
process.StartInfo.ArgumentList.Add("-o");
170+
process.StartInfo.ArgumentList.Add(outputDirectory);
171+
172+
process.Start();
173+
string stdout = process.StandardOutput.ReadToEnd();
174+
string stderr = process.StandardError.ReadToEnd();
175+
process.WaitForExit(TimeSpan.FromMinutes(5));
176+
177+
Assert.That(
178+
process.ExitCode,
179+
Is.EqualTo(0),
180+
$"dotnet publish failed.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}"
181+
);
182+
}
183+
184+
private static string FindSolutionRoot()
185+
{
186+
var directory = new DirectoryInfo(AppContext.BaseDirectory);
187+
188+
while (directory is not null)
189+
{
190+
if (File.Exists(Path.Combine(directory.FullName, "CognitiveCodeAnalysis.sln")))
191+
{
192+
return directory.FullName;
193+
}
194+
195+
directory = directory.Parent;
196+
}
197+
198+
throw new InvalidOperationException("Could not locate CognitiveCodeAnalysis.sln from test output directory.");
199+
}
200+
}

0 commit comments

Comments
 (0)