Skip to content

Commit 2d78831

Browse files
refactor: Add Result.fromExc, 'fix' coverage
1 parent ae7b7cd commit 2d78831

3 files changed

Lines changed: 65 additions & 12 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package net.marcellperger.mathexpr.util;
2+
3+
public @interface JacocoIgnoreNotGenerated {
4+
}

src/main/java/net/marcellperger/mathexpr/util/rs/Result.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.marcellperger.mathexpr.util.rs;
22

3+
import net.marcellperger.mathexpr.util.JacocoIgnoreNotGenerated;
34
import net.marcellperger.mathexpr.util.ThrowingSupplier;
45
import net.marcellperger.mathexpr.util.Util;
56
import org.jetbrains.annotations.NotNull;
@@ -52,17 +53,30 @@ static <T, E> Result<T, E> newErr(E err) {
5253
return new Err<>(err);
5354
}
5455

56+
/** Same as fromExc but also fills in the stack trace using
57+
* {@link Throwable#fillInStackTrace()} for more useful error messages */
58+
static <T, E extends Throwable> @NotNull Result<T, E> fromExc(@NotNull E exc) {
59+
exc.fillInStackTrace();
60+
return newErr(exc);
61+
}
62+
5563
static <T, E extends Throwable> Result<T, E> fromTry(ThrowingSupplier<? extends T, E> inner, Class<E> catchThis) {
5664
try {
5765
return newOk(inner.get());
5866
} catch (Throwable exc) {
59-
try {
60-
return newErr(catchThis.cast(exc));
61-
} catch (ClassCastException c) {
62-
// We've handled E, so only unchecked exceptions should reach here
63-
// so it's safe to throw them (but Java doesn't know that so we trick it)
64-
return Util.throwAsUnchecked(exc);
65-
}
67+
return _makeErrTypeOrFailUnchecked(exc, catchThis);
68+
}
69+
}
70+
71+
@NotNull
72+
@JacocoIgnoreNotGenerated
73+
private static <T, E extends Throwable> Result<T, E> _makeErrTypeOrFailUnchecked(Throwable exc, Class<E> catchThis) {
74+
try {
75+
return newErr(catchThis.cast(exc));
76+
} catch (ClassCastException c) {
77+
// We've handled E, so only unchecked exceptions should reach here
78+
// so it's safe to throw them (but Java doesn't know that so we trick it)
79+
return Util.throwAsUnchecked(exc); // Jacoco doesn't realize that the `return` is unreachable
6680
}
6781
}
6882

src/test/java/net/marcellperger/mathexpr/util/rs/ResultTest.java

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
import net.marcellperger.mathexpr.util.rs.Result.Ok;
55
import org.junit.jupiter.api.Test;
66

7-
import java.util.ArrayList;
8-
import java.util.Iterator;
9-
import java.util.List;
10-
import java.util.Optional;
7+
import java.util.*;
118

129
import static net.marcellperger.mathexpr.MiniMock.*;
1310
import static org.junit.jupiter.api.Assertions.*;
@@ -479,4 +476,42 @@ public UnexpectedCheckedCustomException(String message) {
479476
super(message);
480477
}
481478
}
482-
}
479+
480+
@Test
481+
void fromExc() {
482+
CheckedCustomException cce = new CheckedCustomException("Message");
483+
Result<Object, CheckedCustomException> result = inner0(cce);
484+
CheckedCustomException cceOut = result.expectErr("fromExc() didn't return Err value");
485+
assertEquals(cce, cceOut);
486+
487+
StackTraceElement currFrame = getCurrentStack();
488+
List<StackTraceElement> st = Arrays.stream(cceOut.getStackTrace())
489+
.filter(f -> f.getClassName().equals(currFrame.getClassName()))
490+
.filter(f -> Objects.equals(f.getFileName(), currFrame.getFileName()))
491+
.filter(f -> Objects.equals(f.getModuleName(), currFrame.getModuleName()))
492+
.filter(f -> Objects.equals(f.getModuleVersion(), currFrame.getModuleVersion()))
493+
.filter(f -> Objects.equals(f.getClassLoaderName(), currFrame.getClassLoaderName()))
494+
.toList();
495+
List<StackTraceElement> i0 = st.stream()
496+
.filter(f -> f.getMethodName().equals("inner0"))
497+
.toList();
498+
assertEquals(1, i0.size(), "Expected exactly 1 inner0 frame");
499+
List<StackTraceElement> i1 = st.stream()
500+
.filter(f -> f.getMethodName().equals("inner0"))
501+
.toList();
502+
assertEquals(1, i1.size(), "Expected exactly 1 inner1 frame");
503+
}
504+
505+
private StackTraceElement getCurrentStack() {
506+
return StackWalker.getInstance()
507+
.walk(s -> /*Skip this methods*/s.skip(1).findFirst())
508+
.orElseThrow().toStackTraceElement();
509+
}
510+
511+
private Result<Object, CheckedCustomException> inner0(CheckedCustomException exc) {
512+
return inner1(exc);
513+
}
514+
private Result<Object, CheckedCustomException> inner1(CheckedCustomException exc) {
515+
return Result.fromExc(exc);
516+
}
517+
}

0 commit comments

Comments
 (0)