1 /* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.base; 18 19 import static com.google.common.testing.SerializableTester.reserialize; 20 import static com.google.common.truth.Truth.assertThat; 21 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.annotations.J2ktIncompatible; 25 import com.google.common.collect.FluentIterable; 26 import com.google.common.collect.ImmutableList; 27 import com.google.common.testing.EqualsTester; 28 import com.google.common.testing.NullPointerTester; 29 import java.util.Collections; 30 import java.util.List; 31 import java.util.Set; 32 import junit.framework.TestCase; 33 import org.checkerframework.checker.nullness.qual.Nullable; 34 35 /** 36 * Unit test for {@link Optional}. 37 * 38 * @author Kurt Alfred Kluever 39 */ 40 @ElementTypesAreNonnullByDefault 41 @GwtCompatible(emulated = true) 42 public final class OptionalTest extends TestCase { testToJavaUtil_static()43 public void testToJavaUtil_static() { 44 assertNull(Optional.toJavaUtil(null)); 45 assertEquals(java.util.Optional.empty(), Optional.toJavaUtil(Optional.absent())); 46 assertEquals(java.util.Optional.of("abc"), Optional.toJavaUtil(Optional.of("abc"))); 47 } 48 testToJavaUtil_instance()49 public void testToJavaUtil_instance() { 50 assertEquals(java.util.Optional.empty(), Optional.absent().toJavaUtil()); 51 assertEquals(java.util.Optional.of("abc"), Optional.of("abc").toJavaUtil()); 52 } 53 testFromJavaUtil()54 public void testFromJavaUtil() { 55 assertNull(Optional.fromJavaUtil(null)); 56 assertEquals(Optional.absent(), Optional.fromJavaUtil(java.util.Optional.empty())); 57 assertEquals(Optional.of("abc"), Optional.fromJavaUtil(java.util.Optional.of("abc"))); 58 } 59 testAbsent()60 public void testAbsent() { 61 Optional<String> optionalName = Optional.absent(); 62 assertFalse(optionalName.isPresent()); 63 } 64 testOf()65 public void testOf() { 66 assertEquals("training", Optional.of("training").get()); 67 } 68 testOf_null()69 public void testOf_null() { 70 try { 71 Optional.of(null); 72 fail(); 73 } catch (NullPointerException expected) { 74 } 75 } 76 testFromNullable()77 public void testFromNullable() { 78 Optional<String> optionalName = Optional.fromNullable("bob"); 79 assertEquals("bob", optionalName.get()); 80 } 81 testFromNullable_null()82 public void testFromNullable_null() { 83 // not promised by spec, but easier to test 84 assertSame(Optional.absent(), Optional.fromNullable(null)); 85 } 86 testIsPresent_no()87 public void testIsPresent_no() { 88 assertFalse(Optional.absent().isPresent()); 89 } 90 91 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testIsPresent_yes()92 public void testIsPresent_yes() { 93 assertTrue(Optional.of("training").isPresent()); 94 } 95 testGet_absent()96 public void testGet_absent() { 97 Optional<String> optional = Optional.absent(); 98 try { 99 optional.get(); 100 fail(); 101 } catch (IllegalStateException expected) { 102 } 103 } 104 testGet_present()105 public void testGet_present() { 106 assertEquals("training", Optional.of("training").get()); 107 } 108 109 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_T_present()110 public void testOr_T_present() { 111 assertEquals("a", Optional.of("a").or("default")); 112 } 113 testOr_T_absent()114 public void testOr_T_absent() { 115 assertEquals("default", Optional.absent().or("default")); 116 } 117 118 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_supplier_present()119 public void testOr_supplier_present() { 120 assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback"))); 121 } 122 testOr_supplier_absent()123 public void testOr_supplier_absent() { 124 assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback"))); 125 } 126 testOr_nullSupplier_absent()127 public void testOr_nullSupplier_absent() { 128 Supplier<Object> nullSupplier = Suppliers.ofInstance(null); 129 Optional<Object> absentOptional = Optional.absent(); 130 try { 131 absentOptional.or(nullSupplier); 132 fail(); 133 } catch (NullPointerException expected) { 134 } 135 } 136 137 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_nullSupplier_present()138 public void testOr_nullSupplier_present() { 139 Supplier<String> nullSupplier = Suppliers.ofInstance(null); 140 assertEquals("a", Optional.of("a").or(nullSupplier)); 141 } 142 143 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_Optional_present()144 public void testOr_Optional_present() { 145 assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback"))); 146 } 147 testOr_Optional_absent()148 public void testOr_Optional_absent() { 149 assertEquals(Optional.of("fallback"), Optional.absent().or(Optional.of("fallback"))); 150 } 151 152 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOrNull_present()153 public void testOrNull_present() { 154 assertEquals("a", Optional.of("a").orNull()); 155 } 156 testOrNull_absent()157 public void testOrNull_absent() { 158 assertNull(Optional.absent().orNull()); 159 } 160 testAsSet_present()161 public void testAsSet_present() { 162 Set<String> expected = Collections.singleton("a"); 163 assertEquals(expected, Optional.of("a").asSet()); 164 } 165 testAsSet_absent()166 public void testAsSet_absent() { 167 assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty()); 168 } 169 testAsSet_presentIsImmutable()170 public void testAsSet_presentIsImmutable() { 171 Set<String> presentAsSet = Optional.of("a").asSet(); 172 try { 173 presentAsSet.add("b"); 174 fail(); 175 } catch (UnsupportedOperationException expected) { 176 } 177 } 178 testAsSet_absentIsImmutable()179 public void testAsSet_absentIsImmutable() { 180 Set<Object> absentAsSet = Optional.absent().asSet(); 181 try { 182 absentAsSet.add("foo"); 183 fail(); 184 } catch (UnsupportedOperationException expected) { 185 } 186 } 187 testTransform_absent()188 public void testTransform_absent() { 189 assertEquals(Optional.absent(), Optional.absent().transform(Functions.identity())); 190 assertEquals(Optional.absent(), Optional.absent().transform(Functions.toStringFunction())); 191 } 192 testTransform_presentIdentity()193 public void testTransform_presentIdentity() { 194 assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity())); 195 } 196 testTransform_presentToString()197 public void testTransform_presentToString() { 198 assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction())); 199 } 200 testTransform_present_functionReturnsNull()201 public void testTransform_present_functionReturnsNull() { 202 try { 203 Optional<String> unused = 204 Optional.of("a") 205 .transform( 206 (Function<String, String>) 207 new Function<String, @Nullable String>() { 208 @Override 209 public @Nullable String apply(String input) { 210 return null; 211 } 212 }); 213 fail("Should throw if Function returns null."); 214 } catch (NullPointerException expected) { 215 } 216 } 217 testTransform_absent_functionReturnsNull()218 public void testTransform_absent_functionReturnsNull() { 219 assertEquals( 220 Optional.absent(), 221 Optional.absent() 222 .transform( 223 (Function<Object, Object>) 224 new Function<Object, @Nullable Object>() { 225 @Override 226 public @Nullable Object apply(Object input) { 227 return null; 228 } 229 })); 230 } 231 testEqualsAndHashCode()232 public void testEqualsAndHashCode() { 233 new EqualsTester() 234 .addEqualityGroup(Optional.absent(), reserialize(Optional.absent())) 235 .addEqualityGroup(Optional.of(new Long(5)), reserialize(Optional.of(new Long(5)))) 236 .addEqualityGroup(Optional.of(new Long(42)), reserialize(Optional.of(new Long(42)))) 237 .testEquals(); 238 } 239 testToString_absent()240 public void testToString_absent() { 241 assertEquals("Optional.absent()", Optional.absent().toString()); 242 } 243 testToString_present()244 public void testToString_present() { 245 assertEquals("Optional.of(training)", Optional.of("training").toString()); 246 } 247 testPresentInstances_allPresent()248 public void testPresentInstances_allPresent() { 249 List<Optional<String>> optionals = 250 ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c")); 251 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "b", "c").inOrder(); 252 } 253 testPresentInstances_allAbsent()254 public void testPresentInstances_allAbsent() { 255 List<Optional<Object>> optionals = ImmutableList.of(Optional.absent(), Optional.absent()); 256 assertThat(Optional.presentInstances(optionals)).isEmpty(); 257 } 258 testPresentInstances_somePresent()259 public void testPresentInstances_somePresent() { 260 List<Optional<String>> optionals = 261 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 262 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "c").inOrder(); 263 } 264 testPresentInstances_callingIteratorTwice()265 public void testPresentInstances_callingIteratorTwice() { 266 List<Optional<String>> optionals = 267 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 268 Iterable<String> onlyPresent = Optional.presentInstances(optionals); 269 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 270 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 271 } 272 testPresentInstances_wildcards()273 public void testPresentInstances_wildcards() { 274 List<Optional<? extends Number>> optionals = 275 ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2)); 276 Iterable<Number> onlyPresent = Optional.presentInstances(optionals); 277 assertThat(onlyPresent).containsExactly(2); 278 } 279 getSomeOptionalInt()280 private static Optional<Integer> getSomeOptionalInt() { 281 return Optional.of(1); 282 } 283 getSomeNumbers()284 private static FluentIterable<? extends Number> getSomeNumbers() { 285 return FluentIterable.from(ImmutableList.<Number>of()); 286 } 287 288 /* 289 * The following tests demonstrate the shortcomings of or() and test that the casting workaround 290 * mentioned in the method Javadoc does in fact compile. 291 */ 292 293 @SuppressWarnings("unused") // compilation test testSampleCodeError1()294 public void testSampleCodeError1() { 295 Optional<Integer> optionalInt = getSomeOptionalInt(); 296 // Number value = optionalInt.or(0.5); // error 297 } 298 299 @SuppressWarnings("unused") // compilation test testSampleCodeError2()300 public void testSampleCodeError2() { 301 FluentIterable<? extends Number> numbers = getSomeNumbers(); 302 Optional<? extends Number> first = numbers.first(); 303 // Number value = first.or(0.5); // error 304 } 305 306 @SuppressWarnings("unused") // compilation test testSampleCodeFine1()307 public void testSampleCodeFine1() { 308 Optional<Number> optionalInt = Optional.of((Number) 1); 309 Number value = optionalInt.or(0.5); // fine 310 } 311 312 @SuppressWarnings("unused") // compilation test testSampleCodeFine2()313 public void testSampleCodeFine2() { 314 FluentIterable<? extends Number> numbers = getSomeNumbers(); 315 316 // Sadly, the following is what users will have to do in some circumstances. 317 318 @SuppressWarnings("unchecked") // safe covariant cast 319 Optional<Number> first = (Optional<Number>) numbers.first(); 320 Number value = first.or(0.5); // fine 321 } 322 323 @J2ktIncompatible 324 @GwtIncompatible // NullPointerTester testNullPointers()325 public void testNullPointers() { 326 NullPointerTester npTester = new NullPointerTester(); 327 npTester.testAllPublicConstructors(Optional.class); 328 npTester.testAllPublicStaticMethods(Optional.class); 329 npTester.testAllPublicInstanceMethods(Optional.absent()); 330 npTester.testAllPublicInstanceMethods(Optional.of("training")); 331 } 332 } 333