diff --git a/README.md b/README.md
index 9eb5d06ec3..71354ce75b 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,6 @@
`$ ant clean dist-dev`
- or if you don't have `python` and `g++` just run
-
- `$ ant clean dist-dev`
-
Then you will get all `.jar` files in the folder `build/lib` and
the redistributable file will be: `build/dist/gwt-0.0.0.zip`
diff --git a/build_tools/doctool/build.xml b/build_tools/doctool/build.xml
index e6524f1496..c4870197b6 100644
--- a/build_tools/doctool/build.xml
+++ b/build_tools/doctool/build.xml
@@ -4,7 +4,11 @@
-
+
+
diff --git a/common.ant.xml b/common.ant.xml
index 7b3604ba60..36a56b4882 100755
--- a/common.ant.xml
+++ b/common.ant.xml
@@ -62,8 +62,7 @@
-
-
+
@@ -158,8 +157,7 @@
-
-
+
@@ -172,7 +170,7 @@
diff --git a/doc/build.xml b/doc/build.xml
index ae20a50add..97c85ef8e4 100644
--- a/doc/build.xml
+++ b/doc/build.xml
@@ -97,6 +97,7 @@
diff --git a/user/build.xml b/user/build.xml
index d488079c87..f7d2545510 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -15,10 +15,9 @@
-
+ value="**/*JreSuite.class,**/OptimizedOnly*"
+ else="**/*JreSuite.class,**/OptimizedOnly*,**/*Java9Suite.class,**/*Java10Suite.class,**/*Java11Suite.class">
@@ -31,10 +30,9 @@
-
+ value="**/EmulSuite.class,**/JSONSuite.class,**/RunAsyncSuite.class,**/*CompilerSuite.class,**/*JsInteropSuite.class,**/*JreSuite.class,**/OptimizedOnly*"
+ else="**/EmulSuite.class,**/JSONSuite.class,**/RunAsyncSuite.class,**/*CompilerSuite.class,**/*JsInteropSuite.class,**/*JreSuite.class,**/OptimizedOnly*,**/*Java9Suite.class,**/*Java10Suite.class,**/*Java11Suite.class">
@@ -298,13 +296,13 @@
Compiles the test code for this project
-->
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/user/super/com/google/gwt/emul/java/util/List.java b/user/super/com/google/gwt/emul/java/util/List.java
index f8c3ac7f02..d1d20110b8 100644
--- a/user/super/com/google/gwt/emul/java/util/List.java
+++ b/user/super/com/google/gwt/emul/java/util/List.java
@@ -18,6 +18,7 @@
import static javaemul.internal.InternalPreconditions.checkNotNull;
import java.util.function.UnaryOperator;
+import javaemul.internal.ArrayHelper;
import jsinterop.annotations.JsIgnore;
import jsinterop.annotations.JsMethod;
@@ -34,6 +35,85 @@
@JsType
public interface List extends Collection {
+ @JsIgnore
+ static List of() {
+ return Collections.unmodifiableList(Collections.emptyList());
+ }
+
+ @JsIgnore
+ static List of(E e1) {
+ return __ofInternal((E[]) new Object[] {e1});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2) {
+ return __ofInternal((E[]) new Object[] {e1, e2});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5, E e6) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5, e6});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8, e9});
+ }
+
+ @JsIgnore
+ static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+ return __ofInternal((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8, e9, e10});
+ }
+
+ // CHECKSTYLE_OFF: Internal only method that cannot collide with future JRE changes
+ /**
+ * Internal-only helper to avoid copying the incoming array, and instead just wrap it with an
+ * immutable List after checking there are no nulls.
+ */
+ @JsIgnore
+ static List __ofInternal(E[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ checkNotNull(elements[i]);
+ }
+ return Collections.unmodifiableList(Arrays.asList(elements));
+ }
+ // CHECKSTYLE_ON
+
+ @JsIgnore
+ static List of(E... elements) {
+ for (int i = 0; i < elements.length; i++) {
+ checkNotNull(elements[i]);
+ }
+ return Collections.unmodifiableList(
+ Arrays.asList((E[]) ArrayHelper.unsafeClone(elements, 0, elements.length))
+ );
+ }
+
@JsMethod(name = "addAtIndex")
void add(int index, E element);
diff --git a/user/super/com/google/gwt/emul/java/util/Map.java b/user/super/com/google/gwt/emul/java/util/Map.java
index 9c134bc6b3..fd3178b041 100644
--- a/user/super/com/google/gwt/emul/java/util/Map.java
+++ b/user/super/com/google/gwt/emul/java/util/Map.java
@@ -15,6 +15,7 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkArgument;
import static javaemul.internal.InternalPreconditions.checkNotNull;
import java.io.Serializable;
@@ -35,6 +36,211 @@
@JsType
public interface Map {
+ @JsIgnore
+ static Map of() {
+ return Collections.unmodifiableMap(Collections.emptyMap());
+ }
+
+ @JsIgnore
+ static Map of(K key, V value) {
+ return ofEntries(
+ entry(key, value)
+ );
+ }
+
+ @JsIgnore
+ static Map of(K k1, V v1, K k2, V v2) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5,
+ K k6, V v6
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5),
+ entry(k6, v6)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5,
+ K k6, V v6,
+ K k7, V v7
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5),
+ entry(k6, v6),
+ entry(k7, v7)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5,
+ K k6, V v6,
+ K k7, V v7,
+ K k8, V v8
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5),
+ entry(k6, v6),
+ entry(k7, v7),
+ entry(k8, v8)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5,
+ K k6, V v6,
+ K k7, V v7,
+ K k8, V v8,
+ K k9, V v9
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5),
+ entry(k6, v6),
+ entry(k7, v7),
+ entry(k8, v8),
+ entry(k9, v9)
+ );
+ }
+
+ @JsIgnore
+ static Map of(
+ K k1, V v1,
+ K k2, V v2,
+ K k3, V v3,
+ K k4, V v4,
+ K k5, V v5,
+ K k6, V v6,
+ K k7, V v7,
+ K k8, V v8,
+ K k9, V v9,
+ K k10, V v10
+ ) {
+ return ofEntries(
+ entry(k1, v1),
+ entry(k2, v2),
+ entry(k3, v3),
+ entry(k4, v4),
+ entry(k5, v5),
+ entry(k6, v6),
+ entry(k7, v7),
+ entry(k8, v8),
+ entry(k9, v9),
+ entry(k10, v10)
+ );
+ }
+
+ @JsIgnore
+ static Entry entry(K key, V value) {
+ // This isn't quite consistent with the javadoc, since this is serializable, while entry()
+ // need not be serializable.
+ return new AbstractMap.SimpleImmutableEntry<>(
+ checkNotNull(key),
+ checkNotNull(value)
+ );
+ }
+
+ @JsIgnore
+ static Map ofEntries(Entry extends K,? extends V>... entries) {
+ Map map = new HashMap<>();
+
+ for (int i = 0; i < entries.length; i++) {
+ // TODO this perhaps can be optimized if we know the entry is an instance of
+ // AbstractMap.SimpleImmutableEntry, or something more specialized?
+ Entry extends K, ? extends V> entry = checkNotNull(entries[i]);
+ checkArgument(map.put(checkNotNull(entry.getKey()), checkNotNull(entry.getValue())) == null,
+ "Can't add multiple entries with the same key");
+ }
+
+ return Collections.unmodifiableMap(map);
+ }
+
/**
* Represents an individual map entry.
*/
diff --git a/user/super/com/google/gwt/emul/java/util/Optional.java b/user/super/com/google/gwt/emul/java/util/Optional.java
index 3258444409..9485ce88fc 100644
--- a/user/super/com/google/gwt/emul/java/util/Optional.java
+++ b/user/super/com/google/gwt/emul/java/util/Optional.java
@@ -15,14 +15,15 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import static javaemul.internal.InternalPreconditions.checkCriticalNotNull;
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+
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;
-import static javaemul.internal.InternalPreconditions.checkNotNull;
+import java.util.stream.Stream;
/**
* See
@@ -72,6 +73,14 @@ public void ifPresent(Consumer super T> consumer) {
}
}
+ public void ifPresentOrElse(Consumer super T> action, Runnable emptyAction) {
+ if (isPresent()) {
+ action.accept(ref);
+ } else {
+ emptyAction.run();
+ }
+ }
+
public Optional filter(Predicate super T> predicate) {
checkNotNull(predicate);
if (!isPresent() || predicate.test(ref)) {
@@ -96,6 +105,23 @@ public Optional flatMap(Function super T, Optional> mapper) {
return empty();
}
+ public Optional or(Supplier extends Optional extends T>> supplier) {
+ checkNotNull(supplier);
+ if (isPresent()) {
+ return this;
+ } else {
+ return (Optional) checkNotNull(supplier.get());
+ }
+ }
+
+ public Stream stream() {
+ if (isPresent()) {
+ return Stream.of(ref);
+ } else {
+ return Stream.empty();
+ }
+ }
+
public T orElse(T other) {
return isPresent() ? ref : other;
}
@@ -104,6 +130,10 @@ public T orElseGet(Supplier extends T> other) {
return isPresent() ? ref : other.get();
}
+ public T orElseThrow() {
+ return get();
+ }
+
public T orElseThrow(Supplier extends X> exceptionSupplier) throws X {
if (isPresent()) {
return ref;
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalDouble.java b/user/super/com/google/gwt/emul/java/util/OptionalDouble.java
index e6b06af100..fa695b2090 100644
--- a/user/super/com/google/gwt/emul/java/util/OptionalDouble.java
+++ b/user/super/com/google/gwt/emul/java/util/OptionalDouble.java
@@ -15,11 +15,12 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
import java.util.function.DoubleConsumer;
import java.util.function.DoubleSupplier;
import java.util.function.Supplier;
-
-import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import java.util.stream.DoubleStream;
/**
* See
@@ -65,6 +66,22 @@ public void ifPresent(DoubleConsumer consumer) {
}
}
+ public void ifPresentOrElse(DoubleConsumer action, Runnable emptyAction) {
+ if (isPresent()) {
+ action.accept(ref);
+ } else {
+ emptyAction.run();
+ }
+ }
+
+ public DoubleStream stream() {
+ if (isPresent()) {
+ return DoubleStream.of(ref);
+ } else {
+ return DoubleStream.empty();
+ }
+ }
+
public double orElse(double other) {
return present ? ref : other;
}
@@ -73,6 +90,10 @@ public double orElseGet(DoubleSupplier other) {
return present ? ref : other.getAsDouble();
}
+ public double orElseThrow() {
+ return getAsDouble();
+ }
+
public double orElseThrow(Supplier exceptionSupplier) throws X {
if (present) {
return ref;
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalInt.java b/user/super/com/google/gwt/emul/java/util/OptionalInt.java
index 10b7ce6639..63663b73bc 100644
--- a/user/super/com/google/gwt/emul/java/util/OptionalInt.java
+++ b/user/super/com/google/gwt/emul/java/util/OptionalInt.java
@@ -15,11 +15,12 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
-
-import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import java.util.stream.IntStream;
/**
* See
@@ -65,6 +66,22 @@ public void ifPresent(IntConsumer consumer) {
}
}
+ public void ifPresentOrElse(IntConsumer action, Runnable emptyAction) {
+ if (present) {
+ action.accept(ref);
+ } else {
+ emptyAction.run();
+ }
+ }
+
+ public IntStream stream() {
+ if (present) {
+ return IntStream.of(ref);
+ } else {
+ return IntStream.empty();
+ }
+ }
+
public int orElse(int other) {
return present ? ref : other;
}
@@ -73,6 +90,10 @@ public int orElseGet(IntSupplier other) {
return present ? ref : other.getAsInt();
}
+ public int orElseThrow() {
+ return getAsInt();
+ }
+
public int orElseThrow(Supplier exceptionSupplier) throws X {
if (present) {
return ref;
diff --git a/user/super/com/google/gwt/emul/java/util/OptionalLong.java b/user/super/com/google/gwt/emul/java/util/OptionalLong.java
index 8551777860..978bddeb1c 100644
--- a/user/super/com/google/gwt/emul/java/util/OptionalLong.java
+++ b/user/super/com/google/gwt/emul/java/util/OptionalLong.java
@@ -15,11 +15,12 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+
import java.util.function.LongConsumer;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
-
-import static javaemul.internal.InternalPreconditions.checkCriticalElement;
+import java.util.stream.LongStream;
/**
* See
@@ -65,6 +66,22 @@ public void ifPresent(LongConsumer consumer) {
}
}
+ public void ifPresentOrElse(LongConsumer action, Runnable emptyAction) {
+ if (present) {
+ action.accept(ref);
+ } else {
+ emptyAction.run();
+ }
+ }
+
+ public LongStream stream() {
+ if (present) {
+ return LongStream.of(ref);
+ } else {
+ return LongStream.empty();
+ }
+ }
+
public long orElse(long other) {
return present ? ref : other;
}
@@ -73,6 +90,10 @@ public long orElseGet(LongSupplier other) {
return present ? ref : other.getAsLong();
}
+ public long orElseThrow() {
+ return getAsLong();
+ }
+
public long orElseThrow(Supplier exceptionSupplier) throws X {
if (present) {
return ref;
diff --git a/user/super/com/google/gwt/emul/java/util/Set.java b/user/super/com/google/gwt/emul/java/util/Set.java
index 8a5bf8cb38..eddd4dffe9 100644
--- a/user/super/com/google/gwt/emul/java/util/Set.java
+++ b/user/super/com/google/gwt/emul/java/util/Set.java
@@ -15,6 +15,9 @@
*/
package java.util;
+import static javaemul.internal.InternalPreconditions.checkArgument;
+import static javaemul.internal.InternalPreconditions.checkNotNull;
+
import jsinterop.annotations.JsIgnore;
import jsinterop.annotations.JsType;
@@ -26,6 +29,70 @@
*/
@JsType
public interface Set extends Collection {
+ @JsIgnore
+ static Set of() {
+ return Collections.unmodifiableSet(Collections.emptySet());
+ }
+
+ @JsIgnore
+ static Set of(E e1) {
+ return of((E[]) new Object[] {e1});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2) {
+ return of((E[]) new Object[] {e1, e2});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3) {
+ return of((E[]) new Object[] {e1, e2, e3});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4) {
+ return of((E[]) new Object[] {e1, e2, e3, e4});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5, e6});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8, e9});
+ }
+
+ @JsIgnore
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+ return of((E[]) new Object[] {e1, e2, e3, e4, e5, e6, e7, e8, e9, e10});
+ }
+
+ @JsIgnore
+ static Set of(E... elements) {
+ HashSet set = new HashSet<>();
+ for (int i = 0; i < elements.length; i++) {
+ checkArgument(set.add(checkNotNull(elements[i])), "Can't add the same item multiple times");
+ }
+ return Collections.unmodifiableSet(set);
+ }
+
@JsIgnore
@Override
default Spliterator spliterator() {
diff --git a/user/test/com/google/gwt/emultest/EmulJava10Suite.java b/user/test/com/google/gwt/emultest/EmulJava10Suite.java
new file mode 100644
index 0000000000..e691477626
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/EmulJava10Suite.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2023 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;
+
+import com.google.gwt.emultest.java10.util.OptionalDoubleTest;
+import com.google.gwt.emultest.java10.util.OptionalIntTest;
+import com.google.gwt.emultest.java10.util.OptionalLongTest;
+import com.google.gwt.emultest.java10.util.OptionalTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/** Test JRE emulations. */
+@RunWith(Suite.class)
+@SuiteClasses({
+ OptionalDoubleTest.class,
+ OptionalIntTest.class,
+ OptionalLongTest.class,
+ OptionalTest.class,
+})
+public class EmulJava10Suite {
+}
diff --git a/user/test/com/google/gwt/emultest/EmulJava9Suite.java b/user/test/com/google/gwt/emultest/EmulJava9Suite.java
new file mode 100644
index 0000000000..6cdf37ed74
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/EmulJava9Suite.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 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;
+
+import com.google.gwt.emultest.java9.util.ListTest;
+import com.google.gwt.emultest.java9.util.MapTest;
+import com.google.gwt.emultest.java9.util.OptionalDoubleTest;
+import com.google.gwt.emultest.java9.util.OptionalIntTest;
+import com.google.gwt.emultest.java9.util.OptionalLongTest;
+import com.google.gwt.emultest.java9.util.OptionalTest;
+import com.google.gwt.emultest.java9.util.SetTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/** Test JRE emulations. */
+@RunWith(Suite.class)
+@SuiteClasses({
+ ListTest.class,
+ MapTest.class,
+ OptionalDoubleTest.class,
+ OptionalIntTest.class,
+ OptionalLongTest.class,
+ OptionalTest.class,
+ SetTest.class
+})
+public class EmulJava9Suite {
+}
diff --git a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
index 550ef4bbf3..85c3a4cf6b 100644
--- a/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
+++ b/user/test/com/google/gwt/emultest/EmulSuite.gwt.xml
@@ -17,6 +17,9 @@
+
+
+
diff --git a/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java b/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
index c1fc5de991..93fd94b9e7 100644
--- a/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
+++ b/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
@@ -57,6 +57,24 @@ public static void assertEquals(double[] expected, double[] actual) {
Arrays.equals(expected, actual));
}
+ public static void assertNPE(String methodName, Runnable runnable) {
+ try {
+ runnable.run();
+ fail("Expected NPE from calling " + methodName);
+ } catch (NullPointerException ignored) {
+ // expected
+ }
+ }
+
+ public static void assertIAE(String methodName, Runnable runnable) {
+ try {
+ runnable.run();
+ fail("Expected IAE from calling " + methodName);
+ } catch (IllegalArgumentException ignored) {
+ // expected
+ }
+ }
+
@Override
public String getModuleName() {
return "com.google.gwt.emultest.EmulSuite";
diff --git a/user/test/com/google/gwt/emultest/java10/util/OptionalDoubleTest.java b/user/test/com/google/gwt/emultest/java10/util/OptionalDoubleTest.java
new file mode 100644
index 0000000000..ac39290ff1
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java10/util/OptionalDoubleTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 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.java10.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalDouble;
+
+/**
+ * Tests for java.util.OptionalDouble Java 10 API emulation.
+ */
+public class OptionalDoubleTest extends EmulTestBase {
+ public void testOrElseThrow() {
+ try {
+ OptionalDouble.empty().orElseThrow();
+ fail("Expected NoSuchElementException from empty Optional: orElseThrow");
+ } catch (NoSuchElementException ignore) {
+ // expected
+ }
+
+ double value = OptionalDouble.of(10.0).orElseThrow();
+ assertEquals(10.0, value);
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java10/util/OptionalIntTest.java b/user/test/com/google/gwt/emultest/java10/util/OptionalIntTest.java
new file mode 100644
index 0000000000..59b3953987
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java10/util/OptionalIntTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 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.java10.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalInt;
+
+/**
+ * Tests for java.util.OptionalInt Java 10 API emulation.
+ */
+public class OptionalIntTest extends EmulTestBase {
+ public void testOrElseThrow() {
+ try {
+ OptionalInt.empty().orElseThrow();
+ fail("Expected NoSuchElementException from empty Optional: orElseThrow");
+ } catch (NoSuchElementException ignore) {
+ // expected
+ }
+
+ int value = OptionalInt.of(10).orElseThrow();
+ assertEquals(10, value);
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java10/util/OptionalLongTest.java b/user/test/com/google/gwt/emultest/java10/util/OptionalLongTest.java
new file mode 100644
index 0000000000..1fb35891bd
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java10/util/OptionalLongTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2023 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.java10.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.NoSuchElementException;
+import java.util.OptionalLong;
+
+/**
+ * Tests for java.util.OptionalLong Java 10 API emulation.
+ */
+public class OptionalLongTest extends EmulTestBase {
+ public void testOrElseThrow() {
+ try {
+ OptionalLong.empty().orElseThrow();
+ fail("Expected NoSuchElementException from empty Optional: orElseThrow");
+ } catch (NoSuchElementException ignore) {
+ // expected
+ }
+
+ long value = OptionalLong.of(10L).orElseThrow();
+ assertEquals(10L, value);
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java10/util/OptionalTest.java b/user/test/com/google/gwt/emultest/java10/util/OptionalTest.java
new file mode 100644
index 0000000000..d263599388
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java10/util/OptionalTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 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.java10.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+/**
+ * Tests for java.util.Optional Java 10 API emulation.
+ */
+public class OptionalTest extends EmulTestBase {
+ @SuppressWarnings("OptionalOfRedundantMethod")
+ public void testOrElseThrow() {
+ try {
+ Optional.empty().orElseThrow();
+ fail("Expected NoSuchElementException from empty Optional: orElseThrow");
+ } catch (NoSuchElementException ignore) {
+ // expected
+ }
+
+ String value = Optional.of("value").orElseThrow();
+ assertEquals("value", value);
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/ListTest.java b/user/test/com/google/gwt/emultest/java9/util/ListTest.java
new file mode 100644
index 0000000000..d1487a477f
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/ListTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Tests for java.util.List Java 9 API emulation.
+ */
+public class ListTest extends EmulTestBase {
+
+ public void testOf() {
+ assertIsImmutableListOf(List.of());
+ assertIsImmutableListOf(List.of("a"), "a");
+ assertIsImmutableListOf(
+ List.of("a", "b"),
+ "a", "b"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c"),
+ "a", "b", "c"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d"),
+ "a", "b", "c", "d"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e"),
+ "a", "b", "c", "d", "e"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f"),
+ "a", "b", "c", "d", "e", "f"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f", "g"),
+ "a", "b", "c", "d", "e", "f", "g"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f", "g", "h"),
+ "a", "b", "c", "d", "e", "f", "g", "h"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+ "a", "b", "c", "d", "e", "f", "g", "h", "i"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"
+ );
+ assertIsImmutableListOf(
+ List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"),
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"
+ );
+
+ // ensure that NPE is thrown if a value is null
+ assertNPE("of", () -> List.of((String) null));
+ assertNPE("of", () -> List.of("a", null));
+ assertNPE("of", () -> List.of("a", "b", null));
+ assertNPE("of", () -> List.of("a", "b", "c", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", "f", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", "f", "g", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", "f", "g", "h", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null));
+ assertNPE("of", () -> List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", null));
+ }
+
+ protected static void assertIsImmutableListOf(List list, String... contents) {
+ assertEquals(contents, list);
+
+ // quick test that the list impl is sane
+ if (contents.length == 0) {
+ assertFalse(list.iterator().hasNext());
+ } else {
+ Iterator itr = list.iterator();
+ assertTrue(itr.hasNext());
+ assertEquals(contents[0], itr.next());
+ assertEquals(contents.length > 1, itr.hasNext());
+ }
+
+ // quick check that the list is immutable
+ try {
+ list.add("another item");
+ fail("List should be unmodifiable: add(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+
+ try {
+ list.remove(0);
+ fail("List should be unmodifiable: remove(int)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+
+ // if any, remove an item actually in the list
+ if (contents.length > 0) {
+ // Without any items, remove(T) defaults to iterating items present, so we only test from
+ // present items
+ try {
+ list.remove(contents[0]);
+ fail("List should be unmodifiable: remove(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+ }
+
+ // Remove an item that will not be in the list
+ try {
+ list.remove("not present");
+ fail("List should be unmodifiable: remove(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+
+ try {
+ list.clear();
+ fail("List should be unmodifiable: clear()");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/MapTest.java b/user/test/com/google/gwt/emultest/java9/util/MapTest.java
new file mode 100644
index 0000000000..9d1356f9ca
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/MapTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.Map;
+
+/**
+ * Tests for java.util.Map Java 9 API emulation.
+ */
+public class MapTest extends EmulTestBase {
+
+ public void testOf() {
+ assertIsImmutableMapOf(Map.of());
+ assertIsImmutableMapOf(Map.of("a", 1), "a");
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2),
+ "a", "b"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3),
+ "a", "b", "c"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4),
+ "a", "b", "c", "d"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5),
+ "a", "b", "c", "d", "e"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6),
+ "a", "b", "c", "d", "e", "f"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7),
+ "a", "b", "c", "d", "e", "f", "g"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8),
+ "a", "b", "c", "d", "e", "f", "g", "h"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9),
+ "a", "b", "c", "d", "e", "f", "g", "h", "i"
+ );
+ assertIsImmutableMapOf(
+ Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 10),
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"
+ );
+
+ // ensure NullPointerException if either key or value are null for any param
+ assertNPE("Map.of(1)", () -> Map.of(null, 1));
+ assertNPE("Map.of(1)", () -> Map.of("a", null));
+ assertNPE("Map.of(2)", () -> Map.of("a", 1, null, 2));
+ assertNPE("Map.of(2)", () -> Map.of("a", 1, "b", null));
+ assertNPE("Map.of(3)", () -> Map.of("a", 1, "b", 2, null, 3));
+ assertNPE("Map.of(3)", () -> Map.of("a", 1, "b", 2, "c", null));
+ assertNPE("Map.of(4)", () -> Map.of("a", 1, "b", 2, "c", 3, null, 4));
+ assertNPE("Map.of(4)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", null));
+ assertNPE("Map.of(5)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, null, 5));
+ assertNPE("Map.of(5)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", null));
+ assertNPE("Map.of(6)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, null, 6));
+ assertNPE("Map.of(6)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", null));
+ assertNPE("Map.of(7)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ null, 7));
+ assertNPE("Map.of(7)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", null));
+ assertNPE("Map.of(8)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, null, 8));
+ assertNPE("Map.of(8)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, "h", null));
+ assertNPE("Map.of(9)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, "h", 8, null, 9));
+ assertNPE("Map.of(9)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, "h", 8, "i", null));
+ assertNPE("Map.of(10)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, "h", 8, "i", 9, null, 10));
+ assertNPE("Map.of(10)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6,
+ "g", 7, "h", 8, "i", 9, "j", null));
+
+ // ensure IllegalArgumentException if any key is repeated
+ assertIAE("Map.of(2)", () -> Map.of("a", 1, "a", 2));
+ assertIAE("Map.of(3)", () -> Map.of("a", 1, "b", 2, "a", 3));
+ assertIAE("Map.of(4)", () -> Map.of("a", 1, "b", 2, "c", 3, "a", 4));
+ assertIAE("Map.of(5)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "a", 5));
+ assertIAE("Map.of(6)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "a", 6));
+ assertIAE("Map.of(7)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "a", 7));
+ assertIAE("Map.of(8)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7,
+ "a", 8));
+ assertIAE("Map.of(9)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7,
+ "h", 8, "a", 9));
+ assertIAE("Map.of(10)", () -> Map.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7,
+ "h", 8, "i", 9, "a", 10));
+ }
+
+ protected static void assertIsImmutableMapOf(Map map, String... contents) {
+ assertEquals(contents.length, map.size());
+ for (int i = 0; i < contents.length; i++) {
+ assertTrue(map.containsKey(contents[i]));
+ assertFalse(map.containsKey(contents[i] + "nope"));
+ assertEquals(i + 1, (int) map.get(contents[i]));
+ }
+
+ // quick check that the map is immutable
+ try {
+ map.put("another item", 1);
+ fail("Set should be unmodifiable: add(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+
+ if (contents.length > 1) {
+ // Without any items, remove(T) defaults to iterating items present, so we only test from
+ // present items
+ try {
+ map.remove(contents[0]);
+ fail("Map should be unmodifiable: remove(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+ }
+
+ try {
+ map.remove("not found");
+ fail("Map should be unmodifiable: remove(T)");
+ } catch (UnsupportedOperationException ignored) {
+ // success
+ }
+
+ try {
+ map.clear();
+ fail("Set should be unmodifiable: clear()");
+ } catch (UnsupportedOperationException ignored) {
+ // expected
+ }
+ }
+
+ public void testEntry() {
+ Map.Entry entry = Map.entry("a", "b");
+
+ assertEquals("a", entry.getKey());
+ assertEquals("b", entry.getValue());
+
+ try {
+ entry.setValue("z");
+ fail("Entry should be immutable: setValue");
+ } catch (UnsupportedOperationException ignore) {
+ // expected
+ }
+
+ assertNPE("Map.entry", () -> {
+ Map.entry(null, "value");
+ });
+ assertNPE("Map.entry", () -> {
+ Map.entry("key", null);
+ });
+ }
+
+ @SuppressWarnings("DuplicateMapKeys")
+ public void testOfEntries() {
+ Map map = Map.ofEntries(
+ Map.entry("a", 1),
+ Map.entry("b", 2)
+ );
+
+ assertIsImmutableMapOf(map, "a", "b");
+
+ // ensure NullPointerException if any entry is null, if any key is null, or value is null
+ assertNPE("Map.ofEntries", () -> {
+ Map.ofEntries(
+ Map.entry("a", "b"),
+ null
+ );
+ });
+ assertNPE("Map.ofEntries", () -> {
+ Map.ofEntries(
+ Map.entry("a", "b"),
+ Map.entry("c", null)
+ );
+ });
+ assertNPE("Map.ofEntries", () -> {
+ Map.ofEntries(
+ Map.entry("a", "b"),
+ Map.entry(null, "d")
+ );
+ });
+
+ // ensure IllegalArgumentException if any pair has the same key (same or different value)
+ assertIAE("Map.ofEntries", () -> {
+ Map.ofEntries(
+ Map.entry("a", "b"),
+ Map.entry("a", "b")
+ );
+ });
+ assertIAE("Map.ofEntries", () -> {
+ Map.ofEntries(
+ Map.entry("a", "b"),
+ Map.entry("a", "c")
+ );
+ });
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/OptionalDoubleTest.java b/user/test/com/google/gwt/emultest/java9/util/OptionalDoubleTest.java
new file mode 100644
index 0000000000..6c1aaf294e
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/OptionalDoubleTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.OptionalDouble;
+import java.util.stream.Stream;
+
+/**
+ * Tests for java.util.OptionalDouble Java 9 API emulation.
+ */
+public class OptionalDoubleTest extends EmulTestBase {
+ public void testIfPresentOrElse() {
+ int[] called = {0};
+ OptionalDouble.of(10.0).ifPresentOrElse(value -> {
+ assertEquals(10.0, value);
+ called[0]++;
+ }, () -> {
+ fail("should not call empty action");
+ });
+ assertEquals(1, called[0]);
+ called[0] = 0;
+ OptionalDouble.empty().ifPresentOrElse(ignore -> {
+ fail("Should not call present action");
+ }, () -> called[0]++);
+ assertEquals(1, called[0]);
+ }
+
+ public void testStream() {
+ assertEquals(0, OptionalDouble.empty().stream().count());
+ assertEquals(1, OptionalDouble.of(10.0).stream().count());
+
+ assertEquals(
+ new double[] {10.0, 100.0, 1000.0},
+ Stream.of(
+ OptionalDouble.of(10.0),
+ OptionalDouble.empty(),
+ OptionalDouble.of(100.0),
+ OptionalDouble.of(1000.0)
+ ).flatMapToDouble(OptionalDouble::stream).toArray()
+ );
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/OptionalIntTest.java b/user/test/com/google/gwt/emultest/java9/util/OptionalIntTest.java
new file mode 100644
index 0000000000..b6fa378345
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/OptionalIntTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.OptionalInt;
+import java.util.stream.Stream;
+
+/**
+ * Tests for java.util.OptionalInt Java 9 API emulation.
+ */
+public class OptionalIntTest extends EmulTestBase {
+ public void testIfPresentOrElse() {
+ int[] called = {0};
+ OptionalInt.of(10).ifPresentOrElse(value -> {
+ assertEquals(10, value);
+ called[0]++;
+ }, () -> {
+ fail("should not call empty action");
+ });
+ assertEquals(1, called[0]);
+ called[0] = 0;
+ OptionalInt.empty().ifPresentOrElse(ignore -> {
+ fail("Should not call present action");
+ }, () -> called[0]++);
+ assertEquals(1, called[0]);
+ }
+
+ public void testStream() {
+ assertEquals(0, OptionalInt.empty().stream().count());
+ assertEquals(1, OptionalInt.of(10).stream().count());
+
+ assertEquals(
+ new int[] {10, 100, 1000},
+ Stream.of(
+ OptionalInt.of(10),
+ OptionalInt.empty(),
+ OptionalInt.of(100),
+ OptionalInt.of(1000)
+ ).flatMapToInt(OptionalInt::stream).toArray()
+ );
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/OptionalLongTest.java b/user/test/com/google/gwt/emultest/java9/util/OptionalLongTest.java
new file mode 100644
index 0000000000..5bb4ed670d
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/OptionalLongTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.OptionalLong;
+import java.util.stream.Stream;
+
+/**
+ * Tests for java.util.OptionalLong Java 9 API emulation.
+ */
+public class OptionalLongTest extends EmulTestBase {
+ public void testIfPresentOrElse() {
+ int[] called = {0};
+ OptionalLong.of(10).ifPresentOrElse(value -> {
+ assertEquals(10, value);
+ called[0]++;
+ }, () -> {
+ fail("should not call empty action");
+ });
+ assertEquals(1, called[0]);
+ called[0] = 0;
+ OptionalLong.empty().ifPresentOrElse(ignore -> {
+ fail("Should not call present action");
+ }, () -> called[0]++);
+ assertEquals(1, called[0]);
+ }
+
+ public void testStream() {
+ assertEquals(0, OptionalLong.empty().stream().count());
+ assertEquals(1, OptionalLong.of(10).stream().count());
+
+ assertEquals(
+ new long[] {10, 100, 1000},
+ Stream.of(
+ OptionalLong.of(10),
+ OptionalLong.empty(),
+ OptionalLong.of(100),
+ OptionalLong.of(1000)
+ ).flatMapToLong(OptionalLong::stream).toArray()
+ );
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java9/util/OptionalTest.java b/user/test/com/google/gwt/emultest/java9/util/OptionalTest.java
new file mode 100644
index 0000000000..e7befa7724
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java9/util/OptionalTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2023 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.java9.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * Tests for java.util.Optional Java 9 API emulation.
+ */
+public class OptionalTest extends EmulTestBase {
+ public void testIfPresentOrElse() {
+ int[] called = {0};
+ Optional.of("value").ifPresentOrElse(value -> {
+ assertEquals("value", value);
+ called[0]++;
+ }, () -> {
+ fail("should not call empty action");
+ });
+ assertEquals(1, called[0]);
+ called[0] = 0;
+ Optional.empty().ifPresentOrElse(ignore -> {
+ fail("Should not call present action");
+ }, () -> called[0]++);
+ assertEquals(1, called[0]);
+ }
+
+ public void testOr() {
+ Optional or = Optional.of("value").or(() -> Optional.of("replacement"));
+ assertTrue(or.isPresent());
+ assertEquals("value", or.get());
+
+ or = Optional.empty().or(() -> Optional.of("replacement"));
+ assertTrue(or.isPresent());
+ assertEquals("replacement", or.get());
+
+ or = Optional.of("value").or(() -> Optional.empty());
+ assertTrue(or.isPresent());
+ assertEquals("value", or.get());
+
+ or = Optional.empty().or(() -> Optional.empty());
+ assertFalse(or.isPresent());
+
+ Optional