/* __ __ __ __ __ ___
* \ \ / / \ \ / / __/
* \ \/ / /\ \ \/ / /
* \____/__/ \__\____/__/.ɪᴏ
* ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
*/
package io.vavr;
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*\
G E N E R A T O R C R A F T E D
\*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
import static org.assertj.core.api.Assertions.assertThat;
import io.vavr.control.Try;
import java.lang.CharSequence;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
public class CheckedFunction0Test {
@Test
public void shouldCreateFromMethodReference() {
class Type {
Object methodReference() {
return null;
}
}
final Type type = new Type();
assertThat(CheckedFunction0.of(type::methodReference)).isNotNull();
}
@Test
public void shouldLiftPartialFunction() {
assertThat(CheckedFunction0.lift(() -> { while(true); })).isNotNull();
}
@Test
public void shouldGetArity() {
final CheckedFunction0<Object> f = () -> null;
assertThat(f.arity()).isEqualTo(0);
}
@Test
public void shouldConstant() throws Throwable {
final CheckedFunction0<Object> f = CheckedFunction0.constant(6);
assertThat(f.apply()).isEqualTo(6);
}
@Test
public void shouldCurry() {
final CheckedFunction0<Object> f = () -> null;
final CheckedFunction0<Object> curried = f.curried();
assertThat(curried).isNotNull();
}
@Test
public void shouldTuple() {
final CheckedFunction0<Object> f = () -> null;
final CheckedFunction1<Tuple0, Object> tupled = f.tupled();
assertThat(tupled).isNotNull();
}
@Test
public void shouldReverse() {
final CheckedFunction0<Object> f = () -> null;
assertThat(f.reversed()).isNotNull();
}
@Test
public void shouldMemoize() throws Throwable {
final AtomicInteger integer = new AtomicInteger();
final CheckedFunction0<Integer> f = () -> integer.getAndIncrement();
final CheckedFunction0<Integer> memo = f.memoized();
// should apply f on first apply()
final int expected = memo.apply();
// should return memoized value of second apply()
assertThat(memo.apply()).isEqualTo(expected);
}
@Test
public void shouldNotMemoizeAlreadyMemoizedFunction() throws Throwable {
final CheckedFunction0<Integer> f = () -> null;
final CheckedFunction0<Integer> memo = f.memoized();
assertThat(memo.memoized() == memo).isTrue();
}
@Test
public void shouldRecognizeMemoizedFunctions() {
final CheckedFunction0<Integer> f = () -> null;
final CheckedFunction0<Integer> memo = f.memoized();
assertThat(f.isMemoized()).isFalse();
assertThat(memo.isMemoized()).isTrue();
}
@Test
public void shouldRecover() {
final AtomicInteger integer = new AtomicInteger();
CheckedFunction0<MessageDigest> digest = () -> MessageDigest.getInstance(integer.get() == 0 ? "MD5" : "Unknown");
Function0<MessageDigest> recover = digest.recover(throwable -> () -> null);
MessageDigest md5 = recover.apply();
assertThat(md5).isNotNull();
assertThat(md5.getAlgorithm()).isEqualToIgnoringCase("MD5");
assertThat(md5.getDigestLength()).isEqualTo(16);
integer.incrementAndGet();
assertThat(recover.apply()).isNull();
}
@Test
public void shouldRecoverNonNull() {
final AtomicInteger integer = new AtomicInteger();
CheckedFunction0<MessageDigest> digest = () -> MessageDigest.getInstance(integer.get() == 0 ? "MD5" : "Unknown");
Function0<MessageDigest> recover = digest.recover(throwable -> null);
MessageDigest md5 = recover.apply();
assertThat(md5).isNotNull();
assertThat(md5.getAlgorithm()).isEqualToIgnoringCase("MD5");
assertThat(md5.getDigestLength()).isEqualTo(16);
integer.incrementAndGet();
Try<MessageDigest> unknown = Function0.liftTry(recover).apply();
assertThat(unknown).isNotNull();
assertThat(unknown.isFailure()).isTrue();
assertThat(unknown.getCause()).isNotNull().isInstanceOf(NullPointerException.class);
assertThat(unknown.getCause().getMessage()).isNotEmpty().isEqualToIgnoringCase("recover return null for class java.security.NoSuchAlgorithmException: Unknown MessageDigest not available");
}
@Test
public void shouldUncheckedWork() {
CheckedFunction0<MessageDigest> digest = () -> MessageDigest.getInstance("MD5");
Function0<MessageDigest> unchecked = digest.unchecked();
MessageDigest md5 = unchecked.apply();
assertThat(md5).isNotNull();
assertThat(md5.getAlgorithm()).isEqualToIgnoringCase("MD5");
assertThat(md5.getDigestLength()).isEqualTo(16);
}
@Test(expected = NoSuchAlgorithmException.class)
public void shouldThrowCheckedExceptionWhenUnchecked() {
CheckedFunction0<MessageDigest> digest = () -> MessageDigest.getInstance("Unknown");
Function0<MessageDigest> unchecked = digest.unchecked();
unchecked.apply(); // Look ma, we throw an undeclared checked exception!
}
@Test
public void shouldLiftTryPartialFunction() {
final AtomicInteger integer = new AtomicInteger();
CheckedFunction0<MessageDigest> digest = () -> MessageDigest.getInstance(integer.get() == 0 ? "MD5" : "Unknown");
Function0<Try<MessageDigest>> liftTry = CheckedFunction0.liftTry(digest);
Try<MessageDigest> md5 = liftTry.apply();
assertThat(md5.isSuccess()).isTrue();
assertThat(md5.get()).isNotNull();
assertThat(md5.get().getAlgorithm()).isEqualToIgnoringCase("MD5");
assertThat(md5.get().getDigestLength()).isEqualTo(16);
integer.incrementAndGet();
Try<MessageDigest> unknown = liftTry.apply();
assertThat(unknown.isFailure()).isTrue();
assertThat(unknown.getCause()).isNotNull();
assertThat(unknown.getCause().getMessage()).isEqualToIgnoringCase("Unknown MessageDigest not available");
}
private static final CheckedFunction0<Integer> recurrent1 = () -> 11;
@Test
public void shouldCalculatedRecursively() throws Throwable {
assertThat(recurrent1.apply()).isEqualTo(11);
}
@Test
public void shouldComposeWithAndThen() {
final CheckedFunction0<Object> f = () -> null;
final CheckedFunction1<Object, Object> after = o -> null;
final CheckedFunction0<Object> composed = f.andThen(after);
assertThat(composed).isNotNull();
}
@Test
public void shouldNarrow() throws Throwable{
final CheckedFunction0<String> wideFunction = () -> "Zero args";
final CheckedFunction0<CharSequence> narrowFunction = CheckedFunction0.narrow(wideFunction);
assertThat(narrowFunction.apply()).isEqualTo("Zero args");
}
}