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