1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.tools;
|
---|
3 |
|
---|
4 | import static org.junit.jupiter.api.Assertions.assertAll;
|
---|
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
|
---|
6 |
|
---|
7 | import java.text.Collator;
|
---|
8 | import java.util.ArrayList;
|
---|
9 | import java.util.Arrays;
|
---|
10 | import java.util.List;
|
---|
11 | import java.util.function.BiFunction;
|
---|
12 | import java.util.stream.Stream;
|
---|
13 |
|
---|
14 | import org.junit.jupiter.api.AfterEach;
|
---|
15 | import org.junit.jupiter.api.Test;
|
---|
16 |
|
---|
17 | /**
|
---|
18 | * Unit tests of {@link AlphanumComparator}.
|
---|
19 | */
|
---|
20 | class AlphanumComparatorTest {
|
---|
21 | @AfterEach
|
---|
22 | void teardown() {
|
---|
23 | AlphanumComparator.useFastASCIISort = true;
|
---|
24 | }
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * Test numeric strings.
|
---|
28 | */
|
---|
29 | @Test
|
---|
30 | void testNumeric() {
|
---|
31 | List<String> lst = Arrays.asList("1", "20", "-1", "00999", "100");
|
---|
32 | lst.sort(AlphanumComparator.getInstance());
|
---|
33 | assertEquals(Arrays.asList("-1", "1", "20", "100", "00999"), lst);
|
---|
34 | }
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * Test mixed character strings.
|
---|
38 | */
|
---|
39 | @Test
|
---|
40 | void testMixed() {
|
---|
41 | List<String> lst = Arrays.asList("b1", "b20", "a5", "a00999", "a100");
|
---|
42 | lst.sort(AlphanumComparator.getInstance());
|
---|
43 | assertEquals(Arrays.asList("a5", "a100", "a00999", "b1", "b20"), lst);
|
---|
44 | }
|
---|
45 |
|
---|
46 | private static Stream<String[]> testNonRegression23471Arguments() {
|
---|
47 | List<String> testStrings = Arrays.asList(
|
---|
48 | "AMEN",
|
---|
49 | "Ameriabank",
|
---|
50 | "America First Credit Union",
|
---|
51 | "BAC Credomatic",
|
---|
52 | "BADR Banque",
|
---|
53 | "BAI",
|
---|
54 | "Banca Popolare di Cividale",
|
---|
55 | "Banca Popolare di Sondrio",
|
---|
56 | "Banca Sella",
|
---|
57 | "Banca Transilvania",
|
---|
58 | "Bancaribe",
|
---|
59 | "BancaStato",
|
---|
60 | "Banco Agrario",
|
---|
61 | "Banco AV Villas",
|
---|
62 | "Banco Azteca",
|
---|
63 | "Banco Bicentenario",
|
---|
64 | "Banco BISA",
|
---|
65 | "Banco BMG",
|
---|
66 | "Banco BPI (Portugal)",
|
---|
67 | "Banco BPM",
|
---|
68 | "Banco Caja Social",
|
---|
69 | "Banco Ciudad",
|
---|
70 | "Banco Continental (Paraguay)",
|
---|
71 | "Banco di Sardegna"
|
---|
72 | );
|
---|
73 | List<String> testChars = new ArrayList<>(AlphanumComparator.ASCII_SORT_ORDER.length());
|
---|
74 | for (char c : AlphanumComparator.ASCII_SORT_ORDER.toCharArray()) {
|
---|
75 | testChars.add(Character.toString(c));
|
---|
76 | }
|
---|
77 | BiFunction<List<String>, String, List<String>> subList = (list, string) -> list.subList(list.indexOf(string), list.size());
|
---|
78 | return Stream.concat(
|
---|
79 | testStrings.stream().flatMap(first -> subList.apply(testStrings, first).stream().map(second -> new String[]{first, second})),
|
---|
80 | testChars.stream().flatMap(first -> subList.apply(testChars, first).stream().map(second -> new String[]{first, second}))
|
---|
81 | );
|
---|
82 | }
|
---|
83 |
|
---|
84 | /**
|
---|
85 | * Non-regression test for #23471
|
---|
86 | * This ensures that the comparison contract holds.
|
---|
87 | * There are ~5300 combinations run in <1s (as of 2024-02-14).
|
---|
88 | */
|
---|
89 | @Test
|
---|
90 | void testNonRegression23471() {
|
---|
91 | assertAll(testNonRegression23471Arguments().map(strings -> () -> testNonRegression23471(strings[0], strings[1])));
|
---|
92 | }
|
---|
93 |
|
---|
94 | private static void testNonRegression23471(String first, String second) {
|
---|
95 | AlphanumComparator.useFastASCIISort = true;
|
---|
96 | final AlphanumComparator instance = AlphanumComparator.getInstance();
|
---|
97 | assertEquals(-instance.compare(first, second), instance.compare(second, first));
|
---|
98 | // Ensure that the fast sort is equivalent to the slow sort
|
---|
99 | AlphanumComparator.useFastASCIISort = false;
|
---|
100 | final int slowFirstSecond = instance.compare(first, second);
|
---|
101 | final int slowSecondFirst = instance.compare(second, first);
|
---|
102 | AlphanumComparator.useFastASCIISort = true;
|
---|
103 | final int fastFirstSecond = instance.compare(first, second);
|
---|
104 | final int fastSecondFirst = instance.compare(second, first);
|
---|
105 | assertEquals(slowFirstSecond, fastFirstSecond);
|
---|
106 | assertEquals(slowSecondFirst, fastSecondFirst);
|
---|
107 |
|
---|
108 | final Collator collator = Collator.getInstance();
|
---|
109 | collator.setStrength(Collator.SECONDARY);
|
---|
110 | // Check against the collator instance
|
---|
111 | assertEquals(Utils.clamp(collator.compare(first, second), -1, 1),
|
---|
112 | Utils.clamp(instance.compare(first, second), -1, 1));
|
---|
113 | assertEquals(Utils.clamp(collator.compare(second, first), -1, 1),
|
---|
114 | Utils.clamp(instance.compare(second, first), -1, 1));
|
---|
115 | }
|
---|
116 |
|
---|
117 | }
|
---|