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.channels;
19  
20  import static org.apache.commons.lang3.ArrayUtils.EMPTY_BYTE_ARRAY;
21  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.IOException;
27  import java.nio.ByteBuffer;
28  import java.nio.channels.SeekableByteChannel;
29  import java.nio.charset.StandardCharsets;
30  import java.util.stream.Stream;
31  
32  import org.apache.commons.io.IOUtils;
33  import org.apache.commons.io.function.IOSupplier;
34  import org.junit.jupiter.api.Test;
35  import org.junit.jupiter.params.ParameterizedTest;
36  import org.junit.jupiter.params.provider.Arguments;
37  import org.junit.jupiter.params.provider.MethodSource;
38  
39  /**
40   * A sanity test to make sure {@link AbstractSeekableByteChannelTest} works for files.
41   */
42  public class ByteArraySeekableByteChannelTest extends AbstractSeekableByteChannelTest {
43  
44      private static final byte[] testData = "Some data".getBytes(StandardCharsets.UTF_8);
45  
46      static Stream<Arguments> testConstructor() {
47          return Stream.of(
48                  Arguments.of((IOSupplier<ByteArraySeekableByteChannel>) ByteArraySeekableByteChannel::new, EMPTY_BYTE_ARRAY, IOUtils.DEFAULT_BUFFER_SIZE),
49                  Arguments.of((IOSupplier<ByteArraySeekableByteChannel>) () -> new ByteArraySeekableByteChannel(8), EMPTY_BYTE_ARRAY, 8),
50                  Arguments.of((IOSupplier<ByteArraySeekableByteChannel>) () -> new ByteArraySeekableByteChannel(16), EMPTY_BYTE_ARRAY, 16),
51                  Arguments.of((IOSupplier<ByteArraySeekableByteChannel>) () -> ByteArraySeekableByteChannel.wrap(EMPTY_BYTE_ARRAY), EMPTY_BYTE_ARRAY, 0),
52                  Arguments.of((IOSupplier<ByteArraySeekableByteChannel>) () -> ByteArraySeekableByteChannel.wrap(testData), testData, testData.length));
53      }
54  
55      static Stream<Arguments> testShouldResizeWhenWritingMoreDataThanCapacity() {
56          return Stream.of(
57                  // Resize from 0
58                  Arguments.of(EMPTY_BYTE_ARRAY, 1),
59                  // Resize less than double
60                  Arguments.of(new byte[8], 1),
61                  // Resize more that double
62                  Arguments.of(new byte[8], 20));
63      }
64  
65      @Override
66      protected SeekableByteChannel createChannel() throws IOException {
67          return new ByteArraySeekableByteChannel();
68      }
69  
70      @ParameterizedTest
71      @MethodSource
72      void testConstructor(final IOSupplier<ByteArraySeekableByteChannel> supplier, final byte[] expected, final int capacity) throws IOException {
73          try (ByteArraySeekableByteChannel channel = supplier.get()) {
74              assertEquals(0, channel.position());
75              assertEquals(expected.length, channel.size());
76              assertEquals(capacity, channel.array().length);
77              assertArrayEquals(expected, channel.toByteArray());
78          }
79      }
80  
81      @Test
82      void testConstructorInvalid() {
83          assertThrows(IllegalArgumentException.class, () -> new ByteArraySeekableByteChannel(-1));
84          assertThrows(NullPointerException.class, () -> ByteArraySeekableByteChannel.wrap(null));
85      }
86  
87      @ParameterizedTest
88      @MethodSource
89      void testShouldResizeWhenWritingMoreDataThanCapacity(final byte[] data, final int wanted) throws IOException {
90          try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(data)) {
91              c.position(data.length);
92              final ByteBuffer inData = ByteBuffer.wrap(new byte[wanted]);
93              final int writeCount = c.write(inData);
94              assertEquals(wanted, writeCount);
95              assertTrue(c.array().length >= data.length + wanted, "Capacity not increased sufficiently");
96          }
97      }
98  
99  }