private static XElement CreateCoverageElement(InstrumentationResult result, HitsInfo hitsInfo) { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var allLines = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .Where(h => hitsInfo.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); var allBranches = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.Conditions) .SelectMany(c => c.Branches) .Count(); var coveredBranches = result.GetSourceFiles() .SelectMany(kvFile => kvFile.Value.Sequences) .SelectMany(i => i.Conditions) .SelectMany(c => c.Branches) .Where(b => hitsInfo.WasHit(b.HitId)) .Count(); var lineRate = allLines == 0 ? 1d : (double)coveredLines / (double)allLines; var branchRate = allBranches == 0 ? 1d : (double)coveredBranches / (double)allBranches; return(new XElement( XName.Get("coverage"), new XAttribute(XName.Get("lines-valid"), allLines), new XAttribute(XName.Get("lines-covered"), coveredLines), new XAttribute(XName.Get("line-rate"), lineRate), new XAttribute(XName.Get("branches-valid"), allBranches), new XAttribute(XName.Get("branches-covered"), coveredBranches), new XAttribute(XName.Get("branch-rate"), branchRate), new XAttribute(XName.Get("complexity"), 0), new XAttribute(XName.Get("timestamp"), timestamp), new XAttribute(XName.Get("version"), "1.0.0"), CrateSourcesElement(result, hitsInfo), CratePackagesElement(result, hitsInfo) )); }
public static int IsHigherThanThreshold(InstrumentationResult result, float threshold) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Sequences .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Sequences .Where(h => hits.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; } var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; return(isHigherThanThreshold ? 0 : 1); }
public Summary CalculateSummary( InstrumentationResult result, float threshold) { var hitsInfo = _hitsReader.TryReadFromDirectory(result.HitsPath); return(CalculateFilesSummary( result.GetSourceFiles(), hitsInfo, threshold)); }
public virtual int Execute(InstrumentationResult result, float threshold) { var hits = File.Exists(result.HitsFile) ? File.ReadAllLines(result.HitsFile).Select(h => int.Parse(h)).ToHashSet() : new HashSet <int>(); var files = result.GetSourceFiles(); SetFileColumnLength(files.Keys.Select(s => s.Length).Concat(new[] { 10 }).Max()); WriteHeader(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Instructions .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Instructions .Where(h => hits.Contains(h.Id)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; var coveragePercentage = (float)coveredLines / lines; var fileColor = coveragePercentage >= threshold ? ConsoleColor.Green : ConsoleColor.Red; WriteReport(kvFile, lines, coveredLines, coveragePercentage, fileColor); } WriteDetailedReport(result, files, hits); var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalsColor = isHigherThanThreshold ? ConsoleColor.Green : ConsoleColor.Red; WriteFooter(totalLines, totalCoveredLines, totalCoveragePercentage, threshold, totalsColor); return(isHigherThanThreshold ? 0 : 1); }
public virtual int Execute(InstrumentationResult result, float threshold) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); SetFileColumnLength(files.Keys.Select(s => s.Length).Concat(new[] { 10 }).Max()); WriteHeader(); var totalLines = 0; var totalCoveredLines = 0; foreach (var kvFile in files) { var lines = kvFile.Value.Sequences .SelectMany(i => i.GetLines()) .Distinct() .Count(); var coveredLines = kvFile.Value.Sequences .Where(h => hits.WasHit(h.HitId)) .SelectMany(i => i.GetLines()) .Distinct() .Count(); totalLines += lines; totalCoveredLines += coveredLines; var coveragePercentage = (float)coveredLines / lines; var fileColor = coveragePercentage >= threshold ? ConsoleColor.Green : ConsoleColor.Red; WriteReport(kvFile, lines, coveredLines, coveragePercentage, fileColor); } WriteDetailedReport(result, files, hits); var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalsColor = isHigherThanThreshold ? ConsoleColor.Green : ConsoleColor.Red; WriteFooter(totalLines, totalCoveredLines, totalCoveragePercentage, threshold, totalsColor); return(isHigherThanThreshold ? 0 : 1); }
public int Execute( InstrumentationResult result, float threshold, bool noFail) { var hitsInfo = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); var summary = SummaryFactory.CalculateFilesSummary(files, hitsInfo, threshold); var tableRows = SummaryFactory.GetSummaryGrid(files, hitsInfo, threshold); var consoleTable = new ConsoleTable { Header = CreateHeader(), Body = tableRows.Where(r => !r.Root).Select(f => CreateRow(f)).ToArray(), Footer = CreateFooter(summary) }; consoleTable.WriteTable(); return(noFail || summary.LinesCoveragePass ? 0 : 1); }
public virtual int Execute(InstrumentationResult result, IDirectoryInfo output, float threshold, bool noFail) { _fileSystem.Directory.CreateDirectory(output.FullName); var hitsInfo = _hitsReader.TryReadFromDirectory(result.HitsPath); var fileName = Path.Combine(output.FullName, "index.html"); var sourceFiles = result.GetSourceFiles(); var totalLines = sourceFiles.Sum(sf => sf.Sequences .SelectMany(s => s.GetLines()) .Distinct() .Count() ); var totalCoveredLines = sourceFiles.Sum(sf => sf.Sequences .Where(s => hitsInfo.WasHit(s.HitId)) .SelectMany(s => s.GetLines()) .Distinct() .Count() ); var totalCoveragePercentage = (float)totalCoveredLines / totalLines; var isHigherThanThreshold = totalCoveragePercentage >= threshold; var totalThresholdClass = isHigherThanThreshold ? "green" : "red"; using (var htmlWriter = (TextWriter)File.CreateText(fileName)) { htmlWriter.WriteLine("<html>"); htmlWriter.WriteLine("<style>"); htmlWriter.WriteLine(ResourceUtils.GetContent("MiniCover.Reports.Html.Shared.css")); htmlWriter.WriteLine(ResourceUtils.GetContent("MiniCover.Reports.Html.Summary.css")); htmlWriter.WriteLine("</style>"); htmlWriter.WriteLine("<script>"); htmlWriter.WriteLine(ResourceUtils.GetContent("MiniCover.Reports.Html.Shared.js")); htmlWriter.WriteLine("</script>"); htmlWriter.WriteLine("<body>"); // Write summary htmlWriter.WriteLine("<h2>Summary</h2>"); htmlWriter.WriteLine("<table>"); htmlWriter.WriteLine($"<tr><th>Generated on</th><td>{DateTime.Now}</td></tr>"); htmlWriter.WriteLine($"<tr><th>Threshold</th><td>{threshold:P}</td></tr>"); htmlWriter.WriteLine("</table>"); // Write detailed report htmlWriter.WriteLine("<h2>Source Files</h2>"); htmlWriter.WriteLine("<table border=\"1\" cellpadding=\"5\">"); htmlWriter.WriteLine("<tr>"); htmlWriter.WriteLine("<th>File</th>"); htmlWriter.WriteLine("<th class=\"value\">Lines</th>"); htmlWriter.WriteLine("<th class=\"value\">% Lines</th>"); htmlWriter.WriteLine("<th class=\"value\">Stmts</th>"); htmlWriter.WriteLine("<th class=\"value\">% Stmts</th>"); htmlWriter.WriteLine("<th class=\"value\">Branches</th>"); htmlWriter.WriteLine("<th class=\"value\">% Branches</th>"); htmlWriter.WriteLine("</tr>"); foreach (var summaryRow in _summaryFactory.GetSummaryGrid(result.GetSourceFiles(), hitsInfo, threshold)) { var summary = summaryRow.Summary; var statementsCoverageClass = summary.StatementsCoveragePass ? "green" : "red"; var linesCoverageClass = summary.LinesCoveragePass ? "green" : "red"; var branchesCoverageClass = summary.BranchesCoveragePass ? "green" : "red"; var classes = new List <string> { }; if (summaryRow.Level == 0) { classes.Add("root"); } if (summaryRow.Folder) { classes.Add("folder"); } if (summaryRow.File) { classes.Add("file"); } var marginLeft = Math.Max(summaryRow.Level - 1, 0) * 20; htmlWriter.WriteLine($"<tr class=\"{string.Join(" ", classes)}\">"); htmlWriter.WriteLine($"<td>"); if (summaryRow.SourceFiles.Length == 1) { var indexRelativeFileName = GetIndexRelativeHtmlFileName(summaryRow.SourceFiles[0].Path); htmlWriter.WriteLine($"<a class=\"name\" href=\"{indexRelativeFileName}\" style=\"margin-left: {marginLeft}px\">{summaryRow.Name}</a>"); } else { htmlWriter.WriteLine($"<span class=\"name\" style=\"margin-left: {marginLeft}px\">{summaryRow.Name}</span"); } htmlWriter.WriteLine("</td>"); htmlWriter.WriteLine($"<td class=\"value {linesCoverageClass}\">{summary.CoveredLines} / {summary.Lines}</td>"); htmlWriter.WriteLine($"<td class=\"value {linesCoverageClass}\">{summary.LinesPercentage:P}</td>"); htmlWriter.WriteLine($"<td class=\"value {statementsCoverageClass}\">{summary.CoveredStatements} / {summary.Statements}</td>"); htmlWriter.WriteLine($"<td class=\"value {statementsCoverageClass}\">{summary.StatementsPercentage:P}</td>"); htmlWriter.WriteLine($"<td class=\"value {branchesCoverageClass}\">{summary.CoveredBranches} / {summary.Branches}</td>"); htmlWriter.WriteLine($"<td class=\"value {branchesCoverageClass}\">{summary.BranchesPercentage:P}</td>"); htmlWriter.WriteLine("</tr>"); if (summaryRow.SourceFiles.Length == 1) { var relativeFileName = GetHtmlFileName(output, summaryRow.SourceFiles[0].Path); _htmlSourceFileReport.Generate(result, summaryRow.SourceFiles.First(), hitsInfo, threshold, relativeFileName); } } htmlWriter.WriteLine("</table>"); htmlWriter.WriteLine("</body>"); htmlWriter.WriteLine("</html>"); } return(noFail || isHigherThanThreshold ? 0 : 1); }
public virtual async Task <int> Execute(InstrumentationResult result, string output, string repoToken, string serviceJobId, string serviceName, string commitMessage, string rootFolder, string commit, string commitAuthorName, string commitAuthorEmail, string commitCommitterName, string commitCommitterEmail, string branch, string remoteName, string remoteUrl) { var hits = _hitsReader.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); var coverallsJob = new CoverallsJobModel { ServiceJobId = serviceJobId, ServiceName = serviceName, RepoToken = repoToken, CoverallsGitModel = !string.IsNullOrWhiteSpace(branch) ? new CoverallsGitModel { Head = !string.IsNullOrWhiteSpace(commit) ? new CoverallsCommitModel { Id = commit, AuthorName = commitAuthorName, AuthorEmail = commitAuthorEmail, CommitterName = commitCommitterName, CommitterEmail = commitCommitterEmail, Message = commitMessage } : null, Branch = branch, Remotes = !string.IsNullOrWhiteSpace(remoteUrl) ? new List <CoverallsRemote> { new CoverallsRemote { Name = remoteName, Url = remoteUrl } } : null } : null, SourceFiles = new List <CoverallsSourceFileModel>() }; foreach (var file in files) { var sourceFile = Path.Combine(result.SourcePath, file.Path); if (!_fileSystem.File.Exists(sourceFile)) { System.Console.WriteLine($"File not found: {sourceFile}"); continue; } var sourceLines = _fileSystem.File.ReadAllLines(sourceFile); var hitsPerLine = file.Sequences .GroupByMany(f => f.GetLines()) .ToDictionary(g => g.Key, g => g.Sum(i => hits.GetHitCount(i.HitId))); var fileName = PathUtils.GetRelativePath(rootFolder, sourceFile).Replace("\\", "/"); var coverallsSourceFileModel = new CoverallsSourceFileModel { Name = fileName, SourceDigest = ComputeSourceDigest(sourceFile), Coverage = Enumerable.Range(1, sourceLines.Length).Select(line => { return(hitsPerLine.ContainsKey(line) ? hitsPerLine[line] : default(int?)); }).ToArray() }; coverallsJob.SourceFiles.Add(coverallsSourceFileModel); } var coverallsJson = JsonConvert.SerializeObject(coverallsJob, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); if (!string.IsNullOrWhiteSpace(output)) { _fileSystem.File.WriteAllText(output, coverallsJson); } return(await Post(coverallsJson)); }
public virtual async Task <int> Execute(InstrumentationResult result) { var hits = HitsInfo.TryReadFromDirectory(result.HitsPath); var files = result.GetSourceFiles(); var coverallsJob = new CoverallsJobModel { ServiceJobId = _serviceJobId, ServiceName = _serviceName, RepoToken = _repoToken, CoverallsGitModel = !string.IsNullOrWhiteSpace(_branch) ? new CoverallsGitModel { Head = !string.IsNullOrWhiteSpace(_commit) ? new CoverallsCommitModel { Id = _commit, AuthorName = _commitAuthorName, AuthorEmail = _commitAuthorEmail, CommitterName = _commitCommitterName, CommitterEmail = _commitCommitterEmail, Message = _commitMessage } : null, Branch = _branch, Remotes = !string.IsNullOrWhiteSpace(_remoteUrl) ? new List <CoverallsRemote> { new CoverallsRemote { Name = _remoteName, Url = _remoteUrl } } : null } : null, SourceFiles = new List <CoverallsSourceFileModel>() }; foreach (var kvFile in files) { var sourceFile = Path.Combine(result.SourcePath, kvFile.Key); if (!File.Exists(sourceFile)) { Console.WriteLine($"File not found: {sourceFile}"); continue; } var sourceLines = File.ReadAllLines(sourceFile); var hitsPerLine = kvFile.Value.Instructions .SelectMany(i => i.GetLines(), (instruction, line) => new { instruction, line }) .GroupBy(i => i.line) .ToDictionary(g => g.Key, g => g.Sum(j => hits.GetInstructionHitCount(j.instruction.Id))); var fileName = Path.GetRelativePath(_rootFolder, sourceFile).Replace("\\", "/"); var coverallsSourceFileModel = new CoverallsSourceFileModel { Name = fileName, SourceDigest = ComputeSourceDigest(sourceFile), Coverage = Enumerable.Range(1, sourceLines.Length).Select(line => { return(hitsPerLine.ContainsKey(line) ? hitsPerLine[line] : default(int?)); }).ToArray() }; coverallsJob.SourceFiles.Add(coverallsSourceFileModel); } var coverallsJson = JsonConvert.SerializeObject(coverallsJob, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); if (!string.IsNullOrWhiteSpace(_output)) { File.WriteAllText(_output, coverallsJson); } return(await Post(coverallsJson)); }