1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
56 final SimpleTupleFormat formatter = new SimpleTupleFormat("|", "{", "}");
57
58
59 Assertions.assertEquals("|", formatter.getSeparator());
60 Assertions.assertEquals("{", formatter.getPrefix());
61 Assertions.assertEquals("}", formatter.getSuffix());
62 }
63
64 @Test
65 void testConstructor_defaultSeparator() {
66
67 final SimpleTupleFormat formatter = new SimpleTupleFormat("{", "}");
68
69
70 Assertions.assertEquals(",", formatter.getSeparator());
71 Assertions.assertEquals("{", formatter.getPrefix());
72 Assertions.assertEquals("}", formatter.getSuffix());
73 }
74
75 @Test
76 void testFormat1D() {
77
78 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
79
80
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
91 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
92
93
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
104 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
105
106
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
116 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
117
118
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
128 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
129
130
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
139 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
140
141
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
150 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
151
152
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
161 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
162
163
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
172 final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
173
174
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
183 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
184
185
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
209 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
210
211
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
235 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
236
237
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
249 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
250
251
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
273 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
274
275
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
297 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
298
299
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
311 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
312
313
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
334 final SimpleTupleFormat formatter = new SimpleTupleFormat(null, null);
335
336
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
357 final SimpleTupleFormat formatter = new SimpleTupleFormat(OPEN_PAREN, CLOSE_PAREN);
358
359
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
371 final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
372
373
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
382 final SimpleTupleFormat formatter = new SimpleTupleFormat("||", "<<", ">>");
383
384
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
394 final SimpleTupleFormat formatter = SimpleTupleFormat.getDefault();
395
396
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 }