View Javadoc
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    *      https://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  
18  package org.apache.commons.io.function;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.io.ByteArrayInputStream;
25  import java.io.IOException;
26  import java.io.UncheckedIOException;
27  import java.util.concurrent.atomic.AtomicBoolean;
28  import java.util.concurrent.atomic.AtomicInteger;
29  import java.util.concurrent.atomic.AtomicLong;
30  import java.util.concurrent.atomic.AtomicReference;
31  import java.util.function.Supplier;
32  
33  import org.apache.commons.io.input.BrokenInputStream;
34  import org.junit.jupiter.api.BeforeEach;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Tests {@link Uncheck}.
39   */
40  class UncheckTest {
41  
42      private static final byte[] BYTES = { 'a', 'b' };
43      private static final String CAUSE_MESSAGE = "CauseMessage";
44      private static final String CUSTOM_MESSAGE = "Custom message";
45  
46      private AtomicInteger atomicInt;
47      private AtomicLong atomicLong;
48      private AtomicBoolean atomicBoolean;
49      private AtomicReference<String> ref1;
50      private AtomicReference<String> ref2;
51      private AtomicReference<String> ref3;
52      private AtomicReference<String> ref4;
53  
54      private void assertUncheckedIOException(final IOException expected, final UncheckedIOException e) {
55          assertEquals(CUSTOM_MESSAGE, e.getMessage());
56          final IOException cause = e.getCause();
57          assertEquals(expected.getClass(), cause.getClass());
58          assertEquals(CAUSE_MESSAGE, cause.getMessage());
59      }
60  
61      @BeforeEach
62      public void beforeEach() {
63          ref1 = new AtomicReference<>();
64          ref2 = new AtomicReference<>();
65          ref3 = new AtomicReference<>();
66          ref4 = new AtomicReference<>();
67          atomicInt = new AtomicInteger();
68          atomicLong = new AtomicLong();
69          atomicBoolean = new AtomicBoolean();
70      }
71  
72      private ByteArrayInputStream newInputStream() {
73          return new ByteArrayInputStream(BYTES);
74      }
75  
76      /**
77       * Tests {@link Uncheck#accept(IOConsumer, Object)}.
78       */
79      @Test
80      void testAccept() {
81          final ByteArrayInputStream stream = newInputStream();
82          Uncheck.accept(n -> stream.skip(n), 1);
83          assertEquals('b', Uncheck.get(stream::read).intValue());
84      }
85  
86      @Test
87      void testAcceptIOBiConsumerOfTUTU() {
88          assertThrows(UncheckedIOException.class, () -> Uncheck.accept((t, u) -> {
89              throw new IOException();
90          }, null, null));
91          assertThrows(UncheckedIOException.class, () -> Uncheck.accept(TestConstants.THROWING_IO_BI_CONSUMER, null, null));
92          Uncheck.accept((t, u) -> {
93              TestUtils.compareAndSetThrowsIO(ref1, t);
94              TestUtils.compareAndSetThrowsIO(ref2, u);
95          }, "new1", "new2");
96          assertEquals("new1", ref1.get());
97          assertEquals("new2", ref2.get());
98      }
99  
100     @Test
101     void testAcceptIOConsumerOfTT() {
102         assertThrows(UncheckedIOException.class, () -> Uncheck.accept(t -> {
103             throw new IOException();
104         }, null));
105         assertThrows(UncheckedIOException.class, () -> Uncheck.accept(TestUtils.throwingIOConsumer(), null));
106         Uncheck.accept(t -> TestUtils.compareAndSetThrowsIO(ref1, t), "new1");
107         assertEquals("new1", ref1.get());
108     }
109 
110     @Test
111     void testAcceptIOTriConsumerOfTUVTUV() {
112         assertThrows(UncheckedIOException.class, () -> Uncheck.accept((t, u, v) -> {
113             throw new IOException();
114         }, null, null, null));
115         assertThrows(UncheckedIOException.class, () -> Uncheck.accept(TestConstants.THROWING_IO_TRI_CONSUMER, null, null, null));
116         Uncheck.accept((t, u, v) -> {
117             TestUtils.compareAndSetThrowsIO(ref1, t);
118             TestUtils.compareAndSetThrowsIO(ref2, u);
119             TestUtils.compareAndSetThrowsIO(ref3, v);
120         }, "new1", "new2", "new3");
121         assertEquals("new1", ref1.get());
122         assertEquals("new2", ref2.get());
123         assertEquals("new3", ref3.get());
124     }
125 
126     /**
127      * Tests {@link Uncheck#apply(IOFunction, Object)}.
128      */
129     @Test
130     void testApply1() {
131         final ByteArrayInputStream stream = newInputStream();
132         assertEquals(1, Uncheck.apply(n -> stream.skip(n), 1).intValue());
133         assertEquals('b', Uncheck.get(stream::read).intValue());
134     }
135 
136     /**
137      * Tests {@link Uncheck#apply(IOBiFunction, Object, Object)}.
138      */
139     @Test
140     void testApply2() {
141         final ByteArrayInputStream stream = newInputStream();
142         final byte[] buf = new byte[BYTES.length];
143         assertEquals(1, Uncheck.apply((o, l) -> stream.read(buf, o, l), 0, 1).intValue());
144         assertEquals('a', buf[0]);
145     }
146 
147     /**
148      * Tests {@link Uncheck#apply(IOTriFunction, Object, Object, Object)}.
149      */
150     @Test
151     void testApply3() {
152         final ByteArrayInputStream stream = newInputStream();
153         final byte[] buf = new byte[BYTES.length];
154         assertEquals(1, Uncheck.apply((b, o, l) -> stream.read(b, o, l), buf, 0, 1).intValue());
155         assertEquals('a', buf[0]);
156     }
157 
158     @Test
159     void testApplyIOBiFunctionOfTURTU() {
160         assertThrows(UncheckedIOException.class, () -> Uncheck.apply((t, u) -> {
161             throw new IOException();
162         }, null, null));
163         assertThrows(UncheckedIOException.class, () -> Uncheck.apply(TestConstants.THROWING_IO_BI_FUNCTION, null, null));
164         assertEquals("new0", Uncheck.apply((t, u) -> {
165             TestUtils.compareAndSetThrowsIO(ref1, t);
166             TestUtils.compareAndSetThrowsIO(ref2, u);
167             return "new0";
168         }, "new1", "new2"));
169         assertEquals("new1", ref1.get());
170         assertEquals("new2", ref2.get());
171     }
172 
173     @Test
174     void testApplyIOFunctionOfTRT() {
175         assertThrows(UncheckedIOException.class, () -> Uncheck.apply(t -> {
176             throw new IOException();
177         }, null));
178         assertThrows(UncheckedIOException.class, () -> Uncheck.apply(TestConstants.THROWING_IO_FUNCTION, null));
179         Uncheck.apply(t -> TestUtils.compareAndSetThrowsIO(ref1, t), "new1");
180         assertEquals("new1", ref1.get());
181     }
182 
183     @Test
184     void testApplyIOQuadFunctionOfTUVWRTUVW() {
185         assertThrows(UncheckedIOException.class, () -> Uncheck.apply((t, u, v, w) -> {
186             throw new IOException();
187         }, null, null, null, null));
188         assertThrows(UncheckedIOException.class, () -> Uncheck.apply(TestConstants.THROWING_IO_QUAD_FUNCTION, null, null, null, null));
189         assertEquals("new0", Uncheck.apply((t, u, v, w) -> {
190             TestUtils.compareAndSetThrowsIO(ref1, t);
191             TestUtils.compareAndSetThrowsIO(ref2, u);
192             TestUtils.compareAndSetThrowsIO(ref3, v);
193             TestUtils.compareAndSetThrowsIO(ref4, w);
194             return "new0";
195         }, "new1", "new2", "new3", "new4"));
196         assertEquals("new1", ref1.get());
197         assertEquals("new2", ref2.get());
198         assertEquals("new3", ref3.get());
199         assertEquals("new4", ref4.get());
200     }
201 
202     @Test
203     void testApplyIOTriFunctionOfTUVRTUV() {
204         assertThrows(UncheckedIOException.class, () -> Uncheck.apply((t, u, v) -> {
205             throw new IOException();
206         }, null, null, null));
207         assertThrows(UncheckedIOException.class, () -> Uncheck.apply(TestConstants.THROWING_IO_TRI_FUNCTION, null, null, null));
208         assertEquals("new0", Uncheck.apply((t, u, v) -> {
209             TestUtils.compareAndSetThrowsIO(ref1, t);
210             TestUtils.compareAndSetThrowsIO(ref2, u);
211             TestUtils.compareAndSetThrowsIO(ref3, v);
212             return "new0";
213         }, "new1", "new2", "new3"));
214         assertEquals("new1", ref1.get());
215         assertEquals("new2", ref2.get());
216         assertEquals("new3", ref3.get());
217     }
218 
219     /**
220      * Tests {@link Uncheck#get(IOSupplier)}.
221      */
222     @Test
223     void testGet() {
224         assertEquals('a', Uncheck.get(() -> newInputStream().read()).intValue());
225         assertThrows(UncheckedIOException.class, () -> Uncheck.get(() -> {
226             throw new IOException();
227         }));
228         assertThrows(UncheckedIOException.class, () -> Uncheck.get(TestConstants.THROWING_IO_SUPPLIER));
229         assertEquals("new1", Uncheck.get(() -> TestUtils.compareAndSetThrowsIO(ref1, "new1")));
230         assertEquals("new1", ref1.get());
231     }
232 
233     @Test
234     void testGetAsBoolean() {
235         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsBoolean(() -> {
236             throw new IOException();
237         }));
238         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsBoolean(TestConstants.THROWING_IO_BOOLEAN_SUPPLIER));
239         assertTrue(Uncheck.getAsBoolean(() -> TestUtils.compareAndSetThrowsIO(atomicBoolean, true)));
240         assertTrue(atomicBoolean.get());
241     }
242 
243     @Test
244     void testGetAsInt() {
245         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(() -> {
246             throw new IOException();
247         }));
248         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(TestConstants.THROWING_IO_INT_SUPPLIER));
249         assertEquals(1, Uncheck.getAsInt(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1)));
250         assertEquals(1, atomicInt.get());
251     }
252 
253     @Test
254     void testGetAsIntMessage() {
255         // No exception
256         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(() -> {
257             throw new IOException();
258         }, () -> CUSTOM_MESSAGE));
259         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(TestConstants.THROWING_IO_INT_SUPPLIER, () -> CUSTOM_MESSAGE));
260         assertEquals(1, Uncheck.getAsInt(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1), () -> CUSTOM_MESSAGE));
261         assertEquals(1, atomicInt.get());
262         // exception
263         final IOException expected = new IOException(CAUSE_MESSAGE);
264         assertUncheckedIOException(expected,
265                 assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE)));
266     }
267 
268     @Test
269     void testGetAsLong() {
270         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(() -> {
271             throw new IOException();
272         }));
273         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(TestConstants.THROWING_IO_LONG_SUPPLIER));
274         assertEquals(1L, Uncheck.getAsLong(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L)));
275         assertEquals(1L, atomicLong.get());
276     }
277 
278     @Test
279     void testGetAsLongMessage() {
280         // No exception
281         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(() -> {
282             throw new IOException();
283         }, () -> CUSTOM_MESSAGE));
284         assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(TestConstants.THROWING_IO_LONG_SUPPLIER, () -> CUSTOM_MESSAGE));
285         assertEquals(1L, Uncheck.getAsLong(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L), () -> CUSTOM_MESSAGE));
286         assertEquals(1L, atomicLong.get());
287         // exception
288         final IOException expected = new IOException(CAUSE_MESSAGE);
289         assertUncheckedIOException(expected,
290                 assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE)));
291     }
292 
293     /**
294      * Tests {@link Uncheck#get(IOSupplier, Supplier)}.
295      */
296     @Test
297     void testGetMessage() {
298         // No exception
299         assertEquals('a', Uncheck.get(() -> newInputStream().read()).intValue(), () -> CUSTOM_MESSAGE);
300         // Exception
301         final IOException expected = new IOException(CAUSE_MESSAGE);
302         assertUncheckedIOException(expected,
303                 assertThrows(UncheckedIOException.class, () -> Uncheck.get(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE)));
304     }
305 
306     /**
307      * Tests {@link Uncheck#run(IORunnable)}.
308      */
309     @Test
310     void testRun() {
311         final ByteArrayInputStream stream = newInputStream();
312         Uncheck.run(() -> stream.skip(1));
313         assertEquals('b', Uncheck.get(stream::read).intValue());
314         //
315         assertThrows(UncheckedIOException.class, () -> Uncheck.run(() -> {
316             throw new IOException();
317         }));
318         assertThrows(UncheckedIOException.class, () -> Uncheck.run(TestConstants.THROWING_IO_RUNNABLE));
319         Uncheck.run(() -> TestUtils.compareAndSetThrowsIO(ref1, "new1"));
320         assertEquals("new1", ref1.get());
321     }
322 
323     /**
324      * Tests {@link Uncheck#run(IORunnable, Supplier)}.
325      *
326      * @throws IOException Thrown on a test failure.
327      */
328     @Test
329     void testRunMessage() throws IOException {
330         // No exception
331         final ByteArrayInputStream stream = newInputStream();
332         Uncheck.run(() -> stream.skip(1), () -> CUSTOM_MESSAGE);
333         assertEquals('b', Uncheck.get(stream::read).intValue());
334         final IOException expected = new IOException(CAUSE_MESSAGE);
335         // Exception
336         assertUncheckedIOException(expected,
337                 assertThrows(UncheckedIOException.class, () -> Uncheck.run(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE)));
338     }
339 
340     @Test
341     void testTest() {
342         assertThrows(UncheckedIOException.class, () -> Uncheck.test(t -> {
343             throw new IOException();
344         }, null));
345         assertThrows(UncheckedIOException.class, () -> Uncheck.test(TestConstants.THROWING_IO_PREDICATE, null));
346         assertTrue(Uncheck.test(t -> TestUtils.compareAndSetThrowsIO(ref1, t).equals(t), "new1"));
347         assertEquals("new1", ref1.get());
348     }
349 
350 }