1 /** 2 Copyright: Copyright (c) 2019, 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_test_case_unique; 11 12 import logger = std.experimental.logger; 13 import std.format : format; 14 import std.datetime : Clock, dur; 15 16 import arsd.dom : Element, RawSource; 17 18 import dextool.plugin.mutate.backend.database : Database; 19 import dextool.plugin.mutate.backend.report.analyzers : TestCaseUniqueness, 20 reportTestCaseUniqueness; 21 import dextool.plugin.mutate.backend.report.html.constants : Html; 22 import dextool.plugin.mutate.backend.resource : jsTableOnClick; 23 import dextool.plugin.mutate.backend.report.html.tmpl : tmplBasicPage, 24 tmplDefaultTable, dashboardCss; 25 import dextool.plugin.mutate.backend.type : Mutation; 26 import dextool.plugin.mutate.config : ConfigReport; 27 import dextool.plugin.mutate.type : MutationKind; 28 29 auto makeTestCaseUnique(ref Database db, ref const ConfigReport conf, 30 const(MutationKind)[] humanReadableKinds, const(Mutation.Kind)[] kinds) @trusted { 31 auto doc = tmplBasicPage.dashboardCss; 32 33 auto s = doc.root.childElements("head")[0].addChild("script"); 34 s.addChild(new RawSource(doc, jsTableOnClick)); 35 36 doc.title(format("Test Case Uniqueness %(%s %) %s", humanReadableKinds, Clock.currTime)); 37 doc.mainBody.setAttribute("onload", "init()"); 38 doc.mainBody.addChild("p", "This report contains the test cases that uniquely kill mutants, which those mutants are and test cases that aren't unique."); 39 40 toHtml(db, reportTestCaseUniqueness(db, kinds), doc.mainBody); 41 42 return doc.toPrettyString; 43 } 44 45 private: 46 47 void toHtml(ref Database db, TestCaseUniqueness result, Element root) { 48 import std.algorithm : sort, map; 49 import std.array : array; 50 import std.conv : to; 51 import std.path : buildPath; 52 import dextool.cachetools; 53 import dextool.plugin.mutate.backend.database : spinSql, MutationId; 54 import dextool.plugin.mutate.backend.report.html.page_files : pathToHtmlLink; 55 import dextool.type : Path; 56 57 auto getPath = nullableCache!(MutationId, string, (MutationId id) { 58 auto path = spinSql!(() => db.getPath(id)).get; 59 return format!"%s#%s"(buildPath(Html.fileDir, pathToHtmlLink(path)), id); 60 })(0, 30.dur!"seconds"); 61 62 with (root.addChild("button", "expand all")) { 63 setAttribute("type", "button"); 64 setAttribute("id", "expand_all"); 65 } 66 with (root.addChild("button", "collapse all")) { 67 setAttribute("type", "button"); 68 setAttribute("id", "collapse_all"); 69 } 70 71 foreach (const k; result.uniqueKills.byKey.array.sort) { 72 // Containers allows for hiding a table by clicking the corresponding header. 73 // Defaults to hiding tables. 74 auto comp_container = root.addChild("div").addClass("comp_container"); 75 auto heading = comp_container.addChild("h2").addClass("tbl_header"); 76 heading.addChild("i").addClass("right"); 77 heading.appendText(" "); 78 heading.appendText(k.name); 79 80 auto tbl_container = comp_container.addChild("div") 81 .addClass("tbl_container").setAttribute("style", "display: none;"); 82 auto tbl = tmplDefaultTable(tbl_container, ["Mutation ID"]); 83 84 auto r = tbl.appendRow(); 85 auto mut_ids = r.addChild("td"); 86 foreach (const m; result.uniqueKills[k].sort) { 87 auto link = mut_ids.addChild("a", m.to!string); 88 link.href = getPath(m).get; 89 mut_ids.appendText(" "); 90 } 91 } 92 93 { 94 root.addChild("p", "These are test cases that have no unique kills"); 95 auto tbl = tmplDefaultTable(root, ["Test Case"]); 96 foreach (const tc; result.noUniqueKills.sort) { 97 auto r = tbl.appendRow; 98 r.addChild("td", tc.name); 99 } 100 } 101 }