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 }