Changeset 15459 in josm


Ignore:
Timestamp:
2019-10-16T17:23:02+02:00 (5 years ago)
Author:
GerdP
Message:

fix #17837 and #18223, add unit tests

TODO:

  • Will havily blow up size of preferences.xml when user ignores lots of "single elements" instead of the group.
  • Maybe ignore entries in preferences with many (how many?) elements, as those probably were caused by error #18223 and are meaningless
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java

    r15405 r15459  
    260260
    261261    /**
    262      *  Make sure that we don't keep single entries for a "group ignore" or
    263      *  multiple different entries for the single entries that are in the same group.
    264      */
    265     private static void cleanupIgnoredErrors() {
     262     *  Make sure that we don't keep single entries for a "group ignore".
     263     */
     264    protected static void cleanupIgnoredErrors() {
    266265        if (ignoredErrors.size() > 1) {
    267266            List<String> toRemove = new ArrayList<>();
    268267
    269268            Iterator<Entry<String, String>> iter = ignoredErrors.entrySet().iterator();
    270             Entry<String, String> last = iter.next();
     269            String lastKey = iter.next().getKey();
    271270            while (iter.hasNext()) {
    272                 Entry<String, String> entry = iter.next();
    273                 if (entry.getKey().startsWith(last.getKey())) {
    274                     toRemove.add(entry.getKey());
     271                String currKey = iter.next().getKey();
     272                if (currKey.startsWith(lastKey) && sameCode(currKey, lastKey)) {
     273                    toRemove.add(currKey);
    275274                } else {
    276                     last = entry;
     275                    lastKey = currKey;
    277276                }
    278277            }
     
    285284            ignoredErrors.putAll(tmap);
    286285        }
     286    }
     287
     288    private static boolean sameCode(String key1, String key2) {
     289        return extractCodeFromIgnoreKey(key1).equals(extractCodeFromIgnoreKey(key2));
     290    }
     291
     292    /**
     293     * Extract the leading digits building the code for the error key.
     294     * @param key the error key
     295     * @return the leading digits
     296     */
     297    private static String extractCodeFromIgnoreKey(String key) {
     298        int lenCode = 0;
     299
     300        for (int i = 0; i < key.length(); i++) {
     301            if (key.charAt(i) >= '0' && key.charAt(i) <= '9') {
     302                lenCode++;
     303            } else {
     304                break;
     305            }
     306        }
     307        return key.substring(0, lenCode);
    287308    }
    288309
     
    314335        for (Entry<String, String> e: ignoredErrors.entrySet()) {
    315336            String key = e.getKey();
    316             String value = e.getValue();
    317             ArrayList<String> ignoredWayList = new ArrayList<>();
     337            // key starts with a code, it maybe followed by a string (eg. a MapCSS rule) and
     338            // optionally with a list of one or more OSM element IDs
     339            String description = e.getValue();
     340
     341            ArrayList<String> ignoredElementList = new ArrayList<>();
    318342            String[] osmobjects = elemId1Pattern.split(key);
    319343            for (int i = 1; i < osmobjects.length; i++) {
     
    324348                    if (index < key.lastIndexOf(']')) continue;
    325349                    char type = key.charAt(index - 1);
    326                     ignoredWayList.add(type + osmid);
    327                 }
    328             }
    329             for (String osmignore : ignoredWayList) {
     350                    ignoredElementList.add(type + osmid);
     351                }
     352            }
     353            for (String osmignore : ignoredElementList) {
    330354                key = key.replace(':' + osmignore, "");
    331355            }
     
    334358            DefaultMutableTreeNode branch;
    335359
    336             if (value != null && !value.isEmpty()) {
    337                 trunk = inTree(root, value);
     360            if (description != null && !description.isEmpty()) {
     361                trunk = inTree(root, description);
    338362                branch = inTree(trunk, key);
    339363                trunk.add(branch);
     
    342366                branch = trunk;
    343367            }
    344             ignoredWayList.forEach(osmignore -> branch.add(new DefaultMutableTreeNode(osmignore)));
    345 
     368            if (!ignoredElementList.isEmpty()) {
     369                String item;
     370                if (ignoredElementList.size() == 1) {
     371                    item = ignoredElementList.iterator().next();
     372                } else {
     373                    // combination of two or more objects, keep them together
     374                    item = ignoredElementList.toString(); // [ID1, ID2, ..., IDn]
     375                }
     376                branch.add(new DefaultMutableTreeNode(item));
     377            }
    346378            root.add(trunk);
    347379        }
     
    378410        HashMap<String, String> rHashMap = new HashMap<>();
    379411
    380         String osmids = node.getUserObject().toString();
    381         String description = "";
    382 
    383         if (!model.getRoot().equals(node)) {
    384             description = ((DefaultMutableTreeNode) node.getParent()).getUserObject().toString();
    385         } else {
    386             description = node.getUserObject().toString();
    387         }
    388         if (tr("Ignore list").equals(description)) description = "";
    389         if (!osmids.matches("^[0-9]+(_.*|$)")) {
    390             description = osmids;
    391             osmids = "";
    392         }
    393 
    394 
    395         StringBuilder sb = new StringBuilder();
    396412        for (int i = 0; i < model.getChildCount(node); i++) {
    397413            DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(node, i);
    398414            if (model.getChildCount(child) == 0) {
    399                 String ignoreName = child.getUserObject().toString();
    400                 if (ignoreName.matches("^(r|w|n)_.*")) {
    401                     sb.append(':').append(child.getUserObject().toString());
    402                 } else if (ignoreName.matches("^[0-9]+(_.*|)$")) {
    403                     rHashMap.put(ignoreName, description);
     415                // create an entry for the error list
     416                String key = node.getUserObject().toString();
     417                String description;
     418
     419                if (!model.getRoot().equals(node)) {
     420                    description = ((DefaultMutableTreeNode) node.getParent()).getUserObject().toString();
     421                } else {
     422                    description = key; // we get here when reading old file ignorederrors
     423                }
     424                if (tr("Ignore list").equals(description))
     425                    description = "";
     426                if (!key.matches("^[0-9]+(_.*|$)")) {
     427                    description = key;
     428                    key = "";
     429                }
     430
     431                String item = child.getUserObject().toString();
     432                String entry = null;
     433                if (item.matches("^\\[(r|w|n)_.*")) {
     434                    // list of elements (produced with list.toString() method)
     435                    entry = key + ":" + item.substring(1, item.lastIndexOf(']')).replace(", ", ":");
     436                } else if (item.matches("^(r|w|n)_.*")) {
     437                    // single element
     438                    entry = key + ":" + item;
     439                } else if (item.matches("^[0-9]+(_.*|)$")) {
     440                    // no element ids
     441                    entry = item;
     442                }
     443                if (entry != null) {
     444                    rHashMap.put(entry, description);
     445                } else {
     446                    Logging.warn("ignored unexpected item in validator ignore list management dialog:'" + item + "'");
    404447                }
    405448            } else {
     
    407450            }
    408451        }
    409         osmids += sb.toString();
    410         if (!osmids.isEmpty() && osmids.indexOf(':') != 0) rHashMap.put(osmids, description);
    411452        return rHashMap;
    412453    }
     
    616657                                ))));
    617658    }
     659
     660    /**
     661     * For unit tests
     662     */
     663    protected static void clearIgnoredErrors() {
     664        ignoredErrors.clear();
     665    }
    618666}
  • trunk/test/unit/org/openstreetmap/josm/data/validation/OsmValidatorTest.java

    r14138 r15459  
    22package org.openstreetmap.josm.data.validation;
    33
     4import static org.junit.Assert.assertFalse;
     5import static org.junit.Assert.assertTrue;
     6
     7import org.junit.Before;
    48import org.junit.Rule;
    59import org.junit.Test;
     
    1923    @Rule
    2024    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    21     public JOSMTestRules test = new JOSMTestRules();
     25    public JOSMTestRules test = new JOSMTestRules().projection();
    2226
     27    /**
     28     * Setup test.
     29     * @throws Exception if an error occurs
     30     */
     31    @Before
     32    public void setUp() throws Exception {
     33        OsmValidator.clearIgnoredErrors();
     34    }
    2335    /**
    2436     * Tests that {@code OsmValidator} satisfies utility class criterias.
     
    2941        UtilityClassTestUtil.assertUtilityClassWellDefined(OsmValidator.class);
    3042    }
     43
     44    /**
     45     * Test that {@link OsmValidator#cleanupIgnoredErrors()} really removes entry with element IDs when group is ignored
     46     */
     47    @Test
     48    public void testCleanupIgnoredErrors1() {
     49        OsmValidator.addIgnoredError("1351:n_2449148994:w_236955234", "Way end node near other way");
     50        OsmValidator.addIgnoredError("1351:n_6871910559:w_733713588", "Way end node near other way");
     51        OsmValidator.addIgnoredError("1351");
     52        OsmValidator.cleanupIgnoredErrors();
     53        assertTrue(OsmValidator.hasIgnoredError("1351"));
     54        assertFalse(OsmValidator.hasIgnoredError("1351:n_6871910559:w_733713588"));
     55        assertFalse(OsmValidator.hasIgnoredError("1351:n_2449148994:w_236955234"));
     56    }
     57
     58    /**
     59     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17837">Bug #17837</a>.
     60     * {@link OsmValidator#cleanupIgnoredErrors()} must not remove entry 1201 when 120 is before it.
     61     */
     62    @Test
     63    public void testCleanupIgnoredErrorsTicket17837() {
     64        OsmValidator.addIgnoredError("120");
     65        OsmValidator.addIgnoredError("3000");
     66        OsmValidator.addIgnoredError("1201"); // starts with 120, but has different code
     67        OsmValidator.cleanupIgnoredErrors();
     68        assertTrue(OsmValidator.hasIgnoredError("1201"));
     69    }
     70
     71    /**
     72     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/18223">Bug #18223</a>.
     73     * {@link OsmValidator#cleanupIgnoredErrors()} must not combine primitives.
     74     */
     75    @Test
     76    public void testCleanupIgnoredErrorsTicket18223() {
     77        OsmValidator.addIgnoredError("1351:n_2449148994:w_236955234", "Way end node near other way");
     78        OsmValidator.addIgnoredError("1351:n_6871910559:w_733713588", "Way end node near other way");
     79        OsmValidator.cleanupIgnoredErrors();
     80        assertFalse(OsmValidator.hasIgnoredError("1351"));
     81        assertTrue(OsmValidator.hasIgnoredError("1351:n_2449148994:w_236955234"));
     82        assertTrue(OsmValidator.hasIgnoredError("1351:n_6871910559:w_733713588"));
     83    }
     84
    3185}
Note: See TracChangeset for help on using the changeset viewer.