From ac3e253bf2a0fe5fc878ff4abc79e3140e805d8e Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 13 Mar 2018 17:53:16 +0000 Subject: [PATCH] Value: secondary clauses now use Supplier's to enable short circuiting --- README.adoc | 69 +++++--- .../kemitix/conditional/FalseValueClause.java | 13 +- .../kemitix/conditional/TrueValueClause.java | 14 +- .../java/net/kemitix/conditional/Value.java | 33 ++-- .../net/kemitix/conditional/ValueTest.java | 149 ++++++++++++------ 5 files changed, 180 insertions(+), 98 deletions(-) diff --git a/README.adoc b/README.adoc index d4bebd6..5eadee4 100644 --- a/README.adoc +++ b/README.adoc @@ -59,7 +59,7 @@ if (isTrue() && isAlsoTrue()) { [[source,java]] ---- Condition.where(isTrue()) - .and(isAlsoTrue()) + .and(() -> isAlsoTrue()) .then(() -> doSomething()) .otherwise(() -> doSomethingElse()); ---- @@ -78,7 +78,7 @@ if (isTrue() || alternativeIsTrue()) { [[source,java]] ---- Condition.where(isTrue()) - .or(alternativeIsTrue()) + .or(() -> alternativeIsTrue()) .then(() -> doSomething()) .otherwise(() -> doSomethingElse()); ---- @@ -115,7 +115,7 @@ if (isTrue() || !isFalse()) { [[source,java]] ---- Condition.where(isTrue()) - .andNot(isFalse()) + .andNot(() -> isFalse()) .then(() -> doSomething()) .otherwise(() -> doSomethingElse()); ---- @@ -134,7 +134,7 @@ if (isFalse() || !isAlsoFalse()) { [[source,java]] ---- Condition.where(isFalse()) - .orNot(isAlsoFalse()) + .orNot(() -> isAlsoFalse()) .then(() -> doSomething()) .otherwise(() -> doSomethingElse()); ---- @@ -154,7 +154,7 @@ if (isFalse()) { ---- Condition.where(isFalse()) .then(() -> doSomething()) - .otherwise(isTrue()) + .otherwise(() -> isTrue()) .then(() -> doSomethingElse()); ---- @@ -174,7 +174,7 @@ if (isTrue()) { ---- Condition.where(isTrue()) .then(() -> doSomething()) - .and(isAlsoTrue()) + .and(() -> isAlsoTrue()) .then(() -> doSomethingElse()); ---- @@ -213,8 +213,9 @@ final Optional result = Value.where(isTrue(), () -> TRUE); [[source,java]] ---- -final String result = Value.where(isTrue()).then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.where(isTrue()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- ### if-not-then-else @@ -231,8 +232,9 @@ if (!isTrue()) { [[source,java]] ---- -final String result = Value.whereNot(isTrue()).then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.whereNot(isTrue()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- ### if-and-then-else @@ -249,9 +251,10 @@ if (isTrue() && alternativeIsTrue()) { [[source,java]] ---- -final String result = Value.where(isTrue()).and(alternativeIsTrue()) - .then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.where(isTrue()) + .and(() -> alternativeIsTrue()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- ### if-and-not-then-else @@ -268,9 +271,10 @@ if (isTrue() && !alternativeIsFalse()) { [[source,java]] ---- -final String result = Value.where(isTrue()).andNot(alternativeIsFalse()) - .then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.where(isTrue()) + .andNot(() -> alternativeIsFalse()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- ### if-or-then-else @@ -287,9 +291,10 @@ if (isTrue() || alternativeIsTrue()) { [[source,java]] ---- -final String result = Value.where(isTrue()).or(alternativeIsTrue()) - .then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.where(isTrue()) + .or(() -> alternativeIsTrue()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- ### if-or-not-then-else @@ -306,7 +311,27 @@ if (isTrue() || !isFalse()) { [[source,java]] ---- -final String result = Value.where(isTrue()).orNot(isFalse()) - .then(() -> TRUE) - .otherwise(() -> FALSE); +final String result = Value.where(isTrue()) + .orNot(() -> isFalse()) + .then(() -> TRUE) + .otherwise(() -> FALSE); ---- + +### if-then + +[[source,java]] +----- +Optional result; +if (isTrue()) { + result = Optional.of(TRUE); +} else { + result = Optional.empty(); +} +----- + +[[source,java]] +----- +final Optional result = Value.where(isTrue()) + .then(() -> TRUE) + .optional(); +----- diff --git a/src/main/java/net/kemitix/conditional/FalseValueClause.java b/src/main/java/net/kemitix/conditional/FalseValueClause.java index 3f6be53..94775f2 100644 --- a/src/main/java/net/kemitix/conditional/FalseValueClause.java +++ b/src/main/java/net/kemitix/conditional/FalseValueClause.java @@ -21,6 +21,7 @@ package net.kemitix.conditional; +import java.util.Optional; import java.util.function.Supplier; /** @@ -40,14 +41,13 @@ class FalseValueClause implements Value.ValueClause { } @Override - public Value.ValueClause and(final boolean clause) { + public Value.ValueClause and(final Supplier clause) { return this; } @Override - @SuppressWarnings("PMD.ShortMethodName") - public Value.ValueClause or(final boolean clause) { - return Value.where(clause); + public Value.ValueClause or(final Supplier clause) { + return Value.where(clause.get()); } /** @@ -62,6 +62,11 @@ class FalseValueClause implements Value.ValueClause { return falseSupplier.get(); } + @Override + public Optional optional() { + return Optional.empty(); + } + } } diff --git a/src/main/java/net/kemitix/conditional/TrueValueClause.java b/src/main/java/net/kemitix/conditional/TrueValueClause.java index 8179e27..c5c04ad 100644 --- a/src/main/java/net/kemitix/conditional/TrueValueClause.java +++ b/src/main/java/net/kemitix/conditional/TrueValueClause.java @@ -23,6 +23,7 @@ package net.kemitix.conditional; import lombok.RequiredArgsConstructor; +import java.util.Optional; import java.util.function.Supplier; /** @@ -42,13 +43,12 @@ class TrueValueClause implements Value.ValueClause { } @Override - public Value.ValueClause and(final boolean clause) { - return Value.where(clause); + public Value.ValueClause and(final Supplier clause) { + return Value.where(clause.get()); } @Override - @SuppressWarnings("PMD.ShortMethodName") - public Value.ValueClause or(final boolean clause) { + public Value.ValueClause or(final Supplier clause) { return this; } @@ -60,7 +60,6 @@ class TrueValueClause implements Value.ValueClause { @RequiredArgsConstructor private static final class TrueValueSupplier implements ValueSupplier { - @SuppressWarnings("PMD.BeanMembersShouldSerialize") private final Supplier valueSupplier; @Override @@ -68,6 +67,11 @@ class TrueValueClause implements Value.ValueClause { return valueSupplier.get(); } + @Override + public Optional optional() { + return Optional.ofNullable(valueSupplier.get()); + } + } } diff --git a/src/main/java/net/kemitix/conditional/Value.java b/src/main/java/net/kemitix/conditional/Value.java index 9b1c3b6..55a0e68 100644 --- a/src/main/java/net/kemitix/conditional/Value.java +++ b/src/main/java/net/kemitix/conditional/Value.java @@ -41,11 +41,10 @@ public interface Value { * * @return the value from either the trueSupplier or the falseSupplier */ - @SuppressWarnings("PMD.LawOfDemeter") static T where( - boolean clause, - Supplier trueSupplier, - Supplier falseSupplier + final boolean clause, + final Supplier trueSupplier, + final Supplier falseSupplier ) { return Value.where(clause).then(trueSupplier) .otherwise(falseSupplier); @@ -61,8 +60,8 @@ public interface Value { * @return an Optional either containing the value from the trueSupplier or empty */ static Optional where( - boolean clause, - Supplier trueSupplier + final boolean clause, + final Supplier trueSupplier ) { return Optional.ofNullable(Value.where(clause, trueSupplier, () -> null)); } @@ -75,7 +74,6 @@ public interface Value { * * @return a true or false value clause */ - @SuppressWarnings({"unchecked", "avoidinlineconditionals"}) static ValueClause where(final boolean clause) { return (ValueClause) (clause ? TrueValueClause.TRUE : FalseValueClause.FALSE); } @@ -88,7 +86,7 @@ public interface Value { * * @return a true or false value clause */ - static ValueClause whereNot(boolean clause) { + static ValueClause whereNot(final boolean clause) { return where(!clause); } @@ -115,7 +113,7 @@ public interface Value { * * @return a true or false value clause */ - ValueClause and(boolean clause); + ValueClause and(Supplier clause); /** * Logically OR combine the current {@link ValueClause} with clause. @@ -124,8 +122,7 @@ public interface Value { * * @return a true or false value clause */ - @SuppressWarnings("PMD.ShortMethodName") - ValueClause or(boolean clause); + ValueClause or(Supplier clause); /** * Logically AND combine the current {@link ValueClause} with boolean opposite of the clause. @@ -134,8 +131,8 @@ public interface Value { * * @return a true or false value clause */ - default ValueClause andNot(final boolean clause) { - return and(!clause); + default ValueClause andNot(final Supplier clause) { + return and(() -> !clause.get()); } /** @@ -145,8 +142,8 @@ public interface Value { * * @return a true or false value clause */ - default ValueClause orNot(boolean clause) { - return or(!clause); + default ValueClause orNot(final Supplier clause) { + return or(() -> !clause.get()); } /** @@ -165,6 +162,12 @@ public interface Value { */ T otherwise(Supplier falseSupplier); + /** + * Returns the value in an Optional if the {@link ValueClause} is true, or an empty Optional if it is false. + * + * @return an Optional, possibly containing the value + */ + Optional optional(); } } diff --git a/src/test/java/net/kemitix/conditional/ValueTest.java b/src/test/java/net/kemitix/conditional/ValueTest.java index d76011b..3c72c6e 100644 --- a/src/test/java/net/kemitix/conditional/ValueTest.java +++ b/src/test/java/net/kemitix/conditional/ValueTest.java @@ -4,6 +4,7 @@ import lombok.val; import org.junit.Test; import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; import static org.assertj.core.api.Assertions.assertThat; @@ -52,7 +53,7 @@ public class ValueTest { public void valueWhereClauseIsTrue() { //when val result = Value.where(true).then(() -> TRUE) - .otherwise(() -> FALSE); + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -61,7 +62,7 @@ public class ValueTest { public void valueWhereClauseIsFalse() { //when val result = Value.where(false).then(() -> TRUE) - .otherwise(() -> FALSE); + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -69,9 +70,9 @@ public class ValueTest { @Test public void valueWhereTrueAndTrueIsTrue() { //when - val result = Value.where(true).and(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).and(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -79,9 +80,9 @@ public class ValueTest { @Test public void valueWhereTrueAndFalseIsFalse() { //when - val result = Value.where(true).and(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).and(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -89,9 +90,9 @@ public class ValueTest { @Test public void valueWhereFalseAndTrueIsFalse() { //when - val result = Value.where(false).and(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).and(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -99,9 +100,9 @@ public class ValueTest { @Test public void valueWhereFalseAndFalseIsFalse() { //when - val result = Value.where(false).and(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).and(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -109,9 +110,9 @@ public class ValueTest { @Test public void valueWhereTrueOrTrueIsTrue() { //when - val result = Value.where(true).or(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).or(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -119,9 +120,9 @@ public class ValueTest { @Test public void valueWhereTrueOrFalseIsTrue() { //when - val result = Value.where(true).or(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).or(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -129,9 +130,9 @@ public class ValueTest { @Test public void valueWhereFalseOrTrueIsTrue() { //when - val result = Value.where(false).or(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).or(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -139,9 +140,9 @@ public class ValueTest { @Test public void valueWhereFalseOrFalseIsFalse() { //when - val result = Value.where(false).or(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).or(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -150,7 +151,7 @@ public class ValueTest { public void valueWhereNotTrueIsFalse() { //when val result = Value.whereNot(true).then(() -> TRUE) - .otherwise(() -> FALSE); + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -159,7 +160,7 @@ public class ValueTest { public void valueWhereNotFalseIsTrue() { //when val result = Value.whereNot(false).then(() -> TRUE) - .otherwise(() -> FALSE); + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -167,9 +168,9 @@ public class ValueTest { @Test public void valueWhereTrueAndNotTrueIsFalse() { //when - val result = Value.where(true).andNot(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).andNot(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -177,9 +178,9 @@ public class ValueTest { @Test public void valueWhereTrueAndNotFalseIsTrue() { //when - val result = Value.where(true).andNot(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).andNot(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -187,9 +188,9 @@ public class ValueTest { @Test public void valueWhereFalseAndNotTrueIsFalse() { //when - val result = Value.where(false).andNot(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).andNot(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -197,9 +198,9 @@ public class ValueTest { @Test public void valueWhereFalseAndNotFalseIsFalse() { //when - val result = Value.where(false).andNot(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).andNot(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -207,9 +208,9 @@ public class ValueTest { @Test public void valueWhereTrueOrNotTrueIsTrue() { //when - val result = Value.where(true).orNot(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).orNot(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -217,9 +218,9 @@ public class ValueTest { @Test public void valueWhereTrueOrNotFalseIsTrue() { //when - val result = Value.where(true).orNot(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(true).orNot(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } @@ -227,9 +228,9 @@ public class ValueTest { @Test public void valueWhereFalseOrNotTrueIsFalse() { //when - val result = Value.where(false).orNot(true) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).orNot(() -> true) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(FALSE); } @@ -237,10 +238,54 @@ public class ValueTest { @Test public void valueWhereFalseOrNotFalseIsTrue() { //when - val result = Value.where(false).orNot(false) - .then(() -> TRUE) - .otherwise(() -> FALSE); + val result = Value.where(false).orNot(() -> false) + .then(() -> TRUE) + .otherwise(() -> FALSE); //then assertThat(result).isEqualTo(TRUE); } + + @Test + public void valueWhereTrueThenIsNotEmpty() { + //given + final Optional result = Value.where(true).then(() -> "value").optional(); + //then + assertThat(result).contains("value"); + } + + @Test + public void valueWhereFalseThenIsEmpty() { + //given + final Optional result = Value.where(false).then(() -> "value").optional(); + //when + assertThat(result).isEmpty(); + } + + @Test + public void shortCurcuitOr() { + //given + final AtomicInteger atomicInteger = new AtomicInteger(); + //when + final Optional result = Value.where(true) + .or(() -> atomicInteger.compareAndSet(0, 2)) + .then(() -> "Pass") + .optional(); + //then + assertThat(result).contains("Pass"); + assertThat(atomicInteger).hasValue(0); + } + + @Test + public void shortCurcuitAnd() { + //given + final AtomicInteger atomicInteger = new AtomicInteger(); + //when + final Optional result = Value.where(false) + .and(() -> atomicInteger.compareAndSet(0, 2)) + .then(() -> "Pass") + .optional(); + //then + assertThat(result).isEmpty(); + assertThat(atomicInteger).hasValue(0); + } }