1 /*
2  * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /* @test
25  * @bug 8195649
26  * @summary Basic functional test of Optional
27  * @author Mike Duigou
28  * @build ObscureException
29  * @run testng Basic
30  */
31 
32 import java.util.List;
33 import java.util.NoSuchElementException;
34 import java.util.Optional;
35 import java.util.concurrent.atomic.AtomicBoolean;
36 
37 import static java.util.stream.Collectors.toList;
38 
39 import static org.testng.Assert.*;
40 import org.testng.annotations.Test;
41 
42 public class Basic {
43 
44     /**
45      * Checks a block of assertions over an empty Optional.
46      */
checkEmpty(Optional<String> empty)47     void checkEmpty(Optional<String> empty) {
48         assertTrue(empty.equals(Optional.empty()));
49         assertTrue(Optional.empty().equals(empty));
50         assertFalse(empty.equals(Optional.of("unexpected")));
51         assertFalse(Optional.of("unexpected").equals(empty));
52         assertFalse(empty.equals("unexpected"));
53 
54         assertFalse(empty.isPresent());
55         assertTrue(empty.isEmpty());
56         assertEquals(empty.hashCode(), 0);
57         assertEquals(empty.orElse("x"), "x");
58         assertEquals(empty.orElseGet(() -> "y"), "y");
59 
60         assertThrows(NoSuchElementException.class, () -> empty.get());
61         assertThrows(NoSuchElementException.class, () -> empty.orElseThrow());
62         assertThrows(ObscureException.class,       () -> empty.orElseThrow(ObscureException::new));
63 
64         var b = new AtomicBoolean();
65         empty.ifPresent(s -> b.set(true));
66         assertFalse(b.get());
67 
68         var b1 = new AtomicBoolean(false);
69         var b2 = new AtomicBoolean(false);
70         empty.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true));
71         assertFalse(b1.get());
72         assertTrue(b2.get());
73 
74         assertEquals(empty.toString(), "Optional.empty");
75     }
76 
77     /**
78      * Checks a block of assertions over an Optional that is expected to
79      * have a particular value present.
80      */
checkPresent(Optional<String> opt, String expected)81     void checkPresent(Optional<String> opt, String expected) {
82         assertFalse(opt.equals(Optional.empty()));
83         assertFalse(Optional.empty().equals(opt));
84         assertTrue(opt.equals(Optional.of(expected)));
85         assertTrue(Optional.of(expected).equals(opt));
86         assertFalse(opt.equals(Optional.of("unexpected")));
87         assertFalse(Optional.of("unexpected").equals(opt));
88         assertFalse(opt.equals("unexpected"));
89 
90         assertTrue(opt.isPresent());
91         assertFalse(opt.isEmpty());
92         assertEquals(opt.hashCode(), expected.hashCode());
93         assertEquals(opt.orElse("unexpected"), expected);
94         assertEquals(opt.orElseGet(() -> "unexpected"), expected);
95 
96         assertEquals(opt.get(), expected);
97         assertEquals(opt.orElseThrow(), expected);
98         assertEquals(opt.orElseThrow(ObscureException::new), expected);
99 
100         var b = new AtomicBoolean(false);
101         opt.ifPresent(s -> b.set(true));
102         assertTrue(b.get());
103 
104         var b1 = new AtomicBoolean(false);
105         var b2 = new AtomicBoolean(false);
106         opt.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true));
107         assertTrue(b1.get());
108         assertFalse(b2.get());
109 
110         assertEquals(opt.toString(), "Optional[" + expected + "]");
111     }
112 
113     @Test(groups = "unit")
testEmpty()114     public void testEmpty() {
115         checkEmpty(Optional.empty());
116     }
117 
118     @Test(groups = "unit")
testOfNull()119     public void testOfNull() {
120         assertThrows(NullPointerException.class, () -> Optional.of(null));
121     }
122 
123     @Test(groups = "unit")
testOfPresent()124     public void testOfPresent() {
125         checkPresent(Optional.of("xyzzy"), "xyzzy");
126     }
127 
128     @Test(groups = "unit")
testOfNullableNull()129     public void testOfNullableNull() {
130         checkEmpty(Optional.ofNullable(null));
131     }
132 
133     @Test(groups = "unit")
testOfNullablePresent()134     public void testOfNullablePresent() {
135         checkPresent(Optional.ofNullable("xyzzy"), "xyzzy");
136     }
137 
138     @Test(groups = "unit")
testFilterEmpty()139     public void testFilterEmpty() {
140         checkEmpty(Optional.<String>empty().filter(s -> { fail(); return true; }));
141     }
142 
143     @Test(groups = "unit")
testFilterFalse()144     public void testFilterFalse() {
145         checkEmpty(Optional.of("xyzzy").filter(s -> s.equals("plugh")));
146     }
147 
148     @Test(groups = "unit")
testFilterTrue()149     public void testFilterTrue() {
150         checkPresent(Optional.of("xyzzy").filter(s -> s.equals("xyzzy")), "xyzzy");
151     }
152 
153     @Test(groups = "unit")
testMapEmpty()154     public void testMapEmpty() {
155         checkEmpty(Optional.empty().map(s -> { fail(); return ""; }));
156     }
157 
158     @Test(groups = "unit")
testMapPresent()159     public void testMapPresent() {
160         checkPresent(Optional.of("xyzzy").map(s -> s.replace("xyzzy", "plugh")), "plugh");
161     }
162 
163     @Test(groups = "unit")
testFlatMapEmpty()164     public void testFlatMapEmpty() {
165         checkEmpty(Optional.empty().flatMap(s -> { fail(); return Optional.of(""); }));
166     }
167 
168     @Test(groups = "unit")
testFlatMapPresentReturnEmpty()169     public void testFlatMapPresentReturnEmpty() {
170         checkEmpty(Optional.of("xyzzy")
171                            .flatMap(s -> { assertEquals(s, "xyzzy"); return Optional.empty(); }));
172     }
173 
174     @Test(groups = "unit")
testFlatMapPresentReturnPresent()175     public void testFlatMapPresentReturnPresent() {
176         checkPresent(Optional.of("xyzzy")
177                              .flatMap(s -> { assertEquals(s, "xyzzy"); return Optional.of("plugh"); }),
178                      "plugh");
179     }
180 
181     @Test(groups = "unit")
testOrEmptyEmpty()182     public void testOrEmptyEmpty() {
183         checkEmpty(Optional.<String>empty().or(() -> Optional.empty()));
184     }
185 
186     @Test(groups = "unit")
testOrEmptyPresent()187     public void testOrEmptyPresent() {
188         checkPresent(Optional.<String>empty().or(() -> Optional.of("plugh")), "plugh");
189     }
190 
191     @Test(groups = "unit")
testOrPresentDontCare()192     public void testOrPresentDontCare() {
193         checkPresent(Optional.of("xyzzy").or(() -> { fail(); return Optional.of("plugh"); }), "xyzzy");
194     }
195 
196     @Test(groups = "unit")
testStreamEmpty()197     public void testStreamEmpty() {
198         assertEquals(Optional.empty().stream().collect(toList()), List.of());
199     }
200 
201     @Test(groups = "unit")
testStreamPresent()202     public void testStreamPresent() {
203         assertEquals(Optional.of("xyzzy").stream().collect(toList()), List.of("xyzzy"));
204     }
205 }
206