1 /**
2 Copyright: Copyright (c) 2018, 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_minimal_set;
11 
12 import logger = std.experimental.logger;
13 import std.format : format;
14 
15 import arsd.dom : Document, Element, require, Table, RawSource;
16 
17 import dextool.plugin.mutate.backend.database : Database;
18 import dextool.plugin.mutate.backend.report.analyzers : MinimalTestSet, reportMinimalSet;
19 import dextool.plugin.mutate.backend.report.html.constants;
20 import dextool.plugin.mutate.backend.resource;
21 import dextool.plugin.mutate.backend.report.html.tmpl : tmplBasicPage,
22     tmplDefaultTable, dashboardCss, tmplDefaultMatrixTable;
23 import dextool.plugin.mutate.backend.type : Mutation;
24 import dextool.plugin.mutate.config : ConfigReport;
25 import dextool.plugin.mutate.type : MutationKind;
26 
27 auto makeMinimalSetAnalyse(ref Database db, ref const ConfigReport conf,
28         const(MutationKind)[] humanReadableKinds, const(Mutation.Kind)[] kinds) @trusted {
29     import std.datetime : Clock;
30 
31     auto doc = tmplBasicPage.dashboardCss;
32 
33     auto s = doc.root.childElements("head")[0].addChild("script");
34     s.addChild(new RawSource(doc, jsTableOnClick));
35 
36     doc.title(format("Minimal Set Analyse %(%s %) %s", humanReadableKinds, Clock.currTime));
37     doc.mainBody.setAttribute("onload", "init()");
38     doc.mainBody.addChild("p",
39             "This are the minimal set of mutants that result in the mutation score.");
40 
41     auto p = doc.mainBody.addChild("p");
42 
43     toHtml(reportMinimalSet(db, kinds), doc.mainBody);
44 
45     return doc.toPrettyString;
46 }
47 
48 private:
49 
50 void toHtml(MinimalTestSet min_set, Element root) {
51     import core.time : Duration;
52     import std.conv : to;
53 
54     {
55         root.addChild("p",
56                 "The tables are hidden by default, click on the corresponding header to display a table.");
57         with (root.addChild("button", "expand all")) {
58             setAttribute("type", "button");
59             setAttribute("id", "expand_all");
60         }
61         with (root.addChild("button", "collapse all")) {
62             setAttribute("type", "button");
63             setAttribute("id", "collapse_all");
64         }
65         auto comp_container = root.addChild("div").addClass("comp_container");
66         auto heading = comp_container.addChild("h2").addClass("tbl_header");
67         heading.addChild("i").addClass("right");
68         heading.appendText(format!" Ineffective Test Cases (%s/%s %s)"(min_set.redundant.length,
69                 min_set.total, cast(double) min_set.redundant.length / cast(double) min_set.total));
70         comp_container.addChild("p",
71                 "These test cases do not contribute towards the mutation score.");
72         auto tbl_container = comp_container.addChild("div").addClass("tbl_container");
73         tbl_container.setAttribute("style", "display: none;");
74         auto tbl = tmplDefaultTable(tbl_container, [
75                 "Test Case", "Killed", "Sum of test time"
76                 ]);
77 
78         Duration sum;
79         foreach (const tc; min_set.redundant) {
80             auto r = tbl.appendRow();
81             r.addChild("td", tc.name);
82             r.addChild("td", min_set.testCaseTime[tc.name].killedMutants.to!string);
83             r.addChild("td", min_set.testCaseTime[tc.name].time.sum.to!string);
84             sum += min_set.testCaseTime[tc.name].time.sum;
85         }
86         tbl_container.addChild("p", format("Total test time: %s", sum));
87     }
88     {
89         auto comp_container = root.addChild("div").addClass("comp_container");
90         auto heading = comp_container.addChild("h2").addClass("tbl_header");
91         heading.addChild("i").addClass("right");
92         heading.appendText(format!" Minimal Set (%s/%s %s)"(min_set.minimalSet.length,
93                 min_set.total, cast(double) min_set.minimalSet.length / cast(double) min_set.total));
94         comp_container.addChild("p",
95                 "This is the minimum set of tests that achieve the mutation score.");
96 
97         auto tbl_container = comp_container.addChild("div").addClass("tbl_container");
98         tbl_container.setAttribute("style", "display: none;");
99         auto tbl = tmplDefaultTable(tbl_container, [
100                 "Test Case", "Killed", "Sum of test time"
101                 ]);
102 
103         Duration sum;
104         foreach (const tc; min_set.minimalSet) {
105             auto r = tbl.appendRow();
106             r.addChild("td", tc.name);
107             r.addChild("td", min_set.testCaseTime[tc.name].killedMutants.to!string);
108             r.addChild("td", min_set.testCaseTime[tc.name].time.sum.to!string);
109             sum += min_set.testCaseTime[tc.name].time.sum;
110         }
111         tbl_container.addChild("p", format("Total test time: %s", sum));
112     }
113 }