From 083d70a9035e34a1681a206576bf7f14b01d5de9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 13 Feb 2026 11:55:25 +0000
Subject: [PATCH 1/4] Initial plan
From 196130cc5d9d597cb4c09a93ea04fdb4ea4377a9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 13 Feb 2026 12:03:44 +0000
Subject: [PATCH 2/4] Fix Sonar code smell issues - part 1
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
src/DemaConsulting.ReqStream/TraceMatrix.cs | 2 +-
.../ContextTests.cs | 183 ++++--------------
.../RequirementsExportTests.cs | 22 +--
.../RequirementsReadTests.cs | 156 ++++-----------
.../TraceMatrixExportTests.cs | 22 +--
.../TraceMatrixReadTests.cs | 22 +--
6 files changed, 86 insertions(+), 321 deletions(-)
diff --git a/src/DemaConsulting.ReqStream/TraceMatrix.cs b/src/DemaConsulting.ReqStream/TraceMatrix.cs
index 0d5efb3..362f860 100644
--- a/src/DemaConsulting.ReqStream/TraceMatrix.cs
+++ b/src/DemaConsulting.ReqStream/TraceMatrix.cs
@@ -475,7 +475,7 @@ private void ExportRequirementSection(TextWriter writer, Section section, int de
/// The section to check.
/// The set of filter tags.
/// True if the section has filtered content, false otherwise.
- private bool SectionHasFilteredContent(Section section, HashSet? filterTags)
+ private static bool SectionHasFilteredContent(Section section, HashSet? filterTags)
{
// Check if section has any matching requirements
if (filterTags == null || filterTags.Count == 0)
diff --git a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
index 36dfd24..63ac9db 100644
--- a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
@@ -148,15 +148,8 @@ public void Context_Create_ResultsFlag_SetsResultsFileProperty()
[TestMethod]
public void Context_Create_MissingResultsFilename_ThrowsException()
{
- try
- {
- Context.Create(["--results"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--results requires a filename argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--results"]));
+ Assert.Contains("--results requires a filename argument", ex.Message);
}
///
@@ -225,15 +218,8 @@ public void Context_Create_MatrixFile_SetsMatrixProperty()
[TestMethod]
public void Context_Create_UnsupportedArgument_ThrowsException()
{
- try
- {
- Context.Create(["--unsupported"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("Unsupported argument '--unsupported'", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--unsupported"]));
+ Assert.Contains("Unsupported argument '--unsupported'", ex.Message);
}
///
@@ -242,15 +228,8 @@ public void Context_Create_UnsupportedArgument_ThrowsException()
[TestMethod]
public void Context_Create_MissingLogFilename_ThrowsException()
{
- try
- {
- Context.Create(["--log"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--log requires a filename argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--log"]));
+ Assert.Contains("--log requires a filename argument", ex.Message);
}
///
@@ -259,14 +238,8 @@ public void Context_Create_MissingLogFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingReportFilename_ThrowsException()
{
- try
- {
- Context.Create(["--report"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--report requires a filename argument", ex.Message);
+ var ex = Assert.ThrowsException(() => Context.Create(["--report"]));
+ Assert.Contains("--report requires a filename argument", ex.Message);
}
}
@@ -276,15 +249,8 @@ public void Context_Create_MissingReportFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingMatrixFilename_ThrowsException()
{
- try
- {
- Context.Create(["--matrix"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--matrix requires a filename argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--matrix"]));
+ Assert.Contains("--matrix requires a filename argument", ex.Message);
}
///
@@ -293,15 +259,8 @@ public void Context_Create_MissingMatrixFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingReportDepth_ThrowsException()
{
- try
- {
- Context.Create(["--report-depth"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--report-depth requires a depth argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--report-depth"]));
+ Assert.Contains("--report-depth requires a depth argument", ex.Message);
}
///
@@ -310,15 +269,8 @@ public void Context_Create_MissingReportDepth_ThrowsException()
[TestMethod]
public void Context_Create_MissingMatrixDepth_ThrowsException()
{
- try
- {
- Context.Create(["--matrix-depth"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--matrix-depth requires a depth argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--matrix-depth"]));
+ Assert.Contains("--matrix-depth requires a depth argument", ex.Message);
}
///
@@ -327,35 +279,14 @@ public void Context_Create_MissingMatrixDepth_ThrowsException()
[TestMethod]
public void Context_Create_InvalidReportDepth_ThrowsException()
{
- try
- {
- Context.Create(["--report-depth", "invalid"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--report-depth requires a positive integer", ex.Message);
- }
+ var ex1 = Assert.ThrowsException(() => Context.Create(["--report-depth", "invalid"]));
+ Assert.Contains("--report-depth requires a positive integer", ex1.Message);
- try
- {
- Context.Create(["--report-depth", "0"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--report-depth requires a positive integer", ex.Message);
- }
+ var ex2 = Assert.ThrowsException(() => Context.Create(["--report-depth", "0"]));
+ Assert.Contains("--report-depth requires a positive integer", ex2.Message);
- try
- {
- Context.Create(["--report-depth", "-1"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--report-depth requires a positive integer", ex.Message);
- }
+ var ex3 = Assert.ThrowsException(() => Context.Create(["--report-depth", "-1"]));
+ Assert.Contains("--report-depth requires a positive integer", ex3.Message);
}
///
@@ -364,25 +295,11 @@ public void Context_Create_InvalidReportDepth_ThrowsException()
[TestMethod]
public void Context_Create_InvalidMatrixDepth_ThrowsException()
{
- try
- {
- Context.Create(["--matrix-depth", "invalid"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--matrix-depth requires a positive integer", ex.Message);
- }
+ var ex1 = Assert.ThrowsException(() => Context.Create(["--matrix-depth", "invalid"]));
+ Assert.Contains("--matrix-depth requires a positive integer", ex1.Message);
- try
- {
- Context.Create(["--matrix-depth", "0"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--matrix-depth requires a positive integer", ex.Message);
- }
+ var ex2 = Assert.ThrowsException(() => Context.Create(["--matrix-depth", "0"]));
+ Assert.Contains("--matrix-depth requires a positive integer", ex2.Message);
}
///
@@ -553,8 +470,8 @@ public void Context_Create_WithRequirementsPattern_ExpandsGlobPattern()
using var context = Context.Create(["--requirements", "*.yaml"]);
Assert.HasCount(2, context.RequirementsFiles);
- Assert.IsTrue(context.RequirementsFiles.Any(f => f.EndsWith("req1.yaml")));
- Assert.IsTrue(context.RequirementsFiles.Any(f => f.EndsWith("req2.yaml")));
+ Assert.Contains(context.RequirementsFiles.Single(f => f.EndsWith("req1.yaml")), context.RequirementsFiles);
+ Assert.Contains(context.RequirementsFiles.Single(f => f.EndsWith("req2.yaml")), context.RequirementsFiles);
Assert.AreEqual(0, context.ExitCode);
}
finally
@@ -584,8 +501,8 @@ public void Context_Create_WithTestsPattern_ExpandsGlobPattern()
using var context = Context.Create(["--tests", "*.trx"]);
Assert.HasCount(2, context.TestFiles);
- Assert.IsTrue(context.TestFiles.Any(f => f.EndsWith("test1.trx")));
- Assert.IsTrue(context.TestFiles.Any(f => f.EndsWith("test2.trx")));
+ Assert.Contains(context.TestFiles.Single(f => f.EndsWith("test1.trx")), context.TestFiles);
+ Assert.Contains(context.TestFiles.Single(f => f.EndsWith("test2.trx")), context.TestFiles);
Assert.AreEqual(0, context.ExitCode);
}
finally
@@ -600,15 +517,8 @@ public void Context_Create_WithTestsPattern_ExpandsGlobPattern()
[TestMethod]
public void Context_Create_MissingRequirementsPattern_ThrowsException()
{
- try
- {
- Context.Create(["--requirements"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--requirements requires a pattern argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--requirements"]));
+ Assert.Contains("--requirements requires a pattern argument", ex.Message);
}
///
@@ -617,15 +527,8 @@ public void Context_Create_MissingRequirementsPattern_ThrowsException()
[TestMethod]
public void Context_Create_MissingTestsPattern_ThrowsException()
{
- try
- {
- Context.Create(["--tests"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--tests requires a pattern argument", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--tests"]));
+ Assert.Contains("--tests requires a pattern argument", ex.Message);
}
///
@@ -672,15 +575,8 @@ public void Context_Create_InvalidLogPath_ThrowsException()
{
var invalidPath = Path.Combine(_testDirectory, "nonexistent", "test.log");
- try
- {
- Context.Create(["--log", invalidPath]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("Failed to open log file", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--log", invalidPath]));
+ Assert.Contains("Failed to open log file", ex.Message);
}
///
@@ -720,15 +616,8 @@ public void Context_Create_FilterArgumentWithSpaces_TrimsAndParsesTagsCorrectly(
[TestMethod]
public void Context_Create_FilterArgumentMissingValue_ThrowsArgumentException()
{
- try
- {
- Context.Create(["--filter"]);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("--filter requires a comma-separated list of tags", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Context.Create(["--filter"]));
+ Assert.Contains("--filter requires a comma-separated list of tags", ex.Message);
}
///
diff --git a/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs b/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
index 150af66..14effa7 100644
--- a/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
@@ -183,15 +183,8 @@ public void Requirements_Export_NullFilePath_ThrowsArgumentException()
File.WriteAllText(reqPath, yamlContent);
var requirements = Requirements.Read(reqPath);
- try
- {
- requirements.Export(null!);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("File path cannot be null or empty", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => requirements.Export(null!));
+ Assert.Contains("File path cannot be null or empty", ex.Message);
}
///
@@ -211,15 +204,8 @@ public void Requirements_Export_EmptyFilePath_ThrowsArgumentException()
File.WriteAllText(reqPath, yamlContent);
var requirements = Requirements.Read(reqPath);
- try
- {
- requirements.Export(string.Empty);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("File path cannot be null or empty", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => requirements.Export(string.Empty));
+ Assert.Contains("File path cannot be null or empty", ex.Message);
}
///
diff --git a/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs b/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
index 3fb4ae6..e248bd0 100644
--- a/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
@@ -326,16 +326,9 @@ public void Requirements_Read_DuplicateRequirementId_ThrowsException()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains("Duplicate requirement ID", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("SYS-SEC-001", ex.Message);
+ Assert.Contains("Duplicate requirement ID", ex.Message);
}
///
@@ -383,15 +376,8 @@ public void Requirements_Read_FileNotFound_ThrowsException()
{
var nonExistentPath = Path.Combine(_testDirectory, "nonexistent.yaml");
- try
- {
- Requirements.Read(nonExistentPath);
- Assert.Fail("Expected FileNotFoundException was not thrown");
- }
- catch (FileNotFoundException ex)
- {
- Assert.Contains("Requirements file not found", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(nonExistentPath));
+ Assert.Contains("Requirements file not found", ex.Message);
}
///
@@ -496,17 +482,10 @@ public void Requirements_Read_BlankRequirementId_ThrowsExceptionWithFileLocation
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Requirement ID cannot be blank", ex.Message);
- Assert.Contains("System Security", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Requirement ID cannot be blank", ex.Message);
+ Assert.Contains("System Security", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -525,17 +504,10 @@ public void Requirements_Read_BlankRequirementTitle_ThrowsExceptionWithFileLocat
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Requirement title cannot be blank", ex.Message);
- Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Requirement title cannot be blank", ex.Message);
+ Assert.Contains("SYS-SEC-001", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -554,16 +526,9 @@ public void Requirements_Read_BlankSectionTitle_ThrowsExceptionWithFileLocation(
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Section title cannot be blank", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Section title cannot be blank", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -586,15 +551,9 @@ public void Requirements_Read_BlankTestNameInRequirement_ThrowsExceptionWithFile
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Test name cannot be blank", ex.Message);
- Assert.Contains("SYS-SEC-001", ex.Message);
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Test name cannot be blank", ex.Message);
+ Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains(filePath, ex.Message);
}
}
@@ -621,17 +580,10 @@ public void Requirements_Read_BlankTestNameInMapping_ThrowsExceptionWithFileLoca
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Test name cannot be blank", ex.Message);
- Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Test name cannot be blank", ex.Message);
+ Assert.Contains("SYS-SEC-001", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -655,16 +607,9 @@ public void Requirements_Read_BlankMappingId_ThrowsExceptionWithFileLocation()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Mapping requirement ID cannot be blank", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Mapping requirement ID cannot be blank", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -685,15 +630,9 @@ public void Requirements_Read_DuplicateRequirementId_ExceptionIncludesFileLocati
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains("Duplicate requirement ID", ex.Message);
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("SYS-SEC-001", ex.Message);
+ Assert.Contains("Duplicate requirement ID", ex.Message);
Assert.Contains(filePath, ex.Message);
}
}
@@ -810,15 +749,8 @@ public void Requirements_Read_SingleFileWithParamsArray_WorksCorrectly()
[TestMethod]
public void Requirements_Read_NoArguments_ThrowsArgumentException()
{
- try
- {
- Requirements.Read();
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("At least one file path must be provided", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read());
+ Assert.Contains("At least one file path must be provided", ex.Message);
}
///
@@ -827,15 +759,8 @@ public void Requirements_Read_NoArguments_ThrowsArgumentException()
[TestMethod]
public void Requirements_Read_NullArgument_ThrowsArgumentException()
{
- try
- {
- Requirements.Read(null!);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("At least one file path must be provided", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(null!));
+ Assert.Contains("At least one file path must be provided", ex.Message);
}
///
@@ -925,16 +850,9 @@ public void Requirements_Read_BlankTagName_ThrowsExceptionWithFileLocation()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- try
- {
- Requirements.Read(filePath);
- Assert.Fail("Expected InvalidOperationException was not thrown");
- }
- catch (InvalidOperationException ex)
- {
- Assert.Contains("Tag name cannot be blank", ex.Message);
- Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ Assert.Contains("Tag name cannot be blank", ex.Message);
+ Assert.Contains("SYS-SEC-001", ex.Message);
+ Assert.Contains(filePath, ex.Message);
}
}
diff --git a/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs b/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
index 5770e82..35410c9 100644
--- a/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
@@ -358,15 +358,8 @@ public void TraceMatrix_Export_NullFilePath_ThrowsArgumentException()
// Create TraceMatrix
var matrix = new TraceMatrix(requirements);
- try
- {
- matrix.Export(null!);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("File path cannot be null or empty", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => matrix.Export(null!));
+ Assert.Contains("File path cannot be null or empty", ex.Message);
}
///
@@ -392,15 +385,8 @@ public void TraceMatrix_Export_EmptyFilePath_ThrowsArgumentException()
// Create TraceMatrix
var matrix = new TraceMatrix(requirements);
- try
- {
- matrix.Export(string.Empty);
- Assert.Fail("Expected ArgumentException was not thrown");
- }
- catch (ArgumentException ex)
- {
- Assert.Contains("File path cannot be null or empty", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => matrix.Export(string.Empty));
+ Assert.Contains("File path cannot be null or empty", ex.Message);
}
///
diff --git a/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs b/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
index 45040da..65ca2aa 100644
--- a/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
@@ -266,15 +266,8 @@ public void TraceMatrix_WithExtraTests_IgnoresUnreferencedTests()
[TestMethod]
public void TraceMatrix_NullRequirements_ThrowsArgumentNullException()
{
- try
- {
- _ = new TraceMatrix(null!, Array.Empty());
- Assert.Fail("Expected ArgumentNullException was not thrown");
- }
- catch (ArgumentNullException ex)
- {
- Assert.Contains("requirements", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => _ = new TraceMatrix(null!, Array.Empty()));
+ Assert.Contains("requirements", ex.Message);
}
///
@@ -299,15 +292,8 @@ public void TraceMatrix_MissingFile_ThrowsFileNotFoundException()
var nonExistentPath = Path.Combine(_testDirectory, "nonexistent.trx");
- try
- {
- _ = new TraceMatrix(requirements, nonExistentPath);
- Assert.Fail("Expected FileNotFoundException was not thrown");
- }
- catch (FileNotFoundException ex)
- {
- Assert.Contains("Test result file not found", ex.Message);
- }
+ var ex = Assert.ThrowsException(() => _ = new TraceMatrix(requirements, nonExistentPath));
+ Assert.Contains("Test result file not found", ex.Message);
}
///
From e8791220d5f3e5494a668af4548c38f39108e9ef Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 13 Feb 2026 12:07:26 +0000
Subject: [PATCH 3/4] Fix MSTest method name - use ThrowsExactly instead of
ThrowsException
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
.../ContextTests.cs | 33 +++++++++----------
.../RequirementsExportTests.cs | 4 +--
.../RequirementsReadTests.cs | 30 ++++++++---------
.../TraceMatrixExportTests.cs | 4 +--
.../TraceMatrixReadTests.cs | 4 +--
5 files changed, 36 insertions(+), 39 deletions(-)
diff --git a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
index 63ac9db..31a6fb2 100644
--- a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
@@ -148,7 +148,7 @@ public void Context_Create_ResultsFlag_SetsResultsFileProperty()
[TestMethod]
public void Context_Create_MissingResultsFilename_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--results"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--results"]));
Assert.Contains("--results requires a filename argument", ex.Message);
}
@@ -218,7 +218,7 @@ public void Context_Create_MatrixFile_SetsMatrixProperty()
[TestMethod]
public void Context_Create_UnsupportedArgument_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--unsupported"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--unsupported"]));
Assert.Contains("Unsupported argument '--unsupported'", ex.Message);
}
@@ -228,7 +228,7 @@ public void Context_Create_UnsupportedArgument_ThrowsException()
[TestMethod]
public void Context_Create_MissingLogFilename_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--log"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--log"]));
Assert.Contains("--log requires a filename argument", ex.Message);
}
@@ -238,9 +238,8 @@ public void Context_Create_MissingLogFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingReportFilename_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--report"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--report"]));
Assert.Contains("--report requires a filename argument", ex.Message);
- }
}
///
@@ -249,7 +248,7 @@ public void Context_Create_MissingReportFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingMatrixFilename_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--matrix"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--matrix"]));
Assert.Contains("--matrix requires a filename argument", ex.Message);
}
@@ -259,7 +258,7 @@ public void Context_Create_MissingMatrixFilename_ThrowsException()
[TestMethod]
public void Context_Create_MissingReportDepth_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--report-depth"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--report-depth"]));
Assert.Contains("--report-depth requires a depth argument", ex.Message);
}
@@ -269,7 +268,7 @@ public void Context_Create_MissingReportDepth_ThrowsException()
[TestMethod]
public void Context_Create_MissingMatrixDepth_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--matrix-depth"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--matrix-depth"]));
Assert.Contains("--matrix-depth requires a depth argument", ex.Message);
}
@@ -279,13 +278,13 @@ public void Context_Create_MissingMatrixDepth_ThrowsException()
[TestMethod]
public void Context_Create_InvalidReportDepth_ThrowsException()
{
- var ex1 = Assert.ThrowsException(() => Context.Create(["--report-depth", "invalid"]));
+ var ex1 = Assert.ThrowsExactly(() => Context.Create(["--report-depth", "invalid"]));
Assert.Contains("--report-depth requires a positive integer", ex1.Message);
- var ex2 = Assert.ThrowsException(() => Context.Create(["--report-depth", "0"]));
+ var ex2 = Assert.ThrowsExactly(() => Context.Create(["--report-depth", "0"]));
Assert.Contains("--report-depth requires a positive integer", ex2.Message);
- var ex3 = Assert.ThrowsException(() => Context.Create(["--report-depth", "-1"]));
+ var ex3 = Assert.ThrowsExactly(() => Context.Create(["--report-depth", "-1"]));
Assert.Contains("--report-depth requires a positive integer", ex3.Message);
}
@@ -295,10 +294,10 @@ public void Context_Create_InvalidReportDepth_ThrowsException()
[TestMethod]
public void Context_Create_InvalidMatrixDepth_ThrowsException()
{
- var ex1 = Assert.ThrowsException(() => Context.Create(["--matrix-depth", "invalid"]));
+ var ex1 = Assert.ThrowsExactly(() => Context.Create(["--matrix-depth", "invalid"]));
Assert.Contains("--matrix-depth requires a positive integer", ex1.Message);
- var ex2 = Assert.ThrowsException(() => Context.Create(["--matrix-depth", "0"]));
+ var ex2 = Assert.ThrowsExactly(() => Context.Create(["--matrix-depth", "0"]));
Assert.Contains("--matrix-depth requires a positive integer", ex2.Message);
}
@@ -517,7 +516,7 @@ public void Context_Create_WithTestsPattern_ExpandsGlobPattern()
[TestMethod]
public void Context_Create_MissingRequirementsPattern_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--requirements"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--requirements"]));
Assert.Contains("--requirements requires a pattern argument", ex.Message);
}
@@ -527,7 +526,7 @@ public void Context_Create_MissingRequirementsPattern_ThrowsException()
[TestMethod]
public void Context_Create_MissingTestsPattern_ThrowsException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--tests"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--tests"]));
Assert.Contains("--tests requires a pattern argument", ex.Message);
}
@@ -575,7 +574,7 @@ public void Context_Create_InvalidLogPath_ThrowsException()
{
var invalidPath = Path.Combine(_testDirectory, "nonexistent", "test.log");
- var ex = Assert.ThrowsException(() => Context.Create(["--log", invalidPath]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--log", invalidPath]));
Assert.Contains("Failed to open log file", ex.Message);
}
@@ -616,7 +615,7 @@ public void Context_Create_FilterArgumentWithSpaces_TrimsAndParsesTagsCorrectly(
[TestMethod]
public void Context_Create_FilterArgumentMissingValue_ThrowsArgumentException()
{
- var ex = Assert.ThrowsException(() => Context.Create(["--filter"]));
+ var ex = Assert.ThrowsExactly(() => Context.Create(["--filter"]));
Assert.Contains("--filter requires a comma-separated list of tags", ex.Message);
}
diff --git a/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs b/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
index 14effa7..6f2eebe 100644
--- a/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/RequirementsExportTests.cs
@@ -183,7 +183,7 @@ public void Requirements_Export_NullFilePath_ThrowsArgumentException()
File.WriteAllText(reqPath, yamlContent);
var requirements = Requirements.Read(reqPath);
- var ex = Assert.ThrowsException(() => requirements.Export(null!));
+ var ex = Assert.ThrowsExactly(() => requirements.Export(null!));
Assert.Contains("File path cannot be null or empty", ex.Message);
}
@@ -204,7 +204,7 @@ public void Requirements_Export_EmptyFilePath_ThrowsArgumentException()
File.WriteAllText(reqPath, yamlContent);
var requirements = Requirements.Read(reqPath);
- var ex = Assert.ThrowsException(() => requirements.Export(string.Empty));
+ var ex = Assert.ThrowsExactly(() => requirements.Export(string.Empty));
Assert.Contains("File path cannot be null or empty", ex.Message);
}
diff --git a/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs b/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
index e248bd0..a89b731 100644
--- a/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/RequirementsReadTests.cs
@@ -326,7 +326,7 @@ public void Requirements_Read_DuplicateRequirementId_ThrowsException()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains("Duplicate requirement ID", ex.Message);
}
@@ -376,7 +376,7 @@ public void Requirements_Read_FileNotFound_ThrowsException()
{
var nonExistentPath = Path.Combine(_testDirectory, "nonexistent.yaml");
- var ex = Assert.ThrowsException(() => Requirements.Read(nonExistentPath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(nonExistentPath));
Assert.Contains("Requirements file not found", ex.Message);
}
@@ -482,7 +482,7 @@ public void Requirements_Read_BlankRequirementId_ThrowsExceptionWithFileLocation
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Requirement ID cannot be blank", ex.Message);
Assert.Contains("System Security", ex.Message);
Assert.Contains(filePath, ex.Message);
@@ -504,7 +504,7 @@ public void Requirements_Read_BlankRequirementTitle_ThrowsExceptionWithFileLocat
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Requirement title cannot be blank", ex.Message);
Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains(filePath, ex.Message);
@@ -526,7 +526,7 @@ public void Requirements_Read_BlankSectionTitle_ThrowsExceptionWithFileLocation(
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Section title cannot be blank", ex.Message);
Assert.Contains(filePath, ex.Message);
}
@@ -551,11 +551,10 @@ public void Requirements_Read_BlankTestNameInRequirement_ThrowsExceptionWithFile
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Test name cannot be blank", ex.Message);
Assert.Contains("SYS-SEC-001", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -580,7 +579,7 @@ public void Requirements_Read_BlankTestNameInMapping_ThrowsExceptionWithFileLoca
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Test name cannot be blank", ex.Message);
Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains(filePath, ex.Message);
@@ -607,7 +606,7 @@ public void Requirements_Read_BlankMappingId_ThrowsExceptionWithFileLocation()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Mapping requirement ID cannot be blank", ex.Message);
Assert.Contains(filePath, ex.Message);
}
@@ -630,11 +629,10 @@ public void Requirements_Read_DuplicateRequirementId_ExceptionIncludesFileLocati
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains("Duplicate requirement ID", ex.Message);
- Assert.Contains(filePath, ex.Message);
- }
+ Assert.Contains(filePath, ex.Message);
}
///
@@ -749,7 +747,7 @@ public void Requirements_Read_SingleFileWithParamsArray_WorksCorrectly()
[TestMethod]
public void Requirements_Read_NoArguments_ThrowsArgumentException()
{
- var ex = Assert.ThrowsException(() => Requirements.Read());
+ var ex = Assert.ThrowsExactly(() => Requirements.Read());
Assert.Contains("At least one file path must be provided", ex.Message);
}
@@ -759,7 +757,7 @@ public void Requirements_Read_NoArguments_ThrowsArgumentException()
[TestMethod]
public void Requirements_Read_NullArgument_ThrowsArgumentException()
{
- var ex = Assert.ThrowsException(() => Requirements.Read(null!));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(null!));
Assert.Contains("At least one file path must be provided", ex.Message);
}
@@ -850,7 +848,7 @@ public void Requirements_Read_BlankTagName_ThrowsExceptionWithFileLocation()
var filePath = Path.Combine(_testDirectory, "requirements.yaml");
File.WriteAllText(filePath, yamlContent);
- var ex = Assert.ThrowsException(() => Requirements.Read(filePath));
+ var ex = Assert.ThrowsExactly(() => Requirements.Read(filePath));
Assert.Contains("Tag name cannot be blank", ex.Message);
Assert.Contains("SYS-SEC-001", ex.Message);
Assert.Contains(filePath, ex.Message);
diff --git a/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs b/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
index 35410c9..de1faa1 100644
--- a/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/TraceMatrixExportTests.cs
@@ -358,7 +358,7 @@ public void TraceMatrix_Export_NullFilePath_ThrowsArgumentException()
// Create TraceMatrix
var matrix = new TraceMatrix(requirements);
- var ex = Assert.ThrowsException(() => matrix.Export(null!));
+ var ex = Assert.ThrowsExactly(() => matrix.Export(null!));
Assert.Contains("File path cannot be null or empty", ex.Message);
}
@@ -385,7 +385,7 @@ public void TraceMatrix_Export_EmptyFilePath_ThrowsArgumentException()
// Create TraceMatrix
var matrix = new TraceMatrix(requirements);
- var ex = Assert.ThrowsException(() => matrix.Export(string.Empty));
+ var ex = Assert.ThrowsExactly(() => matrix.Export(string.Empty));
Assert.Contains("File path cannot be null or empty", ex.Message);
}
diff --git a/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs b/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
index 65ca2aa..1bdf865 100644
--- a/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/TraceMatrixReadTests.cs
@@ -266,7 +266,7 @@ public void TraceMatrix_WithExtraTests_IgnoresUnreferencedTests()
[TestMethod]
public void TraceMatrix_NullRequirements_ThrowsArgumentNullException()
{
- var ex = Assert.ThrowsException(() => _ = new TraceMatrix(null!, Array.Empty()));
+ var ex = Assert.ThrowsExactly(() => _ = new TraceMatrix(null!, Array.Empty()));
Assert.Contains("requirements", ex.Message);
}
@@ -292,7 +292,7 @@ public void TraceMatrix_MissingFile_ThrowsFileNotFoundException()
var nonExistentPath = Path.Combine(_testDirectory, "nonexistent.trx");
- var ex = Assert.ThrowsException(() => _ = new TraceMatrix(requirements, nonExistentPath));
+ var ex = Assert.ThrowsExactly(() => _ = new TraceMatrix(requirements, nonExistentPath));
Assert.Contains("Test result file not found", ex.Message);
}
From 209aa4302a68e0d8acb8bc59f74d2f6b6d41b12f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 13 Feb 2026 12:08:31 +0000
Subject: [PATCH 4/4] Address code review feedback - revert redundant
Assert.Contains checks
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
test/DemaConsulting.ReqStream.Tests/ContextTests.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
index 31a6fb2..cdcad5a 100644
--- a/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
+++ b/test/DemaConsulting.ReqStream.Tests/ContextTests.cs
@@ -469,8 +469,8 @@ public void Context_Create_WithRequirementsPattern_ExpandsGlobPattern()
using var context = Context.Create(["--requirements", "*.yaml"]);
Assert.HasCount(2, context.RequirementsFiles);
- Assert.Contains(context.RequirementsFiles.Single(f => f.EndsWith("req1.yaml")), context.RequirementsFiles);
- Assert.Contains(context.RequirementsFiles.Single(f => f.EndsWith("req2.yaml")), context.RequirementsFiles);
+ Assert.IsTrue(context.RequirementsFiles.Any(f => f.EndsWith("req1.yaml")));
+ Assert.IsTrue(context.RequirementsFiles.Any(f => f.EndsWith("req2.yaml")));
Assert.AreEqual(0, context.ExitCode);
}
finally
@@ -500,8 +500,8 @@ public void Context_Create_WithTestsPattern_ExpandsGlobPattern()
using var context = Context.Create(["--tests", "*.trx"]);
Assert.HasCount(2, context.TestFiles);
- Assert.Contains(context.TestFiles.Single(f => f.EndsWith("test1.trx")), context.TestFiles);
- Assert.Contains(context.TestFiles.Single(f => f.EndsWith("test2.trx")), context.TestFiles);
+ Assert.IsTrue(context.TestFiles.Any(f => f.EndsWith("test1.trx")));
+ Assert.IsTrue(context.TestFiles.Any(f => f.EndsWith("test2.trx")));
Assert.AreEqual(0, context.ExitCode);
}
finally