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