Home | History | Annotate | Download | only in base
      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 {
     41   public void testAbsent() {
     42     Optional<String> optionalName = Optional.absent();
     43     assertFalse(optionalName.isPresent());
     44   }
     45 
     46   public void testOf() {
     47     assertEquals("training", Optional.of("training").get());
     48   }
     49 
     50   public void testOf_null() {
     51     try {
     52       Optional.of(null);
     53       fail();
     54     } catch (NullPointerException expected) {
     55     }
     56   }
     57 
     58   public void testFromNullable() {
     59     Optional<String> optionalName = Optional.fromNullable("bob");
     60     assertEquals("bob", optionalName.get());
     61   }
     62 
     63   public void testFromNullable_null() {
     64     // not promised by spec, but easier to test
     65     assertSame(Optional.absent(), Optional.fromNullable(null));
     66   }
     67 
     68   public void testIsPresent_no() {
     69     assertFalse(Optional.absent().isPresent());
     70   }
     71 
     72   public void testIsPresent_yes() {
     73     assertTrue(Optional.of("training").isPresent());
     74   }
     75 
     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 
     85   public void testGet_present() {
     86     assertEquals("training", Optional.of("training").get());
     87   }
     88 
     89   public void testOr_T_present() {
     90     assertEquals("a", Optional.of("a").or("default"));
     91   }
     92 
     93   public void testOr_T_absent() {
     94     assertEquals("default", Optional.absent().or("default"));
     95   }
     96 
     97   public void testOr_supplier_present() {
     98     assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback")));
     99   }
    100 
    101   public void testOr_supplier_absent() {
    102     assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback")));
    103   }
    104 
    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 
    115   public void testOr_nullSupplier_present() {
    116     Supplier<String> nullSupplier = Suppliers.ofInstance(null);
    117     assertEquals("a", Optional.of("a").or(nullSupplier));
    118   }
    119 
    120   public void testOr_Optional_present() {
    121     assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback")));
    122   }
    123 
    124   public void testOr_Optional_absent() {
    125     assertEquals(Optional.of("fallback"), Optional.absent().or(Optional.of("fallback")));
    126   }
    127 
    128   public void testOrNull_present() {
    129     assertEquals("a", Optional.of("a").orNull());
    130   }
    131 
    132   public void testOrNull_absent() {
    133     assertNull(Optional.absent().orNull());
    134   }
    135 
    136   public void testAsSet_present() {
    137     Set<String> expected = Collections.singleton("a");
    138     assertEquals(expected, Optional.of("a").asSet());
    139   }
    140 
    141   public void testAsSet_absent() {
    142     assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty());
    143   }
    144 
    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 
    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 
    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 
    168   public void testTransform_presentIdentity() {
    169     assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity()));
    170   }
    171 
    172   public void testTransform_presentToString() {
    173     assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction()));
    174   }
    175 
    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 
    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 
    201   public void testEqualsAndHashCode_absent() {
    202     assertEquals(Optional.<String>absent(), Optional.<Integer>absent());
    203     assertEquals(Optional.absent().hashCode(), Optional.absent().hashCode());
    204   }
    205 
    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 
    213   public void testToString_absent() {
    214     assertEquals("Optional.absent()", Optional.absent().toString());
    215   }
    216 
    217   public void testToString_present() {
    218     assertEquals("Optional.of(training)", Optional.of("training").toString());
    219   }
    220 
    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 
    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 
    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 
    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 
    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 
    254   private static Optional<Integer> getSomeOptionalInt() {
    255     return Optional.of(1);
    256   }
    257 
    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
    268   public void testSampleCodeError1() {
    269     Optional<Integer> optionalInt = getSomeOptionalInt();
    270     // Number value = optionalInt.or(0.5); // error
    271   }
    272 
    273   @SuppressWarnings("unused") // compilation test
    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
    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
    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")
    298   public void testSerialization() {
    299     SerializableTester.reserializeAndAssert(Optional.absent());
    300     SerializableTester.reserializeAndAssert(Optional.of("foo"));
    301   }
    302 
    303   @GwtIncompatible("NullPointerTester")
    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