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  package org.apache.commons.geometry.io.core.internal;
    18
    19  import java.io.IOException;
    20  import java.io.Reader;
    21  import java.io.StringReader;
    22  import java.io.UncheckedIOException;
    23  import java.util.Random;
    24
    25  import org.apache.commons.geometry.core.GeometryTestUtils;
    26  import org.junit.jupiter.api.Assertions;
    27  import org.junit.jupiter.api.Test;
    28
    29  class CharReadBufferTest {
    30
    31      @Test
    32      void testCtor() {
    33          // act/assert
    34          GeometryTestUtils.assertThrowsWithMessage(() -> {
    35              new CharReadBuffer(null, 1, 1);
    36          }, NullPointerException.class, "Reader cannot be null");
    37
    38          GeometryTestUtils.assertThrowsWithMessage(() -> {
    39              new CharReadBuffer(reader("a"), 0, 1);
    40          }, IllegalArgumentException.class, "Initial buffer capacity must be greater than 0; was 0");
    41
    42          GeometryTestUtils.assertThrowsWithMessage(() -> {
    43              new CharReadBuffer(reader("a"), 1, 0);
    44          }, IllegalArgumentException.class, "Min read value must be greater than 0; was 0");
    45      }
    46
    47      @Test
    48      void testHasMoreCharacters() {
    49          // act/assert
    50          for (int s = 1; s < 10; s += 2) {
    51              Assertions.assertFalse(new CharReadBuffer(reader("")).hasMoreCharacters());
    52              Assertions.assertFalse(new CharReadBuffer(reader(""), s).hasMoreCharacters());
    53              Assertions.assertFalse(new CharReadBuffer(reader(""), s, s).hasMoreCharacters());
    54          }
    55
    56          String str;
    57          for (int i = 1; i < 10; ++i) {
    58              str = repeat("a", i);
    59
    60              for (int s = 1; s < 10; s += 2) {
    61                  Assertions.assertTrue(new CharReadBuffer(reader(str)).hasMoreCharacters());
    62                  Assertions.assertTrue(new CharReadBuffer(reader(str), s).hasMoreCharacters());
    63                  Assertions.assertTrue(new CharReadBuffer(reader(str), s, s).hasMoreCharacters());
    64              }
    65          }
    66      }
    67
    68      @Test
    69      void testPeekRead() {
    70          // arrange
    71          final String str = "abcdefg";
    72          final CharReadBuffer buf = new CharReadBuffer(reader(str), 1);
    73
    74          final StringBuilder peek = new StringBuilder();
    75          final StringBuilder read = new StringBuilder();
    76
    77          // act
    78          while (buf.hasMoreCharacters()) {
    79              peek.append((char) buf.peek());
    80              read.append((char) buf.read());
    81          }
    82
    83          // assert
    84          Assertions.assertEquals(str, peek.toString());
    85          Assertions.assertEquals(str, read.toString());
    86
    87          Assertions.assertEquals(-1, buf.peek());
    88          Assertions.assertEquals(-1, buf.read());
    89      }
    90
    91      @Test
    92      void testCharAt() {
    93          // arrange
    94          final String str = "abcdefgh";
    95          final CharReadBuffer buf = new CharReadBuffer(reader(str), 3);
    96
    97          // act/assert
    98          Assertions.assertEquals('a', buf.charAt(0));
    99          Assertions.assertEquals('b', buf.charAt(1));
    100         Assertions.assertEquals('c', buf.charAt(2));
    101         Assertions.assertEquals('d', buf.charAt(3));
    102         Assertions.assertEquals('e', buf.charAt(4));
    103         Assertions.assertEquals('f', buf.charAt(5));
    104         Assertions.assertEquals('g', buf.charAt(6));
    105         Assertions.assertEquals('h', buf.charAt(7));
    106
    107         Assertions.assertEquals(-1, buf.charAt(8));
    108         Assertions.assertEquals(-1, buf.charAt(9));
    109         Assertions.assertEquals(-1, buf.charAt(10));
    110     }
    111
    112     @Test
    113     void testCharAt_invalidArg() {
    114         // arrange
    115         final String str = "abcdefgh";
    116         final CharReadBuffer buf = new CharReadBuffer(reader(str), 3);
    117
    118         // act/assert
    119         GeometryTestUtils.assertThrowsWithMessage(() -> {
    120             buf.charAt(-1);
    121         }, IllegalArgumentException.class, "Character index cannot be negative; was -1");
    122     }
    123
    124     @Test
    125     void testReadPeek_string() {
    126         // arrange
    127         final String str = "abcdefgh";
    128         final CharReadBuffer buf = new CharReadBuffer(reader(str), 50);
    129
    130         // act/assert
    131         Assertions.assertEquals("", buf.peekString(0));
    132         Assertions.assertEquals("", buf.readString(0));
    133
    134         Assertions.assertEquals("abc", buf.peekString(3));
    135         Assertions.assertEquals("abc", buf.readString(3));
    136
    137         Assertions.assertEquals("defgh", buf.peekString(100));
    138         Assertions.assertEquals("defgh", buf.readString(100));
    139
    140         Assertions.assertEquals(null, buf.peekString(1));
    141         Assertions.assertEquals(null, buf.readString(1));
    142     }
    143
    144     @Test
    145     void testReadPeek_tring_zeroLen() {
    146         // act/assert
    147         Assertions.assertNull(new CharReadBuffer(reader("")).peekString(0));
    148         Assertions.assertNull(new CharReadBuffer(reader("")).readString(0));
    149
    150         Assertions.assertEquals("", new CharReadBuffer(reader("a")).peekString(0));
    151         Assertions.assertEquals("", new CharReadBuffer(reader("a")).readString(0));
    152     }
    153
    154     @Test
    155     void testReadPeek_string_invalidArg() {
    156         // arrange
    157         final CharReadBuffer buf = new CharReadBuffer(reader("a"));
    158         final String msg = "Requested string length cannot be negative; was -1";
    159
    160         // act/assert
    161         GeometryTestUtils.assertThrowsWithMessage(() -> {
    162             buf.peekString(-1);
    163         }, IllegalArgumentException.class, msg);
    164
    165         GeometryTestUtils.assertThrowsWithMessage(() -> {
    166             buf.readString(-1);
    167         }, IllegalArgumentException.class, msg);
    168     }
    169
    170     @Test
    171     void testReadPeek_failure() {
    172         // arrange
    173         final CharReadBuffer buf = new CharReadBuffer(failReader());
    174         final String msg = "IOException: read";
    175
    176         // act/assert
    177         GeometryTestUtils.assertThrowsWithMessage(() -> {
    178             buf.peekString(3);
    179         }, UncheckedIOException.class, msg);
    180
    181         GeometryTestUtils.assertThrowsWithMessage(() -> {
    182             buf.readString(3);
    183         }, UncheckedIOException.class, msg);
    184     }
    185
    186     @Test
    187     void testSkip() {
    188         // arrange
    189         final CharReadBuffer buf = new CharReadBuffer(reader("abcdefg"), 3);
    190         buf.peekString(2);
    191
    192         // act/assert
    193         Assertions.assertEquals(0, buf.skip(0));
    194         Assertions.assertEquals("a", buf.peekString(1));
    195
    196         Assertions.assertEquals(1, buf.skip(1));
    197         Assertions.assertEquals("b", buf.peekString(1));
    198
    199         Assertions.assertEquals(4, buf.skip(4));
    200         Assertions.assertEquals("f", buf.peekString(1));
    201
    202         Assertions.assertEquals(1, buf.skip(1));
    203         Assertions.assertEquals("g", buf.peekString(1));
    204
    205         Assertions.assertEquals(1, buf.skip(100));
    206         Assertions.assertNull(buf.peekString(1));
    207
    208         Assertions.assertEquals(0, buf.skip(100));
    209         Assertions.assertNull(buf.peekString(1));
    210     }
    211
    212     @Test
    213     void testSkip_invalidArg() {
    214         // arrange
    215         final CharReadBuffer buf = new CharReadBuffer(reader("a"));
    216
    217         // act/assert
    218         GeometryTestUtils.assertThrowsWithMessage(() -> {
    219             buf.skip(-1);
    220         }, IllegalArgumentException.class, "Character skip count cannot be negative; was -1");
    221     }
    222
    223     @Test
    224     void testSkip_failure() {
    225         // arrange
    226         final CharReadBuffer buf = new CharReadBuffer(failReader());
    227
    228         // act/assert
    229         GeometryTestUtils.assertThrowsWithMessage(() -> {
    230             buf.skip(10);
    231         }, UncheckedIOException.class, "IOException: skip");
    232     }
    233
    234     @Test
    235     void testPushString_emptyReader() {
    236         // arrange
    237         final String a = "abcd";
    238         final String b = "efgh";
    239         final CharReadBuffer buf = new CharReadBuffer(reader(""), 1);
    240
    241         // act
    242         buf.pushString(a);
    243         buf.pushString(b);
    244
    245         // assert
    246         Assertions.assertTrue(buf.hasMoreCharacters());
    247         Assertions.assertEquals("efghabcd", buf.readString(8));
    248     }
    249
    250     @Test
    251     void testPushString_nonEmptyReader() {
    252         // arrange
    253         final String a = "abcd";
    254         final String b = "efgh";
    255         final CharReadBuffer buf = new CharReadBuffer(reader("ABCD"), 1);
    256
    257         // act
    258         buf.pushString(a);
    259         buf.pushString(b);
    260
    261         // assert
    262         Assertions.assertTrue(buf.hasMoreCharacters());
    263         Assertions.assertEquals("efghabcdABCD", buf.readString(12));
    264     }
    265
    266     @Test
    267     void testPush_emptyReader() {
    268         // arrange
    269         final CharReadBuffer buf = new CharReadBuffer(reader("ABCD"), 1);
    270
    271         // act
    272         buf.push('a');
    273         buf.push('b');
    274         buf.push('c');
    275         buf.push('d');
    276
    277         // assert
    278         Assertions.assertTrue(buf.hasMoreCharacters());
    279         Assertions.assertEquals("dcbaABCD", buf.readString(8));
    280     }
    281
    282     @Test
    283     void testAlternatingPushAndRead() {
    284         // arrange
    285         final String str = repeat("abcdefghijlmnopqrstuvwxyz", 10);
    286
    287         final CharReadBuffer buf = new CharReadBuffer(reader(str), 8);
    288
    289         final Random rnd = new Random(1L);
    290
    291         // act
    292         final StringBuilder result = new StringBuilder();
    293         String tmp;
    294         while (buf.hasMoreCharacters()) {
    295             buf.pushString("ABC");
    296
    297             tmp = buf.readString(rnd.nextInt(10) + 4);
    298
    299             result.append(tmp.charAt(3));
    300
    301             buf.pushString(tmp.substring(4));
    302         }
    303
    304         // assert
    305         Assertions.assertEquals(str, result.toString());
    306     }
    307
    308     private static Reader reader(final String content) {
    309         return new StringReader(content);
    310     }
    311
    312     private static Reader failReader() {
    313         return new Reader() {
    314
    315             @Override
    316             public int read(char[] cbuf, int off, int len) throws IOException {
    317                 throw new IOException("read");
    318             }
    319
    320             @Override
    321             public long skip(final long skip) throws IOException {
    322                 throw new IOException("skip");
    323             }
    324
    325             @Override
    326             public void close() {
    327             }
    328         };
    329     }
    330
    331     private static String repeat(final String str, final int count) {
    332         final StringBuilder sb = new StringBuilder();
    333         for (int i = 0; i < count; ++i) {
    334             sb.append(str);
    335         }
    336
    337         return sb.toString();
    338     }
    339 }