1 /* 2 * Copyright (c) 2013, 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 * @summary Basic functional test of Optional 26 * @author Mike Duigou 27 * @run testng Basic 28 */ 29 30 import java.lang.AssertionError; 31 import java.lang.NullPointerException; 32 import java.lang.Throwable; 33 import java.util.NoSuchElementException; 34 import java.util.Optional; 35 import java.util.concurrent.atomic.AtomicBoolean; 36 import java.util.stream.Stream; 37 38 import static org.testng.Assert.*; 39 import org.testng.annotations.Test; 40 41 42 public class Basic { 43 44 @Test(groups = "unit") 45 public void testEmpty() { 46 Optional<Boolean> empty = Optional.empty(); 47 Optional<String> presentEmptyString = Optional.of(""); 48 Optional<Boolean> present = Optional.of(Boolean.TRUE); 49 50 // empty 51 assertTrue(empty.equals(empty)); 52 assertTrue(empty.equals(Optional.empty())); 53 assertTrue(!empty.equals(present)); 54 assertTrue(0 == empty.hashCode()); 55 assertTrue(!empty.toString().isEmpty()); 56 assertTrue(!empty.toString().equals(presentEmptyString.toString())); 57 assertTrue(!empty.isPresent()); 58 59 empty.ifPresent(v -> fail()); 60 61 AtomicBoolean emptyCheck = new AtomicBoolean(); 62 empty.ifPresentOrElse(v -> fail(), () -> emptyCheck.set(true)); 63 assertTrue(emptyCheck.get()); 64 65 try { 66 empty.ifPresentOrElse(v -> fail(), () -> { throw new ObscureException(); }); 67 fail(); 68 } catch (ObscureException expected) { 69 } catch (AssertionError e) { 70 throw e; 71 } catch (Throwable t) { 72 fail(); 73 } 74 75 assertSame(null, empty.orElse(null)); 76 RuntimeException orElse = new RuntimeException() { }; 77 assertSame(Boolean.FALSE, empty.orElse(Boolean.FALSE)); 78 assertSame(null, empty.orElseGet(() -> null)); 79 assertSame(Boolean.FALSE, empty.orElseGet(() -> Boolean.FALSE)); 80 } 81 82 @Test(groups = "unit") 83 public void testIfPresentAndOrElseAndNull() { 84 Optional<Boolean> empty = Optional.empty(); 85 Optional<Boolean> present = Optional.of(Boolean.TRUE); 86 87 // No NPE 88 present.ifPresentOrElse(v -> {}, null); 89 empty.ifPresent(null); 90 empty.ifPresentOrElse(null, () -> {}); 91 92 // NPE 93 try { 94 present.ifPresent(null); 95 fail(); 96 } catch (NullPointerException ex) {} 97 try { 98 present.ifPresentOrElse(null, () -> {}); 99 fail(); 100 } catch (NullPointerException ex) {} 101 try { 102 empty.ifPresentOrElse(v -> {}, null); 103 fail(); 104 } catch (NullPointerException ex) {} 105 } 106 107 @Test(expectedExceptions=NoSuchElementException.class) 108 public void testEmptyGet() { 109 Optional<Boolean> empty = Optional.empty(); 110 111 Boolean got = empty.get(); 112 } 113 114 @Test(expectedExceptions=NullPointerException.class) 115 public void testEmptyOrElseGetNull() { 116 Optional<Boolean> empty = Optional.empty(); 117 118 Boolean got = empty.orElseGet(null); 119 } 120 121 @Test(expectedExceptions=NullPointerException.class) 122 public void testEmptyOrElseThrowNull() throws Throwable { 123 Optional<Boolean> empty = Optional.empty(); 124 125 Boolean got = empty.orElseThrow(null); 126 } 127 128 @Test(expectedExceptions=ObscureException.class) 129 public void testEmptyOrElseThrow() throws Exception { 130 Optional<Boolean> empty = Optional.empty(); 131 132 Boolean got = empty.orElseThrow(ObscureException::new); 133 } 134 135 @Test(expectedExceptions=NoSuchElementException.class) 136 public void testEmptyOrElseThrowNoArg() throws Exception { 137 Optional<Boolean> empty = Optional.empty(); 138 139 Boolean got = empty.orElseThrow(); 140 } 141 142 @Test(groups = "unit") 143 public void testPresent() { 144 Optional<Boolean> empty = Optional.empty(); 145 Optional<String> presentEmptyString = Optional.of(""); 146 Optional<Boolean> present = Optional.of(Boolean.TRUE); 147 148 // present 149 assertTrue(present.equals(present)); 150 assertTrue(present.equals(Optional.of(Boolean.TRUE))); 151 assertTrue(!present.equals(empty)); 152 assertTrue(Boolean.TRUE.hashCode() == present.hashCode()); 153 assertTrue(!present.toString().isEmpty()); 154 assertTrue(!present.toString().equals(presentEmptyString.toString())); 155 assertTrue(-1 != present.toString().indexOf(Boolean.TRUE.toString())); 156 assertSame(Boolean.TRUE, present.get()); 157 assertSame(Boolean.TRUE, present.orElseThrow()); 158 159 AtomicBoolean presentCheck = new AtomicBoolean(); 160 present.ifPresent(v -> presentCheck.set(true)); 161 assertTrue(presentCheck.get()); 162 presentCheck.set(false); 163 present.ifPresentOrElse(v -> presentCheck.set(true), () -> fail()); 164 assertTrue(presentCheck.get()); 165 166 try { 167 present.ifPresent(v -> { throw new ObscureException(); }); 168 fail(); 169 } catch (ObscureException expected) { 170 } catch (AssertionError e) { 171 throw e; 172 } catch (Throwable t) { 173 fail(); 174 } 175 try { 176 present.ifPresentOrElse(v -> { throw new ObscureException(); }, () -> fail()); 177 fail(); 178 } catch (ObscureException expected) { 179 } catch (AssertionError e) { 180 throw e; 181 } catch (Throwable t) { 182 fail(); 183 } 184 185 assertSame(Boolean.TRUE, present.orElse(null)); 186 assertSame(Boolean.TRUE, present.orElse(Boolean.FALSE)); 187 assertSame(Boolean.TRUE, present.orElseGet(null)); 188 assertSame(Boolean.TRUE, present.orElseGet(() -> null)); 189 assertSame(Boolean.TRUE, present.orElseGet(() -> Boolean.FALSE)); 190 assertSame(Boolean.TRUE, present.<RuntimeException>orElseThrow(null)); 191 assertSame(Boolean.TRUE, present.<RuntimeException>orElseThrow(ObscureException::new)); 192 } 193 194 @Test(groups = "unit") 195 public void testOfNullable() { 196 Optional<String> instance = Optional.ofNullable(null); 197 assertFalse(instance.isPresent()); 198 199 instance = Optional.ofNullable("Duke"); 200 assertTrue(instance.isPresent()); 201 assertEquals(instance.get(), "Duke"); 202 assertEquals(instance.orElseThrow(), "Duke"); 203 } 204 205 @Test(groups = "unit") 206 public void testFilter() { 207 // Null mapper function 208 Optional<String> empty = Optional.empty(); 209 Optional<String> duke = Optional.of("Duke"); 210 211 try { 212 Optional<String> result = empty.filter(null); 213 fail("Should throw NPE on null mapping function"); 214 } catch (NullPointerException npe) { 215 // expected 216 } 217 218 Optional<String> result = empty.filter(String::isEmpty); 219 assertFalse(result.isPresent()); 220 221 result = duke.filter(String::isEmpty); 222 assertFalse(result.isPresent()); 223 result = duke.filter(s -> s.startsWith("D")); 224 assertTrue(result.isPresent()); 225 assertEquals(result.get(), "Duke"); 226 assertEquals(result.orElseThrow(), "Duke"); 227 228 Optional<String> emptyString = Optional.of(""); 229 result = emptyString.filter(String::isEmpty); 230 assertTrue(result.isPresent()); 231 assertEquals(result.get(), ""); 232 assertEquals(result.orElseThrow(), ""); 233 } 234 235 @Test(groups = "unit") 236 public void testMap() { 237 Optional<String> empty = Optional.empty(); 238 Optional<String> duke = Optional.of("Duke"); 239 240 // Null mapper function 241 try { 242 Optional<Boolean> b = empty.map(null); 243 fail("Should throw NPE on null mapping function"); 244 } catch (NullPointerException npe) { 245 // expected 246 } 247 248 // Map an empty value 249 Optional<Boolean> b = empty.map(String::isEmpty); 250 assertFalse(b.isPresent()); 251 252 // Map into null 253 b = empty.map(n -> null); 254 assertFalse(b.isPresent()); 255 b = duke.map(s -> null); 256 assertFalse(b.isPresent()); 257 258 // Map to value 259 Optional<Integer> l = duke.map(String::length); 260 assertEquals(l.get().intValue(), 4); 261 } 262 263 @Test(groups = "unit") 264 public void testFlatMap() { 265 Optional<String> empty = Optional.empty(); 266 Optional<String> duke = Optional.of("Duke"); 267 268 // Null mapper function 269 try { 270 Optional<Boolean> b = empty.flatMap(null); 271 fail("Should throw NPE on null mapping function"); 272 } catch (NullPointerException npe) { 273 // expected 274 } 275 276 // Map into null 277 try { 278 Optional<Boolean> b = duke.flatMap(s -> null); 279 fail("Should throw NPE when mapper return null"); 280 } catch (NullPointerException npe) { 281 // expected 282 } 283 284 // Empty won't invoke mapper function 285 try { 286 Optional<Boolean> b = empty.flatMap(s -> null); 287 assertFalse(b.isPresent()); 288 } catch (NullPointerException npe) { 289 fail("Mapper function should not be invoked"); 290 } 291 292 // Map an empty value 293 Optional<Integer> l = empty.flatMap(s -> Optional.of(s.length())); 294 assertFalse(l.isPresent()); 295 296 // Map to value 297 Optional<Integer> fixture = Optional.of(Integer.MAX_VALUE); 298 l = duke.flatMap(s -> Optional.of(s.length())); 299 assertTrue(l.isPresent()); 300 assertEquals(l.get().intValue(), 4); 301 assertEquals(l.orElseThrow().intValue(), 4); 302 303 // Verify same instance 304 l = duke.flatMap(s -> fixture); 305 assertSame(l, fixture); 306 } 307 308 @Test(groups = "unit") 309 public void testOr() { 310 Optional<String> empty = Optional.empty(); 311 Optional<String> duke = Optional.of("Duke"); 312 313 // Null supplier 314 try { 315 Optional<String> b = empty.or(null); 316 fail("Should throw NPE on null supplier"); 317 } catch (NullPointerException npe) { 318 // expected 319 } 320 321 // Supply null 322 try { 323 Optional<String> b = empty.or(() -> null); 324 fail("Should throw NPE when supplier returns null"); 325 } catch (NullPointerException npe) { 326 // expected 327 } 328 329 // Non-empty won't invoke supplier 330 try { 331 Optional<String> b = duke.or(() -> null); 332 assertTrue(b.isPresent()); 333 } catch (NullPointerException npe) { 334 fail("Supplier should not be invoked"); 335 } 336 337 // Supply for empty 338 Optional<String> suppliedDuke = empty.or(() -> duke); 339 assertTrue(suppliedDuke.isPresent()); 340 assertSame(suppliedDuke, duke); 341 342 // Supply for non-empty 343 Optional<String> actualDuke = duke.or(() -> Optional.of("Other Duke")); 344 assertTrue(actualDuke.isPresent()); 345 assertSame(actualDuke, duke); 346 } 347 348 @Test(groups = "unit") 349 public void testStream() { 350 { 351 Stream<String> s = Optional.<String>empty().stream(); 352 assertFalse(s.isParallel()); 353 354 Object[] es = s.toArray(); 355 assertEquals(es.length, 0); 356 } 357 358 { 359 Stream<String> s = Optional.of("Duke").stream(); 360 assertFalse(s.isParallel()); 361 362 String[] es = s.toArray(String[]::new); 363 assertEquals(es.length, 1); 364 assertEquals(es[0], "Duke"); 365 } 366 } 367 368 private static class ObscureException extends RuntimeException { 369 370 } 371 }