Skip to content

Commit

Permalink
Closes #29 - shh for Runnable
Browse files Browse the repository at this point in the history
- There is a shh method taking AnnoyingRunnable then returns Runner so that any nullary function case can be solved.
  • Loading branch information
kevin-lee committed Nov 16, 2019
1 parent 9887a15 commit 91deb15
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/main/java/j8plus/types/Runner.java
Expand Up @@ -22,7 +22,7 @@
* @version 0.0.1 (2014-06-30)
*/
@FunctionalInterface
public interface Runner {
public interface Runner extends Runnable {
void run();

/**
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/j8plus/types/annoying/AnnoyingFuns.java
Expand Up @@ -15,6 +15,8 @@
*/
package j8plus.types.annoying;

import j8plus.types.Runner;

import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
Expand Down Expand Up @@ -98,4 +100,16 @@ public static <T, U, R> BiFunction<T, U, R> shh(final AnnoyingBiFunction<T, U, R
}
};
}

public static Runner shh(final AnnoyingRunnable annoyingRunnable) {
Objects.requireNonNull(annoyingRunnable, "The given AnnoyingRunner cannot be null.");
return () -> {
try {
annoyingRunnable.run();
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}

}
22 changes: 22 additions & 0 deletions src/main/java/j8plus/types/annoying/AnnoyingRunnable.java
@@ -0,0 +1,22 @@
package j8plus.types.annoying;

/**
* @author Kevin Lee
* @since 2017-06-10
*/
@FunctionalInterface
public interface AnnoyingRunnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
* @throws Exception
*/
void run() throws Exception;
}
31 changes: 31 additions & 0 deletions src/main/java/j8plus/types/annoying/AnnoyingRunner.java
@@ -0,0 +1,31 @@
package j8plus.types.annoying;

import java.util.Objects;

/**
* @author Kevin Lee
* @since 2017-06-10
*/
@FunctionalInterface
public interface AnnoyingRunner extends AnnoyingRunnable {
void run() throws Exception;

/**
* Returns a composed {@code Consumer} that performs, in sequence, this operation followed by the {@code after}
* operation. If performing either operation throws an exception, it is relayed to the caller of the composed
* operation. If performing this operation throws an exception, the {@code after} operation will not be performed.
*
* @param after
* the operation to perform after this operation
* @return a composed {@code Runner} that performs in sequence this operation followed by the {@code after} operation
* @throws NullPointerException
* if {@code after} is null
*/
default AnnoyingRunner andThen(final AnnoyingRunner after) {
Objects.requireNonNull(after);
return () -> {
run();
after.run();
};
}
}
4 changes: 2 additions & 2 deletions src/test/java/j8plus/types/Function3Test.java
Expand Up @@ -39,10 +39,10 @@ public void testAndThen() throws Exception {
test("Function3.andThen(Function)", "f3.andThen(f) should apply f3.apply(p1, p2, p3) then f.apply(f3Result). \n" +
"In other words, f3.andThen(f) == f(f3(p1, p2, p3))")
.when(() ->
first.andThen(second).apply(input1, input2, input3)
first.andThen(second).apply(input1, input2, input3)
)
.then(actual ->
assertThat(actual).isEqualTo(second.apply(first.apply(input1, input2, input3)))
assertThat(actual).isEqualTo(second.apply(first.apply(input1, input2, input3)))
);
}
}
4 changes: 2 additions & 2 deletions src/test/java/j8plus/types/Function6Test.java
Expand Up @@ -20,10 +20,10 @@ public void testCurried() {
(t1, t2, t3, t4, t5, t6) -> t1 + t2 + t3 + t4 + t5 + t6;
test("Function6.curried", "curried should return Function5 and t1 is already set in the function")
.when(() ->
function.curried(1)
function.curried(1)
)
.then(actual ->
assertThat(actual.apply(10, 100, 1_000, 10_000, 100_000)).isEqualTo(111_111)
assertThat(actual.apply(10, 100, 1_000, 10_000, 100_000)).isEqualTo(111_111)
);
}

Expand Down
1 change: 0 additions & 1 deletion src/test/java/j8plus/types/Predicate10Test.java
Expand Up @@ -6,7 +6,6 @@
import static kevinlee.testosterone.Testosterone.*;
import static org.assertj.core.api.Assertions.*;


/**
* @author Lee, Seong Hyun (Kevin)
* @since 2015-06-29
Expand Down
92 changes: 92 additions & 0 deletions src/test/java/j8plus/types/annoying/AnnoyingFunsTest.java
@@ -1,5 +1,6 @@
package j8plus.types.annoying;

import j8plus.types.Runner;
import org.junit.jupiter.api.Test;

import java.util.function.BiFunction;
Expand Down Expand Up @@ -98,4 +99,95 @@ public void testShhForAnnoyingBiFunction() throws Exception {
assertThat(actual).isEqualTo(expected)
);
}


private void runItWithAnnoyance() throws Exception {
throw new Exception("Annoying exception!");
}


private void runSomething(final Runnable runnable) {
runnable.run();
}




@Test
public void testShhForAnnoyingRunnable() throws Exception {

test("testShhForAnnoyingRunnable", "testShh with a method reference to AnnoyingRunnable throwing checked Exception")
.when(() ->
runSomething(AnnoyingFuns.shh(this::runItWithAnnoyance))
)
.expect(
throwing(RuntimeException.class)
.causedBy(Exception.class)
.hasMessage("Annoying exception!")
);

test("testShhForAnnoyingRunnable (2)", "testShh with a lambda expression for AnnoyingRunnable throwing checked Exception")
.when(() ->
runSomething(AnnoyingFuns.shh(() -> runItWithAnnoyance()))
)
.expect(
throwing(RuntimeException.class)
.causedBy(Exception.class)
.hasMessage("Annoying exception!")
);

final boolean expected = true;
final boolean[] actual = {false};
test("testShhForAnnoyingRunnable (3)", "testShh with a lambda expression for AnnoyingRunnable throwing no exception")
.when(() ->
runSomething(AnnoyingFuns.shh(() -> actual[0] = true))
)
.then(() ->
assertThat(actual[0]).isEqualTo(expected)
);
}



private void runWithRunner(final Runner runnable) {
runnable.run();
}



@Test
public void testShhForAnnoyingRunner() throws Exception {

test("testShhForAnnoyingRunner", "testShh with a method reference to AnnoyingRunner throwing checked Exception")
.when(() ->
runWithRunner(AnnoyingFuns.shh(this::runItWithAnnoyance))
)
.expect(
throwing(RuntimeException.class)
.causedBy(Exception.class)
.hasMessage("Annoying exception!")
);

test("testShhForAnnoyingRunner (2)", "testShh with a lambda expression for AnnoyingRunner throwing checked Exception")
.when(() ->
runWithRunner(AnnoyingFuns.shh(() -> runItWithAnnoyance()))
)
.expect(
throwing(RuntimeException.class)
.causedBy(Exception.class)
.hasMessage("Annoying exception!")
);

final boolean expected = true;
final boolean[] actual = { false };
test("testShhForAnnoyingRunner (3)", "testShh with a lambda expression for AnnoyingRunner throwing no exception")
.when(() -> {
AnnoyingRunner f = () -> actual[0] = true;
runWithRunner(AnnoyingFuns.shh(f));
})
.then(() ->
assertThat(actual[0]).isEqualTo(expected)
);
}

}
44 changes: 44 additions & 0 deletions src/test/java/j8plus/types/annoying/AnnoyingRunnerTest.java
@@ -0,0 +1,44 @@
package j8plus.types.annoying;

import org.junit.jupiter.api.Test;

import static org.mockito.Mockito.*;

/**
* @author Kevin Lee
* @since 2017-06-10
*/
public class AnnoyingRunnerTest {

interface ResultChecker {
void result1();
void result2();
}

@Test
public void testAndThen() throws Exception {
final ResultChecker resultChecker = mock(ResultChecker.class);

final AnnoyingRunner f = () -> resultChecker.result1();
final AnnoyingRunner g = f.andThen(() -> resultChecker.result2());

g.run();

verify(resultChecker).result1();
verify(resultChecker).result2();
}

@Test
public void testAndThenWithMethodReference() throws Exception {
final ResultChecker resultChecker = mock(ResultChecker.class);

final AnnoyingRunner f = resultChecker::result1;
final AnnoyingRunner g = f.andThen(resultChecker::result2);

g.run();

verify(resultChecker).result1();
verify(resultChecker).result2();
}

}

0 comments on commit 91deb15

Please sign in to comment.