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.core.internal;
    18
    19  import org.junit.jupiter.api.Assertions;
    20  import org.junit.jupiter.api.Test;
    21
    22  class SimpleTupleFormatTest {
    23
    24      private static final double EPS = 1e-10;
    25
    26      private static final String OPEN_PAREN = "(";
    27      private static final String CLOSE_PAREN = ")";
    28
    29      private static final DoubleFunction1N<Stub1D> FACTORY_1D = v -> {
    30          Stub1D result = new Stub1D();
    31          result.v = v;
    32
    33          return result;
    34      };
    35
    36      private static final DoubleFunction2N<Stub2D> FACTORY_2D = (v1, v2) -> {
    37          Stub2D result = new Stub2D();
    38          result.v1 = v1;
    39          result.v2 = v2;
    40
    41          return result;
    42      };
    43
    44      private static final DoubleFunction3N<Stub3D> FACTORY_3D = (v1, v2, v3) -> {
    45          Stub3D result = new Stub3D();
    46          result.v1 = v1;
    47          result.v2 = v2;
    48          result.v3 = v3;
    49
    50          return result;
    51      };
    52
    53      @Test
    54      void testConstructor() {
    55          // act
    56          final SimpleTupleFormat formatter = new SimpleTupleFormat("|", "{", "}");
    57
    58          // assert
    59          Assertions.assertEquals("|", formatter.getSeparator());
    60          Assertions.assertEquals("{", formatter.getPrefix());
    61          Assertions.assertEquals("}", formatter.getSuffix());
    62      }
    63
    64      @Test
    65      void testConstructor_defaultSeparator() {
    66          // act
    67          final SimpleTupleFormat formatter = new SimpleTupleFormat("{", "}");
    68
    69          // assert
    70          Assertions.assertEquals(",", formatter.getSeparator());
    71          Assertions.assertEquals("{", formatter.getPrefix());
    72          Assertions.assertEquals("}", formatter.getSuffix());
    73      }
    74
    75      @Test
    76      void testFormat1D() {
    77          // arrange
    78          final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    79
    80          // act/assert
    81          Assertions.assertEquals("(1.0)", formatter.format(1.0));
    82          Assertions.assertEquals("(-1.0)", formatter.format(-1.0));
    83          Assertions.assertEquals("(NaN)", formatter.format(Double.NaN));
    84          Assertions.assertEquals("(-Infinity)", formatter.format(Double.NEGATIVE_INFINITY));
    85          Assertions.assertEquals("(Infinity)", formatter.format(Double.POSITIVE_INFINITY));
    86      }
    87
    88      @Test
    89      void testFormat1D_noPrefixSuffix() {
    90          // arrange
    91          final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    92
    93          // act/assert
    94          Assertions.assertEquals("1.0", formatter.format(1.0));
    95          Assertions.assertEquals("-1.0", formatter.format(-1.0));
    96          Assertions.assertEquals("NaN", formatter.format(Double.NaN));
    97          Assertions.assertEquals("-Infinity", formatter.format(Double.NEGATIVE_INFINITY));
    98          Assertions.assertEquals("Infinity", formatter.format(Double.POSITIVE_INFINITY));
    99      }
    100
    101     @Test
    102     void testFormat2D() {
    103         // arrange
    104         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    105
    106         // act/assert
    107         Assertions.assertEquals("(1.0, -1.0)", formatter.format(1.0, -1.0));
    108         Assertions.assertEquals("(-1.0, 1.0)", formatter.format(-1.0, 1.0));
    109         Assertions.assertEquals("(NaN, -Infinity)", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY));
    110         Assertions.assertEquals("(-Infinity, Infinity)", formatter.format(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
    111     }
    112
    113     @Test
    114     void testFormat2D_noPrefixSuffix() {
    115         // arrange
    116         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    117
    118         // act/assert
    119         Assertions.assertEquals("1.0, -1.0", formatter.format(1.0, -1.0));
    120         Assertions.assertEquals("-1.0, 1.0", formatter.format(-1.0, 1.0));
    121         Assertions.assertEquals("NaN, -Infinity", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY));
    122         Assertions.assertEquals("-Infinity, Infinity", formatter.format(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
    123     }
    124
    125     @Test
    126     void testFormat3D() {
    127         // arrange
    128         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    129
    130         // act/assert
    131         Assertions.assertEquals("(1.0, 0.0, -1.0)", formatter.format(1.0, 0.0, -1.0));
    132         Assertions.assertEquals("(-1.0, 1.0, 0.0)", formatter.format(-1.0, 1.0, 0.0));
    133         Assertions.assertEquals("(NaN, -Infinity, Infinity)", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
    134     }
    135
    136     @Test
    137     void testFormat3D_noPrefixSuffix() {
    138         // arrange
    139         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    140
    141         // act/assert
    142         Assertions.assertEquals("1.0, 0.0, -1.0", formatter.format(1.0, 0.0, -1.0));
    143         Assertions.assertEquals("-1.0, 1.0, 0.0", formatter.format(-1.0, 1.0, 0.0));
    144         Assertions.assertEquals("NaN, -Infinity, Infinity", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
    145     }
    146
    147     @Test
    148     void testFormat4D() {
    149         // arrange
    150         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    151
    152         // act/assert
    153         Assertions.assertEquals("(1.0, 0.0, -1.0, 2.0)", formatter.format(1.0, 0.0, -1.0, 2.0));
    154         Assertions.assertEquals("(-1.0, 1.0, 0.0, 2.0)", formatter.format(-1.0, 1.0, 0.0, 2.0));
    155         Assertions.assertEquals("(NaN, -Infinity, Infinity, NaN)", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN));
    156     }
    157
    158     @Test
    159     void testFormat4D_noPrefixSuffix() {
    160         // arrange
    161         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    162
    163         // act/assert
    164         Assertions.assertEquals("1.0, 0.0, -1.0, 2.0", formatter.format(1.0, 0.0, -1.0, 2.0));
    165         Assertions.assertEquals("-1.0, 1.0, 0.0, 2.0", formatter.format(-1.0, 1.0, 0.0, 2.0));
    166         Assertions.assertEquals("NaN, -Infinity, Infinity, NaN", formatter.format(Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN));
    167     }
    168
    169     @Test
    170     void testFormat_longTokens() {
    171         // arrange
    172         final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
    173
    174         // act/assert
    175         Assertions.assertEquals("<<1.0>>", formatter.format(1.0));
    176         Assertions.assertEquals("<<1.0|| 2.0>>", formatter.format(1.0, 2.0));
    177         Assertions.assertEquals("<<1.0|| 2.0|| 3.0>>", formatter.format(1.0, 2.0, 3.0));
    178     }
    179
    180     @Test
    181     void testParse1D() {
    182         // arrange
    183         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    184
    185         // act/assert
    186         checkParse1D(formatter, "(1)", 1.0);
    187         checkParse1D(formatter, "(-1)", -1.0);
    188
    189         checkParse1D(formatter, "(0.01)", 0.01);
    190         checkParse1D(formatter, "(-1e-2)", -0.01);
    191
    192         checkParse1D(formatter, "(100)", 100);
    193         checkParse1D(formatter, "(-1e2)", -100);
    194
    195         checkParse1D(formatter, " (\n 1 \t) ", 1);
    196         checkParse1D(formatter, "\n ( -1 \t)\r\n", -1);
    197
    198         checkParse1D(formatter, "(1, )", 1.0);
    199         checkParse1D(formatter, "(-1, )", -1.0);
    200
    201         checkParse1D(formatter, "(NaN)", Double.NaN);
    202         checkParse1D(formatter, "(-Infinity)", Double.NEGATIVE_INFINITY);
    203         checkParse1D(formatter, "(Infinity)", Double.POSITIVE_INFINITY);
    204     }
    205
    206     @Test
    207     void testParse1D_noPrefixSuffix() {
    208         // arrange
    209         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    210
    211         // act/assert
    212         checkParse1D(formatter, "1", 1.0);
    213         checkParse1D(formatter, "-1", -1.0);
    214
    215         checkParse1D(formatter, "0.01", 0.01);
    216         checkParse1D(formatter, "-1e-2", -0.01);
    217
    218         checkParse1D(formatter, "100", 100);
    219         checkParse1D(formatter, "-1e2", -100);
    220
    221         checkParse1D(formatter, " \n 1 \t ", 1);
    222         checkParse1D(formatter, "\n  -1 \t\r\n", -1);
    223
    224         checkParse1D(formatter, "1, ", 1.0);
    225         checkParse1D(formatter, "-1, ", -1.0);
    226
    227         checkParse1D(formatter, "NaN", Double.NaN);
    228         checkParse1D(formatter, "-Infinity", Double.NEGATIVE_INFINITY);
    229         checkParse1D(formatter, "Infinity", Double.POSITIVE_INFINITY);
    230     }
    231
    232     @Test
    233     void testParse1D_failure() {
    234         // arrange
    235         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    236
    237         // act/assert
    238         checkParse1DFailure(formatter, "", "index 0: expected \"(\" but found \"\"");
    239         checkParse1DFailure(formatter, "(1 ", "index 3: expected \")\" but found \"\"");
    240
    241         checkParse1DFailure(formatter, "(abc)", "unable to parse number from string \"abc\"");
    242
    243         checkParse1DFailure(formatter, "(1) 1", "index 4: unexpected content");
    244     }
    245
    246     @Test
    247     void testParse2D() {
    248         // arrange
    249         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    250
    251         // act/assert
    252         checkParse2D(formatter, "(1,-2)", 1.0, -2.0);
    253         checkParse2D(formatter, "(2,-1)", 2.0, -1.0);
    254
    255         checkParse2D(formatter, "(0.01, -0.02)", 0.01, -0.02);
    256         checkParse2D(formatter, "(-1e-2,2e-2)", -0.01, 0.02);
    257
    258         checkParse2D(formatter, "(100,  -1e2)", 100, -100);
    259
    260         checkParse2D(formatter, " (\n 1 , 2 \t) ", 1, 2);
    261         checkParse2D(formatter, "\n ( -1 , -2 \t)\r\n", -1, -2);
    262
    263         checkParse2D(formatter, "(1, 2, )", 1.0, 2.0);
    264         checkParse2D(formatter, "(-1, -2,)", -1.0, -2.0);
    265
    266         checkParse2D(formatter, "(NaN, -Infinity)", Double.NaN, Double.NEGATIVE_INFINITY);
    267         checkParse2D(formatter, "(-Infinity, Infinity)", Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    268     }
    269
    270     @Test
    271     void testParse2D_noPrefixSuffix() {
    272         // arrange
    273         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    274
    275         // act/assert
    276         checkParse2D(formatter, "1,-2", 1.0, -2.0);
    277         checkParse2D(formatter, "2,-1", 2.0, -1.0);
    278
    279         checkParse2D(formatter, "0.01, -0.02", 0.01, -0.02);
    280         checkParse2D(formatter, "-1e-2,2e-2", -0.01, 0.02);
    281
    282         checkParse2D(formatter, "100,  -1e2", 100, -100);
    283
    284         checkParse2D(formatter, " \n 1 , 2 \t ", 1, 2);
    285         checkParse2D(formatter, "\n  -1 , -2 \t\r\n", -1, -2);
    286
    287         checkParse2D(formatter, "1, 2, ", 1.0, 2.0);
    288         checkParse2D(formatter, "-1, -2,", -1.0, -2.0);
    289
    290         checkParse2D(formatter, "NaN, -Infinity", Double.NaN, Double.NEGATIVE_INFINITY);
    291         checkParse2D(formatter, "-Infinity, Infinity", Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    292     }
    293
    294     @Test
    295     void testParse2D_failure() {
    296         // arrange
    297         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    298
    299         // act/assert
    300         checkParse2DFailure(formatter, "", "index 0: expected \"(\" but found \"\"");
    301         checkParse2DFailure(formatter, "(1, 2 ", "index 6: expected \")\" but found \"\"");
    302
    303         checkParse2DFailure(formatter, "(0,abc)", "index 3: unable to parse number from string \"abc\"");
    304
    305         checkParse2DFailure(formatter, "(1, 2) 1", "index 7: unexpected content");
    306     }
    307
    308     @Test
    309     void testParse3D() {
    310         // arrange
    311         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    312
    313         // act/assert
    314         checkParse3D(formatter, "(1,-2,3)", 1.0, -2.0, 3.0);
    315         checkParse3D(formatter, "(2,-1,3)", 2.0, -1.0, 3.0);
    316
    317         checkParse3D(formatter, "(0.01, -0.02, 0.3)", 0.01, -0.02, 0.3);
    318         checkParse3D(formatter, "(-1e-2,2e-2,-3E-1)", -0.01, 0.02, -0.3);
    319
    320         checkParse3D(formatter, "(100,  -1e2,2E10)", 100, -100, 2e10);
    321
    322         checkParse3D(formatter, " (\n 1 , 2 , 3 \t) ", 1, 2, 3);
    323         checkParse3D(formatter, "\n ( -1 , -2 ,  -3 \t)\r\n", -1, -2, -3);
    324
    325         checkParse3D(formatter, "(1, 2, 3, )", 1.0, 2.0, 3.0);
    326         checkParse3D(formatter, "(-1, -2, -3,)", -1.0, -2.0, -3.0);
    327
    328         checkParse3D(formatter, "(NaN, -Infinity, Infinity)", Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    329     }
    330
    331     @Test
    332     void testParse3D_noPrefixSuffix() {
    333         // arrange
    334         final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
    335
    336         // act/assert
    337         checkParse3D(formatter, "1,-2,3", 1.0, -2.0, 3.0);
    338         checkParse3D(formatter, "2,-1,3", 2.0, -1.0, 3.0);
    339
    340         checkParse3D(formatter, "0.01, -0.02, 0.3", 0.01, -0.02, 0.3);
    341         checkParse3D(formatter, "-1e-2,2e-2,-3E-1", -0.01, 0.02, -0.3);
    342
    343         checkParse3D(formatter, "100,  -1e2,2E10", 100, -100, 2e10);
    344
    345         checkParse3D(formatter, " \n 1 , 2 , 3 \t ", 1, 2, 3);
    346         checkParse3D(formatter, "\n  -1 , -2 ,  -3 \t\r\n", -1, -2, -3);
    347
    348         checkParse3D(formatter, "1, 2, 3, ", 1.0, 2.0, 3.0);
    349         checkParse3D(formatter, "-1, -2, -3,", -1.0, -2.0, -3.0);
    350
    351         checkParse3D(formatter, "NaN, -Infinity, Infinity", Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    352     }
    353
    354     @Test
    355     void testParse3D_failure() {
    356         // arrange
    357         final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
    358
    359         // act/assert
    360         checkParse3DFailure(formatter, "", "index 0: expected \"(\" but found \"\"");
    361         checkParse3DFailure(formatter, "(1, 2, 3", "index 8: expected \")\" but found \"\"");
    362
    363         checkParse3DFailure(formatter, "(0,0,abc)", "index 5: unable to parse number from string \"abc\"");
    364
    365         checkParse3DFailure(formatter, "(1, 2, 3) 1", "index 10: unexpected content");
    366     }
    367
    368     @Test
    369     void testParse_longTokens() {
    370         // arrange
    371         final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
    372
    373         // act/assert
    374         checkParse1D(formatter, "<<1.0>>", 1.0);
    375         checkParse2D(formatter, "<<1.0|| 2.0>>", 1.0, 2.0);
    376         checkParse3D(formatter, "<<1.0|| 2.0|| 3.0>>", 1.0, 2.0, 3.0);
    377     }
    378
    379     @Test
    380     void testParse_longTokens_failure() {
    381         // arrange
    382         final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
    383
    384         // act/assert
    385         checkParse1DFailure(formatter, "<", "index 0: expected \"<<\" but found \"<\"");
    386         checkParse1DFailure(formatter, "<1.0>>", "index 0: expected \"<<\" but found \"<1\"");
    387         checkParse2DFailure(formatter, "<<1.0| 2.0>>", "index 2: unable to parse number from string \"1.0| 2.0\"");
    388         checkParse3DFailure(formatter, "<<1.0|| 2.0|| 3.0>", "index 13: unable to parse number from string \" 3.0>\"");
    389     }
    390
    391     @Test
    392     void testDefaultInstance() {
    393         // act
    394         final SimpleTupleFormat formatter = SimpleTupleFormat.getDefault();
    395
    396         // assert
    397         Assertions.assertEquals(",", formatter.getSeparator());
    398         Assertions.assertEquals("(", formatter.getPrefix());
    399         Assertions.assertEquals(")", formatter.getSuffix());
    400
    401         Assertions.assertEquals("(1.0, 2.0)", formatter.format(1, 2));
    402     }
    403
    404     private void checkParse1D(final SimpleTupleFormat formatter, final String str, final double v) {
    405         final Stub1D result = formatter.parse(str, FACTORY_1D);
    406
    407         Assertions.assertEquals(v, result.v, EPS);
    408     }
    409
    410     private void checkParse1DFailure(final SimpleTupleFormat formatter, final String str, final String msgSubstr) {
    411         try {
    412             formatter.parse(str, FACTORY_1D);
    413             Assertions.fail("Operation should have failed");
    414         } catch (final IllegalArgumentException exc) {
    415             final String excMsg = exc.getMessage();
    416             Assertions.assertTrue(excMsg.contains(msgSubstr), "Expected message to contain [" + msgSubstr + "] but was [" + excMsg + "]");
    417         }
    418     }
    419
    420     private void checkParse2D(final SimpleTupleFormat formatter, final String str, final double v1, final double v2) {
    421         final Stub2D result = formatter.parse(str, FACTORY_2D);
    422
    423         Assertions.assertEquals(v1, result.v1, EPS);
    424         Assertions.assertEquals(v2, result.v2, EPS);
    425     }
    426
    427     private void checkParse2DFailure(final SimpleTupleFormat formatter, final String str, final String msgSubstr) {
    428         try {
    429             formatter.parse(str, FACTORY_2D);
    430             Assertions.fail("Operation should have failed");
    431         } catch (final IllegalArgumentException exc) {
    432             final String excMsg = exc.getMessage();
    433             Assertions.assertTrue(excMsg.contains(msgSubstr),
    434                     "Expected message to contain [" + msgSubstr + "] but was [" + excMsg + "]");
    435         }
    436     }
    437
    438     private void checkParse3D(final SimpleTupleFormat formatter, final String str, final double v1, final double v2, final double v3) {
    439         final Stub3D result = formatter.parse(str, FACTORY_3D);
    440
    441         Assertions.assertEquals(v1, result.v1, EPS);
    442         Assertions.assertEquals(v2, result.v2, EPS);
    443         Assertions.assertEquals(v3, result.v3, EPS);
    444     }
    445
    446     private void checkParse3DFailure(final SimpleTupleFormat formatter, final String str, final String msgSubstr) {
    447         try {
    448             formatter.parse(str, FACTORY_3D);
    449             Assertions.fail("Operation should have failed");
    450         } catch (final IllegalArgumentException exc) {
    451             final String excMsg = exc.getMessage();
    452             Assertions.assertTrue(excMsg.contains(msgSubstr),
    453                     "Expected message to contain [" + msgSubstr + "] but was [" + excMsg + "]");
    454         }
    455     }
    456
    457     private static class Stub1D {
    458         private double v;
    459     }
    460
    461     private static class Stub2D {
    462         private double v1;
    463         private double v2;
    464     }
    465
    466     private static class Stub3D {
    467         private double v1;
    468         private double v2;
    469         private double v3;
    470     }
    471 }