From 7eb20deff6ecc4b8deed15cbd87600f990984d0b Mon Sep 17 00:00:00 2001 From: Daniel Dietrich Date: Sun, 5 Mar 2017 22:31:34 +0100 Subject: [PATCH 1/2] Serializable tests --- .../java/javaslang/control/Validation.java | 28 ++++++------- .../java/javaslang/AbstractValueTest.java | 41 ++++++++++++++++-- .../collection/AbstractTraversableTest.java | 42 +++---------------- .../javaslang/collection/IteratorTest.java | 5 --- .../java/javaslang/collection/TreeTest.java | 18 +------- .../java/javaslang/concurrent/FutureTest.java | 5 --- .../control/EitherLeftProjectionTest.java | 5 --- .../control/EitherRightProjectionTest.java | 5 --- 8 files changed, 60 insertions(+), 89 deletions(-) diff --git a/javaslang/src/main/java/javaslang/control/Validation.java b/javaslang/src/main/java/javaslang/control/Validation.java index a7a7e86fca..23fb140912 100644 --- a/javaslang/src/main/java/javaslang/control/Validation.java +++ b/javaslang/src/main/java/javaslang/control/Validation.java @@ -457,10 +457,10 @@ default U fold(Function fInvalid, Function U fold(Function fInvalid, Function swap() { if (isInvalid()) { - E error = this.getError(); + final E error = this.getError(); return Validation.valid(error); } else { - T value = this.get(); + final T value = this.get(); return Validation.invalid(value); } } @@ -487,7 +487,7 @@ default Validation map(Function f) { if (isInvalid()) { return Validation.invalid(this.getError()); } else { - T value = this.get(); + final T value = this.get(); return Validation.valid(f.apply(value)); } } @@ -510,10 +510,10 @@ default Validation bimap(Function erro Objects.requireNonNull(errorMapper, "errorMapper is null"); Objects.requireNonNull(valueMapper, "valueMapper is null"); if (isInvalid()) { - E error = this.getError(); + final E error = this.getError(); return Validation.invalid(errorMapper.apply(error)); } else { - T value = this.get(); + final T value = this.get(); return Validation.valid(valueMapper.apply(value)); } } @@ -545,7 +545,7 @@ default Validation leftMap(Function f) { default Validation mapError(Function f) { Objects.requireNonNull(f, "f is null"); if (isInvalid()) { - E error = this.getError(); + final E error = this.getError(); return Validation.invalid(f.apply(error)); } else { return Validation.valid(this.get()); @@ -556,20 +556,20 @@ default Validation, U> ap(Validation, ? extends Function f = validation.get(); - U u = f.apply(this.get()); + final Function f = validation.get(); + final U u = f.apply(this.get()); return valid(u); } else { - List errors = validation.getError(); + final List errors = validation.getError(); return invalid(errors); } } else { if (validation.isValid()) { - E error = this.getError(); + final E error = this.getError(); return invalid(List.of(error)); } else { - List errors = validation.getError(); - E error = this.getError(); + final List errors = validation.getError(); + final E error = this.getError(); return invalid(errors.append(error)); } } diff --git a/javaslang/src/test/java/javaslang/AbstractValueTest.java b/javaslang/src/test/java/javaslang/AbstractValueTest.java index 135c29d59c..b9f2dab77f 100644 --- a/javaslang/src/test/java/javaslang/AbstractValueTest.java +++ b/javaslang/src/test/java/javaslang/AbstractValueTest.java @@ -9,6 +9,7 @@ import javaslang.collection.CharSeq; import javaslang.collection.HashMap; import javaslang.collection.HashSet; +import javaslang.collection.Iterator; import javaslang.collection.LinkedHashMap; import javaslang.collection.LinkedHashSet; import javaslang.collection.List; @@ -24,6 +25,7 @@ import javaslang.collection.TreeMap; import javaslang.collection.TreeSet; import javaslang.collection.Vector; +import javaslang.concurrent.Future; import javaslang.control.Either; import javaslang.control.Option; import javaslang.control.Try; @@ -31,12 +33,15 @@ import org.assertj.core.api.*; import org.junit.Test; +import java.io.Serializable; import java.util.*; import java.util.Collections; import java.util.function.Function; import java.util.function.Supplier; import static javaslang.API.*; +import static javaslang.Predicates.anyOf; +import static javaslang.Predicates.instanceOf; import static javaslang.Serializables.deserialize; import static javaslang.Serializables.serialize; @@ -141,7 +146,8 @@ public void shouldCalculateGetOrElseWithNonNull() { @Test(expected = NullPointerException.class) public void shouldThrowOnGetOrElseWithNullSupplier() { - empty().getOrElse((Supplier) null); + final Supplier supplier = null; + empty().getOrElse(supplier); } @Test @@ -965,8 +971,28 @@ public void shouldHaveAReasonableToString() { * * @return true (by default), if the Value is Serializable, false otherwise */ - protected boolean isSerializable() { - return true; + private boolean isSerializable() { + if (empty() instanceof Serializable != of(1) instanceof Serializable) { + throw new Error("empty and non-empty do not consistently implement Serializable"); + } + final boolean actual = empty() instanceof Serializable; + final boolean expected = Match(empty()).of( + Case(anyOf( + instanceOf(Either.LeftProjection.class), + instanceOf(Either.RightProjection.class), + instanceOf(Future.class), + instanceOf(Iterator.class), + instanceOf(Validation.class) + ), false), + Case(anyOf( + instanceOf(Either.class), + instanceOf(Option.class), + instanceOf(Try.class), + instanceOf(Traversable.class) + ), true) + ); + assertThat(actual).isEqualTo(expected); + return actual; } @Test @@ -996,6 +1022,15 @@ public void shouldSerializeDeserializeMultiValued() { } } + @Test + public void shouldPreserveSingletonInstanceOnDeserialization() { + if (isSerializable() && !useIsEqualToInsteadOfIsSameAs()) { + final Value empty = empty(); + final Value actual = deserialize(serialize(empty)); + assertThat(actual).isSameAs(empty); + } + } + // -- equals @Test diff --git a/javaslang/src/test/java/javaslang/collection/AbstractTraversableTest.java b/javaslang/src/test/java/javaslang/collection/AbstractTraversableTest.java index abe450eea6..d541964531 100644 --- a/javaslang/src/test/java/javaslang/collection/AbstractTraversableTest.java +++ b/javaslang/src/test/java/javaslang/collection/AbstractTraversableTest.java @@ -22,8 +22,6 @@ import static java.lang.System.lineSeparator; import static java.util.Arrays.asList; import static java.util.Comparator.comparingInt; -import static javaslang.Serializables.deserialize; -import static javaslang.Serializables.serialize; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.assertj.core.api.Assertions.within; @@ -1259,7 +1257,7 @@ public void shouldCalculateNonEmpty() { @Test public void shouldCaclEmptyOrElseSameOther() { - Iterable other = of(42); + final Iterable other = of(42); assertThat(empty().orElse(other)).isSameAs(other); } @@ -1270,14 +1268,14 @@ public void shouldCaclEmptyOrElseEqualOther() { @Test public void shouldCaclNonemptyOrElseOther() { - Traversable src = of(42); + final Traversable src = of(42); assertThat(src.orElse(List.of(1))).isSameAs(src); } @Test public void shouldCaclEmptyOrElseSameSupplier() { - Iterable other = of(42); - Supplier> supplier = () -> other; + final Iterable other = of(42); + final Supplier> supplier = () -> other; assertThat(empty().orElse(supplier)).isSameAs(other); } @@ -1288,7 +1286,7 @@ public void shouldCaclEmptyOrElseEqualSupplier() { @Test public void shouldCaclNonemptyOrElseSupplier() { - Traversable src = of(42); + final Traversable src = of(42); assertThat(src.orElse(() -> List.of(1))).isSameAs(src); } @@ -2449,7 +2447,7 @@ public void shouldComputeHashCodeOfEmpty() { @Test public void shouldNotThrowStackOverflowErrorWhenCalculatingHashCodeOf1000000Integers() { - ofAll(Iterator.range(0, 1000000)).hashCode(); + assertThat(ofAll(Iterator.range(0, 1000000)).hashCode()).isNotNull(); } // -- toString @@ -2482,34 +2480,6 @@ private static String toString(Traversable traversable) { return traversable.mkString(traversable.stringPrefix() + "(", ", ", ")"); } - // -- Serializable interface - - @Test - public void shouldSerializeDeserializeNil() { - if (isSerializable()) { - final Object actual = deserialize(serialize(empty())); - final Object expected = empty(); - assertThat(actual).isEqualTo(expected); - } - } - - @Test - public void shouldPreserveSingletonInstanceOnDeserialization() { - if (isSerializable()) { - final Object actual = deserialize(serialize(empty())); - assertThat(actual).isSameAs(empty()); - } - } - - @Test - public void shouldSerializeDeserializeNonNil() { - if (isSerializable()) { - final Object actual = deserialize(serialize(of(1, 2, 3))); - final Object expected = of(1, 2, 3); - assertThat(actual).isEqualTo(expected); - } - } - // -- static collector() @Test diff --git a/javaslang/src/test/java/javaslang/collection/IteratorTest.java b/javaslang/src/test/java/javaslang/collection/IteratorTest.java index 8c0eef5d56..38de3f5879 100644 --- a/javaslang/src/test/java/javaslang/collection/IteratorTest.java +++ b/javaslang/src/test/java/javaslang/collection/IteratorTest.java @@ -87,11 +87,6 @@ private Object wrapIterator(Object o) { }; } - @Override - protected boolean isSerializable() { - return false; - } - @Override protected Collector, ? extends Iterator> collector() { throw new UnsupportedOperationException(); diff --git a/javaslang/src/test/java/javaslang/collection/TreeTest.java b/javaslang/src/test/java/javaslang/collection/TreeTest.java index 4008587884..a0cb5fe391 100644 --- a/javaslang/src/test/java/javaslang/collection/TreeTest.java +++ b/javaslang/src/test/java/javaslang/collection/TreeTest.java @@ -623,24 +623,10 @@ public void shouldReturnDrawStringOfNode() { " └──9"); } - // -- Serializable interface + // -- serialization @Test - public void shouldSerializeDeserializeEmpty() { - final Object actual = deserialize(serialize(Tree.empty())); - final Object expected = Tree.empty(); - assertThat(actual).isEqualTo(expected); - } - - @Override - @Test - public void shouldPreserveSingletonInstanceOnDeserialization() { - final boolean actual = deserialize(serialize(Tree.empty())) == Tree.empty(); - assertThat(actual).isTrue(); - } - - @Test - public void shouldSerializeDeserializeNonEmpty() { + public void shouldSerializeDeserializeComplexTree() { final Object actual = deserialize(serialize(tree)); assertThat(actual).isEqualTo(tree); } diff --git a/javaslang/src/test/java/javaslang/concurrent/FutureTest.java b/javaslang/src/test/java/javaslang/concurrent/FutureTest.java index da1fb87898..7908b1a493 100644 --- a/javaslang/src/test/java/javaslang/concurrent/FutureTest.java +++ b/javaslang/src/test/java/javaslang/concurrent/FutureTest.java @@ -74,11 +74,6 @@ protected int getPeekNonNilPerformingAnAction() { return 1; } - @Override - protected boolean isSerializable() { - return false; - } - // -- static failed() @Test diff --git a/javaslang/src/test/java/javaslang/control/EitherLeftProjectionTest.java b/javaslang/src/test/java/javaslang/control/EitherLeftProjectionTest.java index cd68019c35..f5fbf6b16b 100644 --- a/javaslang/src/test/java/javaslang/control/EitherLeftProjectionTest.java +++ b/javaslang/src/test/java/javaslang/control/EitherLeftProjectionTest.java @@ -47,11 +47,6 @@ protected int getPeekNonNilPerformingAnAction() { return 1; } - @Override - protected boolean isSerializable() { - return false; - } - // -- LeftProjection // get diff --git a/javaslang/src/test/java/javaslang/control/EitherRightProjectionTest.java b/javaslang/src/test/java/javaslang/control/EitherRightProjectionTest.java index 96548f29b7..4ff0833580 100644 --- a/javaslang/src/test/java/javaslang/control/EitherRightProjectionTest.java +++ b/javaslang/src/test/java/javaslang/control/EitherRightProjectionTest.java @@ -47,11 +47,6 @@ protected int getPeekNonNilPerformingAnAction() { return 1; } - @Override - protected boolean isSerializable() { - return false; - } - // -- RightProjection // get From 26b9322b2bb8bd0feecd3410863ec2e768d5b860 Mon Sep 17 00:00:00 2001 From: Daniel Dietrich Date: Sun, 5 Mar 2017 23:39:07 +0100 Subject: [PATCH 2/2] Fixes interfaces that should extend Serializable --- javaslang/src/main/java/javaslang/collection/Map.java | 3 ++- .../src/main/java/javaslang/collection/Multimap.java | 3 ++- javaslang/src/main/java/javaslang/collection/Seq.java | 3 ++- javaslang/src/main/java/javaslang/collection/Set.java | 3 ++- .../src/main/java/javaslang/collection/Traversable.java | 1 + javaslang/src/main/java/javaslang/collection/Tree.java | 4 +++- javaslang/src/main/java/javaslang/control/Either.java | 4 +++- javaslang/src/main/java/javaslang/control/Option.java | 4 +++- javaslang/src/main/java/javaslang/control/Try.java | 4 +++- javaslang/src/main/java/javaslang/control/Validation.java | 4 +++- javaslang/src/test/java/javaslang/AbstractValueTest.java | 8 ++++---- .../src/test/java/javaslang/control/ValidationTest.java | 2 +- 12 files changed, 29 insertions(+), 14 deletions(-) diff --git a/javaslang/src/main/java/javaslang/collection/Map.java b/javaslang/src/main/java/javaslang/collection/Map.java index 32e10fc979..28fd0b5311 100644 --- a/javaslang/src/main/java/javaslang/collection/Map.java +++ b/javaslang/src/main/java/javaslang/collection/Map.java @@ -11,6 +11,7 @@ import javaslang.Tuple3; import javaslang.control.Option; +import java.io.Serializable; import java.util.*; import java.util.function.*; @@ -82,7 +83,7 @@ * @author Daniel Dietrich, Ruslan Sennov * @since 2.0.0 */ -public interface Map extends Traversable>, Function1 { +public interface Map extends Traversable>, Function1, Serializable { long serialVersionUID = 1L; diff --git a/javaslang/src/main/java/javaslang/collection/Multimap.java b/javaslang/src/main/java/javaslang/collection/Multimap.java index 14d53c24f0..737168fe16 100644 --- a/javaslang/src/main/java/javaslang/collection/Multimap.java +++ b/javaslang/src/main/java/javaslang/collection/Multimap.java @@ -8,6 +8,7 @@ import javaslang.*; import javaslang.control.Option; +import java.io.Serializable; import java.util.*; import java.util.function.*; @@ -73,7 +74,7 @@ * @author Ruslan Sennov * @since 2.1.0 */ -public interface Multimap extends Traversable>, Function1>, Kind2, K, V> { +public interface Multimap extends Traversable>, Function1>, Kind2, K, V>, Serializable { long serialVersionUID = 1L; diff --git a/javaslang/src/main/java/javaslang/collection/Seq.java b/javaslang/src/main/java/javaslang/collection/Seq.java index ca18f928e1..7cf3faa5b3 100644 --- a/javaslang/src/main/java/javaslang/collection/Seq.java +++ b/javaslang/src/main/java/javaslang/collection/Seq.java @@ -11,6 +11,7 @@ import javaslang.Tuple3; import javaslang.control.Option; +import java.io.Serializable; import java.util.Comparator; import java.util.Objects; import java.util.function.*; @@ -87,7 +88,7 @@ * @author Daniel Dietrich * @since 1.1.0 */ -public interface Seq extends Traversable, Function1 { +public interface Seq extends Traversable, Function1, Serializable { long serialVersionUID = 1L; diff --git a/javaslang/src/main/java/javaslang/collection/Set.java b/javaslang/src/main/java/javaslang/collection/Set.java index d5a072dd54..d86a9a9d16 100644 --- a/javaslang/src/main/java/javaslang/collection/Set.java +++ b/javaslang/src/main/java/javaslang/collection/Set.java @@ -10,6 +10,7 @@ import javaslang.Tuple3; import javaslang.control.Option; +import java.io.Serializable; import java.util.Comparator; import java.util.Spliterator; import java.util.Spliterators; @@ -69,7 +70,7 @@ * @author Daniel Dietrich, Ruslan Sennov * @since 2.0.0 */ -public interface Set extends Traversable, Function1 { +public interface Set extends Traversable, Function1, Serializable { long serialVersionUID = 1L; diff --git a/javaslang/src/main/java/javaslang/collection/Traversable.java b/javaslang/src/main/java/javaslang/collection/Traversable.java index 7e5c9da367..45629d55f6 100644 --- a/javaslang/src/main/java/javaslang/collection/Traversable.java +++ b/javaslang/src/main/java/javaslang/collection/Traversable.java @@ -10,6 +10,7 @@ import javaslang.Value; import javaslang.control.Option; +import java.io.Serializable; import java.math.BigInteger; import java.util.Comparator; import java.util.NoSuchElementException; diff --git a/javaslang/src/main/java/javaslang/collection/Tree.java b/javaslang/src/main/java/javaslang/collection/Tree.java index 23addfadf8..81aad4e073 100644 --- a/javaslang/src/main/java/javaslang/collection/Tree.java +++ b/javaslang/src/main/java/javaslang/collection/Tree.java @@ -27,7 +27,9 @@ * @author Daniel Dietrich, Grzegorz Piwowarek * @since 1.1.0 */ -public interface Tree extends Traversable { +public interface Tree extends Traversable, Serializable { + + long serialVersionUID = 1L; /** * Returns a {@link java.util.stream.Collector} which may be used in conjunction with diff --git a/javaslang/src/main/java/javaslang/control/Either.java b/javaslang/src/main/java/javaslang/control/Either.java index 55c6b6f50b..c828b08ca2 100644 --- a/javaslang/src/main/java/javaslang/control/Either.java +++ b/javaslang/src/main/java/javaslang/control/Either.java @@ -42,7 +42,9 @@ * @author Daniel Dietrich * @since 1.0.0 */ -public interface Either extends Value { +public interface Either extends Value, Serializable { + + long serialVersionUID = 1L; /** * Constructs a {@link Right} diff --git a/javaslang/src/main/java/javaslang/control/Option.java b/javaslang/src/main/java/javaslang/control/Option.java index dc6358f97f..b473df56a6 100644 --- a/javaslang/src/main/java/javaslang/control/Option.java +++ b/javaslang/src/main/java/javaslang/control/Option.java @@ -34,7 +34,9 @@ * @author Daniel Dietrich * @since 1.0.0 */ -public interface Option extends Value { +public interface Option extends Value, Serializable { + + long serialVersionUID = 1L; /** * Creates a new {@code Option} of a given value. diff --git a/javaslang/src/main/java/javaslang/control/Try.java b/javaslang/src/main/java/javaslang/control/Try.java index 55d60be9d7..e32803aa71 100644 --- a/javaslang/src/main/java/javaslang/control/Try.java +++ b/javaslang/src/main/java/javaslang/control/Try.java @@ -28,7 +28,9 @@ * @author Daniel Dietrich * @since 1.0.0 */ -public interface Try extends Value { +public interface Try extends Value, Serializable { + + long serialVersionUID = 1L; /** * Creates a Try of a CheckedSupplier. diff --git a/javaslang/src/main/java/javaslang/control/Validation.java b/javaslang/src/main/java/javaslang/control/Validation.java index 23fb140912..e008f80f84 100644 --- a/javaslang/src/main/java/javaslang/control/Validation.java +++ b/javaslang/src/main/java/javaslang/control/Validation.java @@ -61,7 +61,9 @@ * @see Validation * @since 2.0.0 */ -public interface Validation extends Value { +public interface Validation extends Value, Serializable { + + long serialVersionUID = 1L; /** * Creates a {@link Valid} that contains the given {@code value}. diff --git a/javaslang/src/test/java/javaslang/AbstractValueTest.java b/javaslang/src/test/java/javaslang/AbstractValueTest.java index b9f2dab77f..7238b2a1f6 100644 --- a/javaslang/src/test/java/javaslang/AbstractValueTest.java +++ b/javaslang/src/test/java/javaslang/AbstractValueTest.java @@ -98,7 +98,7 @@ protected StringAssert assertThat(String actual) { @SuppressWarnings("unchecked") abstract protected Value of(T... elements); - // TODO: Eliminate this method. Switching the behavior of unit tests is evil. Tests should not contain additional logic. + // TODO: Eliminate this method. Switching the behavior of unit tests is evil. Tests should not contain additional logic. Also it seems currently to be used in different sematic contexts. abstract protected boolean useIsEqualToInsteadOfIsSameAs(); // returns the peek result of the specific Traversable implementation @@ -981,14 +981,14 @@ private boolean isSerializable() { instanceOf(Either.LeftProjection.class), instanceOf(Either.RightProjection.class), instanceOf(Future.class), - instanceOf(Iterator.class), - instanceOf(Validation.class) + instanceOf(Iterator.class) ), false), Case(anyOf( instanceOf(Either.class), instanceOf(Option.class), instanceOf(Try.class), - instanceOf(Traversable.class) + instanceOf(Traversable.class), + instanceOf(Validation.class) ), true) ); assertThat(actual).isEqualTo(expected); diff --git a/javaslang/src/test/java/javaslang/control/ValidationTest.java b/javaslang/src/test/java/javaslang/control/ValidationTest.java index c32c6f576a..f1fb2edccd 100644 --- a/javaslang/src/test/java/javaslang/control/ValidationTest.java +++ b/javaslang/src/test/java/javaslang/control/ValidationTest.java @@ -40,7 +40,7 @@ protected final Value of(T... elements) { @Override protected boolean useIsEqualToInsteadOfIsSameAs() { - return false; + return true; } @Override