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 OptionalLong 27 * @author Mike Duigou 28 * @build ObscureException 29 * @run testng BasicLong 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.LongConsumer; 38 import java.util.stream.LongStream; 39 40 import java.util.NoSuchElementException; 41 import java.util.OptionalLong; 42 import java.util.concurrent.atomic.AtomicBoolean; 43 44 import static org.testng.Assert.*; 45 import org.testng.annotations.Test; 46 47 public class BasicLong { 48 static final long LONGVAL = 2_305_843_008_139_952_128L; 49 static final long UNEXPECTED = 0xFEEDBEEFCAFEBABEL; 50 51 /** 52 * Checks a block of assertions over an empty OptionalLong. 53 */ checkEmpty(OptionalLong empty)54 void checkEmpty(OptionalLong empty) { 55 assertTrue(empty.equals(OptionalLong.empty())); 56 assertTrue(OptionalLong.empty().equals(empty)); 57 assertFalse(empty.equals(OptionalLong.of(UNEXPECTED))); 58 assertFalse(OptionalLong.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(OptionalLong_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.getAsLong()); 70 // Android-changed: Avoid backporting of orElseThrow()) (b/191859202). 71 // assertThrows(NoSuchElementException.class, () -> empty.orElseThrow()); 72 assertThrows(NoSuchElementException.class, () -> OptionalLong_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 OptionalLong_ifPresentOrElse(empty, s -> b1.set(true), () -> b2.set(true)); 84 assertFalse(b1.get()); 85 assertTrue(b2.get()); 86 87 assertEquals(empty.toString(), "OptionalLong.empty"); 88 } 89 90 /** 91 * Checks a block of assertions over an OptionalLong that is expected to 92 * have a particular value present. 93 */ checkPresent(OptionalLong opt, long expected)94 void checkPresent(OptionalLong opt, long expected) { 95 assertFalse(opt.equals(OptionalLong.empty())); 96 assertFalse(OptionalLong.empty().equals(opt)); 97 assertTrue(opt.equals(OptionalLong.of(expected))); 98 assertTrue(OptionalLong.of(expected).equals(opt)); 99 assertFalse(opt.equals(OptionalLong.of(UNEXPECTED))); 100 assertFalse(OptionalLong.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(OptionalLong_isEmpty(opt)); 107 assertEquals(opt.hashCode(), Long.hashCode(expected)); 108 assertEquals(opt.orElse(UNEXPECTED), expected); 109 assertEquals(opt.orElseGet(() -> UNEXPECTED), expected); 110 111 assertEquals(opt.getAsLong(), expected); 112 // Android-changed: Avoid backporting of orElseThrow()) (b/191859202). 113 // assertEquals(opt.orElseThrow(), expected); 114 assertEquals(OptionalLong_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 OptionalLong_ifPresentOrElse(opt, s -> b1.set(true), () -> b2.set(true)); 126 assertTrue(b1.get()); 127 assertFalse(b2.get()); 128 129 assertEquals(opt.toString(), "OptionalLong[" + expected + "]"); 130 } 131 132 @Test(groups = "unit") testEmpty()133 public void testEmpty() { 134 checkEmpty(OptionalLong.empty()); 135 } 136 137 @Test(groups = "unit") testPresent()138 public void testPresent() { 139 checkPresent(OptionalLong.of(LONGVAL), LONGVAL); 140 } 141 142 @Test testStreamEmpty()143 public void testStreamEmpty() { 144 // Android-changed: Avoid backporting of stream() (b/191859202). 145 // assertEquals(OptionalLong.empty().stream().toArray(), new long[] { }); 146 assertEquals(OptionalLong_stream(OptionalLong.empty()).toArray(), new long[] { }); 147 } 148 149 @Test testStreamPresent()150 public void testStreamPresent() { 151 // Android-changed: Avoid backporting of stream() (b/191859202). 152 // assertEquals(OptionalLong.of(LONGVAL).stream().toArray(), new long[] { LONGVAL }); 153 assertEquals(OptionalLong_stream(OptionalLong.of(LONGVAL)).toArray(), 154 new long[] { LONGVAL }); 155 } 156 157 // Android-added: wrapper for d8 backport of OptionalLong.ifPresentOrElse() (b/191859202). OptionalLong_ifPresentOrElse( OptionalLong receiver, LongConsumer action, Runnable emptyAction)158 private static void OptionalLong_ifPresentOrElse( 159 OptionalLong receiver, LongConsumer action, Runnable emptyAction) { 160 try { 161 MethodType type = 162 MethodType.methodType(void.class, LongConsumer.class, Runnable.class); 163 MethodHandle mh = 164 MethodHandles.lookup().findVirtual(OptionalLong.class, "ifPresentOrElse", type); 165 mh.invokeExact(receiver, action, emptyAction); 166 } catch (Throwable t) { 167 throw new RuntimeException(t); 168 } 169 } 170 171 // Android-added: wrapper to avoid d8 backport of OptionalLong.isEmpty() (b/191859202). OptionalLong_isEmpty(OptionalLong receiver)172 private static boolean OptionalLong_isEmpty(OptionalLong receiver) { 173 try { 174 MethodType type = MethodType.methodType(boolean.class); 175 MethodHandle mh = 176 MethodHandles.lookup().findVirtual(OptionalLong.class, "isEmpty", type); 177 return (boolean) mh.invokeExact(receiver); 178 } catch (Throwable t) { 179 throw new RuntimeException(t); 180 } 181 } 182 183 // Android-added: wrapper to avoid d8 backport of OptionalLong.orElseThrow() (b/191859202). OptionalLong_orElseThrow(OptionalLong receiver)184 private static long OptionalLong_orElseThrow(OptionalLong receiver) { 185 try { 186 MethodType type = MethodType.methodType(long.class); 187 MethodHandle mh = 188 MethodHandles.lookup().findVirtual(OptionalLong.class, "orElseThrow", type); 189 return (long) mh.invokeExact(receiver); 190 } catch (NoSuchElementException expected) { 191 throw expected; // Underlying method may throw NoSuchElementException 192 } catch (Throwable t) { 193 throw new RuntimeException(t); 194 } 195 } 196 197 // Android-added: wrapper to avoid d8 backport of OptionalLong.stream() (b/191859202). OptionalLong_stream(OptionalLong receiver)198 private static LongStream OptionalLong_stream(OptionalLong receiver) { 199 try { 200 MethodType type = MethodType.methodType(LongStream.class); 201 MethodHandle mh = 202 MethodHandles.lookup().findVirtual(OptionalLong.class, "stream", type); 203 return (LongStream) mh.invokeExact(receiver); 204 } catch (Throwable t) { 205 throw new RuntimeException(t); 206 } 207 } 208 } 209