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.database.type; 11 12 import core.time : Duration; 13 import std.datetime : SysTime; 14 15 import sumtype; 16 17 import dextool.type : AbsolutePath, Path; 18 import dextool.plugin.mutate.backend.type; 19 20 public import dextool.plugin.mutate.backend.database.schema : MutantTimeoutCtxTbl, MarkedMutantTbl; 21 22 alias MutantTimeoutCtx = MutantTimeoutCtxTbl; 23 alias MarkedMutant = MarkedMutantTbl; 24 25 @safe: 26 27 /// Primary key in the database 28 struct Pkey(Pkeys T) { 29 long payload; 30 alias payload this; 31 } 32 33 enum Pkeys { 34 mutationId, 35 fileId, 36 testCaseId, 37 mutationStatusId, 38 } 39 40 /// Primary key in the mutation table 41 alias MutationId = Pkey!(Pkeys.mutationId); 42 43 /// Primary key for mutation status 44 alias MutationStatusId = Pkey!(Pkeys.mutationStatusId); 45 46 /// Primary key in the files table 47 alias FileId = Pkey!(Pkeys.fileId); 48 49 /// Primary key in the test_case table 50 alias TestCaseId = Pkey!(Pkeys.testCaseId); 51 52 struct MutationEntry { 53 MutationId id; 54 Path file; 55 SourceLoc sloc; 56 MutationPoint mp; 57 Duration timeSpentMutating; 58 Language lang; 59 } 60 61 struct NextMutationEntry { 62 import std.typecons : Nullable; 63 64 enum Status { 65 /// Mutant retrieved. 66 ok, 67 /// All mutants tested. 68 done, 69 } 70 71 Status st; 72 Nullable!MutationEntry entry; 73 } 74 75 struct MutationPointEntry { 76 MutationPoint mp; 77 Path file; 78 /// Start of the mutation point. 79 SourceLoc sloc; 80 /// End of the mutation point. 81 SourceLoc slocEnd; 82 } 83 84 /// The source code mutations for a mutation point. 85 struct MutationPointEntry2 { 86 Path file; 87 Offset offset; 88 /// Start of the mutation point. 89 SourceLoc sloc; 90 /// End of the mutation point. 91 SourceLoc slocEnd; 92 CodeMutant[] cms; 93 94 void put(CodeMutant m) @safe pure nothrow { 95 cms ~= m; 96 } 97 } 98 99 /// Report about mutants of a specific kind(s). 100 struct MutationReportEntry { 101 /// 102 long count; 103 /// Test time spent on the mutants. 104 Duration time; 105 } 106 107 /// Mutants that are tagged with nomut of a specific kind(s). 108 struct MetadataNoMutEntry { 109 /// 110 long count; 111 } 112 113 struct MutantInfo { 114 MutationId id; 115 Mutation.Status status; 116 Mutation.Kind kind; 117 SourceLoc sloc; 118 } 119 120 struct TestCaseInfo { 121 /// The sum on the execution time of killing the mutants. 122 Duration time; 123 /// 124 long killedMutants; 125 } 126 127 /// What mutants a test case killed. 128 struct TestCaseInfo2 { 129 TestCase name; 130 MutationId[] killed; 131 } 132 133 struct MutationStatusTime { 134 import std.datetime : SysTime; 135 136 MutationStatusId id; 137 SysTime updated; 138 } 139 140 struct MutationStatus { 141 import std.datetime : SysTime; 142 import std.typecons : Nullable; 143 144 MutationStatusId statusId; 145 Mutation.Status status; 146 MutantTestCount testCnt; 147 SysTime updated; 148 Nullable!SysTime added; 149 } 150 151 /// Metadata about a line in a file. 152 struct LineMetadata { 153 FileId id; 154 uint line; 155 LineAttr attr; 156 157 this(FileId fid, uint line) { 158 this(fid, line, LineAttr.init); 159 } 160 161 this(FileId fid, uint line, LineAttr attr) { 162 this.id = fid; 163 this.line = line; 164 this.attr = attr; 165 } 166 167 void set(NoMut a) @trusted pure nothrow @nogc { 168 attr = LineAttr(a); 169 } 170 171 bool isNoMut() @safe pure nothrow const @nogc { 172 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 173 } 174 } 175 176 struct NoMetadata { 177 } 178 179 /// A mutation suppression with optional tag and comment. 180 struct NoMut { 181 string tag; 182 string comment; 183 } 184 185 /// Metadata attributes that may be attached to a mutant. 186 alias MutantAttr = SumType!(NoMetadata, NoMut); 187 188 /// Metadata attributes that may be attached to a line. 189 alias LineAttr = SumType!(NoMetadata, NoMut); 190 191 /// Metadata about a mutant. 192 struct MutantMetaData { 193 import std.range : isOutputRange; 194 195 MutationId id; 196 MutantAttr attr; 197 198 this(MutationId id) { 199 this(id, MutantAttr.init); 200 } 201 202 this(MutationId id, MutantAttr attr) { 203 this.id = id; 204 this.attr = attr; 205 } 206 207 void set(NoMut a) @trusted pure nothrow @nogc { 208 attr = MutantAttr(a); 209 } 210 211 bool isNoMut() @safe pure nothrow const @nogc { 212 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 213 } 214 215 string kindToString() @safe pure const { 216 import std.array : appender; 217 import std.format : FormatSpec; 218 219 auto buf = appender!string; 220 kindToString(buf); 221 return buf.data; 222 } 223 224 void kindToString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 225 import std.range : put; 226 227 attr.match!((NoMetadata a) {}, (NoMut a) => put(w, "nomut")); 228 } 229 230 import std.range : isOutputRange; 231 232 string toString() @safe pure const { 233 import std.array : appender; 234 235 auto buf = appender!string; 236 toString(buf); 237 return buf.data; 238 } 239 240 void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 241 kindToString(w); 242 } 243 } 244 245 struct Rationale { 246 string payload; 247 alias payload this; 248 }