• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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