1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 8195649 26 * @summary Basic functional test of OptionalDouble 27 * @author Mike Duigou 28 * @build ObscureException 29 * @run testng BasicDouble 30 */ 31 package test.java.util.Optional; 32 33 // Android-added: support for wrapper to avoid d8 backporting of Optional methods (b/191859202). 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.invoke.MethodType; 37 import java.util.function.DoubleConsumer; 38 import java.util.stream.DoubleStream; 39 40 import java.util.NoSuchElementException; 41 import java.util.OptionalDouble; 42 import java.util.concurrent.atomic.AtomicBoolean; 43 44 import static org.testng.Assert.*; 45 import org.testng.annotations.Test; 46 47 public class BasicDouble { 48 static final double DOUBLEVAL = Math.PI; 49 static final double UNEXPECTED = 6.62607004E-34; 50 51 /** 52 * Checks a block of assertions over an empty OptionalDouble. 53 */ checkEmpty(OptionalDouble empty)54 void checkEmpty(OptionalDouble empty) { 55 assertTrue(empty.equals(OptionalDouble.empty())); 56 assertTrue(OptionalDouble.empty().equals(empty)); 57 assertFalse(empty.equals(OptionalDouble.of(UNEXPECTED))); 58 assertFalse(OptionalDouble.of(UNEXPECTED).equals(empty)); 59 assertFalse(empty.equals("unexpected")); 60 61 assertFalse(empty.isPresent()); 62 // Android-changed: Avoid backporting of isEmpty() (b/191859202). 63 // assertTrue(empty.isEmpty()); 64 assertTrue(OptionalDouble_isEmpty(empty)); 65 assertEquals(empty.hashCode(), 0); 66 assertEquals(empty.orElse(UNEXPECTED), UNEXPECTED); 67 assertEquals(empty.orElseGet(() -> UNEXPECTED), UNEXPECTED); 68 69 assertThrows(NoSuchElementException.class, () -> empty.getAsDouble()); 70 // Android-changed: Avoid backporting of orElseThrow() (b/191859202). 71 // assertThrows(NoSuchElementException.class, () -> empty.orElseThrow()); 72 assertThrows(NoSuchElementException.class, () -> OptionalDouble_orElseThrow(empty)); 73 assertThrows(ObscureException.class, () -> empty.orElseThrow(ObscureException::new)); 74 75 var b = new AtomicBoolean(); 76 empty.ifPresent(s -> b.set(true)); 77 assertFalse(b.get()); 78 79 var b1 = new AtomicBoolean(false); 80 var b2 = new AtomicBoolean(false); 81 // Android-changed: Avoid backporting of ifPresentOrElse() (b/191859202). 82 // empty.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true)); 83 OptionalDouble_ifPresentOrElse(empty, s -> b1.set(true), () -> b2.set(true)); 84 assertFalse(b1.get()); 85 assertTrue(b2.get()); 86 87 assertEquals(empty.toString(), "OptionalDouble.empty"); 88 } 89 90 /** 91 * Checks a block of assertions over an OptionalDouble that is expected to 92 * have a particular value present. 93 */ checkPresent(OptionalDouble opt, double expected)94 void checkPresent(OptionalDouble opt, double expected) { 95 assertFalse(opt.equals(OptionalDouble.empty())); 96 assertFalse(OptionalDouble.empty().equals(opt)); 97 assertTrue(opt.equals(OptionalDouble.of(expected))); 98 assertTrue(OptionalDouble.of(expected).equals(opt)); 99 assertFalse(opt.equals(OptionalDouble.of(UNEXPECTED))); 100 assertFalse(OptionalDouble.of(UNEXPECTED).equals(opt)); 101 assertFalse(opt.equals("unexpected")); 102 103 assertTrue(opt.isPresent()); 104 // Android-changed: Avoid backporting of isEmpty() (b/191859202). 105 // assertFalse(opt.isEmpty()); 106 assertFalse(OptionalDouble_isEmpty(opt)); 107 assertEquals(opt.hashCode(), Double.hashCode(expected)); 108 assertEquals(opt.orElse(UNEXPECTED), expected); 109 assertEquals(opt.orElseGet(() -> UNEXPECTED), expected); 110 111 assertEquals(opt.getAsDouble(), expected); 112 // Android-changed: Avoid backporting of orElseThrow() (b/191859202). 113 // assertEquals(opt.orElseThrow(), expected); 114 assertEquals(OptionalDouble_orElseThrow(opt), expected); 115 assertEquals(opt.orElseThrow(ObscureException::new), expected); 116 117 var b = new AtomicBoolean(false); 118 opt.ifPresent(s -> b.set(true)); 119 assertTrue(b.get()); 120 121 var b1 = new AtomicBoolean(false); 122 var b2 = new AtomicBoolean(false); 123 // Android-changed: Avoid backporting of ifPresentOrElse() (b/191859202). 124 // opt.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true)); 125 OptionalDouble_ifPresentOrElse(opt, s -> b1.set(true), () -> b2.set(true)); 126 assertTrue(b1.get()); 127 assertFalse(b2.get()); 128 129 assertEquals(opt.toString(), "OptionalDouble[" + expected + "]"); 130 } 131 132 @Test(groups = "unit") testEmpty()133 public void testEmpty() { 134 checkEmpty(OptionalDouble.empty()); 135 } 136 137 @Test(groups = "unit") testPresent()138 public void testPresent() { 139 checkPresent(OptionalDouble.of(DOUBLEVAL), DOUBLEVAL); 140 } 141 142 @Test testStreamEmpty()143 public void testStreamEmpty() { 144 // Android-changed: Avoid backporting of stream() (b/191859202). 145 // assertEquals(OptionalDouble.empty().stream().toArray(), new double[] { }); 146 assertEquals(OptionalDouble_stream(OptionalDouble.empty()).toArray(), new double[] { }); 147 } 148 149 @Test testStreamPresent()150 public void testStreamPresent() { 151 // Android-changed: Avoid backporting of stream() (b/191859202). 152 // assertEquals(OptionalDouble.of(DOUBLEVAL).stream().toArray(), new double[] { DOUBLEVAL }); 153 assertEquals(OptionalDouble_stream(OptionalDouble.of(DOUBLEVAL)).toArray(), 154 new double[] { DOUBLEVAL }); 155 } 156 157 // Android-added: wrapper for d8 backport of OptionalDouble.ifPresentOrElse() (b/191859202). OptionalDouble_ifPresentOrElse( OptionalDouble receiver, DoubleConsumer action, Runnable emptyAction)158 private static void OptionalDouble_ifPresentOrElse( 159 OptionalDouble receiver, DoubleConsumer action, Runnable emptyAction) { 160 try { 161 MethodType type = 162 MethodType.methodType(void.class, DoubleConsumer.class, Runnable.class); 163 MethodHandle mh = MethodHandles.lookup().findVirtual(OptionalDouble.class, 164 "ifPresentOrElse", 165 type); 166 mh.invokeExact(receiver, action, emptyAction); 167 } catch (Throwable t) { 168 throw new RuntimeException(t); 169 } 170 } 171 172 // Android-added: wrapper to avoid d8 backport of OptionalDouble.isEmpty() (b/191859202). OptionalDouble_isEmpty(OptionalDouble receiver)173 private static boolean OptionalDouble_isEmpty(OptionalDouble receiver) { 174 try { 175 MethodType type = MethodType.methodType(boolean.class); 176 MethodHandle mh = 177 MethodHandles.lookup().findVirtual(OptionalDouble.class, "isEmpty", type); 178 return (boolean) mh.invokeExact(receiver); 179 } catch (Throwable t) { 180 throw new RuntimeException(t); 181 } 182 } 183 184 // Android-added: wrapper to avoid d8 backport of OptionalDouble.orElseThrow() (b/191859202). OptionalDouble_orElseThrow(OptionalDouble receiver)185 private static double OptionalDouble_orElseThrow(OptionalDouble receiver) { 186 try { 187 MethodType type = MethodType.methodType(double.class); 188 MethodHandle mh = 189 MethodHandles.lookup().findVirtual(OptionalDouble.class, "orElseThrow", type); 190 return (double) mh.invokeExact(receiver); 191 } catch (NoSuchElementException expected) { 192 throw expected; // Underlying method may throw NoSuchElementException 193 } catch (Throwable t) { 194 throw new RuntimeException(t); 195 } 196 } 197 198 // Android-added: wrapper to avoid d8 backport of OptionalDouble.stream() (b/191859202). OptionalDouble_stream(OptionalDouble receiver)199 private static DoubleStream OptionalDouble_stream(OptionalDouble receiver) { 200 try { 201 MethodType type = MethodType.methodType(DoubleStream.class); 202 MethodHandle mh = 203 MethodHandles.lookup().findVirtual(OptionalDouble.class, "stream", type); 204 return (DoubleStream) mh.invokeExact(receiver); 205 } catch (Throwable t) { 206 throw new RuntimeException(t); 207 } 208 } 209 } 210