package com.github.jeysal.java.util.function;

import org.junit.Test;

import java.util.Optional;
import java.util.function.Function;

import static org.junit.gen5.api.Assertions.assertEquals;

/**
 * @author Tim Seckinger
 * @since 13.03.2016
 */
public class FunctionUtilsTest {

    @Test
    public void testFirstPresent() {
        assertEquals(Optional.of(1),
                FunctionUtils.firstPresent(
                        (Function<Object, Optional<Integer>>) o -> Optional.empty(),
                        (Function<Object, Optional<Integer>>) o -> Optional.of(1)
                ).apply(null)
        );
    }

    @Test
    public void testFirstPresentFirstMatch() {
        assertEquals(Optional.of(0),
                FunctionUtils.firstPresent(
                        (Function<Object, Optional<Integer>>) o -> Optional.of(0),
                        (Function<Object, Optional<Integer>>) o -> Optional.of(1)
                ).apply(null)
        );
    }

    @Test
    public void testFirstPresentNoMatch() {
        assertEquals(Optional.empty(),
                FunctionUtils.firstPresent(
                        (Function<Object, Optional<Integer>>) o -> Optional.empty(),
                        (Function<Object, Optional<Integer>>) o -> Optional.empty()
                ).apply(null)
        );
    }


    @Test
    public void testFirstPresentFallback() {
        assertEquals(1, FunctionUtils.firstPresent(
                (Function<Object, Integer>) o -> -1,
                o -> Optional.empty(),
                o -> Optional.of(1)
                ).apply(null)
        );
    }

    @Test
    public void testFirstPresentFallbackFirstMatch() {
        assertEquals(0, FunctionUtils.firstPresent(
                (Function<Object, Integer>) o -> -1,
                o -> Optional.of(0),
                o -> Optional.of(1)
                ).apply(null)
        );
    }

    @Test
    public void testFirstPresentFallbackNoMatch() {
        assertEquals(-1, FunctionUtils.firstPresent(
                (Function<Object, Integer>) o -> -1,
                o -> Optional.empty(),
                o -> Optional.empty()
                ).apply(null)
        );
    }

    @Test(expected = RuntimeException.class)
    public void testFirstPresentFallbackNull() {
        FunctionUtils.firstPresent(
                (Function<Object, Integer>) o -> null,
                o -> Optional.empty(),
                o -> Optional.empty()
        ).apply(null);
    }


    @Test
    public void testTrying() {
        assertEquals(Optional.of(1),
                FunctionUtils.trying(
                        o -> 1
                ).apply(null)
        );
    }

    @Test
    public void testTryingThrows() {
        assertEquals(Optional.empty(),
                FunctionUtils.trying(o -> {
                    throw new Exception();
                }).apply(null)
        );
    }

    @Test
    public void testTryingNull() {
        assertEquals(Optional.empty(),
                FunctionUtils.trying(
                        o -> null
                ).apply(null)
        );
    }

}

@@ -185,16 +185,66 @@
 tEquals;
+%0Aimport static org.junit.gen5.api.Assertions.fail;
 %0A%0A/**%0A *
@@ -3155,10 +3155,1245 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void testRethrowing() %7B%0A        assertEquals(1,%0A                FunctionUtils.rethrowing(%0A                        o -%3E 1%0A                ).apply(null)%0A        );%0A    %7D%0A%0A    @Test%0A    public void testRethrowingThrows() %7B%0A        try %7B%0A            FunctionUtils.rethrowing(o -%3E %7B%0A                throw new Exception(%22asdf%22);%0A            %7D).apply(null);%0A        %7D catch (RuntimeException e) %7B%0A            assertEquals(RuntimeException.class, e.getClass());%0A            assertEquals(Exception.class, e.getCause().getClass());%0A            assertEquals(%22asdf%22, e.getCause().getMessage());%0A            return;%0A        %7D%0A%0A        fail(%22Rethrowing function did not throw%22);%0A    %7D%0A%0A    @Test%0A    public void testRethrowingMapper() %7B%0A        try %7B%0A            FunctionUtils.rethrowing(o -%3E %7B%0A                throw new Exception(%22asdf%22);%0A            %7D, IllegalArgumentException::new).apply(null);%0A        %7D catch (RuntimeException e) %7B%0A            assertEquals(IllegalArgumentException.class, e.getClass());%0A            assertEquals(Exception.class, e.getCause().getClass());%0A            assertEquals(%22asdf%22, e.getCause().getMessage());%0A            return;%0A        %7D%0A%0A        fail(%22Rethrowing function did not throw%22);%0A    %7D%0A%0A
 %7D%0A

add FunctionUtils.rethrowing tests