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 my.named_type; 16 import sumtype; 17 18 import dextool.type : AbsolutePath, Path; 19 import dextool.plugin.mutate.backend.type; 20 21 public import dextool.plugin.mutate.backend.database.schema : MutantTimeoutCtxTbl; 22 public import dextool.plugin.mutate.backend.type : MutantTimeProfile; 23 24 @safe: 25 26 /// The context (state) of how the testing of the timeout mutants are going. 27 alias MutantTimeoutCtx = MutantTimeoutCtxTbl; 28 29 /// Primary key in the mutation table 30 alias MutationId = NamedType!(long, Tag!"MutationId", 0, Comparable, Hashable, ConvertStringable); 31 32 /// Primary key for mutation status 33 alias MutationStatusId = NamedType!(long, Tag!"MutationStatusId", long.init, 34 Comparable, Hashable, ConvertStringable); 35 36 /// Primary key in the files table 37 alias FileId = NamedType!(long, Tag!"FileId", long.init, Comparable, Hashable, TagStringable); 38 39 /// Primary key in the test files table 40 alias TestFileId = NamedType!(long, Tag!"TestFileId", long.init, Comparable, 41 Hashable, TagStringable); 42 43 /// Primary key in the test_case table 44 alias TestCaseId = NamedType!(long, Tag!"TestCaseId", long.init, Comparable, 45 Hashable, TagStringable); 46 47 /// Primary key for mutation schematas. 48 alias SchemataId = NamedType!(long, Tag!"SchemataId", long.init, Comparable, 49 Hashable, TagStringable); 50 51 /// Primary key for a schemata fragment. 52 alias SchemataFragmentId = NamedType!(long, Tag!"SchemataFragmentId", 53 long.init, Comparable, Hashable, TagStringable); 54 55 struct MutationEntry { 56 MutationId id; 57 Path file; 58 SourceLoc sloc; 59 MutationPoint mp; 60 MutantTimeProfile profile; 61 Language lang; 62 } 63 64 struct NextMutationEntry { 65 import std.typecons : Nullable; 66 67 enum Status { 68 /// Mutant retrieved. 69 ok, 70 /// All mutants tested. 71 done, 72 } 73 74 Status st; 75 Nullable!MutationEntry entry; 76 } 77 78 struct MutationPointEntry { 79 MutationPoint mp; 80 Path file; 81 /// Start of the mutation point. 82 SourceLoc sloc; 83 /// End of the mutation point. 84 SourceLoc slocEnd; 85 } 86 87 /// The source code mutations for a mutation point. 88 struct MutationPointEntry2 { 89 Path file; 90 Offset offset; 91 /// Start of the mutation point. 92 SourceLoc sloc; 93 /// End of the mutation point. 94 SourceLoc slocEnd; 95 CodeMutant[] cms; 96 97 void put(CodeMutant m) @safe pure nothrow { 98 cms ~= m; 99 } 100 } 101 102 /// Report about mutants of a specific kind(s). 103 struct MutationReportEntry { 104 /// 105 long count; 106 107 /// Test time spent on the mutants. 108 MutantTimeProfile time; 109 } 110 111 /// Mutants that are tagged with nomut of a specific kind(s). 112 struct MetadataNoMutEntry { 113 /// 114 long count; 115 } 116 117 struct MutantInfo { 118 MutationId id; 119 Mutation.Status status; 120 ExitStatus ecode; 121 Mutation.Kind kind; 122 SourceLoc sloc; 123 } 124 125 struct TestCaseInfo { 126 /// The sum on the execution time of killing the mutants. 127 MutantTimeProfile time; 128 129 /// 130 long killedMutants; 131 } 132 133 /// What mutants a test case killed. 134 struct TestCaseInfo2 { 135 TestCase name; 136 MutationId[] killed; 137 } 138 139 struct MutationStatusTime { 140 import std.datetime : SysTime; 141 142 MutationStatusId id; 143 SysTime updated; 144 } 145 146 alias MutantPrio = NamedType!(long, Tag!"MutantPriority", long.init, TagStringable); 147 148 struct MutationStatus { 149 import std.datetime : SysTime; 150 import std.typecons : Nullable; 151 152 MutationStatusId statusId; 153 Mutation.Status status; 154 MutantPrio prio; 155 SysTime updated; 156 Nullable!SysTime added; 157 ExitStatus exitStatus; 158 } 159 160 /// Metadata about a line in a file. 161 struct LineMetadata { 162 FileId id; 163 uint line; 164 LineAttr attr; 165 166 this(FileId fid, uint line) { 167 this(fid, line, LineAttr.init); 168 } 169 170 this(FileId fid, uint line, LineAttr attr) { 171 this.id = fid; 172 this.line = line; 173 this.attr = attr; 174 } 175 176 void set(NoMut a) @trusted pure nothrow @nogc { 177 attr = LineAttr(a); 178 } 179 180 bool isNoMut() @safe pure nothrow const @nogc { 181 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 182 } 183 } 184 185 struct NoMetadata { 186 } 187 188 /// A mutation suppression with optional tag and comment. 189 struct NoMut { 190 string tag; 191 string comment; 192 } 193 194 /// Metadata attributes that may be attached to a mutant. 195 alias MutantAttr = SumType!(NoMetadata, NoMut); 196 197 /// Metadata attributes that may be attached to a line. 198 alias LineAttr = SumType!(NoMetadata, NoMut); 199 200 /// Metadata about a mutant. 201 struct MutantMetaData { 202 import std.range : isOutputRange; 203 204 MutationId id; 205 MutantAttr attr; 206 207 this(MutationId id) { 208 this(id, MutantAttr.init); 209 } 210 211 this(MutationId id, MutantAttr attr) { 212 this.id = id; 213 this.attr = attr; 214 } 215 216 void set(NoMut a) @trusted pure nothrow @nogc { 217 attr = MutantAttr(a); 218 } 219 220 bool isNoMut() @safe pure nothrow const @nogc { 221 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 222 } 223 224 string kindToString() @safe pure const { 225 import std.array : appender; 226 import std.format : FormatSpec; 227 228 auto buf = appender!string; 229 kindToString(buf); 230 return buf.data; 231 } 232 233 void kindToString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 234 import std.range : put; 235 236 attr.match!((NoMetadata a) {}, (NoMut a) => put(w, "nomut")); 237 } 238 239 import std.range : isOutputRange; 240 241 string toString() @safe pure const { 242 import std.array : appender; 243 244 auto buf = appender!string; 245 toString(buf); 246 return buf.data; 247 } 248 249 void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 250 kindToString(w); 251 } 252 } 253 254 alias Rationale = NamedType!(string, Tag!"Rationale", string.init, TagStringable); 255 256 struct MarkedMutant { 257 MutationStatusId statusId; 258 259 /// Checksum of the marked mutant. 260 Checksum statusChecksum; 261 262 MutationId mutationId; 263 264 SourceLoc sloc; 265 Path path; 266 267 /// The status it should always be changed to. 268 Mutation.Status toStatus; 269 270 /// Time when the mutant where marked. 271 SysTime time; 272 273 Rationale rationale; 274 275 string mutText; 276 } 277 278 /// A fragment of a schemata which is one application. 279 struct SchemataFragment { 280 Path file; 281 Offset offset; 282 const(ubyte)[] text; 283 } 284 285 struct Schemata { 286 SchemataId id; 287 288 /// Sorted in the order they should be applied. 289 SchemataFragment[] fragments; 290 } 291 292 struct TestCmdRuntime { 293 SysTime timeStamp; 294 295 /// The execution time of the test suite. 296 Duration runtime; 297 } 298 299 struct MutationScore { 300 SysTime timeStamp; 301 NamedType!(double, Tag!"MutationScore", 0.0, TagStringable) score; 302 } 303 304 alias TestFilePath = NamedType!(Path, Tag!"TestFilePath", Path.init, Hashable, TagStringable); 305 alias TestFileChecksum = NamedType!(Checksum, Tag!"TestFileChecksum", 306 Checksum.init, TagStringable, Hashable); 307 308 struct TestFile { 309 TestFilePath file; 310 311 /// Checksum of the content. 312 TestFileChecksum checksum; 313 314 /// Last time the file was changed. 315 SysTime timeStamp; 316 } 317 318 alias CoverageRegionId = NamedType!(long, Tag!"CoverageRegionId", long.init, 319 Comparable, Hashable, ConvertStringable); 320 struct CovRegion { 321 CoverageRegionId id; 322 Offset region; 323 } 324 325 /// A file that a root is dependent on. 326 struct DepFile { 327 Path file; 328 Checksum checksum; 329 } 330 331 alias ToolVersion = NamedType!(long, Tag!"ToolVersion", long.init, TagStringable, Comparable);