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_nomut;
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, MutantMetaData;
18 import dextool.plugin.mutate.backend.report.html.constants;
19 import dextool.plugin.mutate.backend.report.html.tmpl : tmplBasicPage,
20     dashboardCss, tmplDefaultTable;
21 import dextool.plugin.mutate.backend.report.utility;
22 import dextool.plugin.mutate.backend.type : Mutation;
23 import dextool.plugin.mutate.config : ConfigReport;
24 import dextool.type : AbsolutePath;
25 
26 auto makeNomut(ref Database db, ref const ConfigReport conf) @trusted {
27     auto doc = tmplBasicPage.dashboardCss;
28     doc.title("NoMut Details");
29     doc.mainBody.addChild("h1", "NoMut Details");
30     doc.mainBody.addChild("p",
31             "This is all the mutation suppressions that are used and affects the analysis.");
32 
33     db.mutantApi.getMutantMetaData(Mutation.Status.alive).toHtml(db, doc.mainBody);
34 
35     return doc.toPrettyString;
36 }
37 
38 private:
39 
40 // TODO: this is very inefficient implementation. There are so many lookups in
41 // the database. It "works" as long as there are only a limited amount of
42 // nomut.
43 void toHtml(MutantMetaData[] data, ref Database db, Element root) {
44     import std.algorithm : sort, map;
45     import std.array : array, empty;
46     import std.path : buildPath;
47     import std.typecons : Tuple;
48     import std.uni : toLower;
49     import sumtype;
50     import dextool.plugin.mutate.backend.database : MutationStatusId, NoMetadata, NoMut;
51     import dextool.plugin.mutate.backend.report.html.utility : pathToHtmlLink;
52 
53     alias IdComment = Tuple!(MutationStatusId, "id", string, "comment");
54     string[MutationStatusId][string] tags;
55 
56     // group by the tag that can be added to a nomut via
57     // // NOMUT (tag) <comment>
58     foreach (x; data) {
59         x.attr.match!((NoMetadata a) {}, (NoMut a) {
60             if (auto v = a.tag.toLower in tags) {
61                 (*v)[x.id] = a.comment;
62             } else {
63                 tags[a.tag.toLower] = [x.id: a.comment];
64             }
65         });
66     }
67 
68     foreach (tag; tags.byKey.array.sort) {
69         if (!tag.empty)
70             root.addChild("h2", tag);
71 
72         auto tbl = tmplDefaultTable(root, ["Mutant"]);
73         foreach (m; tags[tag].byKeyValue
74                 .map!(a => IdComment(a.key, a.value))
75                 .array
76                 .sort!((a, b) => a.comment < b.comment)) {
77             auto r = tbl.appendRow();
78 
79             auto file = db.mutantApi.getPath(m.id);
80             if (file.isNull)
81                 continue;
82 
83             auto td = r.addChild("td");
84             td.addChild("a", file.get).href = format("%s#%s",
85                     buildPath(Html.fileDir, pathToHtmlLink(file.get)), m.id);
86             td.addChild("br");
87             td.appendText(m.comment);
88         }
89     }
90 }