Changeset 18983 in josm for trunk/test/unit/org


Ignore:
Timestamp:
2024-02-14T15:57:09+01:00 (7 months ago)
Author:
taylor.smock
Message:

Fix #23471: fix an inconsistency between fast ASCII sort and slower unicode-aware sort

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/unit/org/openstreetmap/josm/tools/AlphanumComparatorTest.java

    r18690 r18983  
    22package org.openstreetmap.josm.tools;
    33
     4import static org.junit.jupiter.api.Assertions.assertAll;
    45import static org.junit.jupiter.api.Assertions.assertEquals;
    56
     7import java.text.Collator;
     8import java.util.ArrayList;
    69import java.util.Arrays;
    710import java.util.List;
     11import java.util.function.BiFunction;
     12import java.util.stream.Stream;
    813
     14import org.junit.jupiter.api.AfterEach;
    915import org.junit.jupiter.api.Test;
    1016
     
    1319 */
    1420class AlphanumComparatorTest {
     21    @AfterEach
     22    void teardown() {
     23        AlphanumComparator.useFastASCIISort = true;
     24    }
    1525
    1626    /**
     
    3343        assertEquals(Arrays.asList("a5", "a100", "a00999", "b1", "b20"), lst);
    3444    }
     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
    35117}
Note: See TracChangeset for help on using the changeset viewer.