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