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