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    *      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  
18  package org.apache.commons.io.function;
19  
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.assertThrows;
23  
24  import java.io.ByteArrayInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.UncheckedIOException;
28  import java.util.Optional;
29  import java.util.function.Consumer;
30  import java.util.function.Function;
31  import java.util.function.Supplier;
32  
33  import org.apache.commons.lang3.ArrayUtils;
34  import org.junit.jupiter.api.Test;
35  
36  /**
37   * Tests {@link IOFunction}.
38   */
39  public class IOFunctionTest {
40  
41      private static final class Holder<T> {
42          T value;
43      }
44  
45      @Test
46      public void testAndThenConsumer() throws IOException {
47          final Holder<Integer> holder = new Holder<>();
48          final IOFunction<InputStream, Integer> readByte = InputStream::read;
49          final Consumer<Integer> sinkInteger = i -> {
50              holder.value = i * i;
51          };
52          final IOConsumer<InputStream> productFunction = readByte.andThen(sinkInteger);
53  
54          final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
55          productFunction.accept(is);
56          assertEquals(4, holder.value);
57          productFunction.accept(is);
58          assertEquals(9, holder.value);
59      }
60  
61      @Test
62      public void testAndThenFunction() throws IOException {
63          final IOFunction<InputStream, Integer> readByte = InputStream::read;
64          final Function<Integer, Integer> squareInteger = i -> i * i;
65          final IOFunction<InputStream, Integer> productFunction = readByte.andThen(squareInteger);
66  
67          final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
68          assertEquals(4, productFunction.apply(is));
69          assertEquals(9, productFunction.apply(is));
70      }
71  
72      @Test
73      public void testAndThenIOConsumer() throws IOException {
74          final Holder<Integer> holder = new Holder<>();
75          final IOFunction<InputStream, Integer> readByte = InputStream::read;
76          final IOConsumer<Integer> sinkInteger = i -> {
77              holder.value = i * i;
78          };
79          final IOConsumer<InputStream> productFunction = readByte.andThen(sinkInteger);
80  
81          final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
82          productFunction.accept(is);
83          assertEquals(4, holder.value);
84          productFunction.accept(is);
85          assertEquals(9, holder.value);
86      }
87  
88      @Test
89      public void testAndThenIOFunction() throws IOException {
90          final IOFunction<InputStream, Integer> readByte = InputStream::read;
91          final IOFunction<Integer, Integer> squareInteger = i -> i * i;
92          final IOFunction<InputStream, Integer> productFunction = readByte.andThen(squareInteger);
93  
94          final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
95          assertEquals(4, productFunction.apply(is));
96          assertEquals(9, productFunction.apply(is));
97      }
98  
99      @Test
100     public void testApply() throws IOException {
101         final IOFunction<InputStream, Integer> readByte = InputStream::read;
102         final InputStream is = new ByteArrayInputStream(new byte[] {(byte) 0xa, (byte) 0xb, (byte) 0xc});
103         assertEquals(0xa, readByte.apply(is));
104         assertEquals(0xb, readByte.apply(is));
105         assertEquals(0xc, readByte.apply(is));
106         assertEquals(-1, readByte.apply(is));
107     }
108 
109     @Test
110     public void testApplyThrowsException() {
111         final IOFunction<InputStream, Integer> throwException = function -> {
112             throw new IOException("Boom!");
113         };
114         assertThrows(IOException.class, () -> throwException.apply(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)));
115     }
116 
117     @Test
118     public void testAsFunction() {
119         assertThrows(UncheckedIOException.class, () -> Optional.of("a").map(TestConstants.THROWING_IO_FUNCTION.asFunction()).get());
120         assertEquals("a", Optional.of("a").map(IOFunction.identity().asFunction()).get());
121     }
122 
123     @Test
124     public void testComposeFunction() throws IOException {
125         final Function<InputStream, Integer> alwaysSeven = is -> 7;
126         final IOFunction<Integer, Integer> squareInteger = i -> i * i;
127         final IOFunction<InputStream, Integer> productFunction = squareInteger.compose(alwaysSeven);
128 
129         final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
130         assertEquals(49, productFunction.apply(is));
131         assertEquals(49, productFunction.apply(is));
132     }
133 
134     @Test
135     public void testComposeIOFunction() throws IOException {
136         final IOFunction<InputStream, Integer> readByte = InputStream::read;
137         final IOFunction<Integer, Integer> squareInteger = i -> i * i;
138         final IOFunction<InputStream, Integer> productFunction = squareInteger.compose(readByte);
139 
140         final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
141         assertEquals(4, productFunction.apply(is));
142         assertEquals(9, productFunction.apply(is));
143     }
144 
145     @Test
146     public void testComposeIOSupplier() throws IOException {
147         final InputStream is = new ByteArrayInputStream(new byte[] {2, 3});
148 
149         final IOSupplier<Integer> readByte = is::read;
150         final IOFunction<Integer, Integer> squareInteger = i -> i * i;
151         final IOSupplier<Integer> productFunction = squareInteger.compose(readByte);
152 
153         assertEquals(4, productFunction.get());
154         assertEquals(9, productFunction.get());
155     }
156 
157     @Test
158     public void testComposeSupplier() throws IOException {
159         final Supplier<Integer> alwaysNine = () -> 9;
160         final IOFunction<Integer, Integer> squareInteger = i -> i * i;
161         final IOSupplier<Integer> productFunction = squareInteger.compose(alwaysNine);
162 
163         assertEquals(81, productFunction.get());
164         assertEquals(81, productFunction.get());
165     }
166 
167     @Test
168     public void testIdentity() throws IOException {
169         assertEquals(IOFunction.identity(), IOFunction.identity());
170         final IOFunction<byte[], byte[]> identityFunction = IOFunction.identity();
171         final byte[] buf = {(byte) 0xa, (byte) 0xb, (byte) 0xc};
172         assertEquals(buf, identityFunction.apply(buf));
173         assertArrayEquals(buf, identityFunction.apply(buf));
174     }
175 }