Skip to content

Commit 75a1328

Browse files
authored
fix(solve-handler): Change .cast(..) onError param to BiFunction (#240)
1 parent 7c558f1 commit 75a1328

File tree

3 files changed

+37
-16
lines changed

3 files changed

+37
-16
lines changed

src/main/java/io/github/joselion/maybe/SolveHandler.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static java.util.Objects.isNull;
44

55
import java.util.Optional;
6+
import java.util.function.BiFunction;
67
import java.util.function.Consumer;
78
import java.util.function.Function;
89
import java.util.function.Predicate;
@@ -458,23 +459,27 @@ public <U> SolveHandler<U, ClassCastException> cast(final Class<U> type) {
458459
/**
459460
* If the value is present, casts the value to the provided {@code type}
460461
* class. If the value is not assignable to {@code type}, maps the error with
461-
* the provided {@code onError} function, which receives the produced
462-
* {@link ClassCastException} as input. If the error is present, returns a
463-
* handler with the same error so it can be propagated downstream.
462+
* the provided {@code onError} bi-function, which receives the value and the
463+
* produced {@link ClassCastException} as inputs. If the error is present,
464+
* returns a handler with the same error so it can be propagated downstream.
464465
*
465466
* @param <U> the type of the cast value
466467
* @param <X> the type of the mapped exception
467468
* @param type the class instance of the type to cast
468-
* @param onError a function to map the error in case of failure
469+
* @param onError a bi-function to map the error in case of failure
469470
* @return a handler with either the cast value or the mapped error
470471
*/
471472
public <U, X extends Throwable> SolveHandler<U, X> cast(
472473
final Class<U> type,
473-
final Function<ClassCastException, ? extends X> onError
474+
final BiFunction<? super T, ClassCastException, ? extends X> onError
474475
) {
475-
return this
476-
.solve(type::cast)
477-
.mapError(ClassCastException.class, onError);
476+
return this.solve(prev -> {
477+
try {
478+
return type.cast(prev);
479+
} catch (ClassCastException e) {
480+
throw onError.apply(prev, e);
481+
}
482+
});
478483
}
479484

480485
/**

src/test/java/io/github/joselion/maybe/SolveHandlerTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import static org.assertj.core.api.InstanceOfAssertFactories.THROWABLE;
77
import static org.mockito.ArgumentMatchers.any;
88
import static org.mockito.ArgumentMatchers.anyString;
9+
import static org.mockito.ArgumentMatchers.eq;
10+
import static org.mockito.ArgumentMatchers.isA;
911
import static org.mockito.Mockito.never;
1012
import static org.mockito.Mockito.verify;
1113

@@ -649,7 +651,7 @@
649651
@Nested class and_the_value_is_an_instance_of_the_type {
650652
@Test void returns_a_handler_with_the_cast_value() {
651653
final var anyValue = (Object) "Hello";
652-
final var mapperSpy = Spy.function((ClassCastException e) -> new RuntimeException(e));
654+
final var mapperSpy = Spy.biFunction((Object x, ClassCastException e) -> new RuntimeException(e));
653655
final var handler = SolveHandler.from(anyValue);
654656
final var overloads = List.of(
655657
handler.cast(String.class),
@@ -661,7 +663,7 @@
661663
assertThat(overload.error()).isEmpty();
662664
});
663665

664-
verify(mapperSpy, never()).apply(any());
666+
verify(mapperSpy, never()).apply(any(), any());
665667
}
666668
}
667669

@@ -680,21 +682,21 @@
680682

681683
@Nested class and_the_error_mapper_is_provided {
682684
@Test void returns_a_handler_with_the_mapped_error() {
683-
final var mapperSpy = Spy.function((ClassCastException e) -> FAILURE);
685+
final var mapperSpy = Spy.biFunction((Integer x, ClassCastException e) -> FAILURE);
684686
final var handler = SolveHandler.from(3).cast(String.class, mapperSpy);
685687

686688
assertThat(handler.success()).isEmpty();
687689
assertThat(handler.error()).contains(FAILURE);
688690

689-
verify(mapperSpy).apply(any(ClassCastException.class));
691+
verify(mapperSpy).apply(eq(3), isA(ClassCastException.class));
690692
}
691693
}
692694
}
693695
}
694696

695697
@Nested class when_the_error_is_present {
696698
@Test void returns_a_handler_with_the_error() {
697-
final var mapperSpy = Spy.function((ClassCastException e) -> new RuntimeException(e));
699+
final var mapperSpy = Spy.biFunction((Object x, ClassCastException e) -> new RuntimeException(e));
698700
final var handler = SolveHandler.failure(FAILURE);
699701
final var overloads = List.of(
700702
handler.cast(String.class),
@@ -706,7 +708,7 @@
706708
assertThat(overload.error()).get().isSameAs(FAILURE);
707709
});
708710

709-
verify(mapperSpy, never()).apply(any());
711+
verify(mapperSpy, never()).apply(any(), any());
710712
}
711713
}
712714
}

src/test/java/io/github/joselion/testing/Spy.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.mockito.AdditionalAnswers.delegatesTo;
44
import static org.mockito.Mockito.mock;
55

6+
import java.util.function.BiFunction;
67
import java.util.function.Consumer;
78
import java.util.function.Function;
89
import java.util.function.Supplier;
@@ -37,14 +38,27 @@ public static <T> T lambda(final T lambda) {
3738
* Creates a spy of a generic {@link Function} interface.
3839
*
3940
* @param <T> the type of the input to the function
40-
* @param <U> the type of the result of the function
41+
* @param <R> the type of the result of the function
4142
* @param function the function to spy on
4243
* @return a spy of the provided function
4344
*/
44-
public static <T, U> Function<T, U> function(final Function<T, U> function) {
45+
public static <T, R> Function<T, R> function(final Function<T, R> function) {
4546
return lambda(function);
4647
}
4748

49+
/**
50+
* Creates a spy of a generic {@link BiFunction} interface.
51+
*
52+
* @param <T> the type of the first input to the function
53+
* @param <U> the type of the second input to the function
54+
* @param <R> the type of the result of the function
55+
* @param biFunction the bi-function to spy on
56+
* @return a spy of the provided function
57+
*/
58+
public static <T, U, R> BiFunction<T, U, R> biFunction(final BiFunction<T, U, R> biFunction) {
59+
return lambda(biFunction);
60+
}
61+
4862
/**
4963
* Creates a spy of a generic {@link Consumer} interface.
5064
*

0 commit comments

Comments
 (0)