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 }