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 }