1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.stream;
18
19 import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.junit.jupiter.api.DynamicTest.dynamicTest;
28
29 import java.lang.reflect.UndeclaredThrowableException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Hashtable;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.stream.Collectors;
36 import java.util.stream.Stream;
37
38 import org.apache.commons.lang3.AbstractLangTest;
39 import org.apache.commons.lang3.function.Failable;
40 import org.apache.commons.lang3.function.FailableConsumer;
41 import org.apache.commons.lang3.function.FailablePredicate;
42 import org.apache.commons.lang3.stream.Streams.FailableStream;
43 import org.junit.jupiter.api.DynamicTest;
44 import org.junit.jupiter.api.Test;
45 import org.junit.jupiter.api.TestFactory;
46 import org.junit.jupiter.api.function.Executable;
47 import org.xml.sax.SAXException;
48
49
50
51
52 class StreamsTest extends AbstractLangTest {
53
54 protected <T extends Throwable> FailableConsumer<String, T> asIntConsumer(final T throwable) {
55 return s -> {
56 final int i = Integer.parseInt(s);
57 if (i == 4) {
58 throw throwable;
59 }
60 };
61 }
62
63 protected <T extends Throwable> FailablePredicate<Integer, T> asIntPredicate(final T throwable) {
64 return i -> {
65 if (i.intValue() == 5 && throwable != null) {
66 throw throwable;
67 }
68 return i % 2 == 0;
69 };
70 }
71
72 private void assertEvenNumbers(final List<Integer> output) {
73 assertEquals(3, output.size());
74 for (int i = 0; i < 3; i++) {
75 assertEquals((i + 1) * 2, output.get(i).intValue());
76 }
77 }
78
79 @TestFactory
80 public Stream<DynamicTest> simpleStreamFilterFailing() {
81 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
82 final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(null)).collect(Collectors.toList());
83 assertEvenNumbers(output);
84 return Stream.of(
85 dynamicTest("IllegalArgumentException", () -> {
86 final IllegalArgumentException iae = new IllegalArgumentException("Invalid argument: " + 5);
87 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(iae)).collect(Collectors.toList());
88 final IllegalArgumentException thrown = assertIllegalArgumentException(testMethod);
89 assertEquals("Invalid argument: " + 5, thrown.getMessage());
90 }),
91 dynamicTest("OutOfMemoryError", () -> {
92 final OutOfMemoryError oome = new OutOfMemoryError();
93 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(oome)).collect(Collectors.toList());
94 final OutOfMemoryError thrown = assertThrows(OutOfMemoryError.class, testMethod);
95 assertNull(thrown.getMessage());
96 }),
97 dynamicTest("SAXException", () -> {
98 final SAXException se = new SAXException();
99 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(se)).collect(Collectors.toList());
100 final UndeclaredThrowableException thrown = assertThrows(UndeclaredThrowableException.class, testMethod);
101 assertNull(thrown.getMessage());
102 assertEquals(se, thrown.getCause());
103 }));
104 }
105
106 @TestFactory
107 public Stream<DynamicTest> simpleStreamForEachFailing() {
108 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
109 return Stream.of(
110 dynamicTest("IllegalArgumentException", () -> {
111 final IllegalArgumentException ise = new IllegalArgumentException();
112 final Executable testMethod = () -> Failable.stream(input).forEach(asIntConsumer(ise));
113 final IllegalArgumentException thrown = assertIllegalArgumentException(testMethod);
114 assertNull(thrown.getMessage());
115 }),
116 dynamicTest("OutOfMemoryError", () -> {
117 final OutOfMemoryError oome = new OutOfMemoryError();
118 final Executable oomeTestMethod = () -> Failable.stream(input).forEach(asIntConsumer(oome));
119 final OutOfMemoryError oomeThrown = assertThrows(OutOfMemoryError.class, oomeTestMethod);
120 assertNull(oomeThrown.getMessage());
121 }),
122 dynamicTest("SAXException", () -> {
123 final SAXException se = new SAXException();
124 final Executable seTestMethod = () -> Failable.stream(input).forEach(asIntConsumer(se));
125 final UndeclaredThrowableException seThrown = assertThrows(UndeclaredThrowableException.class, seTestMethod);
126 assertNull(seThrown.getMessage());
127 assertEquals(se, seThrown.getCause());
128 }));
129 }
130
131 @Test
132 void testArrayCollectorCombiner() {
133 final String[] expected = { "A1", "B1" };
134 assertArrayEquals(expected, Stream.of("A", "B").collect(Collectors.mapping(s -> s + "1", Streams.toArray(String.class))));
135 assertArrayEquals(expected, Streams.failableStream("A", "B").collect(Collectors.mapping(s -> s + "1", Streams.toArray(String.class))));
136 final List<String> left = new ArrayList<>();
137 left.add("a");
138 assertEquals(Arrays.asList("a", "b", "c"), Streams.toArray(String.class).combiner().apply(left, Arrays.asList("b", "c")));
139 }
140
141 @Test
142 void testAssertNotTerminated() {
143 final FailableStream<String> stream = Streams.failableStream("A", "B");
144 assertTrue(stream.allMatch(s -> s.length() == 1));
145 assertThrows(IllegalStateException.class, () -> stream.allMatch(null));
146 }
147
148 @SuppressWarnings("deprecation")
149 @Test
150 void testDeprefcatedCopnstructor() {
151 assertNotNull(new Streams().toString());
152 }
153
154 @Test
155 void testFailableAllMatch() {
156 assertTrue(Streams.failableStream("A", "B").allMatch(s -> s.length() == 1));
157 assertFalse(Streams.failableStream("A", "B").allMatch(s -> s.length() == 2));
158 }
159
160 @Test
161 void testFailableAnyMatch() {
162 assertTrue(Streams.failableStream("A", "B").anyMatch(s -> s.length() == 1));
163 assertTrue(Streams.failableStream("A", "BC").anyMatch(s -> s.length() == 1));
164 assertFalse(Streams.failableStream("A", "B").anyMatch(s -> s.length() == 2));
165 }
166
167 @Test
168 void testFailableCollect() {
169 assertEquals(Arrays.asList("A", "B"), Streams.failableStream("A", "B").collect(ArrayList::new, ArrayList::add, ArrayList::addAll));
170 }
171
172 @Test
173 void testFailableReduce() {
174 assertEquals(3, Streams.failableStream(1, 2).reduce(0, (a, b) -> a + b));
175 }
176
177 @Test
178 void testFailableStream() {
179 assertEquals(1, Streams.failableStream(1).collect(Collectors.toList()).size());
180 assertEquals(0, Streams.failableStream(Stream.empty()).collect(Collectors.toList()).size());
181 }
182
183 @Test
184 void testInstanceOfStream() {
185 assertEquals(2, Streams.instancesOf(String.class, Arrays.asList("A", "B")).collect(Collectors.toList()).size());
186 assertEquals(2, Streams.instancesOf(String.class, Arrays.asList(null, "A", null, "B", null)).collect(Collectors.toList()).size());
187 assertEquals(0, Streams.instancesOf(String.class, Arrays.asList(null, null)).collect(Collectors.toList()).size());
188
189 final List<Object> objects = Arrays.asList("A", "B");
190 assertEquals(2, Streams.instancesOf(String.class, objects).collect(Collectors.toList()).size());
191 }
192
193 @Test
194 void testNonNull() {
195 assertEquals(0, Streams.nonNull().collect(Collectors.toList()).size());
196 assertEquals(0, Streams.nonNull((Stream<?>) null).collect(Collectors.toList()).size());
197 assertEquals(1, Streams.nonNull("A").collect(Collectors.toList()).size());
198 assertEquals(1, Streams.nonNull("A", null).collect(Collectors.toList()).size());
199 assertEquals(1, Streams.nonNull(null, "A").collect(Collectors.toList()).size());
200 }
201
202 @Test
203 void testNullSafeStreamNotNull() {
204 assertEquals(2, Streams.nonNull(Arrays.asList("A", "B")).collect(Collectors.toList()).size());
205 assertEquals(2, Streams.nonNull(Arrays.asList(null, "A", null, "B", null)).collect(Collectors.toList()).size());
206 assertEquals(0, Streams.nonNull(Arrays.asList(null, null)).collect(Collectors.toList()).size());
207 }
208
209 @Test
210 void testNullSafeStreamNull() {
211 final List<String> input = null;
212 assertEquals(0, Streams.nonNull(input).collect(Collectors.toList()).size());
213 }
214
215 @Test
216 void testOfArray() {
217 assertEquals(0, Streams.of((Object[]) null).count());
218 assertEquals(1, Streams.of("foo").count());
219 assertEquals(2, Streams.of("foo", "bar").count());
220 }
221
222 @Test
223 void testOfCollectionNotNull() {
224 assertEquals(2, Streams.of(Arrays.asList("A", "B")).collect(Collectors.toList()).size());
225 }
226
227 @Test
228 void testOfCollectionNull() {
229 final List<String> input = null;
230 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size());
231 }
232
233 @Test
234 void testOfEnumeration() {
235 final Hashtable<String, Integer> table = new Hashtable<>();
236 assertEquals(0, Streams.of(table.elements()).count());
237 table.put("One", 1);
238 assertEquals(1, Streams.of(table.elements()).count());
239 table.put("Two", 2);
240 assertEquals(2, Streams.of(table.elements()).count());
241 final List<String> collect = Streams.of(table.keys()).collect(Collectors.toList());
242 assertTrue(collect.contains("One"));
243 assertTrue(collect.contains("Two"));
244 assertEquals(2, collect.size());
245 assertFalse(Streams.of(table.keys()).filter(String::isEmpty).findFirst().isPresent());
246 assertEquals(Arrays.asList("OneOne", "TwoTwo"), Streams.of(table.keys()).map(s -> s + s).collect(Collectors.toList()));
247 assertFalse(Streams.of(new Hashtable<String, Object>().keys()).filter(String::isEmpty).findFirst().isPresent());
248 }
249
250 @Test
251 void testOfIterableNotNull() {
252 assertEquals(2, Streams.of((Iterable<String>) Arrays.asList("A", "B")).collect(Collectors.toList()).size());
253 }
254
255 @Test
256 void testOfIterableNull() {
257 final Iterable<String> input = null;
258 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size());
259 }
260
261 @Test
262 void testOfIteratorNotNull() {
263 assertEquals(2, Streams.of(Arrays.asList("A", "B").iterator()).collect(Collectors.toList()).size());
264 }
265
266 @Test
267 void testOfIteratorNull() {
268 final Iterator<String> input = null;
269 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size());
270 }
271
272 @Test
273 void testOfVarArg() {
274 assertEquals(1, Streams.of(1).collect(Collectors.toList()).size());
275 assertEquals(2, Streams.of(1, 2).collect(Collectors.toList()).size());
276 }
277
278 @Test
279 void testSimpleStreamFilter() {
280 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
281 final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(i -> i.intValue() % 2 == 0).collect(Collectors.toList());
282 assertEvenNumbers(output);
283 }
284
285 @Test
286 void testSimpleStreamForEach() {
287 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
288 final List<Integer> output = new ArrayList<>();
289 Failable.stream(input).forEach(s -> output.add(Integer.valueOf(s)));
290 assertEquals(6, output.size());
291 for (int i = 0; i < 6; i++) {
292 assertEquals(i + 1, output.get(i).intValue());
293 }
294 }
295
296 @Test
297 void testSimpleStreamMap() {
298 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
299 final List<Integer> output = Failable.stream(input).map(Integer::valueOf).collect(Collectors.toList());
300 assertEquals(6, output.size());
301 for (int i = 0; i < 6; i++) {
302 assertEquals(i + 1, output.get(i).intValue());
303 }
304 }
305
306 @Test
307 void testSimpleStreamMapFailing() {
308 final List<String> input = Arrays.asList("1", "2", "3", "4 ", "5", "6");
309 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).collect(Collectors.toList());
310 final NumberFormatException thrown = assertThrows(NumberFormatException.class, testMethod);
311 assertEquals("For input string: \"4 \"", thrown.getMessage());
312 }
313
314 @SuppressWarnings("deprecation")
315 @Test
316 void testStream() {
317 assertEquals(0, Streams.stream(Stream.empty()).collect(Collectors.toList()).size());
318 assertEquals(1, Streams.stream(Stream.of("")).collect(Collectors.toList()).size());
319 }
320
321 @Test
322 void testStreamCollection() {
323 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6");
324 assertEquals(6, Streams.stream(input).collect(Collectors.toList()).size());
325 }
326
327 @Test
328 void testStreamCollectionNull() {
329 final List<String> input = null;
330 assertEquals(0, Streams.stream(input).collect(Collectors.toList()).size());
331 }
332
333 @Test
334 void testToArray() {
335 final String[] array = Arrays.asList("2", "3", "1").stream().collect(Streams.toArray(String.class));
336 assertNotNull(array);
337 assertEquals(3, array.length);
338 assertEquals("2", array[0]);
339 assertEquals("3", array[1]);
340 assertEquals("1", array[2]);
341 }
342
343 }