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