1 | package com.github.dakusui.actionunit.visitors; | |
2 | ||
3 | import com.github.dakusui.actionunit.actions.Composite; | |
4 | import com.github.dakusui.actionunit.core.Action; | |
5 | import com.github.dakusui.actionunit.io.Writer; | |
6 | ||
7 | import java.util.LinkedList; | |
8 | import java.util.List; | |
9 | import java.util.Map; | |
10 | import java.util.function.Predicate; | |
11 | ||
12 | import static java.lang.String.format; | |
13 | import static java.util.Objects.requireNonNull; | |
14 | ||
15 | public class ActionReporter extends ActionPrinter { | |
16 |
2
1. lambda$static$0 : replaced boolean return with false for com/github/dakusui/actionunit/visitors/ActionReporter::lambda$static$0 → KILLED 2. lambda$static$0 : replaced boolean return with true for com/github/dakusui/actionunit/visitors/ActionReporter::lambda$static$0 → KILLED |
public static final Predicate<Action> DEFAULT_CONDITION_TO_SQUASH_ACTION = v -> v instanceof Composite; |
17 | private final List<Boolean> failingContext = new LinkedList<>(); | |
18 | private final Predicate<Action> conditionToSquashAction; | |
19 | private int emptyLevel = 0; | |
20 | private int depth = 0; | |
21 | private final Map<Action, Record> report; | |
22 | private final Writer warnWriter; | |
23 | private final Writer traceWriter; | |
24 | private final Writer debugWriter; | |
25 | private final Writer infoWriter; | |
26 | private final int forcePrintLevelForUnexercisedActions; | |
27 | ||
28 | public ActionReporter(Predicate<Action> conditionToSquashAction, Writer warnWriter, Writer infoWriter, Writer debugWriter, Writer traceWriter, Map<Action, Record> report, int forcePrintLevelForUnexercisedActions) { | |
29 | super(infoWriter); | |
30 | this.conditionToSquashAction = conditionToSquashAction; | |
31 | this.report = requireNonNull(report); | |
32 | this.warnWriter = requireNonNull(warnWriter); | |
33 | this.debugWriter = requireNonNull(debugWriter); | |
34 | this.infoWriter = infoWriter; | |
35 | this.traceWriter = traceWriter; | |
36 | this.forcePrintLevelForUnexercisedActions = forcePrintLevelForUnexercisedActions; | |
37 | } | |
38 | ||
39 | public ActionReporter(Writer writer, Map<Action, Record> report) { | |
40 | this(DEFAULT_CONDITION_TO_SQUASH_ACTION, writer, writer, writer, writer, report, 2); | |
41 | } | |
42 | ||
43 | public void report(Action action) { | |
44 |
1
1. report : removed call to com/github/dakusui/actionunit/core/Action::accept → KILLED |
requireNonNull(action).accept(this); |
45 | } | |
46 | ||
47 | @Override | |
48 | protected void handleAction(Action action) { | |
49 |
1
1. handleAction : negated conditional → KILLED |
if (this.conditionToSquashAction.test(action)) { |
50 | this.previousIndent = indent(); | |
51 | return; | |
52 | } | |
53 | Record runs = report.get(action); | |
54 |
1
1. handleAction : negated conditional → KILLED |
String message = format("%s[%s]%s", indent(), runs != null ? runs : "", action); |
55 | this.previousIndent = ""; | |
56 |
1
1. handleAction : negated conditional → SURVIVED |
if (isInFailingContext()) { |
57 |
1
1. handleAction : removed call to com/github/dakusui/actionunit/io/Writer::writeLine → KILLED |
this.warnWriter.writeLine(message); |
58 | } else { | |
59 |
2
1. handleAction : changed conditional boundary → SURVIVED 2. handleAction : negated conditional → SURVIVED |
if (emptyLevel < 1) { // Top level unexercised + exercised ones |
60 |
2
1. handleAction : changed conditional boundary → SURVIVED 2. handleAction : negated conditional → SURVIVED |
if (passingLevels() < 1) { |
61 |
1
1. handleAction : removed call to com/github/dakusui/actionunit/io/Writer::writeLine → KILLED |
this.infoWriter.writeLine(message); |
62 | } else { | |
63 |
1
1. handleAction : removed call to com/github/dakusui/actionunit/visitors/ActionReporter::writeLineForUnexercisedAction → KILLED |
writeLineForUnexercisedAction(message); |
64 | } | |
65 | } else { | |
66 |
1
1. handleAction : removed call to com/github/dakusui/actionunit/visitors/ActionReporter::writeLineForUnexercisedAction → KILLED |
writeLineForUnexercisedAction(message); |
67 | } | |
68 | } | |
69 | } | |
70 | ||
71 | String previousIndent = ""; | |
72 | ||
73 | /** | |
74 | * //@formatter.off | |
75 | * ---- | |
76 | * > [E:0]for each of (noname) parallely | |
77 | * > +-[EE:0]print1 | |
78 | * > | [EE:0](noname) | |
79 | * > +-[]print2 | |
80 | * > | [](noname) | |
81 | * > +-[]print2-1 | |
82 | * > | [](noname) | |
83 | * > +-[]print2-2 | |
84 | * > [](noname) | |
85 | * ---- | |
86 | * //@format:on | |
87 | */ | |
88 | @Override | |
89 | public String indent() { | |
90 | List<? extends Action> path = this.path(); | |
91 | StringBuilder b = new StringBuilder(); | |
92 |
1
1. indent : negated conditional → KILLED |
if (!path.isEmpty()) { |
93 |
1
1. indent : Replaced integer subtraction with addition → KILLED |
Action last = path.get(path.size() - 1); |
94 | for (Action each : path) { | |
95 |
1
1. indent : negated conditional → KILLED |
if (each instanceof Composite) { |
96 |
1
1. indent : negated conditional → KILLED |
if (each == last) { |
97 |
1
1. indent : negated conditional → KILLED |
if (((Composite) each).isParallel()) |
98 | b.append("*-"); | |
99 | else | |
100 | b.append("+-"); | |
101 | } else { | |
102 |
1
1. indent : negated conditional → KILLED |
if (isLastChild(nextOf(each, path), each)) |
103 | b.append(" "); | |
104 | else | |
105 | b.append("| "); | |
106 | } | |
107 | } else { | |
108 | b.append(" "); | |
109 | } | |
110 | } | |
111 | } | |
112 |
1
1. indent : replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionReporter::indent → KILLED |
return mergeStrings(this.previousIndent, b.toString()); |
113 | } | |
114 | ||
115 | private static Action nextOf(Action each, List<? extends Action> path) { | |
116 |
2
1. nextOf : Replaced integer addition with subtraction → KILLED 2. nextOf : replaced return value with null for com/github/dakusui/actionunit/visitors/ActionReporter::nextOf → KILLED |
return path.get(path.indexOf(each) + 1); |
117 | } | |
118 | ||
119 | /** | |
120 | * Merges two string into one. | |
121 | * A white space in `a` or `b` will be replaced with non-white space in the other at the same position. | |
122 | * In case both have non-white space in the same position, the latter's (`b`) overrides the first's (`a`). | |
123 | * <p> | |
124 | * .Example input | |
125 | * ---- | |
126 | * a:"hello " | |
127 | * b:" O WORLD " | |
128 | * ---- | |
129 | * <p> | |
130 | * .Example output | |
131 | * ---- | |
132 | * "hellO WORLD " | |
133 | * ---- | |
134 | * | |
135 | * @param a A string to be merged. | |
136 | * @param b A stringto be merged | |
137 | * @return The merged result string. | |
138 | */ | |
139 | private static String mergeStrings(String a, String b) { | |
140 | StringBuilder builder = new StringBuilder(); | |
141 | int min = Math.min(a.length(), b.length()); | |
142 |
3
1. mergeStrings : changed conditional boundary → KILLED 2. mergeStrings : Changed increment from 1 to -1 → KILLED 3. mergeStrings : negated conditional → KILLED |
for (int i = 0; i < min; i++) { |
143 | char ach = a.charAt(i); | |
144 | char bch = b.charAt(i); | |
145 |
1
1. mergeStrings : negated conditional → SURVIVED |
if (bch != ' ') |
146 | builder.append(bch); | |
147 | else | |
148 | builder.append(ach); | |
149 | } | |
150 | // Whichever longer, the result is the same since the shorter.substring(min) will become an empty | |
151 | // string. | |
152 | builder.append(a.substring(min)); | |
153 | builder.append(b.substring(min)); | |
154 |
1
1. mergeStrings : replaced return value with "" for com/github/dakusui/actionunit/visitors/ActionReporter::mergeStrings → KILLED |
return builder.toString(); |
155 | } | |
156 | ||
157 | private static boolean isLastChild(Action each, Action parent) { | |
158 |
1
1. isLastChild : negated conditional → KILLED |
if (parent instanceof Composite) { |
159 | int index = ((Composite) parent).children().indexOf(each); | |
160 | int size = ((Composite) parent).children().size(); | |
161 | assert index >= 0; | |
162 |
3
1. isLastChild : Replaced integer subtraction with addition → KILLED 2. isLastChild : negated conditional → KILLED 3. isLastChild : replaced boolean return with true for com/github/dakusui/actionunit/visitors/ActionReporter::isLastChild → KILLED |
return index == size - 1; |
163 | } | |
164 |
1
1. isLastChild : replaced boolean return with false for com/github/dakusui/actionunit/visitors/ActionReporter::isLastChild → NO_COVERAGE |
return true; |
165 | } | |
166 | ||
167 | private void writeLineForUnexercisedAction(String message) { | |
168 | // unexercised | |
169 |
2
1. writeLineForUnexercisedAction : changed conditional boundary → SURVIVED 2. writeLineForUnexercisedAction : negated conditional → SURVIVED |
if (depth < this.forcePrintLevelForUnexercisedActions) |
170 |
1
1. writeLineForUnexercisedAction : removed call to com/github/dakusui/actionunit/io/Writer::writeLine → KILLED |
this.debugWriter.writeLine(message); |
171 | else | |
172 |
1
1. writeLineForUnexercisedAction : removed call to com/github/dakusui/actionunit/io/Writer::writeLine → KILLED |
this.traceWriter.writeLine(message); |
173 | } | |
174 | ||
175 | private int passingLevels() { | |
176 | int ret = 0; | |
177 | for (boolean each : this.failingContext) | |
178 |
1
1. passingLevels : negated conditional → SURVIVED |
if (!each) |
179 |
1
1. passingLevels : Changed increment from 1 to -1 → SURVIVED |
ret++; |
180 |
1
1. passingLevels : replaced int return with 0 for com/github/dakusui/actionunit/visitors/ActionReporter::passingLevels → SURVIVED |
return ret; |
181 | } | |
182 | ||
183 | boolean isInFailingContext() { | |
184 |
3
1. isInFailingContext : negated conditional → SURVIVED 2. isInFailingContext : replaced boolean return with true for com/github/dakusui/actionunit/visitors/ActionReporter::isInFailingContext → SURVIVED 3. isInFailingContext : negated conditional → KILLED |
return !this.failingContext.isEmpty() && this.failingContext.get(0); |
185 | } | |
186 | ||
187 | void pushFailingContext(boolean newContext) { | |
188 |
1
1. pushFailingContext : removed call to java/util/List::add → KILLED |
failingContext.add(0, newContext); |
189 | } | |
190 | ||
191 | void popFailingContext() { | |
192 | failingContext.remove(0); | |
193 | } | |
194 | ||
195 | @Override | |
196 | protected void enter(Action action) { | |
197 |
1
1. enter : removed call to com/github/dakusui/actionunit/visitors/ActionPrinter::enter → KILLED |
super.enter(action); |
198 |
1
1. enter : Replaced integer addition with subtraction → SURVIVED |
depth++; |
199 | Record runs = report.get(action); | |
200 |
3
1. enter : negated conditional → SURVIVED 2. enter : negated conditional → KILLED 3. enter : removed call to com/github/dakusui/actionunit/visitors/ActionReporter::pushFailingContext → KILLED |
pushFailingContext(runs != null && runs.allFailing()); |
201 |
1
1. enter : negated conditional → SURVIVED |
if (runs == null) |
202 |
1
1. enter : Replaced integer addition with subtraction → SURVIVED |
emptyLevel++; |
203 | ||
204 | } | |
205 | ||
206 | @Override | |
207 | protected void leave(Action action) { | |
208 | Record runs = report.get(action); | |
209 |
1
1. leave : negated conditional → SURVIVED |
if (runs == null) |
210 |
1
1. leave : Replaced integer subtraction with addition → SURVIVED |
emptyLevel--; |
211 |
1
1. leave : removed call to com/github/dakusui/actionunit/visitors/ActionReporter::popFailingContext → SURVIVED |
popFailingContext(); |
212 |
1
1. leave : Replaced integer subtraction with addition → SURVIVED |
depth--; |
213 |
1
1. leave : removed call to com/github/dakusui/actionunit/visitors/ActionPrinter::leave → KILLED |
super.leave(action); |
214 | } | |
215 | /* | |
216 | [E:0]for each of (noname) parallely | |
217 | [EE:0]do sequentially | |
218 | | [EE:0]print | |
219 | | [EE:0](noname) | |
220 | | []print | |
221 | | [](noname) | |
222 | | :[]print | |
223 | : [](noname) | |
224 | :[]print | |
225 | : [](noname) | |
226 | ||
227 | : []parallel1 | |
228 | : | | []sequential(1.1) | |
229 | : | | []sequential(1.1) | |
230 | : | []sequential(2) | |
231 | : |[]sequential(1) | |
232 | : []parallel2 | |
233 | ||
234 | */ | |
235 | /* | |
236 | [E:0]do sequentially | |
237 | +-[E:0]do sequentially | |
238 | +-[E:0]do sequentially | |
239 | +-[E:0]print2-1 | |
240 | | [E:0](noname) | |
241 | +-[]print2-2 | |
242 | [](noname) | |
243 | ||
244 | | | |
245 | V | |
246 | ||
247 | +- | |
248 | +- | |
249 | +-[E:0]print2-1 | |
250 | | [E:0](noname) | |
251 | +-[]print2-2 | |
252 | [](noname) | |
253 | ||
254 | | | |
255 | V | |
256 | ||
257 | +-+-+-[E:0]print2-1 | |
258 | | [E:0](noname) | |
259 | +-[]print2-2 | |
260 | [](noname) | |
261 | ||
262 | */ | |
263 | } | |
Mutations | ||
16 |
1.1 2.2 |
|
44 |
1.1 |
|
49 |
1.1 |
|
54 |
1.1 |
|
56 |
1.1 |
|
57 |
1.1 |
|
59 |
1.1 2.2 |
|
60 |
1.1 2.2 |
|
61 |
1.1 |
|
63 |
1.1 |
|
66 |
1.1 |
|
92 |
1.1 |
|
93 |
1.1 |
|
95 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
102 |
1.1 |
|
112 |
1.1 |
|
116 |
1.1 2.2 |
|
142 |
1.1 2.2 3.3 |
|
145 |
1.1 |
|
154 |
1.1 |
|
158 |
1.1 |
|
162 |
1.1 2.2 3.3 |
|
164 |
1.1 |
|
169 |
1.1 2.2 |
|
170 |
1.1 |
|
172 |
1.1 |
|
178 |
1.1 |
|
179 |
1.1 |
|
180 |
1.1 |
|
184 |
1.1 2.2 3.3 |
|
188 |
1.1 |
|
197 |
1.1 |
|
198 |
1.1 |
|
200 |
1.1 2.2 3.3 |
|
201 |
1.1 |
|
202 |
1.1 |
|
209 |
1.1 |
|
210 |
1.1 |
|
211 |
1.1 |
|
212 |
1.1 |
|
213 |
1.1 |