25 * @summary Basic functional test of Optional |
25 * @summary Basic functional test of Optional |
26 * @author Mike Duigou |
26 * @author Mike Duigou |
27 * @run testng Basic |
27 * @run testng Basic |
28 */ |
28 */ |
29 |
29 |
30 import java.lang.AssertionError; |
30 import java.util.List; |
31 import java.lang.NullPointerException; |
|
32 import java.lang.Throwable; |
|
33 import java.util.NoSuchElementException; |
31 import java.util.NoSuchElementException; |
34 import java.util.Optional; |
32 import java.util.Optional; |
35 import java.util.concurrent.atomic.AtomicBoolean; |
33 import java.util.concurrent.atomic.AtomicBoolean; |
36 import java.util.stream.Stream; |
34 import java.util.stream.Stream; |
37 |
35 |
|
36 import static java.util.stream.Collectors.toList; |
|
37 |
38 import static org.testng.Assert.*; |
38 import static org.testng.Assert.*; |
39 import org.testng.annotations.Test; |
39 import org.testng.annotations.Test; |
40 |
40 |
41 |
41 |
42 public class Basic { |
42 public class Basic { |
43 |
43 |
44 @Test(groups = "unit") |
44 /** |
|
45 * Asserts that the runnable throws an exception of the given type. |
|
46 * Fails if no exception is thrown, or if an exception of the wrong |
|
47 * type is thrown. This is used instead of @Test(expectedExceptions) |
|
48 * because that can be applied only at the granularity of a test. |
|
49 */ |
|
50 void assertThrows(Runnable r, Class<? extends Exception> clazz) { |
|
51 try { |
|
52 r.run(); |
|
53 fail(); |
|
54 } catch (Exception ex) { |
|
55 assertTrue(clazz.isInstance(ex)); |
|
56 } |
|
57 } |
|
58 |
|
59 /** |
|
60 * Checks a block of assertions over an empty Optional. |
|
61 */ |
|
62 void checkEmpty(Optional<String> empty) { |
|
63 assertTrue(empty.equals(Optional.empty())); |
|
64 assertTrue(Optional.empty().equals(empty)); |
|
65 assertFalse(empty.equals(Optional.of(""))); |
|
66 assertFalse(Optional.of("").equals(empty)); |
|
67 assertFalse(empty.isPresent()); |
|
68 assertEquals(empty.hashCode(), 0); |
|
69 assertEquals(empty.orElse("x"), "x"); |
|
70 assertEquals(empty.orElseGet(() -> "y"), "y"); |
|
71 |
|
72 assertThrows(() -> empty.get(), NoSuchElementException.class); |
|
73 assertThrows(() -> empty.orElseThrow(), NoSuchElementException.class); |
|
74 assertThrows(() -> empty.orElseThrow(ObscureException::new), ObscureException.class); |
|
75 |
|
76 var b = new AtomicBoolean(); |
|
77 empty.ifPresent(s -> b.set(true)); |
|
78 assertFalse(b.get()); |
|
79 |
|
80 var b1 = new AtomicBoolean(false); |
|
81 var b2 = new AtomicBoolean(false); |
|
82 empty.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true)); |
|
83 assertFalse(b1.get()); |
|
84 assertTrue(b2.get()); |
|
85 } |
|
86 |
|
87 /** |
|
88 * Checks a block of assertions over an Optional that is expected to |
|
89 * have a particular value present. |
|
90 */ |
|
91 void checkPresent(Optional<String> opt, String expected) { |
|
92 assertFalse(opt.equals(Optional.empty())); |
|
93 assertFalse(Optional.empty().equals(opt)); |
|
94 assertTrue(opt.equals(Optional.of(expected))); |
|
95 assertTrue(Optional.of(expected).equals(opt)); |
|
96 assertFalse(opt.equals(Optional.of("unexpected"))); |
|
97 assertFalse(Optional.of("unexpected").equals(opt)); |
|
98 assertTrue(opt.isPresent()); |
|
99 assertEquals(opt.hashCode(), expected.hashCode()); |
|
100 assertEquals(opt.orElse("unexpected"), expected); |
|
101 assertEquals(opt.orElseGet(() -> "unexpected"), expected); |
|
102 |
|
103 assertEquals(opt.get(), expected); |
|
104 assertEquals(opt.orElseThrow(), expected); |
|
105 assertEquals(opt.orElseThrow(ObscureException::new), expected); |
|
106 |
|
107 var b = new AtomicBoolean(false); |
|
108 opt.ifPresent(s -> b.set(true)); |
|
109 assertTrue(b.get()); |
|
110 |
|
111 var b1 = new AtomicBoolean(false); |
|
112 var b2 = new AtomicBoolean(false); |
|
113 opt.ifPresentOrElse(s -> b1.set(true), () -> b2.set(true)); |
|
114 assertTrue(b1.get()); |
|
115 assertFalse(b2.get()); |
|
116 } |
|
117 |
|
118 @Test |
45 public void testEmpty() { |
119 public void testEmpty() { |
|
120 checkEmpty(Optional.empty()); |
|
121 } |
|
122 |
|
123 @Test |
|
124 public void testOfNull() { |
|
125 assertThrows(() -> Optional.of(null), NullPointerException.class); |
|
126 } |
|
127 |
|
128 @Test |
|
129 public void testOfPresent() { |
|
130 checkPresent(Optional.of("xyzzy"), "xyzzy"); |
|
131 } |
|
132 |
|
133 @Test |
|
134 public void testOfNullableNull() { |
|
135 checkEmpty(Optional.ofNullable(null)); |
|
136 } |
|
137 |
|
138 @Test |
|
139 public void testOfNullablePresent() { |
|
140 checkPresent(Optional.of("xyzzy"), "xyzzy"); |
|
141 } |
|
142 |
|
143 @Test |
|
144 public void testFilterEmpty() { |
|
145 checkEmpty(Optional.<String>empty().filter(s -> { fail(); return true; })); |
|
146 } |
|
147 |
|
148 @Test |
|
149 public void testFilterFalse() { |
|
150 checkEmpty(Optional.of("xyzzy").filter(s -> s.equals("plugh"))); |
|
151 } |
|
152 |
|
153 @Test |
|
154 public void testFilterTrue() { |
|
155 checkPresent(Optional.of("xyzzy").filter(s -> s.equals("xyzzy")), "xyzzy"); |
|
156 } |
|
157 |
|
158 @Test |
|
159 public void testMapEmpty() { |
|
160 checkEmpty(Optional.empty().map(s -> { fail(); return ""; })); |
|
161 } |
|
162 |
|
163 @Test |
|
164 public void testMapPresent() { |
|
165 checkPresent(Optional.of("xyzzy").map(s -> s.replace("xyzzy", "plugh")), "plugh"); |
|
166 } |
|
167 |
|
168 @Test |
|
169 public void testFlatMapEmpty() { |
|
170 checkEmpty(Optional.empty().flatMap(s -> { fail(); return Optional.of(""); })); |
|
171 } |
|
172 |
|
173 @Test |
|
174 public void testFlatMapPresentReturnEmpty() { |
|
175 checkEmpty(Optional.of("xyzzy") |
|
176 .flatMap(s -> { assertEquals(s, "xyzzy"); return Optional.empty(); })); |
|
177 } |
|
178 |
|
179 @Test |
|
180 public void testFlatMapPresentReturnPresent() { |
|
181 checkPresent(Optional.of("xyzzy") |
|
182 .flatMap(s -> { assertEquals(s, "xyzzy"); return Optional.of("plugh"); }), |
|
183 "plugh"); |
|
184 } |
|
185 |
|
186 @Test |
|
187 public void testOrEmptyEmpty() { |
|
188 checkEmpty(Optional.<String>empty().or(() -> Optional.empty())); |
|
189 } |
|
190 |
|
191 @Test |
|
192 public void testOrEmptyPresent() { |
|
193 checkPresent(Optional.<String>empty().or(() -> Optional.of("plugh")), "plugh"); |
|
194 } |
|
195 |
|
196 @Test |
|
197 public void testOrPresentDontCare() { |
|
198 checkPresent(Optional.of("xyzzy").or(() -> { fail(); return Optional.of("plugh"); }), "xyzzy"); |
|
199 } |
|
200 |
|
201 @Test |
|
202 public void testStreamEmpty() { |
|
203 assertEquals(Optional.empty().stream().collect(toList()), List.of()); |
|
204 } |
|
205 |
|
206 @Test |
|
207 public void testStreamPresent() { |
|
208 assertEquals(Optional.of("xyzzy").stream().collect(toList()), List.of("xyzzy")); |
|
209 } |
|
210 |
|
211 // ===== old tests ===== |
|
212 |
|
213 @Test(groups = "unit") |
|
214 public void testOldEmpty() { |
46 Optional<Boolean> empty = Optional.empty(); |
215 Optional<Boolean> empty = Optional.empty(); |
47 Optional<String> presentEmptyString = Optional.of(""); |
216 Optional<String> presentEmptyString = Optional.of(""); |
48 Optional<Boolean> present = Optional.of(Boolean.TRUE); |
217 Optional<Boolean> present = Optional.of(Boolean.TRUE); |
49 |
218 |
50 // empty |
219 // empty |