1/*
2 * Copyright (C) 2016 The Android Open Source Project
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
17package libcore.java.util;
18
19import junit.framework.TestCase;
20
21import java.io.IOException;
22import java.util.NoSuchElementException;
23import java.util.Optional;
24import java.util.concurrent.atomic.AtomicReference;
25import java.util.function.Consumer;
26import java.util.function.Function;
27import java.util.function.Predicate;
28import java.util.function.Supplier;
29
30public class OptionalTest extends TestCase {
31
32    public void testEmpty_sameInstance() {
33        // empty() is a singleton instance.
34        assertSame(Optional.<Integer>empty(), Optional.<String>empty());
35        assertSame(Optional.<String>empty(), Optional.<String>empty());
36
37        // Note that we assert here that the empty() optional is the same instance
38        // as Optional.ofNullable(null). This allows us to avoid having to write tests
39        // for both cases.
40        assertSame(Optional.<String>empty(), Optional.ofNullable(null));
41    }
42
43    public void testGet() {
44        Optional<String> empty = Optional.empty();
45
46        try {
47            empty.get();
48            fail();
49        } catch (NoSuchElementException expected) {
50        }
51
52        String foo = "foo";
53        Optional<String> optionalFoo = Optional.of(foo);
54        assertSame(foo, optionalFoo.get());
55    }
56
57    public void testIsPresent() {
58        Optional<String> empty = Optional.empty();
59        assertFalse(empty.isPresent());
60
61        Optional<String> optionalFoo = Optional.of("foo");
62        assertTrue(optionalFoo.isPresent());
63
64        assertFalse(Optional.<String>ofNullable(null).isPresent());
65    }
66
67    public void testIfPresent() {
68        Optional<String> empty = Optional.empty();
69        Optional<String> ofNull = Optional.ofNullable(null);
70
71        Consumer<String> alwaysFail = s -> fail();
72
73        // alwaysFail must never be called.
74        empty.ifPresent(alwaysFail);
75        ofNull.ifPresent(alwaysFail);
76
77        final AtomicReference<String> reference = new AtomicReference<>();
78
79        String foo = "foo";
80        Optional.of(foo).ifPresent(s -> reference.set(s));
81        assertSame(foo, reference.get());
82    }
83
84    public void testFilter() {
85        Optional<String> empty = Optional.empty();
86        Optional<String> ofNull = Optional.ofNullable(null);
87
88        Predicate<String> alwaysFail = s -> { fail(); return true; };
89        // If isPresent() == false, optional always returns itself (!!).
90        assertSame(empty, empty.filter(alwaysFail));
91        assertSame(empty, empty.filter(alwaysFail));
92        assertSame(ofNull, ofNull.filter(alwaysFail));
93        assertSame(ofNull, ofNull.filter(alwaysFail));
94
95        final String foo = "foo";
96        Optional<String> optionalFoo = Optional.of(foo);
97        Predicate<String> alwaysTrue = s -> true;
98        Predicate<String> alwaysFalse = s -> false;
99        assertSame(empty, optionalFoo.filter(alwaysFalse));
100        assertSame(optionalFoo, optionalFoo.filter(alwaysTrue));
101
102        final AtomicReference<String> reference = new AtomicReference<>();
103        optionalFoo.filter(s -> { reference.set(s); return true; });
104        assertSame(foo, reference.get());
105    }
106
107    public void testMap() {
108        Optional<String> empty = Optional.empty();
109        Optional<String> ofNull = Optional.ofNullable(null);
110
111        Function<String, String> alwaysFail = s -> { fail(); return ""; };
112        // Should return Optional.empty() if the value isn't present.
113        assertSame(empty, empty.map(alwaysFail));
114        assertSame(empty, ofNull.map(alwaysFail));
115
116        final AtomicReference<String> reference = new AtomicReference<>();
117        Function<String, String> identity = (String s) -> { reference.set(s); return s; };
118        String foo = "foo";
119        Optional<String> optionalFoo = Optional.of(foo);
120        Optional<String> mapped = optionalFoo.map(identity);
121        assertSame(foo, mapped.get());
122        assertSame(foo, reference.get());
123
124        Function<String, String> alwaysNull = s -> null;
125        assertSame(empty, optionalFoo.map(alwaysNull));
126    }
127
128    public void testFlatMap() {
129        Optional<String> empty = Optional.empty();
130        Optional<String> ofNull = Optional.ofNullable(null);
131
132        Function<String, Optional<String>> alwaysFail = s -> { fail(); return Optional.empty(); };
133        // Should return Optional.empty() if the value isn't present.
134        assertSame(empty, empty.flatMap(alwaysFail));
135        assertSame(empty, ofNull.flatMap(alwaysFail));
136
137        final AtomicReference<String> reference = new AtomicReference<>();
138        Function<String, Optional<String>> identity =
139                s -> { reference.set(s); return Optional.of(s); };
140
141        String foo = "foo";
142        Optional<String> optionalFoo = Optional.of(foo);
143        Optional<String> mapped = optionalFoo.flatMap(identity);
144        assertSame(foo, mapped.get());
145        assertSame(foo, reference.get());
146
147        Function<String, Optional<String>> alwaysNull = s -> null;
148
149        try {
150            optionalFoo.flatMap(alwaysNull);
151            fail();
152        } catch (NullPointerException expected) {
153        }
154
155        try {
156            optionalFoo.flatMap(null);
157            fail();
158        } catch (NullPointerException expected) {
159        }
160    }
161
162    public void testOrElse() {
163        Optional<String> empty = Optional.empty();
164        Optional<String> ofNull = Optional.ofNullable(null);
165
166        String bar = "bar";
167        assertSame(bar, empty.orElse(bar));
168        assertSame(bar, ofNull.orElse(bar));
169
170        String foo = "foo";
171        Optional<String> optionalFoo = Optional.of(foo);
172        assertSame(foo, optionalFoo.orElse(bar));
173    }
174
175    public void testOrElseGet() {
176        Optional<String> empty = Optional.empty();
177        Optional<String> ofNull = Optional.ofNullable(null);
178
179        final String bar = "bar";
180        Supplier<String> barSupplier = () -> bar;
181
182        assertSame(bar, empty.orElseGet(barSupplier));
183        assertSame(bar, ofNull.orElseGet(barSupplier));
184
185        String foo = "foo";
186        Optional<String> optionalFoo = Optional.of(foo);
187        assertSame(foo, optionalFoo.orElseGet(barSupplier));
188    }
189
190    public void testOrElseThrow() throws Exception {
191        Optional<String> empty = Optional.empty();
192        Optional<String> ofNull = Optional.ofNullable(null);
193
194        final IOException bar = new IOException("bar");
195        Supplier<IOException> barSupplier = () -> bar;
196        try {
197            empty.orElseThrow(barSupplier);
198            fail();
199        } catch (IOException ioe) {
200            assertSame(bar, ioe);
201        }
202
203        try {
204            ofNull.orElseThrow(barSupplier);
205            fail();
206        } catch (IOException ioe) {
207            assertSame(bar, ioe);
208        }
209
210        String foo = "foo";
211        Optional<String> optionalFoo = Optional.of(foo);
212        assertSame(foo, optionalFoo.orElseThrow(barSupplier));
213    }
214
215    public void testEquals() {
216        assertEquals(Optional.empty(), Optional.<String>ofNullable(null));
217        assertEquals(Optional.of("foo"), Optional.of("foo"));
218
219        assertFalse(Optional.of("foo").equals(Optional.empty()));
220        assertFalse(Optional.of("foo").equals(Optional.of("bar")));
221    }
222
223    public void testHashcode() {
224        assertEquals("foo".hashCode(), Optional.of("foo").hashCode());
225    }
226}
227