1 /** 2 Copyright: Copyright (c) 2020, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module dextool.plugin.mutate.backend.report.html.page_stats; 11 12 import logger = std.experimental.logger; 13 import std.datetime : Clock, dur; 14 import std.format : format; 15 16 import arsd.dom : Element, Link; 17 import my.path : AbsolutePath; 18 19 import dextool.plugin.mutate.backend.database : Database; 20 import dextool.plugin.mutate.backend.report.analyzers : MutationStat, 21 reportStatistics, reportSyncStatus, SyncStatus; 22 import dextool.plugin.mutate.backend.report.html.constants; 23 import dextool.plugin.mutate.backend.report.html.tmpl : tmplDefaultTable, 24 PieGraph, TimeScalePointGraph; 25 import dextool.plugin.mutate.backend.type : Mutation; 26 27 void makeStats(ref Database db, string tag, Element root, 28 const(Mutation.Kind)[] kinds, const AbsolutePath workListFname) @trusted { 29 import dextool.plugin.mutate.backend.report.html.page_worklist; 30 31 DashboardCss.h2(root.addChild(new Link(tag, null)).setAttribute("id", tag[1 .. $]), "Overview"); 32 overallStat(reportStatistics(db, kinds), root.addChild("div")); 33 makeWorklistPage(db, root, workListFname); 34 syncStatus(reportSyncStatus(db, kinds, 100), root); 35 } 36 37 private: 38 39 // TODO: this function contains duplicated logic from the one in ../utility.d 40 void overallStat(const MutationStat s, Element base) { 41 import std.conv : to; 42 import std.typecons : tuple; 43 44 base.addChild("p").appendHtml(format("Mutation Score <b>%.3s</b>", s.score)); 45 base.addChild("p", format("Time spent: %s", s.totalTime)); 46 47 if (s.untested > 0 && s.predictedDone > 0.dur!"msecs") { 48 const pred = Clock.currTime + s.predictedDone; 49 base.addChild("p", format("Remaining: %s (%s)", s.predictedDone, pred.toISOExtString)); 50 } 51 52 PieGraph("score", [ 53 PieGraph.Item("alive", "red", s.alive - s.aliveNoMut), 54 PieGraph.Item("killed", "green", s.killed), 55 PieGraph.Item("Untested", "grey", s.untested), 56 PieGraph.Item("Timeout", "lightgreen", s.timeout) 57 ]).html(base, PieGraph.Width(50)); 58 59 auto tbl = tmplDefaultTable(base, ["Type", "Value"]); 60 foreach (const d; [ 61 tuple("Total", s.total), 62 tuple("Killed by compiler", cast(long) s.killedByCompiler), 63 tuple("Skipped", s.skipped), tuple("Equivalent", s.equivalent), 64 tuple("Worklist", cast(long) s.worklist), 65 ]) { 66 tbl.appendRow(d[0], d[1]); 67 } 68 69 base.addChild("p").appendHtml( 70 "<i>worklist</i> is the number of mutants that are in the queue to be tested/retested."); 71 72 if (s.aliveNoMut != 0) { 73 tbl.appendRow("NoMut", s.aliveNoMut.to!string); 74 tbl.appendRow("NoMut/total", format("%.3s", s.suppressedOfTotal)); 75 76 auto p = base.addChild("p", "NoMut is the number of mutants that are alive but ignored."); 77 p.appendHtml(" They are <i>suppressed</i>."); 78 p.appendText(" This result in those mutants increasing the mutation score."); 79 p.appendText(" The suppressed/total is how much it has increased."); 80 p.appendHtml(" You <b>should</b> react if it is high."); 81 } 82 } 83 84 void syncStatus(SyncStatus status, Element root) { 85 auto ts = TimeScalePointGraph("SyncStatus"); 86 87 ts.put("Test", TimeScalePointGraph.Point(status.test, 1.6)); 88 ts.setColor("Test", "lightBlue"); 89 90 ts.put("Code", TimeScalePointGraph.Point(status.code, 1.4)); 91 ts.setColor("Code", "lightGreen"); 92 93 ts.put("Coverage", TimeScalePointGraph.Point(status.coverage, 1.2)); 94 ts.setColor("Coverage", "purple"); 95 96 if (status.mutants.length != 0) { 97 double y = 0.8; 98 foreach (v; status.mutants) { 99 ts.put("Mutant", TimeScalePointGraph.Point(v.updated, y)); 100 y += 0.3 / status.mutants.length; 101 } 102 ts.setColor("Mutant", "red"); 103 } 104 ts.html(root, TimeScalePointGraph.Width(50)); 105 106 root.addChild("p").appendHtml("<i>sync status</i> is how old the information about mutants and their status is compared to when the tests or source code where last changed"); 107 }