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 { testAbsent()43 public void testAbsent() { 44 Optional<String> optionalName = Optional.absent(); 45 assertFalse(optionalName.isPresent()); 46 } 47 testOf()48 public void testOf() { 49 assertEquals("training", Optional.of("training").get()); 50 } 51 testOf_null()52 public void testOf_null() { 53 try { 54 Optional.of(null); 55 fail(); 56 } catch (NullPointerException expected) { 57 } 58 } 59 testFromNullable()60 public void testFromNullable() { 61 Optional<String> optionalName = Optional.fromNullable("bob"); 62 assertEquals("bob", optionalName.get()); 63 } 64 testFromNullable_null()65 public void testFromNullable_null() { 66 // not promised by spec, but easier to test 67 assertSame(Optional.absent(), Optional.fromNullable(null)); 68 } 69 testIsPresent_no()70 public void testIsPresent_no() { 71 assertFalse(Optional.absent().isPresent()); 72 } 73 74 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testIsPresent_yes()75 public void testIsPresent_yes() { 76 assertTrue(Optional.of("training").isPresent()); 77 } 78 testGet_absent()79 public void testGet_absent() { 80 Optional<String> optional = Optional.absent(); 81 try { 82 optional.get(); 83 fail(); 84 } catch (IllegalStateException expected) { 85 } 86 } 87 testGet_present()88 public void testGet_present() { 89 assertEquals("training", Optional.of("training").get()); 90 } 91 92 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_T_present()93 public void testOr_T_present() { 94 assertEquals("a", Optional.of("a").or("default")); 95 } 96 testOr_T_absent()97 public void testOr_T_absent() { 98 assertEquals("default", Optional.absent().or("default")); 99 } 100 101 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_supplier_present()102 public void testOr_supplier_present() { 103 assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback"))); 104 } 105 testOr_supplier_absent()106 public void testOr_supplier_absent() { 107 assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback"))); 108 } 109 testOr_nullSupplier_absent()110 public void testOr_nullSupplier_absent() { 111 Supplier<Object> nullSupplier = Suppliers.ofInstance(null); 112 Optional<Object> absentOptional = Optional.absent(); 113 try { 114 absentOptional.or(nullSupplier); 115 fail(); 116 } catch (NullPointerException expected) { 117 } 118 } 119 120 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_nullSupplier_present()121 public void testOr_nullSupplier_present() { 122 Supplier<String> nullSupplier = Suppliers.ofInstance(null); 123 assertEquals("a", Optional.of("a").or(nullSupplier)); 124 } 125 126 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_Optional_present()127 public void testOr_Optional_present() { 128 assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback"))); 129 } 130 testOr_Optional_absent()131 public void testOr_Optional_absent() { 132 assertEquals(Optional.of("fallback"), Optional.absent().or(Optional.of("fallback"))); 133 } 134 135 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOrNull_present()136 public void testOrNull_present() { 137 assertEquals("a", Optional.of("a").orNull()); 138 } 139 testOrNull_absent()140 public void testOrNull_absent() { 141 assertNull(Optional.absent().orNull()); 142 } 143 testAsSet_present()144 public void testAsSet_present() { 145 Set<String> expected = Collections.singleton("a"); 146 assertEquals(expected, Optional.of("a").asSet()); 147 } 148 testAsSet_absent()149 public void testAsSet_absent() { 150 assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty()); 151 } 152 testAsSet_presentIsImmutable()153 public void testAsSet_presentIsImmutable() { 154 Set<String> presentAsSet = Optional.of("a").asSet(); 155 try { 156 presentAsSet.add("b"); 157 fail(); 158 } catch (UnsupportedOperationException expected) { 159 } 160 } 161 testAsSet_absentIsImmutable()162 public void testAsSet_absentIsImmutable() { 163 Set<Object> absentAsSet = Optional.absent().asSet(); 164 try { 165 absentAsSet.add("foo"); 166 fail(); 167 } catch (UnsupportedOperationException expected) { 168 } 169 } 170 testTransform_absent()171 public void testTransform_absent() { 172 assertEquals(Optional.absent(), Optional.absent().transform(Functions.identity())); 173 assertEquals(Optional.absent(), Optional.absent().transform(Functions.toStringFunction())); 174 } 175 testTransform_presentIdentity()176 public void testTransform_presentIdentity() { 177 assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity())); 178 } 179 testTransform_presentToString()180 public void testTransform_presentToString() { 181 assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction())); 182 } 183 testTransform_present_functionReturnsNull()184 public void testTransform_present_functionReturnsNull() { 185 try { 186 Optional<String> unused = 187 Optional.of("a") 188 .transform( 189 (Function<String, String>) 190 new Function<String, @Nullable String>() { 191 @Override 192 public @Nullable String apply(String input) { 193 return null; 194 } 195 }); 196 fail("Should throw if Function returns null."); 197 } catch (NullPointerException expected) { 198 } 199 } 200 testTransform_absent_functionReturnsNull()201 public void testTransform_absent_functionReturnsNull() { 202 assertEquals( 203 Optional.absent(), 204 Optional.absent() 205 .transform( 206 (Function<Object, Object>) 207 new Function<Object, @Nullable Object>() { 208 @Override 209 public @Nullable Object apply(Object input) { 210 return null; 211 } 212 })); 213 } 214 testEqualsAndHashCode()215 public void testEqualsAndHashCode() { 216 new EqualsTester() 217 .addEqualityGroup(Optional.absent(), reserialize(Optional.absent())) 218 .addEqualityGroup(Optional.of(new Long(5)), reserialize(Optional.of(new Long(5)))) 219 .addEqualityGroup(Optional.of(new Long(42)), reserialize(Optional.of(new Long(42)))) 220 .testEquals(); 221 } 222 testToString_absent()223 public void testToString_absent() { 224 assertEquals("Optional.absent()", Optional.absent().toString()); 225 } 226 testToString_present()227 public void testToString_present() { 228 assertEquals("Optional.of(training)", Optional.of("training").toString()); 229 } 230 testPresentInstances_allPresent()231 public void testPresentInstances_allPresent() { 232 List<Optional<String>> optionals = 233 ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c")); 234 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "b", "c").inOrder(); 235 } 236 testPresentInstances_allAbsent()237 public void testPresentInstances_allAbsent() { 238 List<Optional<Object>> optionals = ImmutableList.of(Optional.absent(), Optional.absent()); 239 assertThat(Optional.presentInstances(optionals)).isEmpty(); 240 } 241 testPresentInstances_somePresent()242 public void testPresentInstances_somePresent() { 243 List<Optional<String>> optionals = 244 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 245 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "c").inOrder(); 246 } 247 testPresentInstances_callingIteratorTwice()248 public void testPresentInstances_callingIteratorTwice() { 249 List<Optional<String>> optionals = 250 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 251 Iterable<String> onlyPresent = Optional.presentInstances(optionals); 252 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 253 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 254 } 255 testPresentInstances_wildcards()256 public void testPresentInstances_wildcards() { 257 List<Optional<? extends Number>> optionals = 258 ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2)); 259 Iterable<Number> onlyPresent = Optional.presentInstances(optionals); 260 assertThat(onlyPresent).containsExactly(2); 261 } 262 getSomeOptionalInt()263 private static Optional<Integer> getSomeOptionalInt() { 264 return Optional.of(1); 265 } 266 getSomeNumbers()267 private static FluentIterable<? extends Number> getSomeNumbers() { 268 return FluentIterable.from(ImmutableList.<Number>of()); 269 } 270 271 /* 272 * The following tests demonstrate the shortcomings of or() and test that the casting workaround 273 * mentioned in the method Javadoc does in fact compile. 274 */ 275 276 @SuppressWarnings("unused") // compilation test testSampleCodeError1()277 public void testSampleCodeError1() { 278 Optional<Integer> optionalInt = getSomeOptionalInt(); 279 // Number value = optionalInt.or(0.5); // error 280 } 281 282 @SuppressWarnings("unused") // compilation test testSampleCodeError2()283 public void testSampleCodeError2() { 284 FluentIterable<? extends Number> numbers = getSomeNumbers(); 285 Optional<? extends Number> first = numbers.first(); 286 // Number value = first.or(0.5); // error 287 } 288 289 @SuppressWarnings("unused") // compilation test testSampleCodeFine1()290 public void testSampleCodeFine1() { 291 Optional<Number> optionalInt = Optional.of((Number) 1); 292 Number value = optionalInt.or(0.5); // fine 293 } 294 295 @SuppressWarnings("unused") // compilation test testSampleCodeFine2()296 public void testSampleCodeFine2() { 297 FluentIterable<? extends Number> numbers = getSomeNumbers(); 298 299 // Sadly, the following is what users will have to do in some circumstances. 300 301 @SuppressWarnings("unchecked") // safe covariant cast 302 Optional<Number> first = (Optional<Number>) numbers.first(); 303 Number value = first.or(0.5); // fine 304 } 305 306 @J2ktIncompatible 307 @GwtIncompatible // NullPointerTester testNullPointers()308 public void testNullPointers() { 309 NullPointerTester npTester = new NullPointerTester(); 310 npTester.testAllPublicConstructors(Optional.class); 311 npTester.testAllPublicStaticMethods(Optional.class); 312 npTester.testAllPublicInstanceMethods(Optional.absent()); 313 npTester.testAllPublicInstanceMethods(Optional.of("training")); 314 } 315 } 316