ExceptionComposer.java

1
package com.github.dakusui.pcond.validator;
2
3
import com.github.dakusui.pcond.validator.exceptions.PostconditionViolationException;
4
import com.github.dakusui.pcond.validator.exceptions.PreconditionViolationException;
5
import com.github.dakusui.pcond.validator.exceptions.ValidationException;
6
7
import java.lang.reflect.InvocationTargetException;
8
9
import static com.github.dakusui.pcond.validator.ExceptionComposer.Utils.createException;
10
import static com.github.dakusui.pcond.validator.Explanation.reportToString;
11
12
/**
13
 * An interface to define how an exception is composed based on a given message,
14
 * a class of a condition that the value violates (non-null constraint, invalid state,
15
 * input validation), and the context the violation happened (pre-, post-condition check,
16
 * test-assertion, etc.).
17
 *
18
 * This interface has methods to return objects, each of which composes actual exceptions.
19
 * Each of them intended to group methods that compose exceptions for a single context.
20
 */
21
public interface ExceptionComposer {
22
  /**
23
   * Returns an instance to compose exceptions used with `requireXyz` methods in
24
   * {@code Requires} entry-point class of valid8j library.
25
   *
26
   * @return An object to compose exceptions for methods in {@code Requires}.
27
   */
28
  ForRequire forRequire();
29
30
  /**
31
   * Returns an instance to compose exceptions used with `ensureXyz` methods in
32
   * {@code Ensures} entry-point class of valid8j library.
33
   *
34
   * @return An object to compose exceptions for methods in {@code Ensures}.
35
   */
36
  ForEnsure forEnsure();
37
38
  /**
39
   * Returns an instance to compose exceptions used with `validateXyz` methods in
40
   * {@code Validates} entry-point class of valid8j library.
41
   *
42
   * @return An object to compose exceptions for methods in {@code Validates}.
43
   */
44
  ForValidate defaultForValidate();
45
46
  /**
47
   * Returns an instance to compose exceptions used in `assert` statements.
48
   *
49
   * @return An object to compose exceptions for "precondition" violation.
50
   */
51
  ForAssertion forAssert();
52
53
  /**
54
   * Returns an instance to compose exceptions used in `assertThat` and `assumeThat`
55
   * methods in {@code TestAssertions} entry-point class of thincrest library.
56
   * Other entry-point classes provided for use cases of the `pcond` library as
57
   * a test assertion library may also use this method.
58
   *
59
   * @return An object to compose exceptions for test assertions
60
   */
61
  ForTestAssertion forAssertThat();
62
63
  /**
64
   * An implementation of the {@link ExceptionComposer} interface.
65
   * You usually do not need to extend this method to customize its behavior.
66
   * Rather you only need to control the arguments passed to its constructor
67
   * through {@link Validator.Configuration.Builder}.
68
   *
69
   * @see Validator.Configuration
70
   * @see Validator.Configuration.Builder
71
   */
72
  class Impl implements ExceptionComposer {
73
    final private ForRequire       forRequire;
74
    final private ForEnsure        forEnsure;
75
    final private ForValidate      defaultForValidate;
76
    final private ForAssertion     forAssert;
77
    final private ForTestAssertion forAssertThat;
78
79
    public Impl(ForRequire forRequire, ForEnsure forEnsure, ForValidate defaultForValidate, ForAssertion forAssert, ForTestAssertion forAssertThat) {
80
      this.forRequire = forRequire;
81
      this.forEnsure = forEnsure;
82
      this.defaultForValidate = defaultForValidate;
83
      this.forAssert = forAssert;
84
      this.forAssertThat = forAssertThat;
85
    }
86
87
    @Override
88
    public ForRequire forRequire() {
89 1 1. forRequire : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forRequire → KILLED
      return this.forRequire;
90
    }
91
92
    @Override
93
    public ForEnsure forEnsure() {
94 1 1. forEnsure : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forEnsure → KILLED
      return this.forEnsure;
95
    }
96
97
    @Override
98
    public ForValidate defaultForValidate() {
99 1 1. defaultForValidate : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::defaultForValidate → SURVIVED
      return this.defaultForValidate;
100
    }
101
102
    @Override
103
    public ForAssertion forAssert() {
104 1 1. forAssert : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forAssert → KILLED
      return this.forAssert;
105
    }
106
107
    @Override
108
    public ForTestAssertion forAssertThat() {
109 1 1. forAssertThat : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forAssertThat → KILLED
      return this.forAssertThat;
110
    }
111
  }
112
113
  /**
114
   * An interface that defines common methods that an object returned by each method
115
   * in the {@link ExceptionComposer} has.
116
   */
117
  interface Base {
118
    /**
119
     * A method to compose an exception for a "Null-violation".
120
     * When you are checking a "pre-condition", if the value must not be `null`,
121
     * you may prefer a {@link NullPointerException}, rather than an exception
122
     * such as `YourPreconditionException` as Google Guava's `Precondition` does
123
     * so.
124
     *
125
     * This method by default, returns a `NullPointerException`.
126
     *
127
     * In case you prefer to throw `YourPreconditionException` for the sake of uniformity,
128
     * you can override this method for an object returned by {@link ExceptionComposer#forRequire()}
129
     *
130
     * For more detail, please refer to {@link Validator.Configuration}.
131
     *
132
     * @param message A message attached to the composed exception.
133
     * @return A composed exception.
134
     */
135
    default Throwable exceptionForNonNullViolation(String message) {
136 1 1. exceptionForNonNullViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Base::exceptionForNonNullViolation → SURVIVED
      return new NullPointerException(message);
137
    }
138
139
    /**
140
     * A method to compose an exception for a "State-violation".
141
     *
142
     * @param message A message attached to the composed exception.
143
     * @return A composed exception.
144
     * @see Base#exceptionForNonNullViolation(String)
145
     */
146
    default Throwable exceptionForIllegalState(String message) {
147 1 1. exceptionForIllegalState : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Base::exceptionForIllegalState → KILLED
      return new IllegalStateException(message);
148
    }
149
150
    /**
151
     * A method to compose an exception for a general violation.
152
     * An extension-point to customize the exception to be thrown for a certain
153
     * context.
154
     *
155
     * @param message A message attached to the composed exception.
156
     * @return A composed exception.
157
     */
158
    Throwable exceptionForGeneralViolation(String message);
159
  }
160
161
  interface ForRequire extends Base {
162
    @Override
163
    default Throwable exceptionForGeneralViolation(String message) {
164 1 1. exceptionForGeneralViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForRequire::exceptionForGeneralViolation → KILLED
      return new PreconditionViolationException(message);
165
    }
166
167
    Throwable exceptionForIllegalArgument(String message);
168
169
    @SuppressWarnings("unused") // Referenced reflectively
170
    class Default implements ForRequire {
171
      @Override
172
      public Throwable exceptionForIllegalArgument(String message) {
173 1 1. exceptionForIllegalArgument : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForRequire$Default::exceptionForIllegalArgument → KILLED
        return new IllegalArgumentException(message);
174
      }
175
    }
176
  }
177
178
  interface ForEnsure extends Base {
179
    @Override
180
    default Throwable exceptionForGeneralViolation(String message) {
181 1 1. exceptionForGeneralViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForEnsure::exceptionForGeneralViolation → KILLED
      return new PostconditionViolationException(message);
182
    }
183
184
    @SuppressWarnings("unused") // Referenced reflectively
185
    class Default implements ForEnsure {
186
    }
187
  }
188
189
  interface ForValidate extends Base {
190
    @Override
191
    default Throwable exceptionForGeneralViolation(String message) {
192 1 1. exceptionForGeneralViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForValidate::exceptionForGeneralViolation → KILLED
      return new ValidationException(message);
193
    }
194
195
    default Throwable exceptionForIllegalArgument(String message) {
196 1 1. exceptionForIllegalArgument : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForValidate::exceptionForIllegalArgument → KILLED
      return new IllegalArgumentException(message);
197
    }
198
199
    @SuppressWarnings("unused") // Referenced reflectively
200
    class Default implements ForValidate {
201
    }
202
  }
203
204
  interface ForAssertion {
205
    default Throwable exceptionPreconditionViolation(String message) {
206 1 1. exceptionPreconditionViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionPreconditionViolation → KILLED
      return new AssertionError(message);
207
    }
208
209
    default Throwable exceptionInvariantConditionViolation(String message) {
210 1 1. exceptionInvariantConditionViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionInvariantConditionViolation → KILLED
      return new AssertionError(message);
211
    }
212
213
    default Throwable exceptionPostconditionViolation(String message) {
214 1 1. exceptionPostconditionViolation : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionPostconditionViolation → KILLED
      return new AssertionError(message);
215
    }
216
217
    @SuppressWarnings("unused") // Referenced reflectively
218
    class Default implements ForAssertion {
219
    }
220
  }
221
222
  interface ForTestAssertion {
223
    <T extends RuntimeException> T testSkippedException(String message, ReportComposer reportComposer);
224
225
    default <T extends RuntimeException> T testSkippedException(Explanation explanation, ReportComposer reportComposer) {
226 1 1. testSkippedException : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion::testSkippedException → NO_COVERAGE
      return testSkippedException(explanation.toString(), reportComposer);
227
    }
228
229
    <T extends Error> T testFailedException(Explanation explanation, ReportComposer reportComposer);
230
231
    @SuppressWarnings("unused") // Referenced reflectively
232
    class JUnit4 implements ForTestAssertion {
233
      @SuppressWarnings("unchecked")
234
      @Override
235
      public <T extends RuntimeException> T testSkippedException(String message, ReportComposer reportComposer) {
236
        throw (T) createException(
237
            "org.junit.AssumptionViolatedException",
238
            reportComposer.explanationFromMessage(message),
239 1 1. lambda$testSkippedException$0 : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$JUnit4::lambda$testSkippedException$0 → KILLED
            (c, exp) -> c.getConstructor(String.class).newInstance(exp.message()));
240
      }
241
242
      @SuppressWarnings("unchecked")
243
      @Override
244
      public <T extends Error> T testFailedException(Explanation explanation, ReportComposer reportComposer) {
245
        throw (T) createException(
246
            "org.junit.ComparisonFailure",
247
            explanation,
248 1 1. lambda$testFailedException$1 : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$JUnit4::lambda$testFailedException$1 → KILLED
            (c, exp) -> c.getConstructor(String.class, String.class, String.class).newInstance(exp.message(), reportToString(exp.expected()), reportToString(exp.actual())));
249
      }
250
    }
251
252
    @SuppressWarnings("unused") // Referenced reflectively
253
    class Opentest4J implements ForTestAssertion {
254
      @SuppressWarnings("unchecked")
255
      @Override
256
      public <T extends RuntimeException> T testSkippedException(String message, ReportComposer reportComposer) {
257
        throw (T) createException("org.opentest4j.TestSkippedException", reportComposer.explanationFromMessage(message), (c, exp) ->
258 1 1. lambda$testSkippedException$0 : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$Opentest4J::lambda$testSkippedException$0 → KILLED
            c.getConstructor(String.class).newInstance(exp.message()));
259
      }
260
261
      @SuppressWarnings("unchecked")
262
      @Override
263
      public <T extends Error> T testFailedException(Explanation explanation, ReportComposer reportComposer) {
264
        throw (T) createException("org.opentest4j.AssertionFailedError", explanation, (c, exp) ->
265 1 1. lambda$testFailedException$1 : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$Opentest4J::lambda$testFailedException$1 → KILLED
            c.getConstructor(String.class, Object.class, Object.class).newInstance(exp.message(), reportToString(exp.expected()), reportToString(exp.actual())));
266
      }
267
    }
268
  }
269
270
  enum Utils {
271
    ;
272
273
    @SuppressWarnings("unchecked")
274
    public static <T extends Throwable> T createException(String className, Explanation explanation, ReflectiveExceptionFactory<T> reflectiveExceptionFactory) {
275
      try {
276 1 1. createException : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Utils::createException → KILLED
        return reflectiveExceptionFactory.apply((Class<T>) Class.forName(className), explanation);
277
      } catch (ClassNotFoundException e) {
278
        throw new RuntimeException("FAILED TO INSTANTIATE EXCEPTION: '" + className + "' (NOT FOUND)", e);
279
      }
280
    }
281
282
    @FunctionalInterface
283
    public
284
    interface ReflectiveExceptionFactory<T extends Throwable> {
285
      T create(Class<T> c, Explanation explanation) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException;
286
287
      default T apply(Class<T> c, Explanation explanation) {
288
        try {
289 1 1. apply : replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Utils$ReflectiveExceptionFactory::apply → KILLED
          return create(c, explanation);
290
        } catch (InvocationTargetException | InstantiationException |
291
            IllegalAccessException | NoSuchMethodException e) {
292
          throw new RuntimeException("FAILED TO INSTANTIATE EXCEPTION: '" + c.getCanonicalName() + "'", e);
293
        }
294
      }
295
    }
296
  }
297
}

Mutations

89

1.1
Location : forRequire
Killed by : com.github.dakusui.pcond.ut.valuechecker.DefaultValidatorTest.withEvaluator_nativePredicate(com.github.dakusui.pcond.ut.valuechecker.DefaultValidatorTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forRequire → KILLED

94

1.1
Location : forEnsure
Killed by : com.github.dakusui.ut.valid8j.ut.styles.FluentStyleDbCTest$ForEnsuresTest.ensureState_passing(com.github.dakusui.ut.valid8j.ut.styles.FluentStyleDbCTest$ForEnsuresTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forEnsure → KILLED

99

1.1
Location : defaultForValidate
Killed by : none
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::defaultForValidate → SURVIVED

104

1.1
Location : forAssert
Killed by : com.github.dakusui.ut.valid8j.ut.AssertionsTest$Failing
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forAssert → KILLED

109

1.1
Location : forAssertThat
Killed by : com.github.dakusui.ut.thincrest.ut.FluentUtilsTest.example2(com.github.dakusui.ut.thincrest.ut.FluentUtilsTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Impl::forAssertThat → KILLED

136

1.1
Location : exceptionForNonNullViolation
Killed by : none
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Base::exceptionForNonNullViolation → SURVIVED

147

1.1
Location : exceptionForIllegalState
Killed by : com.github.dakusui.ut.valid8j.ut.EnsuresTest
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Base::exceptionForIllegalState → KILLED

164

1.1
Location : exceptionForGeneralViolation
Killed by : com.github.dakusui.ut.valid8j.ut.RequiresTest
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForRequire::exceptionForGeneralViolation → KILLED

173

1.1
Location : exceptionForIllegalArgument
Killed by : com.github.dakusui.pcond.ut.valuechecker.DefaultValidatorTest.withoutEvaluator_conj_thenFail(com.github.dakusui.pcond.ut.valuechecker.DefaultValidatorTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForRequire$Default::exceptionForIllegalArgument → KILLED

181

1.1
Location : exceptionForGeneralViolation
Killed by : com.github.dakusui.ut.valid8j.ut.EnsuresTest
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForEnsure::exceptionForGeneralViolation → KILLED

192

1.1
Location : exceptionForGeneralViolation
Killed by : com.github.dakusui.ut.valid8j.ut.ValidatesTest.test_validate_fail(com.github.dakusui.ut.valid8j.ut.ValidatesTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForValidate::exceptionForGeneralViolation → KILLED

196

1.1
Location : exceptionForIllegalArgument
Killed by : com.github.dakusui.ut.valid8j.ut.ValidatesTest.test_validateArgument_fail(com.github.dakusui.ut.valid8j.ut.ValidatesTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForValidate::exceptionForIllegalArgument → KILLED

206

1.1
Location : exceptionPreconditionViolation
Killed by : com.github.dakusui.ut.valid8j.ut.AssertionsTest$Failing
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionPreconditionViolation → KILLED

210

1.1
Location : exceptionInvariantConditionViolation
Killed by : com.github.dakusui.ut.valid8j.ut.AssertionsTest$Failing
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionInvariantConditionViolation → KILLED

214

1.1
Location : exceptionPostconditionViolation
Killed by : com.github.dakusui.ut.valid8j.ut.AssertionsTest$Failing
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForAssertion::exceptionPostconditionViolation → KILLED

226

1.1
Location : testSkippedException
Killed by : none
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion::testSkippedException → NO_COVERAGE

239

1.1
Location : lambda$testSkippedException$0
Killed by : com.github.dakusui.ut.thincrest.ut.TestAssertionsTest.testAssumeThat(com.github.dakusui.ut.thincrest.ut.TestAssertionsTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$JUnit4::lambda$testSkippedException$0 → KILLED

248

1.1
Location : lambda$testFailedException$1
Killed by : com.github.dakusui.ut.thincrest.ut.FluentUtilsTest.example2(com.github.dakusui.ut.thincrest.ut.FluentUtilsTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$JUnit4::lambda$testFailedException$1 → KILLED

258

1.1
Location : lambda$testSkippedException$0
Killed by : com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest.test_testSkippedException$String(com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$Opentest4J::lambda$testSkippedException$0 → KILLED

265

1.1
Location : lambda$testFailedException$1
Killed by : com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest.test_testFailedException(com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$ForTestAssertion$Opentest4J::lambda$testFailedException$1 → KILLED

276

1.1
Location : createException
Killed by : com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest.test_testSkippedException$String(com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Utils::createException → KILLED

289

1.1
Location : apply
Killed by : com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest.test_testSkippedException$String(com.github.dakusui.pcond.ut.valuechecker.Opentest4jTest)
replaced return value with null for com/github/dakusui/pcond/validator/ExceptionComposer$Utils$ReflectiveExceptionFactory::apply → KILLED

Active mutators

Tests examined


Report generated by PIT 1.7.3