private static CloverCounter CountMetrics(IEnumerable <InstrumentedInstruction> instructions, HitsInfo hits) { var localInstructions = instructions.ToArray(); var coveredInstructions = localInstructions .Where(instruction => hits.IsInstructionHit(instruction.Id)).ToArray(); return(new CloverCounter { Statements = localInstructions.Length, CoveredStatements = coveredInstructions.Length, Methods = localInstructions .GroupBy(instruction => instruction.Method.FullName) .Count(), CoveredMethods = coveredInstructions .GroupBy(instruction => instruction.Method.FullName) .Count() }); }
protected override void WriteDetailedReport(InstrumentationResult result, IDictionary <string, SourceFile> files, HitsInfo hitsInfo) { foreach (var kvFile in files) { var lines = File.ReadAllLines(Path.Combine(result.SourcePath, kvFile.Key)); var fileName = GetHtmlFileName(kvFile.Key); Directory.CreateDirectory(Path.GetDirectoryName(fileName)); using (var htmlWriter = (TextWriter)File.CreateText(fileName)) { htmlWriter.WriteLine("<html>"); htmlWriter.WriteLine("<style>"); htmlWriter.WriteLine("details summary::-webkit-details-marker {"); htmlWriter.WriteLine("display: none;"); htmlWriter.WriteLine("}"); htmlWriter.WriteLine("</style>"); htmlWriter.WriteLine("<body style=\"font-family: monospace;\">"); var uncoveredLineNumbers = new HashSet <int>(); var coveredLineNumbers = new HashSet <int>(); foreach (var i in kvFile.Value.Instructions) { if (hitsInfo.IsInstructionHit(i.Id)) { coveredLineNumbers.UnionWith(i.GetLines()); } else { uncoveredLineNumbers.UnionWith(i.GetLines()); } } var l = 0; foreach (var line in lines) { l++; var style = "white-space: pre;"; if (coveredLineNumbers.Contains(l)) { style += BgColorGreen; style += CursorPointer; } else if (uncoveredLineNumbers.Contains(l)) { style += BgColorRed; } else { style += BgColorNeutral; } var instructions = kvFile.Value.Instructions .Where(i => i.GetLines().Contains(l)) .ToArray(); var counter = instructions.Sum(a => hitsInfo.GetInstructionHitCount(a.Id)); var codeContent = !string.IsNullOrEmpty(line) ? WebUtility.HtmlEncode(line) : " "; var contexts = instructions .SelectMany(i => hitsInfo.GetInstructionHitContexts(i.Id)) .Distinct() .ToArray(); var hitCountHtml = coveredLineNumbers.Contains(l) || uncoveredLineNumbers.Contains(l) ? $"<span style=\"display: inline-block; width: 30px; font-size: 10px;\">{counter}x</span>" : "<span style=\"display: inline-block; width: 30px; font-size: 10px;\"></span>"; if (coveredLineNumbers.Contains(l)) { htmlWriter.WriteLine($"<details>"); htmlWriter.WriteLine($"<summary style=\"{style}\">{hitCountHtml}{codeContent}</summary>"); htmlWriter.WriteLine("<ul>"); foreach (var context in contexts) { var count = instructions.Sum(i => context.GetHitCount(i.Id)); var description = $"{context.ClassName}.{context.MethodName}"; htmlWriter.WriteLine($"<li>{WebUtility.HtmlEncode(description)}: {count}x</li>"); } htmlWriter.WriteLine("</ul>"); htmlWriter.WriteLine($"</details>"); } else { htmlWriter.WriteLine($"<div style=\"{style}\">{hitCountHtml}{codeContent}</div>"); } } htmlWriter.WriteLine("</body>"); htmlWriter.WriteLine("</html>"); } } }