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