Emulate Optional<T> and its int, long, double variants
Change-Id: Id69894008c48a4e3dca06f9f739f7ed2cd5e76e1
diff --git a/user/super/com/google/gwt/emul/java/util/Optional.java b/user/super/com/google/gwt/emul/java/util/Optional.java
new file mode 100644
index 0000000..51b5f15
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/Optional.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import static javaemul.internal.InternalPreconditions.checkCriticalNotNull;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html">
+ * the official Java API doc</a> for details.
+ *
+ * @param <T> type of the wrapped reference
+ */
+public final class Optional<T> {
+
+ @SuppressWarnings("unchecked")
+ public static <T> Optional<T> empty() {
+ return (Optional<T>) EMPTY;
+ }
+
+ public static <T> Optional<T> of(T value) {
+ return new Optional<>(value);
+ }
+
+ public static <T> Optional<T> ofNullable(T value) {
+ return value == null ? empty() : of(value);
+ }
+
+ private static final Optional<?> EMPTY = new Optional<>();
+
+ private final T ref;
+
+ private Optional() {
+ ref = null;
+ }
+
+ private Optional(T ref) {
+ this.ref = checkCriticalNotNull(ref);
+ }
+
+ public boolean isPresent() {
+ return ref != null;
+ }
+
+ public T get() {
+ checkCriticalElement(isPresent());
+ return ref;
+ }
+
+ public void ifPresent(Consumer<? super T> consumer) {
+ if (isPresent()) {
+ consumer.accept(ref);
+ }
+ }
+
+ public Optional<T> filter(Predicate<? super T> predicate) {
+ checkCriticalNotNull(predicate);
+ if (!isPresent() || predicate.test(ref)) {
+ return this;
+ }
+ return empty();
+ }
+
+ public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
+ checkCriticalNotNull(mapper);
+ if (isPresent()) {
+ return ofNullable(mapper.apply(ref));
+ }
+ return empty();
+ }
+
+ public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+ checkCriticalNotNull(mapper);
+ if (isPresent()) {
+ return checkCriticalNotNull(mapper.apply(ref));
+ }
+ return empty();
+ }
+
+ public T orElse(T other) {
+ return isPresent() ? ref : other;
+ }
+
+ public T orElseGet(Supplier<? extends T> other) {
+ return isPresent() ? ref : other.get();
+ }
+
+ public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
+ if (isPresent()) {
+ return ref;
+ }
+ throw exceptionSupplier.get();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof Optional)) {
+ return false;
+ }
+ Optional<?> other = (Optional<?>) obj;
+ return Objects.equals(ref, other.ref);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(ref);
+ }
+
+ @Override
+ public String toString() {
+ return isPresent() ? "Optional.of(" + String.valueOf(ref) + ")" : "Optional.empty()";
+ }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalDouble.java b/user/super/com/google/gwt/emul/java/util/OptionalDouble.java
new file mode 100644
index 0000000..e6b06af
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/OptionalDouble.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import java.util.function.DoubleConsumer;
+import java.util.function.DoubleSupplier;
+import java.util.function.Supplier;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html">
+ * the official Java API doc</a> for details.
+ */
+public final class OptionalDouble {
+
+ public static OptionalDouble empty() {
+ return EMPTY;
+ }
+
+ public static OptionalDouble of(double value) {
+ return new OptionalDouble(value);
+ }
+
+ private static final OptionalDouble EMPTY = new OptionalDouble();
+
+ private final double ref;
+ private final boolean present;
+
+ private OptionalDouble() {
+ ref = 0;
+ present = false;
+ }
+
+ private OptionalDouble(double value) {
+ ref = value;
+ present = true;
+ }
+
+ public boolean isPresent() {
+ return present;
+ }
+
+ public double getAsDouble() {
+ checkCriticalElement(present);
+ return ref;
+ }
+
+ public void ifPresent(DoubleConsumer consumer) {
+ if (present) {
+ consumer.accept(ref);
+ }
+ }
+
+ public double orElse(double other) {
+ return present ? ref : other;
+ }
+
+ public double orElseGet(DoubleSupplier other) {
+ return present ? ref : other.getAsDouble();
+ }
+
+ public <X extends Throwable> double orElseThrow(Supplier<X> exceptionSupplier) throws X {
+ if (present) {
+ return ref;
+ }
+ throw exceptionSupplier.get();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof OptionalDouble)) {
+ return false;
+ }
+ OptionalDouble other = (OptionalDouble) obj;
+ return present == other.present && Double.compare(ref, other.ref) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return present ? Double.hashCode(ref) : 0;
+ }
+
+ @Override
+ public String toString() {
+ return present ? "OptionalDouble.of(" + Double.toString(ref) + ")" : "OptionalDouble.empty()";
+ }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalInt.java b/user/super/com/google/gwt/emul/java/util/OptionalInt.java
new file mode 100644
index 0000000..10b7ce6
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/OptionalInt.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import java.util.function.IntConsumer;
+import java.util.function.IntSupplier;
+import java.util.function.Supplier;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html">
+ * the official Java API doc</a> for details.
+ */
+public final class OptionalInt {
+
+ public static OptionalInt empty() {
+ return EMPTY;
+ }
+
+ public static OptionalInt of(int value) {
+ return new OptionalInt(value);
+ }
+
+ private static final OptionalInt EMPTY = new OptionalInt();
+
+ private final int ref;
+ private final boolean present;
+
+ private OptionalInt() {
+ ref = 0;
+ present = false;
+ }
+
+ private OptionalInt(int value) {
+ ref = value;
+ present = true;
+ }
+
+ public boolean isPresent() {
+ return present;
+ }
+
+ public int getAsInt() {
+ checkCriticalElement(present);
+ return ref;
+ }
+
+ public void ifPresent(IntConsumer consumer) {
+ if (present) {
+ consumer.accept(ref);
+ }
+ }
+
+ public int orElse(int other) {
+ return present ? ref : other;
+ }
+
+ public int orElseGet(IntSupplier other) {
+ return present ? ref : other.getAsInt();
+ }
+
+ public <X extends Throwable> int orElseThrow(Supplier<X> exceptionSupplier) throws X {
+ if (present) {
+ return ref;
+ }
+ throw exceptionSupplier.get();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof OptionalInt)) {
+ return false;
+ }
+ OptionalInt other = (OptionalInt) obj;
+ return present == other.present && Integer.compare(ref, other.ref) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return present ? Integer.hashCode(ref) : 0;
+ }
+
+ @Override
+ public String toString() {
+ return present ? "OptionalInt.of(" + Integer.toString(ref) + ")" : "OptionalInt.empty()";
+ }
+}
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalLong.java b/user/super/com/google/gwt/emul/java/util/OptionalLong.java
new file mode 100644
index 0000000..8551777
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/OptionalLong.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package java.util;
+
+import java.util.function.LongConsumer;
+import java.util.function.LongSupplier;
+import java.util.function.Supplier;
+
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
+/**
+ * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html">
+ * the official Java API doc</a> for details.
+ */
+public final class OptionalLong {
+
+ public static OptionalLong empty() {
+ return EMPTY;
+ }
+
+ public static OptionalLong of(long value) {
+ return new OptionalLong(value);
+ }
+
+ private static final OptionalLong EMPTY = new OptionalLong();
+
+ private final long ref;
+ private final boolean present;
+
+ private OptionalLong() {
+ ref = 0;
+ present = false;
+ }
+
+ private OptionalLong(long value) {
+ ref = value;
+ present = true;
+ }
+
+ public boolean isPresent() {
+ return present;
+ }
+
+ public long getAsLong() {
+ checkCriticalElement(present);
+ return ref;
+ }
+
+ public void ifPresent(LongConsumer consumer) {
+ if (present) {
+ consumer.accept(ref);
+ }
+ }
+
+ public long orElse(long other) {
+ return present ? ref : other;
+ }
+
+ public long orElseGet(LongSupplier other) {
+ return present ? ref : other.getAsLong();
+ }
+
+ public <X extends Throwable> long orElseThrow(Supplier<X> exceptionSupplier) throws X {
+ if (present) {
+ return ref;
+ }
+ throw exceptionSupplier.get();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof OptionalLong)) {
+ return false;
+ }
+ OptionalLong other = (OptionalLong) obj;
+ return present == other.present && Long.compare(ref, other.ref) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return present ? Long.hashCode(ref) : 0;
+ }
+
+ @Override
+ public String toString() {
+ return present ? "OptionalLong.of(" + Long.toString(ref) + ")" : "OptionalLong.empty()";
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/EmulJava8Suite.java b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
index ee43edf..053cbb1 100644
--- a/user/test/com/google/gwt/emultest/EmulJava8Suite.java
+++ b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
@@ -15,6 +15,9 @@
*/
package com.google.gwt.emultest;
+import com.google.gwt.emultest.java8.util.OptionalDoubleTest;
+import com.google.gwt.emultest.java8.util.OptionalIntTest;
+import com.google.gwt.emultest.java8.util.OptionalLongTest;
import com.google.gwt.emultest.java8.util.OptionalTest;
import com.google.gwt.junit.tools.GWTTestSuite;
@@ -30,6 +33,9 @@
//-- java.util
suite.addTestSuite(OptionalTest.class);
+ suite.addTestSuite(OptionalIntTest.class);
+ suite.addTestSuite(OptionalLongTest.class);
+ suite.addTestSuite(OptionalDoubleTest.class);
return suite;
}
diff --git a/user/test/com/google/gwt/emultest/java8/util/OptionalDoubleTest.java b/user/test/com/google/gwt/emultest/java8/util/OptionalDoubleTest.java
new file mode 100644
index 0000000..c8361eb
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/OptionalDoubleTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java8.util;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalDouble;
+
+/**
+ * Tests for OptionalDouble JRE emulation.
+ */
+public class OptionalDoubleTest extends GWTTestCase {
+
+ private static final double REFERENCE = 10d;
+ private static final double OTHER_REFERENCE = 20d;
+ private boolean[] mutableFlag;
+ private OptionalDouble empty;
+ private OptionalDouble present;
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.emultest.EmulSuite";
+ }
+
+ @Override
+ protected void gwtSetUp() throws Exception {
+ super.gwtSetUp();
+ mutableFlag = new boolean[1];
+ empty = OptionalDouble.empty();
+ present = OptionalDouble.of(REFERENCE);
+ }
+
+ public void testIsPresent() {
+ // empty case
+ assertFalse(empty.isPresent());
+
+ // non-empty case
+ assertTrue(present.isPresent());
+ }
+
+ public void testGetAsDouble() {
+ // empty case
+ try {
+ empty.getAsDouble();
+ fail("Empty Optional should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ // non-empty case
+ assertEquals(REFERENCE, present.getAsDouble());
+ }
+
+ public void testIfPresent() {
+ // empty case
+ empty.ifPresent(null); // should not fail as per JavaDoc
+ empty.ifPresent(wrapped -> fail("Empty Optional should not execute consumer"));
+
+ // non-empty case
+ try {
+ present.ifPresent(null);
+ fail("Non-Empty Optional must throw NullPointerException if consumer is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ present.ifPresent((wrapped) -> {
+ assertEquals(REFERENCE, wrapped);
+ mutableFlag[0] = true;
+ });
+ assertTrue("Consumer not executed", mutableFlag[0]);
+ }
+
+ public void testOrElse() {
+ // empty case
+ assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElse(OTHER_REFERENCE));
+ }
+
+ public void testOrElseGet() {
+ // empty case
+ try {
+ empty.orElseGet(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals(OTHER_REFERENCE, empty.orElseGet(() -> OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElseGet(() -> {
+ fail("Optional must not execute supplier");
+ return OTHER_REFERENCE;
+ }));
+ }
+
+ public void testOrElseThrow() {
+ // empty case
+ try {
+ empty.orElseThrow(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(() -> null);
+ fail("Empty Optional must throw NullPointerException if supplier returns null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(IllegalStateException::new);
+ fail("Empty Optional must throw supplied exception");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ // non-empty case
+ try {
+ Object reference = present.orElseThrow(null);
+ assertEquals(REFERENCE, reference);
+ } catch (NullPointerException e) {
+ fail("Optional must not throw NullPointerException if supplier is null");
+ }
+
+ assertEquals(REFERENCE, present.orElseThrow(() -> {
+ fail("Optional must not execute supplier");
+ return new RuntimeException("should not execute");
+ }));
+ }
+
+ public void testEquals() {
+ // empty case
+ assertFalse(empty.equals(null));
+ assertFalse(empty.equals("should not be equal"));
+ assertFalse(empty.equals(present));
+ assertTrue(empty.equals(empty));
+ assertTrue(empty.equals(OptionalDouble.empty()));
+
+ // non empty case
+ assertFalse(present.equals(null));
+ assertFalse(present.equals("should not be equal"));
+ assertFalse(present.equals(empty));
+ assertFalse(present.equals(OptionalDouble.of(OTHER_REFERENCE)));
+ assertTrue(present.equals(present));
+ assertTrue(present.equals(OptionalDouble.of(REFERENCE)));
+ }
+
+ public void testHashcode() {
+ // empty case
+ assertEquals(0, empty.hashCode());
+
+ // non empty case
+ assertEquals(Double.hashCode(REFERENCE), present.hashCode());
+ }
+
+}
diff --git a/user/test/com/google/gwt/emultest/java8/util/OptionalIntTest.java b/user/test/com/google/gwt/emultest/java8/util/OptionalIntTest.java
new file mode 100644
index 0000000..f1080e9
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/OptionalIntTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java8.util;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalInt;
+
+/**
+ * Tests for OptionalInt JRE emulation.
+ */
+public class OptionalIntTest extends GWTTestCase {
+
+ private static final int REFERENCE = 10;
+ private static final int OTHER_REFERENCE = 20;
+ private boolean[] mutableFlag;
+ private OptionalInt empty;
+ private OptionalInt present;
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.emultest.EmulSuite";
+ }
+
+ @Override
+ protected void gwtSetUp() throws Exception {
+ super.gwtSetUp();
+ mutableFlag = new boolean[1];
+ empty = OptionalInt.empty();
+ present = OptionalInt.of(REFERENCE);
+ }
+
+ public void testIsPresent() {
+ // empty case
+ assertFalse(empty.isPresent());
+
+ // non-empty case
+ assertTrue(present.isPresent());
+ }
+
+ public void testGetAsInt() {
+ // empty case
+ try {
+ empty.getAsInt();
+ fail("Empty Optional should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ // non-empty case
+ assertEquals(REFERENCE, present.getAsInt());
+ }
+
+ public void testIfPresent() {
+ // empty case
+ empty.ifPresent(null); // should not fail as per JavaDoc
+ empty.ifPresent(wrapped -> fail("Empty Optional should not execute consumer"));
+
+ // non-empty case
+ try {
+ present.ifPresent(null);
+ fail("Non-Empty Optional must throw NullPointerException if consumer is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ present.ifPresent((wrapped) -> {
+ assertEquals(REFERENCE, wrapped);
+ mutableFlag[0] = true;
+ });
+ assertTrue("Consumer not executed", mutableFlag[0]);
+ }
+
+ public void testOrElse() {
+ // empty case
+ assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElse(OTHER_REFERENCE));
+ }
+
+ public void testOrElseGet() {
+ // empty case
+ try {
+ empty.orElseGet(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals(OTHER_REFERENCE, empty.orElseGet(() -> OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElseGet(() -> {
+ fail("Optional must not execute supplier");
+ return OTHER_REFERENCE;
+ }));
+ }
+
+ public void testOrElseThrow() {
+ // empty case
+ try {
+ empty.orElseThrow(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(() -> null);
+ fail("Empty Optional must throw NullPointerException if supplier returns null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(IllegalStateException::new);
+ fail("Empty Optional must throw supplied exception");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ // non-empty case
+ try {
+ Object reference = present.orElseThrow(null);
+ assertEquals(REFERENCE, reference);
+ } catch (NullPointerException e) {
+ fail("Optional must not throw NullPointerException if supplier is null");
+ }
+
+ assertEquals(REFERENCE, present.orElseThrow(() -> {
+ fail("Optional must not execute supplier");
+ return new RuntimeException("should not execute");
+ }));
+ }
+
+ public void testEquals() {
+ // empty case
+ assertFalse(empty.equals(null));
+ assertFalse(empty.equals("should not be equal"));
+ assertFalse(empty.equals(present));
+ assertTrue(empty.equals(empty));
+ assertTrue(empty.equals(OptionalInt.empty()));
+
+ // non empty case
+ assertFalse(present.equals(null));
+ assertFalse(present.equals("should not be equal"));
+ assertFalse(present.equals(empty));
+ assertFalse(present.equals(OptionalInt.of(OTHER_REFERENCE)));
+ assertTrue(present.equals(present));
+ assertTrue(present.equals(OptionalInt.of(REFERENCE)));
+ }
+
+ public void testHashcode() {
+ // empty case
+ assertEquals(0, empty.hashCode());
+
+ // non empty case
+ assertEquals(Integer.hashCode(REFERENCE), present.hashCode());
+ }
+
+}
diff --git a/user/test/com/google/gwt/emultest/java8/util/OptionalLongTest.java b/user/test/com/google/gwt/emultest/java8/util/OptionalLongTest.java
new file mode 100644
index 0000000..4d1396f
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/OptionalLongTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java8.util;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalLong;
+
+/**
+ * Tests for OptionalLong JRE emulation.
+ */
+public class OptionalLongTest extends GWTTestCase {
+
+ private static final long REFERENCE = 10L;
+ private static final long OTHER_REFERENCE = 20L;
+ private boolean[] mutableFlag;
+ private OptionalLong empty;
+ private OptionalLong present;
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.emultest.EmulSuite";
+ }
+
+ @Override
+ protected void gwtSetUp() throws Exception {
+ super.gwtSetUp();
+ mutableFlag = new boolean[1];
+ empty = OptionalLong.empty();
+ present = OptionalLong.of(REFERENCE);
+ }
+
+ public void testIsPresent() {
+ // empty case
+ assertFalse(empty.isPresent());
+
+ // non-empty case
+ assertTrue(present.isPresent());
+ }
+
+ public void testGetAsLong() {
+ // empty case
+ try {
+ empty.getAsLong();
+ fail("Empty Optional should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ // non-empty case
+ assertEquals(REFERENCE, present.getAsLong());
+ }
+
+ public void testIfPresent() {
+ // empty case
+ empty.ifPresent(null); // should not fail as per JavaDoc
+ empty.ifPresent(wrapped -> fail("Empty Optional should not execute consumer"));
+
+ // non-empty case
+ try {
+ present.ifPresent(null);
+ fail("Non-Empty Optional must throw NullPointerException if consumer is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ present.ifPresent((wrapped) -> {
+ assertEquals(REFERENCE, wrapped);
+ mutableFlag[0] = true;
+ });
+ assertTrue("Consumer not executed", mutableFlag[0]);
+ }
+
+ public void testOrElse() {
+ // empty case
+ assertEquals(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElse(OTHER_REFERENCE));
+ }
+
+ public void testOrElseGet() {
+ // empty case
+ try {
+ empty.orElseGet(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertEquals(OTHER_REFERENCE, empty.orElseGet(() -> OTHER_REFERENCE));
+
+ // non-empty case
+ assertEquals(REFERENCE, present.orElseGet(() -> {
+ fail("Optional must not execute supplier");
+ return OTHER_REFERENCE;
+ }));
+ }
+
+ public void testOrElseThrow() {
+ // empty case
+ try {
+ empty.orElseThrow(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(() -> null);
+ fail("Empty Optional must throw NullPointerException if supplier returns null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(IllegalStateException::new);
+ fail("Empty Optional must throw supplied exception");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ // non-empty case
+ try {
+ Object reference = present.orElseThrow(null);
+ assertEquals(REFERENCE, reference);
+ } catch (NullPointerException e) {
+ fail("Optional must not throw NullPointerException if supplier is null");
+ }
+
+ assertEquals(REFERENCE, present.orElseThrow(() -> {
+ fail("Optional must not execute supplier");
+ return new RuntimeException("should not execute");
+ }));
+ }
+
+ public void testEquals() {
+ // empty case
+ assertFalse(empty.equals(null));
+ assertFalse(empty.equals("should not be equal"));
+ assertFalse(empty.equals(present));
+ assertTrue(empty.equals(empty));
+ assertTrue(empty.equals(OptionalLong.empty()));
+
+ // non empty case
+ assertFalse(present.equals(null));
+ assertFalse(present.equals("should not be equal"));
+ assertFalse(present.equals(empty));
+ assertFalse(present.equals(OptionalLong.of(OTHER_REFERENCE)));
+ assertTrue(present.equals(present));
+ assertTrue(present.equals(OptionalLong.of(REFERENCE)));
+ }
+
+ public void testHashcode() {
+ // empty case
+ assertEquals(0, empty.hashCode());
+
+ // non empty case
+ assertEquals(Long.hashCode(REFERENCE), present.hashCode());
+ }
+
+}
diff --git a/user/test/com/google/gwt/emultest/java8/util/OptionalTest.java b/user/test/com/google/gwt/emultest/java8/util/OptionalTest.java
index fbb8daa..3384a46 100644
--- a/user/test/com/google/gwt/emultest/java8/util/OptionalTest.java
+++ b/user/test/com/google/gwt/emultest/java8/util/OptionalTest.java
@@ -17,34 +17,260 @@
import com.google.gwt.junit.client.GWTTestCase;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
/**
* Tests for Optional JRE emulation.
*/
public class OptionalTest extends GWTTestCase {
+ private static final Object REFERENCE = new Object();
+ private static final Object OTHER_REFERENCE = new Object();
+ private boolean[] mutableFlag;
+ private Optional<Object> empty;
+ private Optional<Object> present;
+
@Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
}
- public void testSomething() {
+ @Override
+ protected void gwtSetUp() throws Exception {
+ super.gwtSetUp();
+ mutableFlag = new boolean[1];
+ empty = Optional.empty();
+ present = Optional.of(REFERENCE);
+ }
+
+ public void testIsPresent() {
+ // empty case
+ assertFalse(empty.isPresent());
+
+ empty = Optional.ofNullable(null);
+ assertFalse(empty.isPresent());
+
+ // non-empty case
+ assertTrue(present.isPresent());
+
+ present = Optional.ofNullable(REFERENCE);
+ assertTrue(present.isPresent());
+ }
+
+ public void testGet() {
+ // empty case
try {
- requireNonNull(null, () -> "Must not be null");
- fail("must throw NPE");
+ empty.get();
+ fail("Empty Optional should throw NoSuchElementException");
+ } catch (NoSuchElementException e) {
+ // expected
+ }
+
+ // non-empty case
+ assertSame(REFERENCE, present.get());
+ }
+
+ public void testIfPresent() {
+ // empty case
+ empty.ifPresent(null); // should not fail as per JavaDoc
+ empty.ifPresent(wrapped -> fail("Empty Optional should not execute consumer"));
+
+ // non-empty case
+ try {
+ present.ifPresent(null);
+ fail("Non-Empty Optional must throw NullPointerException if consumer is null");
} catch (NullPointerException e) {
// expected
}
+
+ present.ifPresent((wrapped) -> {
+ assertSame(REFERENCE, wrapped);
+ mutableFlag[0] = true;
+ });
+ assertTrue("Consumer not executed", mutableFlag[0]);
}
- private static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
- if (obj == null) {
- throw new NullPointerException(messageSupplier.get());
+ public void testFilter() {
+ // empty case
+ try {
+ empty.filter(null);
+ fail("Optional must throw NullPointerException if predicate is null");
+ } catch (NullPointerException e) {
+ // expected
}
- return obj;
+
+ Optional<Object> filtered = empty.filter(wrapped -> true);
+ assertFalse(filtered.isPresent());
+
+ filtered = empty.filter(wrapped -> false);
+ assertFalse(filtered.isPresent());
+
+ // non-empty case
+ try {
+ present.filter(null);
+ fail("Optional must throw NullPointerException if predicate is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ filtered = present.filter(wrapped -> true);
+ assertSame(REFERENCE, filtered.get());
+
+ filtered = present.filter(wrapped -> false);
+ assertFalse(filtered.isPresent());
}
- @FunctionalInterface
- private interface Supplier<T> {
- T get();
+ public void testMap() {
+ // empty case
+ try {
+ empty.map(null);
+ fail("Optional must throw NullPointerException if mapper is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ empty.map(wrapped -> {
+ fail("Empty Optional must not execute mapper");
+ return "should not execute";
+ });
+
+ // non-empty case
+ try {
+ present.map(null);
+ fail("Optional must throw NullPointerException if mapper is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ Optional<String> mapped = present.map(wrapped -> null);
+ assertFalse(mapped.isPresent());
+
+ mapped = present.map(Object::toString);
+ assertEquals(REFERENCE.toString(), mapped.get());
}
+
+ public void testFlatMap() {
+ // empty case
+ try {
+ empty.flatMap(null);
+ fail("Optional must throw NullPointerException if mapper is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ empty.flatMap(wrapped -> {
+ fail("Empty Optional must not execute mapper");
+ return Optional.of("should not execute");
+ });
+
+ // non-empty case
+ try {
+ present.flatMap(null);
+ fail("Optional must throw NullPointerException if mapper is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ present.flatMap(wrapped -> null);
+ fail("Optional must throw NullPointerException if mapper returns null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ Optional<String> mapped = present.flatMap(wrapped -> Optional.empty());
+ assertFalse(mapped.isPresent());
+
+ mapped = present.flatMap(wrapped -> Optional.of(wrapped.toString()));
+ assertEquals(REFERENCE.toString(), mapped.get());
+ }
+
+ public void testOrElse() {
+ // empty case
+ assertSame(OTHER_REFERENCE, empty.orElse(OTHER_REFERENCE));
+
+ // non-empty case
+ assertSame(REFERENCE, present.orElse(OTHER_REFERENCE));
+ }
+
+ public void testOrElseGet() {
+ // empty case
+ try {
+ empty.orElseGet(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ assertSame(OTHER_REFERENCE, empty.orElseGet(() -> OTHER_REFERENCE));
+
+ // non-empty case
+ assertSame(REFERENCE, present.orElseGet(() -> {
+ fail("Optional must not execute supplier");
+ return OTHER_REFERENCE;
+ }));
+ }
+
+ public void testOrElseThrow() {
+ // empty case
+ try {
+ empty.orElseThrow(null);
+ fail("Empty Optional must throw NullPointerException if supplier is null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.<RuntimeException>orElseThrow(() -> null);
+ fail("Empty Optional must throw NullPointerException if supplier returns null");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ empty.orElseThrow(IllegalStateException::new);
+ fail("Empty Optional must throw supplied exception");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ // non-empty case
+ try {
+ Object reference = present.orElseThrow(null);
+ assertSame(REFERENCE, reference);
+ } catch (NullPointerException e) {
+ fail("Optional must not throw NullPointerException if supplier is null");
+ }
+
+ assertSame(REFERENCE, present.orElseThrow(() -> {
+ fail("Optional must not execute supplier");
+ return new RuntimeException("should not execute");
+ }));
+ }
+
+ public void testEquals() {
+ // empty case
+ assertFalse(empty.equals(null));
+ assertFalse(empty.equals("should not be equal"));
+ assertFalse(empty.equals(present));
+ assertTrue(empty.equals(empty));
+ assertTrue(empty.equals(Optional.empty()));
+
+ // non empty case
+ assertFalse(present.equals(null));
+ assertFalse(present.equals("should not be equal"));
+ assertFalse(present.equals(empty));
+ assertFalse(present.equals(Optional.of(OTHER_REFERENCE)));
+ assertTrue(present.equals(present));
+ assertTrue(present.equals(Optional.of(REFERENCE)));
+ }
+
+ public void testHashcode() {
+ // empty case
+ assertEquals(0, empty.hashCode());
+
+ // non empty case
+ assertEquals(REFERENCE.hashCode(), present.hashCode());
+ }
+
}