1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3.stream; 18 19 import static org.hamcrest.MatcherAssert.assertThat; 20 import static org.hamcrest.core.Is.is; 21 import static org.hamcrest.core.IsEqual.equalTo; 22 import static org.hamcrest.core.IsNull.nullValue; 23 import static org.junit.jupiter.api.Assertions.assertAll; 24 import static org.junit.jupiter.api.Assertions.assertEquals; 25 import static org.junit.jupiter.api.Assertions.assertNotNull; 26 import static org.junit.jupiter.api.Assertions.assertThrows; 27 import static org.junit.jupiter.api.Assertions.assertTrue; 28 import static org.junit.jupiter.api.DynamicTest.dynamicTest; 29 30 import java.lang.reflect.UndeclaredThrowableException; 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.Hashtable; 34 import java.util.Iterator; 35 import java.util.List; 36 import java.util.stream.Collectors; 37 import java.util.stream.Stream; 38 39 import org.apache.commons.lang3.AbstractLangTest; 40 import org.apache.commons.lang3.function.Failable; 41 import org.apache.commons.lang3.function.FailableConsumer; 42 import org.apache.commons.lang3.function.FailablePredicate; 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 * Tests {@link Streams}. 51 */ 52 public class StreamsTest extends AbstractLangTest { 53 asIntConsumer(final T pThrowable)54 protected <T extends Throwable> FailableConsumer<String, T> asIntConsumer(final T pThrowable) { 55 return s -> { 56 final int i = Integer.parseInt(s); 57 if (i == 4) { 58 throw pThrowable; 59 } 60 }; 61 } 62 asIntPredicate(final T pThrowable)63 protected <T extends Throwable> FailablePredicate<Integer, T> asIntPredicate(final T pThrowable) { 64 return i -> { 65 if (i.intValue() == 5 && pThrowable != null) { 66 throw pThrowable; 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 85 return Stream.of( 86 87 dynamicTest("IllegalArgumentException", () -> { 88 final IllegalArgumentException iae = new IllegalArgumentException("Invalid argument: " + 5); 89 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(iae)).collect(Collectors.toList()); 90 final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, testMethod); 91 assertThat(thrown.getMessage(), is(equalTo("Invalid argument: " + 5))); 92 }), 93 94 dynamicTest("OutOfMemoryError", () -> { 95 final OutOfMemoryError oome = new OutOfMemoryError(); 96 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(oome)).collect(Collectors.toList()); 97 final OutOfMemoryError thrown = assertThrows(OutOfMemoryError.class, testMethod); 98 assertThat(thrown.getMessage(), is(nullValue())); 99 }), 100 101 dynamicTest("SAXException", () -> { 102 final SAXException se = new SAXException(); 103 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(se)).collect(Collectors.toList()); 104 final UndeclaredThrowableException thrown = assertThrows(UndeclaredThrowableException.class, testMethod); 105 assertAll(() -> assertThat(thrown.getMessage(), is(nullValue())), () -> assertThat(thrown.getCause(), is(equalTo(se)))); 106 })); 107 } 108 109 @TestFactory 110 public Stream<DynamicTest> simpleStreamForEachFailing() { 111 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); 112 113 return Stream.of( 114 115 dynamicTest("IllegalArgumentException", () -> { 116 final IllegalArgumentException ise = new IllegalArgumentException(); 117 final Executable testMethod = () -> Failable.stream(input).forEach(asIntConsumer(ise)); 118 final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, testMethod); 119 assertThat(thrown.getMessage(), is(nullValue())); 120 }), 121 122 dynamicTest("OutOfMemoryError", () -> { 123 final OutOfMemoryError oome = new OutOfMemoryError(); 124 final Executable oomeTestMethod = () -> Failable.stream(input).forEach(asIntConsumer(oome)); 125 final OutOfMemoryError oomeThrown = assertThrows(OutOfMemoryError.class, oomeTestMethod); 126 assertThat(oomeThrown.getMessage(), is(nullValue())); 127 }), 128 129 dynamicTest("SAXException", () -> { 130 final SAXException se = new SAXException(); 131 final Executable seTestMethod = () -> Failable.stream(input).forEach(asIntConsumer(se)); 132 final UndeclaredThrowableException seThrown = assertThrows(UndeclaredThrowableException.class, seTestMethod); 133 assertAll(() -> assertThat(seThrown.getMessage(), is(nullValue())), () -> assertThat(seThrown.getCause(), is(equalTo(se)))); 134 })); 135 } 136 137 @Test 138 public void testInstanceOfStream() { 139 assertEquals(2, Streams.instancesOf(String.class, Arrays.asList("A", "B")).collect(Collectors.toList()).size()); 140 assertEquals(2, Streams.instancesOf(String.class, Arrays.asList(null, "A", null, "B", null)).collect(Collectors.toList()).size()); 141 assertEquals(0, Streams.instancesOf(String.class, Arrays.asList(null, null)).collect(Collectors.toList()).size()); 142 // 143 final List<Object> objects = Arrays.asList("A", "B"); 144 assertEquals(2, Streams.instancesOf(String.class, objects).collect(Collectors.toList()).size()); 145 } 146 147 @Test 148 public void testNullSafeStreamNotNull() { 149 assertEquals(2, Streams.nonNull(Arrays.asList("A", "B")).collect(Collectors.toList()).size()); 150 assertEquals(2, Streams.nonNull(Arrays.asList(null, "A", null, "B", null)).collect(Collectors.toList()).size()); 151 assertEquals(0, Streams.nonNull(Arrays.asList(null, null)).collect(Collectors.toList()).size()); 152 } 153 154 @Test 155 public void testNullSafeStreamNull() { 156 final List<String> input = null; 157 assertEquals(0, Streams.nonNull(input).collect(Collectors.toList()).size()); 158 } 159 160 @Test 161 public void testOfArray() { 162 assertEquals(0, Streams.of((Object[]) null).count()); 163 assertEquals(1, Streams.of("foo").count()); 164 assertEquals(2, Streams.of("foo", "bar").count()); 165 } 166 167 @Test 168 public void testOfCollectionNotNull() { 169 assertEquals(2, Streams.of(Arrays.asList("A", "B")).collect(Collectors.toList()).size()); 170 } 171 172 @Test 173 public void testOfCollectionNull() { 174 final List<String> input = null; 175 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size()); 176 } 177 178 @Test 179 public void testOfEnumeration() { 180 final Hashtable<String, Integer> table = new Hashtable<>(); 181 assertEquals(0, Streams.of(table.elements()).count()); 182 table.put("One", 1); 183 assertEquals(1, Streams.of(table.elements()).count()); 184 table.put("Two", 2); 185 assertEquals(2, Streams.of(table.elements()).count()); 186 final List<String> collect = Streams.of(table.keys()).collect(Collectors.toList()); 187 assertTrue(collect.contains("One")); 188 assertTrue(collect.contains("Two")); 189 assertEquals(2, collect.size()); 190 } 191 192 @Test 193 public void testOfIterableNotNull() { 194 assertEquals(2, Streams.of((Iterable<String>) Arrays.asList("A", "B")).collect(Collectors.toList()).size()); 195 } 196 197 @Test 198 public void testOfIterableNull() { 199 final Iterable<String> input = null; 200 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size()); 201 } 202 203 @Test 204 public void testOfIteratorNotNull() { 205 assertEquals(2, Streams.of(Arrays.asList("A", "B").iterator()).collect(Collectors.toList()).size()); 206 } 207 208 @Test 209 public void testOfIteratorNull() { 210 final Iterator<String> input = null; 211 assertEquals(0, Streams.of(input).collect(Collectors.toList()).size()); 212 } 213 214 @Test 215 public void testSimpleStreamFilter() { 216 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); 217 final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(i -> (i.intValue() % 2 == 0)).collect(Collectors.toList()); 218 assertEvenNumbers(output); 219 } 220 221 @Test 222 public void testSimpleStreamForEach() { 223 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); 224 final List<Integer> output = new ArrayList<>(); 225 Failable.stream(input).forEach(s -> output.add(Integer.valueOf(s))); 226 assertEquals(6, output.size()); 227 for (int i = 0; i < 6; i++) { 228 assertEquals(i + 1, output.get(i).intValue()); 229 } 230 } 231 232 @Test 233 public void testSimpleStreamMap() { 234 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); 235 final List<Integer> output = Failable.stream(input).map(Integer::valueOf).collect(Collectors.toList()); 236 assertEquals(6, output.size()); 237 for (int i = 0; i < 6; i++) { 238 assertEquals(i + 1, output.get(i).intValue()); 239 } 240 } 241 242 @Test 243 public void testSimpleStreamMapFailing() { 244 final List<String> input = Arrays.asList("1", "2", "3", "4 ", "5", "6"); 245 final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).collect(Collectors.toList()); 246 final NumberFormatException thrown = assertThrows(NumberFormatException.class, testMethod); 247 assertEquals("For input string: \"4 \"", thrown.getMessage()); 248 } 249 250 @Test 251 public void testStreamCollection() { 252 final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); 253 assertEquals(6, Streams.stream(input).collect(Collectors.toList()).size()); 254 } 255 256 @Test 257 public void testStreamCollectionNull() { 258 final List<String> input = null; 259 assertEquals(0, Streams.stream(input).collect(Collectors.toList()).size()); 260 } 261 262 @Test 263 public void testToArray() { 264 final String[] array = Arrays.asList("2", "3", "1").stream().collect(Streams.toArray(String.class)); 265 assertNotNull(array); 266 assertEquals(3, array.length); 267 assertEquals("2", array[0]); 268 assertEquals("3", array[1]); 269 assertEquals("1", array[2]); 270 } 271 272 } 273