1 | package com.github.dakusui.pcond.core; | |
2 | ||
3 | import com.github.dakusui.pcond.experimentals.currying.context.CurriedContext; | |
4 | ||
5 | import java.util.List; | |
6 | import java.util.Optional; | |
7 | import java.util.function.Function; | |
8 | import java.util.function.Predicate; | |
9 | import java.util.stream.Stream; | |
10 | ||
11 | /** | |
12 | * An interface that models "forms". | |
13 | * A form is a general idea that covers predicates, functions, and "special-forms". | |
14 | * | |
15 | * A simple form (such as one returned by {@link Predicate#isEqual(Object)}) is | |
16 | * modeled as and held by {@link Evaluable.LeafPred}. | |
17 | * The framework just delegates the evaluation to the object. | |
18 | * | |
19 | * However, for a form which has an internal structure, such as one returned by | |
20 | * {@link Predicate#and(Predicate)}, this approach doesn't work. | |
21 | * Because, in order to make the evaluation process visible and readable for human, | |
22 | * we need intermediate evaluation results. | |
23 | * | |
24 | * That is, when we evaluate a form `v != null && v.startsWith("hello")`, we want | |
25 | * information about which predicate was violated. | |
26 | * Just showing the actual value of `v` is not sufficient, because the `v` and the | |
27 | * predicates in the evaluation might have internal structures or logics that make | |
28 | * it difficult/impossible to infer which predicate is violated. | |
29 | * | |
30 | * @param <T> The type of the value evaluated by this object. | |
31 | */ | |
32 | public interface Evaluable<T> { | |
33 | /** | |
34 | * Performs an evaluation of the `evaluationContext` with a given `evaluator`. | |
35 | * | |
36 | * @param evaluableIo An execution occurrence of an evaluable. | |
37 | * @param evaluationContext An evaluation context. | |
38 | * @param evaluator An evaluator with which the `evaluationContext` is evaluated. | |
39 | */ | |
40 | <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator); | |
41 | ||
42 | default boolean isSquashable() { | |
43 |
1
1. isSquashable : replaced boolean return with true for com/github/dakusui/pcond/core/Evaluable::isSquashable → NO_COVERAGE |
return false; |
44 | } | |
45 | ||
46 | default Evaluable<T> makeTrivial() { | |
47 | throw new UnsupportedOperationException(); | |
48 | } | |
49 | ||
50 | /** | |
51 | * A base interface to model all the predicates in the model of the evaluation | |
52 | * framework. | |
53 | * | |
54 | * @param <T> The type of the value to be tested. | |
55 | */ | |
56 | interface Pred<T> extends Evaluable<T> { | |
57 | } | |
58 | ||
59 | /** | |
60 | * A base interface for conjunction (and) and disjunction (or) of predicates. | |
61 | * | |
62 | * @param <T> The type of the value to be evaluated. | |
63 | */ | |
64 | interface Composite<T> extends Pred<T> { | |
65 | /** | |
66 | * Returns the predicates with which the target value is evaluated. | |
67 | * | |
68 | * @return The list of the child predicates. | |
69 | */ | |
70 | List<Evaluable<T>> children(); | |
71 | ||
72 | /** | |
73 | * Returns `true` if the "shortcut" evaluation is enabled. | |
74 | * | |
75 | * Suppose you have a following predicate. | |
76 | * | |
77 | * ---- | |
78 | * a && b && c | |
79 | * ---- | |
80 | * | |
81 | * If the `a` results in `false`, the `b` and `c` doesn't need to be evaluated. | |
82 | * The optimization, where the evaluations for the `b` and `c` are skipped, | |
83 | * is called "shortcut". | |
84 | * | |
85 | * However, in the context of testing, sometimes we want to know the evaluation | |
86 | * results for the `b` and `c`. | |
87 | * Otherwise, we cannot avoid getting into a fail->fix->run->fail... loop, | |
88 | * sometimes. | |
89 | * | |
90 | * @return `true` if the "shortcut" evaluation is enabled. | |
91 | */ | |
92 | boolean shortcut(); | |
93 | ||
94 | @Override | |
95 | default boolean isSquashable() { | |
96 |
3
1. isSquashable : changed conditional boundary → NO_COVERAGE 2. isSquashable : negated conditional → NO_COVERAGE 3. isSquashable : replaced boolean return with true for com/github/dakusui/pcond/core/Evaluable$Composite::isSquashable → NO_COVERAGE |
return children().size() <= 1; |
97 | } | |
98 | } | |
99 | ||
100 | /** | |
101 | * An interface to model a conjunction (`and`, `&&`) predicate. | |
102 | * | |
103 | * @param <T> The type of the value to be evaluated. | |
104 | */ | |
105 | interface Conjunction<T> extends Composite<T> { | |
106 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
107 | @Override | |
108 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
109 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateConjunction → KILLED |
evaluator.evaluateConjunction((EvaluableIo<T, Conjunction<T>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
110 | } | |
111 | } | |
112 | ||
113 | /** | |
114 | * An interface to model a disjunction (`or`, `||`) predicate. | |
115 | * | |
116 | * @param <T> The type of the value to be evaluated. | |
117 | */ | |
118 | interface Disjunction<T> extends Composite<T> { | |
119 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
120 | @Override | |
121 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
122 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateDisjunction → KILLED |
evaluator.evaluateDisjunction((EvaluableIo<T, Disjunction<T>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
123 | } | |
124 | } | |
125 | ||
126 | /** | |
127 | * An interface to model a negation (`not`, `negate`, `!`) of a predicate. | |
128 | * | |
129 | * @param <T> The type of the value to be evaluated. | |
130 | */ | |
131 | interface Negation<T> extends Pred<T> { | |
132 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
133 | @Override | |
134 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
135 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateNegation → KILLED |
evaluator.evaluateNegation((EvaluableIo<T, Negation<T>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
136 | } | |
137 | ||
138 | /** | |
139 | * The predicate the negation is applied. | |
140 | * | |
141 | * @return A target predicate. | |
142 | */ | |
143 | Evaluable<T> target(); | |
144 | ||
145 | @Override | |
146 | default boolean isSquashable() { | |
147 |
1
1. isSquashable : replaced boolean return with false for com/github/dakusui/pcond/core/Evaluable$Negation::isSquashable → NO_COVERAGE |
return true; |
148 | } | |
149 | } | |
150 | ||
151 | /** | |
152 | * An interface to model a simple predicate in the evaluation framework. | |
153 | * | |
154 | * @param <T> The type of the value to be evaluated. | |
155 | */ | |
156 | interface LeafPred<T> extends Pred<T> { | |
157 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
158 | @Override | |
159 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
160 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateLeaf → KILLED |
evaluator.evaluateLeaf((EvaluableIo<T, LeafPred<T>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
161 | } | |
162 | ||
163 | /** | |
164 | * Returns an actual predicate modeled by this interface. | |
165 | * | |
166 | * @return The predicate modeled by this interface. | |
167 | */ | |
168 | Predicate<? super T> predicate(); | |
169 | } | |
170 | ||
171 | /** | |
172 | * An interface to model a predicate for {@link CurriedContext}. | |
173 | * | |
174 | * @see CurriedContext | |
175 | */ | |
176 | interface CurriedContextPred extends Pred<CurriedContext> { | |
177 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
178 | @Override | |
179 | default <O> void accept(EvaluableIo<CurriedContext, Evaluable<CurriedContext>, O> evaluableIo, EvaluationContext<CurriedContext> evaluationContext, Evaluator evaluator) { | |
180 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateCurriedContextPredicate → KILLED |
evaluator.evaluateCurriedContextPredicate((EvaluableIo<CurriedContext, CurriedContextPred, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
181 | } | |
182 | ||
183 | <T> Evaluable<T> enclosed(); | |
184 | ||
185 | int argIndex(); | |
186 | } | |
187 | ||
188 | /** | |
189 | * An interface to model a predicate for {@link Stream}. | |
190 | * | |
191 | * @param <E> The type of elements in the stream to be evaluated. | |
192 | */ | |
193 | interface StreamPred<E> extends Pred<Stream<E>> { | |
194 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
195 | @Override | |
196 | default <O> void accept(EvaluableIo<Stream<E>, Evaluable<Stream<E>>, O> evaluableIo, EvaluationContext<Stream<E>> evaluationContext, Evaluator evaluator) { | |
197 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateStreamPredicate → KILLED |
evaluator.evaluateStreamPredicate((EvaluableIo<Stream<E>, StreamPred<E>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
198 | } | |
199 | ||
200 | /** | |
201 | * Returns a default value returned as the entire result of this predicate. | |
202 | * The `value` is used when a "cut" happens. | |
203 | * | |
204 | * @return a default value to fallback of this object. | |
205 | */ | |
206 | boolean defaultValue(); | |
207 | ||
208 | /** | |
209 | * Returns an evaluable object which makes "cut" happen. | |
210 | * If the result of the evaluation of the returned object becomes equal to the | |
211 | * returned value of the {@link StreamPred#valueToCut()}, a "cut" will actually happen. | |
212 | * | |
213 | * @return An evaluable which triggers a "cut". | |
214 | */ | |
215 | Evaluable<E> cut(); | |
216 | ||
217 | /** | |
218 | * Returns a value to make a "cut" happen. | |
219 | * | |
220 | * A "cut" is a situation, where an evaluation process for the elements in the | |
221 | * stream is ended without reaching the last one. | |
222 | * This is necessary to model a functionalities of `Stream`, such as | |
223 | * `allMatch`, `noneMatch`, and `anyMatch`. | |
224 | * | |
225 | * @return value ( `true` / `false` ) to make a "cut" happen. | |
226 | */ | |
227 | boolean valueToCut(); | |
228 | ||
229 | /** | |
230 | * In order to generate an informative report, the framework needs information | |
231 | * about the expected value for each predicate. | |
232 | * | |
233 | * The "expected" value of a predicate can be different inside the tree of the `Evaluables`, | |
234 | * when a negation is used. | |
235 | * | |
236 | * If this `Evaluable` node requests to flip the expectation value under the node, | |
237 | * this method should return `true`. | |
238 | * | |
239 | * @return `true`, if the expectation flip is requested. | |
240 | */ | |
241 | default boolean requestExpectationFlip() { | |
242 |
1
1. requestExpectationFlip : replaced boolean return with true for com/github/dakusui/pcond/core/Evaluable$StreamPred::requestExpectationFlip → KILLED |
return false; |
243 | } } | |
244 | ||
245 | /** | |
246 | * An interface to model a "transforming predicate", which models the "transform and check" style of value validation. | |
247 | * The idea of the style is to first transform a value into a type, which is easy to read for human and to check for machine, such as list, integer, string, etc., in order to validate a value. | |
248 | * | |
249 | * @param <T> The type of the value to be evaluated. | |
250 | * @param <R> The type to which the value (`T`) is transformed and then tested. | |
251 | */ | |
252 | interface Transformation<T, R> extends Pred<T> { | |
253 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
254 | @Override | |
255 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
256 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateTransformation → KILLED |
evaluator.evaluateTransformation((EvaluableIo<T, Transformation<T, R>, Boolean>) (EvaluableIo) evaluableIo, evaluationContext); |
257 | } | |
258 | ||
259 | /** | |
260 | * Returns a transformer of this object. | |
261 | * | |
262 | * @return A transformer function. | |
263 | */ | |
264 | Evaluable<T> mapper(); | |
265 | ||
266 | Evaluable<R> checker(); | |
267 | ||
268 | /** | |
269 | * Returns a name of a transformer, if any. | |
270 | * | |
271 | * @return An optional to store a name of the transformer. | |
272 | */ | |
273 | Optional<String> mapperName(); | |
274 | ||
275 | /** | |
276 | * Returns a name of a checker, if any. | |
277 | * | |
278 | * @return An optional to store a name of the checker. | |
279 | */ | |
280 | Optional<String> checkerName(); | |
281 | } | |
282 | ||
283 | /** | |
284 | * An interface to model a function ({@link Function}) in the evaluation framework | |
285 | * of the `pcond`. | |
286 | * | |
287 | * @param <T> The type of the value to be evaluated. | |
288 | */ | |
289 | interface Func<T> extends Evaluable<T> { | |
290 | @SuppressWarnings({ "unchecked", "rawtypes" }) | |
291 | @Override | |
292 | default <O> void accept(EvaluableIo<T, Evaluable<T>, O> evaluableIo, EvaluationContext<T> evaluationContext, Evaluator evaluator) { | |
293 |
1
1. accept : removed call to com/github/dakusui/pcond/core/Evaluator::evaluateFunction → KILLED |
evaluator.evaluateFunction((EvaluableIo<T, Func<T>, O>) (EvaluableIo) evaluableIo, evaluationContext); |
294 | } | |
295 | ||
296 | Function<? super T, Object> head(); | |
297 | ||
298 | Optional<Evaluable<Object>> tail(); | |
299 | } | |
300 | } | |
Mutations | ||
43 |
1.1 |
|
96 |
1.1 2.2 3.3 |
|
109 |
1.1 |
|
122 |
1.1 |
|
135 |
1.1 |
|
147 |
1.1 |
|
160 |
1.1 |
|
180 |
1.1 |
|
197 |
1.1 |
|
242 |
1.1 |
|
256 |
1.1 |
|
293 |
1.1 |