- Timestamp:
- 2024-08-14T19:44:54+02:00 (3 months ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/resources/data/defaultpresets.xml
r19193 r19195 3273 3273 <check key="ferry:cable" text="Reaction ferry" /> 3274 3274 <space /> 3275 <reference ref="oh" />3276 3275 <reference ref="public_transport_route_optionals" /> 3277 3276 <reference ref="pt_route_opt2" /> … … 3809 3808 </checkgroup> 3810 3809 <combo key="sanitary_dump_station" text="Dump Station" values="yes,public,customers,no" /> 3811 <reference ref="wheelchair" />3812 3810 <reference ref="internet" /> 3813 3811 <space /> … … 6983 6981 <combo key="generator:type" text="Generator Type" values_searchable="true"> 6984 6982 <list_entry value="bioreactor" short_description="gasification" /> 6983 <list_entry value="boiler" short_description="" /> 6985 6984 <list_entry value="pyrolysis" short_description="" /> 6986 6985 <list_entry value="reciprocating_engine" short_description="combustion" /> 6987 6986 <list_entry value="steam_generator" short_description="combustion" /> 6988 6987 </combo> 6989 <combo key="generator:type" text="Generator Type" values="bioreactor,boiler,reciprocating_engine,steam_generator" />6990 6988 <reference ref="power_output" /> 6991 6989 </item> <!-- Waste Power Generator --> -
trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
r19172 r19195 719 719 Map<String, String> matchingTags = tp.data.stream() 720 720 .filter(i -> Boolean.TRUE.equals(i.matches(tags))) 721 .filter( i -> i instanceof KeyedItem).map(i -> ((KeyedItem) i).key)722 .collect(Collectors.toMap(k -> k, tags::get ));721 .filter(KeyedItem.class::isInstance).map(i -> ((KeyedItem) i).key) 722 .collect(Collectors.toMap(k -> k, tags::get, (o, n) -> n)); 723 723 if (matchingPresetsOK.stream().noneMatch( 724 724 tp2 -> matchingTags.entrySet().stream().allMatch( -
trunk/test/unit/org/openstreetmap/josm/data/validation/tests/TagCheckerTest.java
r19172 r19195 7 7 8 8 import java.io.IOException; 9 import java.util.Collections; 9 10 import java.util.List; 10 11 import java.util.function.Consumer; … … 18 19 import org.openstreetmap.josm.data.osm.OsmUtils; 19 20 import org.openstreetmap.josm.data.osm.Tag; 21 import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; 20 22 import org.openstreetmap.josm.data.validation.Severity; 21 23 import org.openstreetmap.josm.data.validation.TestError; 24 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset; 25 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType; 26 import org.openstreetmap.josm.gui.tagging.presets.items.Key; 27 import org.openstreetmap.josm.spi.preferences.Config; 22 28 import org.openstreetmap.josm.testutils.annotations.I18n; 23 29 import org.openstreetmap.josm.testutils.annotations.TaggingPresets; … … 415 421 assertEquals(0, errors.size()); 416 422 } 423 424 /** 425 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/23860">Bug #23860</a>. 426 * Duplicate key 427 * @throws IOException if any I/O error occurs 428 */ 429 @Test 430 void testTicket23860Equal() throws IOException { 431 ValidatorPrefHelper.PREF_OTHER.put(true); 432 Config.getPref().putBoolean(TagChecker.PREF_CHECK_PRESETS_TYPES, true); 433 final TaggingPreset originalBusStop = org.openstreetmap.josm.gui.tagging.presets.TaggingPresets.getMatchingPresets( 434 Collections.singleton(TaggingPresetType.NODE), Collections.singletonMap("highway", "bus_stop"), false) 435 .iterator().next(); 436 final Key duplicateKey = new Key(); 437 duplicateKey.key = "highway"; 438 duplicateKey.value = "bus_stop"; 439 try { 440 originalBusStop.data.add(duplicateKey); 441 final List<TestError> errors = test(OsmUtils.createPrimitive("way highway=bus_stop")); 442 assertEquals(1, errors.size()); 443 } finally { 444 originalBusStop.data.remove(duplicateKey); 445 } 446 } 447 448 /** 449 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/23860">Bug #23860</a>. 450 * Duplicate key 451 * @throws IOException if any I/O error occurs 452 */ 453 @Test 454 void testTicket23860NonEqual() throws IOException { 455 ValidatorPrefHelper.PREF_OTHER.put(true); 456 Config.getPref().putBoolean(TagChecker.PREF_CHECK_PRESETS_TYPES, true); 457 final TaggingPreset originalBusStop = org.openstreetmap.josm.gui.tagging.presets.TaggingPresets.getMatchingPresets( 458 Collections.singleton(TaggingPresetType.NODE), Collections.singletonMap("highway", "bus_stop"), false) 459 .iterator().next(); 460 final Key duplicateKey = new Key(); 461 duplicateKey.key = "highway"; 462 duplicateKey.value = "bus_stop2"; 463 try { 464 originalBusStop.data.add(duplicateKey); 465 final List<TestError> errors = test(OsmUtils.createPrimitive("way highway=bus_stop")); 466 assertEquals(0, errors.size()); 467 } finally { 468 originalBusStop.data.remove(duplicateKey); 469 } 470 } 417 471 } -
trunk/test/unit/org/openstreetmap/josm/gui/preferences/map/TaggingPresetPreferenceTestIT.java
r19004 r19195 11 11 import java.util.ArrayList; 12 12 import java.util.Collection; 13 import java.util.HashMap; 13 14 import java.util.HashSet; 14 15 import java.util.List; 15 16 import java.util.Locale; 17 import java.util.Objects; 16 18 import java.util.Set; 17 19 import java.util.concurrent.TimeUnit; 20 import java.util.stream.Collectors; 21 import java.util.stream.Stream; 18 22 19 23 import org.junit.jupiter.api.BeforeAll; … … 25 29 import org.openstreetmap.josm.gui.preferences.AbstractExtendedSourceEntryTestCase; 26 30 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset; 31 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem; 27 32 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetReader; 28 33 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetsTest; 34 import org.openstreetmap.josm.gui.tagging.presets.items.Check; 35 import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup; 36 import org.openstreetmap.josm.gui.tagging.presets.items.Key; 37 import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem; 29 38 import org.openstreetmap.josm.gui.tagging.presets.items.Link; 30 39 import org.openstreetmap.josm.spi.preferences.Config; … … 35 44 import org.openstreetmap.josm.tools.ImageProvider; 36 45 import org.openstreetmap.josm.tools.Logging; 46 import org.openstreetmap.josm.tools.Utils; 37 47 import org.xml.sax.SAXException; 38 48 … … 107 117 TaggingPresetsTest.waitForIconLoading(presets); 108 118 // check that links are correct and not redirections 109 presets.parallelStream().flatMap(x -> x.data.stream().filter( i -> i instanceof Link).map(i -> ((Link) i).getUrl())).forEach(u -> {119 presets.parallelStream().flatMap(x -> x.data.stream().filter(Link.class::isInstance).map(i -> ((Link) i).getUrl())).forEach(u -> { 110 120 try { 111 121 Response cr = HttpClient.create(new URL(u), "HEAD").setMaxRedirects(-1).connect(); … … 121 131 } 122 132 }); 133 presets.parallelStream().flatMap(TaggingPresetPreferenceTestIT::checkForDuplicates) 134 .filter(Objects::nonNull) 135 .forEach(message -> addOrIgnoreError(source, messages, message, ignoredErrors)); 123 136 Collection<String> errorsAndWarnings = Logging.getLastErrorAndWarnings(); 124 137 boolean error = false; … … 141 154 } 142 155 } 156 157 /** 158 * Look for duplicate key/value objects 159 * @param preset to check 160 * @return The messages to print to console for fixing 161 */ 162 private static Stream<String> checkForDuplicates(TaggingPreset preset) { 163 final HashMap<String, List<KeyedItem>> dupMap = preset.data.stream() 164 .flatMap(TaggingPresetPreferenceTestIT::getKeyedItems) 165 .collect(Collectors.groupingBy(i -> i.key, HashMap::new, Collectors.toCollection(ArrayList::new))); 166 dupMap.values().forEach(TaggingPresetPreferenceTestIT::removeUnnecessaryDuplicates); 167 dupMap.values().removeIf(l -> l.size() <= 1); 168 if (!dupMap.isEmpty()) { 169 final StringBuilder prefixBuilder = new StringBuilder(); 170 if (preset.group != null && preset.group.name != null) { 171 prefixBuilder.append(preset.group.name).append('/'); 172 } 173 if (preset.name != null) { 174 prefixBuilder.append(preset.name).append('/'); 175 } 176 final String prefix = prefixBuilder.toString(); 177 return dupMap.keySet().stream().map(k -> "Duplicate key: " + prefix + k); 178 } 179 return Stream.empty(); 180 } 181 182 /** 183 * Remove keys that are technically duplicates, but are otherwise OK due to working around limitations of the XML. 184 * @param l The list of keyed items to look through 185 */ 186 private static void removeUnnecessaryDuplicates(List<KeyedItem> l) { 187 // Remove keys that are "truthy" when a check will be on or off. This seems to be used for setting defaults in chunks. 188 // We might want to extend chunks to have child `<key>` elements which will set default values for the chunk. 189 ArrayList<KeyedItem> toRemove = new ArrayList<>(Math.min(4, l.size() / 10)); 190 for (Key first : Utils.filteredCollection(l, Key.class)) { 191 for (Check second : Utils.filteredCollection(l, Check.class)) { 192 if (second.value_off.equals(first.value) || second.value_on.equals(first.value)) { 193 toRemove.add(first); 194 } 195 } 196 } 197 l.removeAll(toRemove); 198 } 199 200 /** 201 * Convert an item to a collection of items (needed for {@link CheckGroup}) 202 * @param item The item to convert 203 * @return The {@link KeyedItem}s to use 204 */ 205 private static Stream<? extends KeyedItem> getKeyedItems(TaggingPresetItem item) { 206 // We care about cases where a preset has two separate hardcoded values 207 // Check should use default="on|off" and value_(on|off) to control the default. 208 if (item instanceof Key || item instanceof Check) { 209 return Stream.of((KeyedItem) item); 210 } else if (item instanceof CheckGroup) { 211 return ((CheckGroup) item).checks.stream(); 212 } 213 return Stream.empty(); 214 } 143 215 }
Note:
See TracChangeset
for help on using the changeset viewer.