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