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_test_groups;
11 
12 import logger = std.experimental.logger;
13 
14 import arsd.dom : Document, Element, require, Table;
15 
16 import dextool.plugin.mutate.backend.database : Database;
17 import dextool.plugin.mutate.backend.diff_parser : Diff;
18 import dextool.plugin.mutate.backend.report.analyzers : TestGroupStat, reportTestGroups;
19 import dextool.plugin.mutate.backend.report.html.constants;
20 import dextool.plugin.mutate.backend.report.html.tmpl : tmplBasicPage,
21     tmplDefaultTable, dashboardCss;
22 import dextool.plugin.mutate.backend.type : Mutation;
23 import dextool.plugin.mutate.config : ConfigReport;
24 import dextool.type : AbsolutePath;
25 
26 auto makeTestGroups(ref Database db, ref const ConfigReport conf) @trusted {
27     auto doc = tmplBasicPage.dashboardCss;
28     doc.title("Test Groups");
29 
30     if (conf.testGroups.length != 0)
31         doc.mainBody.addChild("h2", "Test Groups");
32     foreach (tg; conf.testGroups)
33         testGroups(reportTestGroups(db, tg), doc.mainBody);
34 
35     return doc.toPrettyString;
36 }
37 
38 private:
39 
40 void testGroups(const TestGroupStat test_g, Element root) {
41     import std.algorithm : sort, map;
42     import std.array : array;
43     import std.conv : to;
44     import std.format : format;
45     import std.path : buildPath;
46     import std.typecons : tuple;
47     import dextool.plugin.mutate.backend.mutation_type : toUser;
48     import dextool.plugin.mutate.backend.report.html.utility : pathToHtmlLink;
49 
50     root.addChild("h3", test_g.description);
51 
52     auto stat_tbl = tmplDefaultTable(root, ["Property", "Value"]);
53     foreach (const d; [
54             tuple("Mutation Score", test_g.stats.score.to!string),
55             tuple("Alive", test_g.stats.alive.to!string),
56             tuple("Total", test_g.stats.total.to!string)
57         ]) {
58         auto r = stat_tbl.appendRow();
59         r.addChild("td", d[0]);
60         r.addChild("td", d[1]);
61     }
62 
63     with (root.addChild("p")) {
64         appendText("Mutation data per file.");
65         appendText("The killed mutants are those that where killed by this test group.");
66         appendText("Therefor the total here is less than the reported total.");
67     }
68 
69     auto file_tbl = tmplDefaultTable(root, ["File", "Alive", "Killed"]);
70 
71     foreach (const pkv; test_g.files
72             .byKeyValue
73             .map!(a => tuple(a.key, a.value.dup))
74             .array
75             .sort!((a, b) => a[1] < b[1])) {
76         auto r = file_tbl.appendRow();
77 
78         const path = test_g.files[pkv[0]];
79         r.addChild("td", path);
80 
81         auto alive_ids = r.addChild("td").setAttribute("valign", "top");
82         if (auto alive = pkv[0] in test_g.alive) {
83             foreach (a; (*alive).dup.sort!((a, b) => a.sloc.line < b.sloc.line)) {
84                 auto link = alive_ids.addChild("a", format("%s:%s", a.kind.toUser, a.sloc.line));
85                 link.href = format("%s#%s", buildPath(Html.fileDir, pathToHtmlLink(path)), a.stId);
86                 alive_ids.appendText(" ");
87             }
88         }
89 
90         auto killed_ids = r.addChild("td").setAttribute("valign", "top");
91         if (auto killed = pkv[0] in test_g.killed) {
92             foreach (a; (*killed).dup.sort!((a, b) => a.sloc.line < b.sloc.line)) {
93                 auto link = killed_ids.addChild("a", format("%s:%s", a.kind.toUser, a.sloc.line));
94                 link.href = format("%s#%s", buildPath(Html.fileDir, pathToHtmlLink(path)), a.stId);
95                 killed_ids.appendText(" ");
96             }
97         }
98     }
99 
100     auto tc_tbl = tmplDefaultTable(root, ["Test Case"]);
101     foreach (tc; test_g.testCases) {
102         tc_tbl.appendRow(tc.name);
103     }
104 }