tools/traceabilitytool/traceability_tool/reportwriter.cs (179 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Text; // Used for StringBuilder class using System.IO; // Used for TextWriter and StreamWriter class. using System; // Used for Exception class. using System.Windows.Forms; // Used for MessageBox class namespace TraceabilityTool { class ReportWriter { // This class is responsible for writing reports generated by ReportGenerator class to plain text files. public static void WriteTraceabilityReport(string outputFolderPath) { StringBuilder sb = new StringBuilder(); foreach (string key in ReportGenerator.reqDocLookup.Keys) { // Print requirement ID. sb.AppendLine(key); // Print the path of the document where the requirement was defined. sb.AppendLine(" Defined in: " + ReportGenerator.reqDocLookup[key]); // Print source code file paths bool firstLine = true; if (ReportGenerator.reqCodeMatrix.ContainsKey(key)) { foreach (FilePathLineNum reqData in ReportGenerator.reqCodeMatrix[key]) { if (firstLine) { sb.AppendLine(" Coded in: " + reqData.filePath + ", line " + reqData.lineNum.ToString()); firstLine = false; } else { sb.AppendLine(" " + reqData.filePath + ", line " + reqData.lineNum.ToString()); } } } else { sb.AppendLine(" Not Coded"); } // Print test code file paths if (ReportGenerator.reqTestMatrix.ContainsKey(key)) { firstLine = true; foreach (FilePathLineNum reqData in ReportGenerator.reqTestMatrix[key]) { if (firstLine) { sb.AppendLine(" Tested in: " + reqData.filePath + ", line " + reqData.lineNum.ToString()); firstLine = false; } else { sb.AppendLine(" " + reqData.filePath + ", line " + reqData.lineNum.ToString()); } } } else { sb.AppendLine(" Not Tested"); } } // Print totals sb.AppendLine("".PadRight(42, '=')); sb.AppendLine("Total unique requirements : " + ReportGenerator.reqDocLookup.Count.ToString()); sb.AppendLine("Total implemented requirements : " + ReportGenerator.reqCodeMatrix.Count.ToString()); sb.AppendLine("Total tested requirements : " + ReportGenerator.reqTestMatrix.Count.ToString()); sb.AppendLine("Total unimplemented requirements: " + ReportGenerator.missingCodeCoverage.Count.ToString()); sb.AppendLine("Total untested requirements : " + ReportGenerator.missingTestCoverage.Count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\traceability_matrix.txt"); } public static void WriteInvalidReqReport(string outputFolderPath) { int maxKeyWidth = ReportGenerator.invalidRequirements.maxKeyLength + 3; int maxReasonWidth = ReportGenerator.invalidRequirements.maxReasonLength + 3; StringBuilder sb = new StringBuilder(); foreach (string key in ReportGenerator.invalidRequirements.Keys) { sb.Append(key.PadRight(maxKeyWidth)); bool newLine = false; foreach (InvalidReqDictEntry entry in ReportGenerator.invalidRequirements[key]) { if (newLine) { sb.AppendLine("".PadRight(maxKeyWidth) + entry.reason.PadRight(maxReasonWidth) + entry.filePath + ", line " + entry.lineNum.ToString()); } else { sb.AppendLine(entry.reason.PadRight(maxReasonWidth) + entry.filePath + ", line " + entry.lineNum.ToString()); newLine = true; } } } sb.AppendLine("".PadRight(35, '=')); sb.AppendLine("Total invalid requirements: " + ReportGenerator.invalidRequirements.Count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\invalid_requirements.txt"); } public static void WriteMissingCodeCoverageReport(string outputFolderPath) { StringBuilder sb = new StringBuilder(); foreach (string key in ReportGenerator.missingCodeCoverage.Keys) { sb.AppendLine(key.PadRight(ReportGenerator.missingCodeCoverageKeyWidth + 3) + ReportGenerator.missingCodeCoverage[key]); } sb.AppendLine("".PadRight(41, '=')); sb.AppendLine("Total unimplemented requirements: " + ReportGenerator.missingCodeCoverage.Count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\missing_code_coverage.txt"); } public static void WriteMissingTestCoverageReport(string outputFolderPath) { StringBuilder sb = new StringBuilder(); foreach (string key in ReportGenerator.missingTestCoverage.Keys) { sb.AppendLine(key.PadRight(ReportGenerator.missingTestCoverageKeyWidth + 3) + ReportGenerator.missingTestCoverage[key]); } sb.AppendLine("".PadRight(35, '=')); sb.AppendLine("Total untested requirements: " + ReportGenerator.missingTestCoverage.Count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\missing_test_coverage.txt"); } public static void WriteMissingCodeAndTestCoverageReport(string outputFolderPath) { int count = 0; int maxKeyWidth = ReportGenerator.missingTestCoverageKeyWidth; StringBuilder sb = new StringBuilder(); // Pick the shorter of the key lengths from missing code and test coverage lists // (if a longer key is not found on both lists at the same time, it will not be output to the report). if (ReportGenerator.missingCodeCoverageKeyWidth < maxKeyWidth) maxKeyWidth = ReportGenerator.missingCodeCoverageKeyWidth; foreach (string key in ReportGenerator.missingTestCoverage.Keys) { if (ReportGenerator.missingCodeCoverage.ContainsKey(key)) { sb.AppendLine(key.PadRight(maxKeyWidth + 3) + ReportGenerator.missingTestCoverage[key]); count++; } } sb.AppendLine("".PadRight(75, '=')); sb.AppendLine("Total number of requirements missing both implementation and tests: " + count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\missing_code_and_test_coverage.txt"); } public static void WriteRepeatingReqReport(string outputFolderPath) { StringBuilder sb = new StringBuilder(); foreach (string key in ReportGenerator.repeatingRequirements.Keys) { sb.Append(key.PadRight(ReportGenerator.repeatingRequirementsKeyWidth + 3)); bool newLine = false; foreach (string reqDocPath in ReportGenerator.repeatingRequirements[key]) { if (newLine) { sb.AppendLine("".PadRight(ReportGenerator.repeatingRequirementsKeyWidth + 3) + reqDocPath); } else { sb.AppendLine(reqDocPath); newLine = true; } } } sb.AppendLine("".PadRight(35, '=')); sb.AppendLine("Total repeating requirements: " + ReportGenerator.repeatingRequirements.Count.ToString()); // Output data to a CSV file. writeStringToFile(sb.ToString(), outputFolderPath + @"\repeating_requirements.txt"); } public static void writeStringToFile(string str, string outputFile) { try { TextWriter outfile = new StreamWriter(outputFile); { outfile.Write(str); outfile.Close(); } } catch (Exception exception) { string message = "An error occurred while attempting to access the file " + outputFile + System.Environment.NewLine + exception.Message + System.Environment.NewLine; if (ReportGenerator.useGUI) MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); else Console.WriteLine(message); Program.exitCode = 1; } } } }