1 /**
2 Copyright: Copyright (c) 2019, 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_test_case_unique;
11 
12 import logger = std.experimental.logger;
13 import std.format : format;
14 import std.datetime : Clock, dur;
15 
16 import arsd.dom : Element, RawSource;
17 
18 import dextool.plugin.mutate.backend.database : Database;
19 import dextool.plugin.mutate.backend.report.analyzers : TestCaseUniqueness,
20     reportTestCaseUniqueness;
21 import dextool.plugin.mutate.backend.report.html.constants : Html;
22 import dextool.plugin.mutate.backend.resource : jsTableOnClick;
23 import dextool.plugin.mutate.backend.report.html.tmpl : tmplBasicPage,
24     tmplDefaultTable, dashboardCss;
25 import dextool.plugin.mutate.backend.type : Mutation;
26 import dextool.plugin.mutate.config : ConfigReport;
27 import dextool.plugin.mutate.type : MutationKind;
28 
29 auto makeTestCaseUnique(ref Database db, ref const ConfigReport conf,
30         const(MutationKind)[] humanReadableKinds, const(Mutation.Kind)[] kinds) @trusted {
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("Test Case Uniqueness %(%s %) %s", humanReadableKinds, Clock.currTime));
37     doc.mainBody.setAttribute("onload", "init()");
38     doc.mainBody.addChild("p", "This report contains the test cases that uniquely kill mutants, which those mutants are and test cases that aren't unique.");
39 
40     toHtml(db, reportTestCaseUniqueness(db, kinds), doc.mainBody);
41 
42     return doc.toPrettyString;
43 }
44 
45 private:
46 
47 void toHtml(ref Database db, TestCaseUniqueness result, Element root) {
48     import std.algorithm : sort, map;
49     import std.array : array;
50     import std.conv : to;
51     import std.path : buildPath;
52     import dextool.cachetools;
53     import dextool.plugin.mutate.backend.database : spinSql, MutationId;
54     import dextool.plugin.mutate.backend.report.html.page_files : pathToHtmlLink;
55     import dextool.type : Path;
56 
57     auto getPath = nullableCache!(MutationId, string, (MutationId id) {
58         auto path = spinSql!(() => db.getPath(id)).get;
59         return format!"%s#%s"(buildPath(Html.fileDir, pathToHtmlLink(path)), id);
60     })(0, 30.dur!"seconds");
61 
62     with (root.addChild("button", "expand all")) {
63         setAttribute("type", "button");
64         setAttribute("id", "expand_all");
65     }
66     with (root.addChild("button", "collapse all")) {
67         setAttribute("type", "button");
68         setAttribute("id", "collapse_all");
69     }
70 
71     foreach (const k; result.uniqueKills.byKey.array.sort) {
72         // Containers allows for hiding a table by clicking the corresponding header.
73         // Defaults to hiding tables.
74         auto comp_container = root.addChild("div").addClass("comp_container");
75         auto heading = comp_container.addChild("h2").addClass("tbl_header");
76         heading.addChild("i").addClass("right");
77         heading.appendText(" ");
78         heading.appendText(k.name);
79 
80         auto tbl_container = comp_container.addChild("div")
81             .addClass("tbl_container").setAttribute("style", "display: none;");
82         auto tbl = tmplDefaultTable(tbl_container, ["Mutation ID"]);
83 
84         auto r = tbl.appendRow();
85         auto mut_ids = r.addChild("td");
86         foreach (const m; result.uniqueKills[k].sort) {
87             auto link = mut_ids.addChild("a", m.to!string);
88             link.href = getPath(m).get;
89             mut_ids.appendText(" ");
90         }
91     }
92 
93     {
94         root.addChild("p", "These are test cases that have no unique kills");
95         auto tbl = tmplDefaultTable(root, ["Test Case"]);
96         foreach (const tc; result.noUniqueKills.sort) {
97             auto r = tbl.appendRow;
98             r.addChild("td", tc.name);
99         }
100     }
101 }