Skip to content

Commit

Permalink
fix(solve-handler): Change .cast(..) onError param to BiFunction (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseLion authored Feb 13, 2024
1 parent 7c558f1 commit 75a1328
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
21 changes: 13 additions & 8 deletions src/main/java/io/github/joselion/maybe/SolveHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static java.util.Objects.isNull;

import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
Expand Down Expand Up @@ -458,23 +459,27 @@ public <U> SolveHandler<U, ClassCastException> cast(final Class<U> type) {
/**
* If the value is present, casts the value to the provided {@code type}
* class. If the value is not assignable to {@code type}, maps the error with
* the provided {@code onError} function, which receives the produced
* {@link ClassCastException} as input. If the error is present, returns a
* handler with the same error so it can be propagated downstream.
* the provided {@code onError} bi-function, which receives the value and the
* produced {@link ClassCastException} as inputs. If the error is present,
* returns a handler with the same error so it can be propagated downstream.
*
* @param <U> the type of the cast value
* @param <X> the type of the mapped exception
* @param type the class instance of the type to cast
* @param onError a function to map the error in case of failure
* @param onError a bi-function to map the error in case of failure
* @return a handler with either the cast value or the mapped error
*/
public <U, X extends Throwable> SolveHandler<U, X> cast(
final Class<U> type,
final Function<ClassCastException, ? extends X> onError
final BiFunction<? super T, ClassCastException, ? extends X> onError
) {
return this
.solve(type::cast)
.mapError(ClassCastException.class, onError);
return this.solve(prev -> {
try {
return type.cast(prev);
} catch (ClassCastException e) {
throw onError.apply(prev, e);
}
});
}

/**
Expand Down
14 changes: 8 additions & 6 deletions src/test/java/io/github/joselion/maybe/SolveHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static org.assertj.core.api.InstanceOfAssertFactories.THROWABLE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

Expand Down Expand Up @@ -649,7 +651,7 @@
@Nested class and_the_value_is_an_instance_of_the_type {
@Test void returns_a_handler_with_the_cast_value() {
final var anyValue = (Object) "Hello";
final var mapperSpy = Spy.function((ClassCastException e) -> new RuntimeException(e));
final var mapperSpy = Spy.biFunction((Object x, ClassCastException e) -> new RuntimeException(e));
final var handler = SolveHandler.from(anyValue);
final var overloads = List.of(
handler.cast(String.class),
Expand All @@ -661,7 +663,7 @@
assertThat(overload.error()).isEmpty();
});

verify(mapperSpy, never()).apply(any());
verify(mapperSpy, never()).apply(any(), any());
}
}

Expand All @@ -680,21 +682,21 @@

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

assertThat(handler.success()).isEmpty();
assertThat(handler.error()).contains(FAILURE);

verify(mapperSpy).apply(any(ClassCastException.class));
verify(mapperSpy).apply(eq(3), isA(ClassCastException.class));
}
}
}
}

@Nested class when_the_error_is_present {
@Test void returns_a_handler_with_the_error() {
final var mapperSpy = Spy.function((ClassCastException e) -> new RuntimeException(e));
final var mapperSpy = Spy.biFunction((Object x, ClassCastException e) -> new RuntimeException(e));
final var handler = SolveHandler.failure(FAILURE);
final var overloads = List.of(
handler.cast(String.class),
Expand All @@ -706,7 +708,7 @@
assertThat(overload.error()).get().isSameAs(FAILURE);
});

verify(mapperSpy, never()).apply(any());
verify(mapperSpy, never()).apply(any(), any());
}
}
}
Expand Down
18 changes: 16 additions & 2 deletions src/test/java/io/github/joselion/testing/Spy.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.mockito.AdditionalAnswers.delegatesTo;
import static org.mockito.Mockito.mock;

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
Expand Down Expand Up @@ -37,14 +38,27 @@ public static <T> T lambda(final T lambda) {
* Creates a spy of a generic {@link Function} interface.
*
* @param <T> the type of the input to the function
* @param <U> the type of the result of the function
* @param <R> the type of the result of the function
* @param function the function to spy on
* @return a spy of the provided function
*/
public static <T, U> Function<T, U> function(final Function<T, U> function) {
public static <T, R> Function<T, R> function(final Function<T, R> function) {
return lambda(function);
}

/**
* Creates a spy of a generic {@link BiFunction} interface.
*
* @param <T> the type of the first input to the function
* @param <U> the type of the second input to the function
* @param <R> the type of the result of the function
* @param biFunction the bi-function to spy on
* @return a spy of the provided function
*/
public static <T, U, R> BiFunction<T, U, R> biFunction(final BiFunction<T, U, R> biFunction) {
return lambda(biFunction);
}

/**
* Creates a spy of a generic {@link Consumer} interface.
*
Expand Down

0 comments on commit 75a1328

Please sign in to comment.