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.base.ReflectionFreeAssertThrows.assertThrows; 20 import static com.google.common.testing.SerializableTester.reserialize; 21 import static com.google.common.truth.Truth.assertThat; 22 23 import com.google.common.annotations.GwtCompatible; 24 import com.google.common.annotations.GwtIncompatible; 25 import com.google.common.annotations.J2ktIncompatible; 26 import com.google.common.collect.FluentIterable; 27 import com.google.common.collect.ImmutableList; 28 import com.google.common.testing.EqualsTester; 29 import com.google.common.testing.NullPointerTester; 30 import java.util.Collections; 31 import java.util.List; 32 import java.util.Set; 33 import junit.framework.TestCase; 34 import org.checkerframework.checker.nullness.qual.Nullable; 35 36 /** 37 * Unit test for {@link Optional}. 38 * 39 * @author Kurt Alfred Kluever 40 */ 41 @ElementTypesAreNonnullByDefault 42 @GwtCompatible(emulated = true) 43 public final class OptionalTest extends TestCase { 44 testAbsent()45 public void testAbsent() { 46 Optional<String> optionalName = Optional.absent(); 47 assertFalse(optionalName.isPresent()); 48 } 49 testOf()50 public void testOf() { 51 assertEquals("training", Optional.of("training").get()); 52 } 53 testOf_null()54 public void testOf_null() { 55 assertThrows(NullPointerException.class, () -> Optional.of(null)); 56 } 57 testFromNullable()58 public void testFromNullable() { 59 Optional<String> optionalName = Optional.fromNullable("bob"); 60 assertEquals("bob", optionalName.get()); 61 } 62 testFromNullable_null()63 public void testFromNullable_null() { 64 // not promised by spec, but easier to test 65 assertSame(Optional.absent(), Optional.fromNullable(null)); 66 } 67 testIsPresent_no()68 public void testIsPresent_no() { 69 assertFalse(Optional.absent().isPresent()); 70 } 71 72 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testIsPresent_yes()73 public void testIsPresent_yes() { 74 assertTrue(Optional.of("training").isPresent()); 75 } 76 testGet_absent()77 public void testGet_absent() { 78 Optional<String> optional = Optional.absent(); 79 assertThrows(IllegalStateException.class, optional::get); 80 } 81 testGet_present()82 public void testGet_present() { 83 assertEquals("training", Optional.of("training").get()); 84 } 85 86 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_t_present()87 public void testOr_t_present() { 88 assertEquals("a", Optional.of("a").or("default")); 89 } 90 testOr_t_absent()91 public void testOr_t_absent() { 92 assertEquals("default", Optional.absent().or("default")); 93 } 94 95 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_supplier_present()96 public void testOr_supplier_present() { 97 assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback"))); 98 } 99 testOr_supplier_absent()100 public void testOr_supplier_absent() { 101 assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback"))); 102 } 103 testOr_nullSupplier_absent()104 public void testOr_nullSupplier_absent() { 105 Supplier<Object> nullSupplier = (Supplier<Object>) Suppliers.<@Nullable Object>ofInstance(null); 106 Optional<Object> absentOptional = Optional.absent(); 107 assertThrows(NullPointerException.class, () -> absentOptional.or(nullSupplier)); 108 } 109 110 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_nullSupplier_present()111 public void testOr_nullSupplier_present() { 112 Supplier<String> nullSupplier = (Supplier<String>) Suppliers.<@Nullable String>ofInstance(null); 113 assertEquals("a", Optional.of("a").or(nullSupplier)); 114 } 115 116 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOr_optional_present()117 public void testOr_optional_present() { 118 assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback"))); 119 } 120 testOr_optional_absent()121 public void testOr_optional_absent() { 122 assertEquals(Optional.of("fallback"), Optional.absent().or(Optional.of("fallback"))); 123 } 124 125 @SuppressWarnings("OptionalOfRedundantMethod") // Unit tests for Optional testOrNull_present()126 public void testOrNull_present() { 127 assertEquals("a", Optional.of("a").orNull()); 128 } 129 testOrNull_absent()130 public void testOrNull_absent() { 131 assertNull(Optional.absent().orNull()); 132 } 133 testAsSet_present()134 public void testAsSet_present() { 135 Set<String> expected = Collections.singleton("a"); 136 assertEquals(expected, Optional.of("a").asSet()); 137 } 138 testAsSet_absent()139 public void testAsSet_absent() { 140 assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty()); 141 } 142 testAsSet_presentIsImmutable()143 public void testAsSet_presentIsImmutable() { 144 Set<String> presentAsSet = Optional.of("a").asSet(); 145 assertThrows(UnsupportedOperationException.class, () -> presentAsSet.add("b")); 146 } 147 testAsSet_absentIsImmutable()148 public void testAsSet_absentIsImmutable() { 149 Set<Object> absentAsSet = Optional.absent().asSet(); 150 assertThrows(UnsupportedOperationException.class, () -> absentAsSet.add("foo")); 151 } 152 testTransform_absent()153 public void testTransform_absent() { 154 assertEquals(Optional.absent(), Optional.absent().transform(Functions.identity())); 155 assertEquals(Optional.absent(), Optional.absent().transform(Functions.toStringFunction())); 156 } 157 testTransform_presentIdentity()158 public void testTransform_presentIdentity() { 159 assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity())); 160 } 161 testTransform_presentToString()162 public void testTransform_presentToString() { 163 assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction())); 164 } 165 testTransform_present_functionReturnsNull()166 public void testTransform_present_functionReturnsNull() { 167 assertThrows(NullPointerException.class, () -> Optional.of("a").transform(input -> null)); 168 } 169 testTransform_absent_functionReturnsNull()170 public void testTransform_absent_functionReturnsNull() { 171 assertEquals(Optional.absent(), Optional.absent().transform(input -> null)); 172 } 173 testEqualsAndHashCode()174 public void testEqualsAndHashCode() { 175 new EqualsTester() 176 .addEqualityGroup(Optional.absent(), reserialize(Optional.absent())) 177 .addEqualityGroup(Optional.of(Long.valueOf(5)), reserialize(Optional.of(Long.valueOf(5)))) 178 .addEqualityGroup(Optional.of(Long.valueOf(42)), reserialize(Optional.of(Long.valueOf(42)))) 179 .testEquals(); 180 } 181 testToString_absent()182 public void testToString_absent() { 183 assertEquals("Optional.absent()", Optional.absent().toString()); 184 } 185 testToString_present()186 public void testToString_present() { 187 assertEquals("Optional.of(training)", Optional.of("training").toString()); 188 } 189 testPresentInstances_allPresent()190 public void testPresentInstances_allPresent() { 191 List<Optional<String>> optionals = 192 ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c")); 193 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "b", "c").inOrder(); 194 } 195 testPresentInstances_allAbsent()196 public void testPresentInstances_allAbsent() { 197 List<Optional<Object>> optionals = ImmutableList.of(Optional.absent(), Optional.absent()); 198 assertThat(Optional.presentInstances(optionals)).isEmpty(); 199 } 200 testPresentInstances_somePresent()201 public void testPresentInstances_somePresent() { 202 List<Optional<String>> optionals = 203 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 204 assertThat(Optional.presentInstances(optionals)).containsExactly("a", "c").inOrder(); 205 } 206 testPresentInstances_callingIteratorTwice()207 public void testPresentInstances_callingIteratorTwice() { 208 List<Optional<String>> optionals = 209 ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c")); 210 Iterable<String> onlyPresent = Optional.presentInstances(optionals); 211 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 212 assertThat(onlyPresent).containsExactly("a", "c").inOrder(); 213 } 214 testPresentInstances_wildcards()215 public void testPresentInstances_wildcards() { 216 List<Optional<? extends Number>> optionals = 217 ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2)); 218 Iterable<Number> onlyPresent = Optional.presentInstances(optionals); 219 assertThat(onlyPresent).containsExactly(2); 220 } 221 getSomeOptionalInt()222 private static Optional<Integer> getSomeOptionalInt() { 223 return Optional.of(1); 224 } 225 getSomeNumbers()226 private static FluentIterable<? extends Number> getSomeNumbers() { 227 return FluentIterable.from(ImmutableList.<Number>of()); 228 } 229 230 /* 231 * The following tests demonstrate the shortcomings of or() and test that the casting workaround 232 * mentioned in the method Javadoc does in fact compile. 233 */ 234 235 @SuppressWarnings("unused") // compilation test testSampleCodeError1()236 public void testSampleCodeError1() { 237 Optional<Integer> optionalInt = getSomeOptionalInt(); 238 // Number value = optionalInt.or(0.5); // error 239 } 240 241 @SuppressWarnings("unused") // compilation test testSampleCodeError2()242 public void testSampleCodeError2() { 243 FluentIterable<? extends Number> numbers = getSomeNumbers(); 244 Optional<? extends Number> first = numbers.first(); 245 // Number value = first.or(0.5); // error 246 } 247 248 @SuppressWarnings("unused") // compilation test testSampleCodeFine1()249 public void testSampleCodeFine1() { 250 Optional<Number> optionalInt = Optional.of((Number) 1); 251 Number value = optionalInt.or(0.5); // fine 252 } 253 254 @SuppressWarnings("unused") // compilation test testSampleCodeFine2()255 public void testSampleCodeFine2() { 256 FluentIterable<? extends Number> numbers = getSomeNumbers(); 257 258 // Sadly, the following is what users will have to do in some circumstances. 259 260 @SuppressWarnings("unchecked") // safe covariant cast 261 Optional<Number> first = (Optional<Number>) numbers.first(); 262 Number value = first.or(0.5); // fine 263 } 264 265 @J2ktIncompatible 266 @GwtIncompatible // NullPointerTester testNullPointers()267 public void testNullPointers() { 268 NullPointerTester npTester = new NullPointerTester(); 269 npTester.testAllPublicConstructors(Optional.class); 270 npTester.testAllPublicStaticMethods(Optional.class); 271 npTester.testAllPublicInstanceMethods(Optional.absent()); 272 npTester.testAllPublicInstanceMethods(Optional.of("training")); 273 } 274 } 275