Skip to content

Commit 3b2c738

Browse files
Rename to WriteLineAsync/WriteErrorLineAsync, rename FakeConsole lists, use instance _console field in tests
Agent-Logs-Url: https://github.com/304NotModified/SLNX-validator/sessions/72e734b1-9ad7-4cb3-91ee-5cddb2c4570e Co-authored-by: 304NotModified <5808377+304NotModified@users.noreply.github.com>
1 parent 4da9119 commit 3b2c738

5 files changed

Lines changed: 36 additions & 38 deletions

File tree

src/SLNX-validator/IConsole.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ namespace JulianVerdurmen.SlnxValidator;
22

33
internal interface IConsole
44
{
5-
Task WriteAsync(string value);
6-
Task WriteErrorAsync(string value);
5+
Task WriteLineAsync(string value);
6+
Task WriteErrorLineAsync(string value);
77
}

src/SLNX-validator/SystemConsole.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ namespace JulianVerdurmen.SlnxValidator;
22

33
internal sealed class SystemConsole : IConsole
44
{
5-
public Task WriteAsync(string value) => Console.Out.WriteAsync(value);
6-
public Task WriteErrorAsync(string value) => Console.Error.WriteAsync(value);
5+
public Task WriteLineAsync(string value) => Console.Out.WriteLineAsync(value);
6+
public Task WriteErrorLineAsync(string value) => Console.Error.WriteLineAsync(value);
77
}

src/SLNX-validator/ValidatorRunner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public async Task<int> RunAsync(ValidatorRunnerOptions options, CancellationToke
2323

2424
if (results.Count == 0)
2525
{
26-
await console.WriteErrorAsync($"No .slnx files found for input: {options.Input}{Environment.NewLine}");
26+
await console.WriteErrorLineAsync($"No .slnx files found for input: {options.Input}");
2727
return options.ContinueOnError ? 0 : 1;
2828
}
2929

@@ -34,14 +34,14 @@ public async Task<int> RunAsync(ValidatorRunnerOptions options, CancellationToke
3434
{
3535
await sonarReporter.WriteReportAsync(reportResults, options.SonarqubeReportPath);
3636
var size = fileSystem.GetFileSize(options.SonarqubeReportPath);
37-
await console.WriteAsync($"SonarQube report written to: {options.SonarqubeReportPath} ({size} bytes){Environment.NewLine}");
37+
await console.WriteLineAsync($"SonarQube report written to: {options.SonarqubeReportPath} ({size} bytes)");
3838
}
3939

4040
if (options.SarifReportPath is not null)
4141
{
4242
await sarifReporter.WriteReportAsync(reportResults, options.SarifReportPath);
4343
var size = fileSystem.GetFileSize(options.SarifReportPath);
44-
await console.WriteAsync($"SARIF report written to: {options.SarifReportPath} ({size} bytes){Environment.NewLine}");
44+
await console.WriteLineAsync($"SARIF report written to: {options.SarifReportPath} ({size} bytes)");
4545
}
4646

4747
var hasErrors = results.Any(r => r.Errors.Any(e => options.SeverityOverrides.IsFailingError(e.Code)));

tests/SLNX-validator.Tests/FakeConsole.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ namespace JulianVerdurmen.SlnxValidator.Tests;
22

33
internal sealed class FakeConsole : IConsole
44
{
5-
public List<string> Output { get; } = [];
6-
public List<string> ErrorOutput { get; } = [];
5+
public List<string> OutputLines { get; } = [];
6+
public List<string> ErrorLines { get; } = [];
77

8-
public Task WriteAsync(string value) { Output.Add(value); return Task.CompletedTask; }
9-
public Task WriteErrorAsync(string value) { ErrorOutput.Add(value); return Task.CompletedTask; }
8+
public Task WriteLineAsync(string value) { OutputLines.Add(value); return Task.CompletedTask; }
9+
public Task WriteErrorLineAsync(string value) { ErrorLines.Add(value); return Task.CompletedTask; }
1010
}

tests/SLNX-validator.Tests/ValidatorRunnerTests.cs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,24 @@ namespace JulianVerdurmen.SlnxValidator.Tests;
99

1010
public class ValidatorRunnerTests
1111
{
12-
private static ValidatorRunner CreateRunner(IFileSystem fileSystem, IConsole console, IRequiredFilesChecker? checker = null)
12+
private readonly FakeConsole _console = new();
13+
14+
private ValidatorRunner CreateRunner(IFileSystem fileSystem, IRequiredFilesChecker? checker = null)
1315
{
1416
checker ??= Substitute.For<IRequiredFilesChecker>();
1517
var resolver = Substitute.For<ISlnxFileResolver>();
1618
var collector = new SlnxCollector(fileSystem, resolver, Substitute.For<ISlnxValidator>(), checker);
1719
var sonarReporter = new SonarReporter(fileSystem);
1820
var sarifReporter = new SarifReporter(fileSystem);
19-
return new ValidatorRunner(collector, sonarReporter, sarifReporter, checker, fileSystem, console);
21+
return new ValidatorRunner(collector, sonarReporter, sarifReporter, checker, fileSystem, _console);
2022
}
2123

2224
private static ValidatorRunnerOptions Options(string input = "test.slnx",
2325
bool continueOnError = false, string? requiredFilesPattern = null) =>
2426
new(input, SonarqubeReportPath: null, continueOnError, requiredFilesPattern, WorkingDirectory: ".");
2527

26-
private static ValidatorRunner CreateRunnerWithSlnx(
27-
string slnxPath, string slnxContent, IConsole console, IRequiredFilesChecker? checker = null)
28+
private ValidatorRunner CreateRunnerWithSlnx(
29+
string slnxPath, string slnxContent, IRequiredFilesChecker? checker = null)
2830
{
2931
checker ??= Substitute.For<IRequiredFilesChecker>();
3032
var fileSystem = new MockFileSystem(new Dictionary<string, string>
@@ -39,7 +41,7 @@ private static ValidatorRunner CreateRunnerWithSlnx(
3941
var collector = new SlnxCollector(fileSystem, resolver, validator, checker);
4042
var sonarReporter = new SonarReporter(fileSystem);
4143
var sarifReporter = new SarifReporter(fileSystem);
42-
return new ValidatorRunner(collector, sonarReporter, sarifReporter, checker, fileSystem, console);
44+
return new ValidatorRunner(collector, sonarReporter, sarifReporter, checker, fileSystem, _console);
4345
}
4446

4547
#region RunAsync – file resolution
@@ -48,7 +50,7 @@ private static ValidatorRunner CreateRunnerWithSlnx(
4850
public async Task RunAsync_FileNotFound_ContinueOnErrorFalse_ReturnsOne()
4951
{
5052
// Arrange
51-
var runner = CreateRunner(new MockFileSystem(), new FakeConsole());
53+
var runner = CreateRunner(new MockFileSystem());
5254

5355
// Act
5456
var exitCode = await runner.RunAsync(Options("nonexistent.slnx"), CancellationToken.None);
@@ -61,7 +63,7 @@ public async Task RunAsync_FileNotFound_ContinueOnErrorFalse_ReturnsOne()
6163
public async Task RunAsync_FileNotFound_ContinueOnErrorTrue_ReturnsZero()
6264
{
6365
// Arrange
64-
var runner = CreateRunner(new MockFileSystem(), new FakeConsole());
66+
var runner = CreateRunner(new MockFileSystem());
6567

6668
// Act
6769
var exitCode = await runner.RunAsync(Options("nonexistent.slnx", continueOnError: true), CancellationToken.None);
@@ -74,7 +76,7 @@ public async Task RunAsync_FileNotFound_ContinueOnErrorTrue_ReturnsZero()
7476
public async Task RunAsync_NoFilesFound_ContinueOnErrorFalse_ReturnsOne()
7577
{
7678
// Arrange
77-
var runner = CreateRunner(new MockFileSystem(), new FakeConsole());
79+
var runner = CreateRunner(new MockFileSystem());
7880

7981
// Act
8082
var exitCode = await runner.RunAsync(Options("src/*.slnx"), CancellationToken.None);
@@ -87,7 +89,7 @@ public async Task RunAsync_NoFilesFound_ContinueOnErrorFalse_ReturnsOne()
8789
public async Task RunAsync_NoFilesFound_ContinueOnErrorTrue_ReturnsZero()
8890
{
8991
// Arrange
90-
var runner = CreateRunner(new MockFileSystem(), new FakeConsole());
92+
var runner = CreateRunner(new MockFileSystem());
9193

9294
// Act
9395
var exitCode = await runner.RunAsync(Options("src/*.slnx", continueOnError: true), CancellationToken.None);
@@ -114,7 +116,7 @@ public async Task RunAsync_RequiredFiles_AllMatchedAndReferenced_ReturnsZero()
114116
checker.CheckInSlnx(Arg.Any<IReadOnlyList<string>>(), Arg.Any<SlnxFile>())
115117
.Returns([]);
116118

117-
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", new FakeConsole(), checker);
119+
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", checker);
118120

119121
// Act
120122
var exitCode = await runner.RunAsync(
@@ -134,7 +136,7 @@ public async Task RunAsync_RequiredFiles_NoMatchOnDisk_ReturnsOne()
134136
checker.ResolveMatchedPaths(Arg.Any<string>(), Arg.Any<string>())
135137
.Returns([]); // nothing matched on disk
136138

137-
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", new FakeConsole(), checker);
139+
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", checker);
138140

139141
// Act
140142
var exitCode = await runner.RunAsync(
@@ -155,7 +157,7 @@ public async Task RunAsync_RequiredFiles_NoMatchOnDisk_ReturnsOne()
155157
public async Task RunAsync_IgnoreAllCodes_WithErrors_ReturnsZero()
156158
{
157159
// Arrange: file with wrong extension generates SLNX002; --ignore * suppresses all codes
158-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
160+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
159161
var overrides = SeverityOverridesParser.Parse(null, null, null, null, null, ignore: "*");
160162

161163
// Act
@@ -171,7 +173,7 @@ public async Task RunAsync_IgnoreAllCodes_WithErrors_ReturnsZero()
171173
public async Task RunAsync_IgnoreSpecificCode_ThatCodeDoesNotCauseExitOne()
172174
{
173175
// Arrange: --ignore SLNX002 suppresses the InvalidExtension error
174-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
176+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
175177
var overrides = SeverityOverridesParser.Parse(null, null, null, null, null, ignore: "SLNX002");
176178

177179
// Act
@@ -187,7 +189,7 @@ public async Task RunAsync_IgnoreSpecificCode_ThatCodeDoesNotCauseExitOne()
187189
public async Task RunAsync_MinorOverrideForErrorCode_ReturnsZero()
188190
{
189191
// Arrange: --minor SLNX002 downgrades InvalidExtension to non-failing severity
190-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
192+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
191193
var overrides = SeverityOverridesParser.Parse(null, null, null, minor: "SLNX002", null, null);
192194

193195
// Act
@@ -203,7 +205,7 @@ public async Task RunAsync_MinorOverrideForErrorCode_ReturnsZero()
203205
public async Task RunAsync_InfoAllCodes_ReturnsZero()
204206
{
205207
// Arrange: --info * downgrades all codes to INFO (non-failing)
206-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
208+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
207209
var overrides = SeverityOverridesParser.Parse(null, null, null, null, info: "*", null);
208210

209211
// Act
@@ -219,7 +221,7 @@ public async Task RunAsync_InfoAllCodes_ReturnsZero()
219221
public async Task RunAsync_InfoAllCodesMajorSpecificCode_SpecificCodeCausesExitOne()
220222
{
221223
// Arrange: --info * --major SLNX002 → SLNX002 stays MAJOR (specific overrides wildcard)
222-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
224+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
223225
var overrides = SeverityOverridesParser.Parse(null, null, major: "SLNX002", null, info: "*", null);
224226

225227
// Act
@@ -235,7 +237,7 @@ public async Task RunAsync_InfoAllCodesMajorSpecificCode_SpecificCodeCausesExitO
235237
public async Task RunAsync_IgnoreAllCodesMajorSpecificCode_SpecificCodeCausesExitOne()
236238
{
237239
// Arrange: --ignore * --major SLNX002 → SLNX002 is MAJOR (specific wins over wildcard ignore)
238-
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />", new FakeConsole());
240+
var runner = CreateRunnerWithSlnx("test.xml", "<Solution />");
239241
var overrides = SeverityOverridesParser.Parse(null, null, major: "SLNX002", null, null, ignore: "*");
240242

241243
// Act
@@ -255,40 +257,37 @@ public async Task RunAsync_IgnoreAllCodesMajorSpecificCode_SpecificCodeCausesExi
255257
public async Task RunAsync_NoFilesFound_WritesErrorToConsole()
256258
{
257259
// Arrange
258-
var console = new FakeConsole();
259-
var runner = CreateRunner(new MockFileSystem(), console);
260+
var runner = CreateRunner(new MockFileSystem());
260261

261262
// Act
262263
await runner.RunAsync(Options("nonexistent.slnx"), CancellationToken.None);
263264

264265
// Assert
265-
console.ErrorOutput.Should().ContainMatch("*No .slnx files found for input: nonexistent.slnx*");
266+
_console.ErrorLines.Should().ContainMatch("*No .slnx files found for input: nonexistent.slnx*");
266267
}
267268

268269
[Test]
269270
public async Task RunAsync_SonarqubeReportPath_WritesConfirmationToConsole()
270271
{
271272
// Arrange
272273
var slnxPath = Path.GetFullPath("test.slnx");
273-
var console = new FakeConsole();
274-
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", console);
274+
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />");
275275
var options = new ValidatorRunnerOptions(slnxPath, SonarqubeReportPath: "report.xml",
276276
ContinueOnError: false, RequiredFilesPattern: null, WorkingDirectory: ".");
277277

278278
// Act
279279
await runner.RunAsync(options, CancellationToken.None);
280280

281281
// Assert
282-
console.Output.Should().ContainMatch("*SonarQube report written to: report.xml*");
282+
_console.OutputLines.Should().ContainMatch("*SonarQube report written to: report.xml*");
283283
}
284284

285285
[Test]
286286
public async Task RunAsync_SarifReportPath_WritesConfirmationToConsole()
287287
{
288288
// Arrange
289289
var slnxPath = Path.GetFullPath("test.slnx");
290-
var console = new FakeConsole();
291-
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />", console);
290+
var runner = CreateRunnerWithSlnx(slnxPath, "<Solution />");
292291
var options = new ValidatorRunnerOptions(slnxPath, SonarqubeReportPath: null,
293292
ContinueOnError: false, RequiredFilesPattern: null, WorkingDirectory: ".",
294293
SarifReportPath: "report.sarif");
@@ -297,9 +296,8 @@ public async Task RunAsync_SarifReportPath_WritesConfirmationToConsole()
297296
await runner.RunAsync(options, CancellationToken.None);
298297

299298
// Assert
300-
console.Output.Should().ContainMatch("*SARIF report written to: report.sarif*");
299+
_console.OutputLines.Should().ContainMatch("*SARIF report written to: report.sarif*");
301300
}
302301

303302
#endregion
304303
}
305-

0 commit comments

Comments
 (0)