source: josm/trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java@ 18690

Last change on this file since 18690 was 18690, checked in by taylor.smock, 14 months ago

See #16567: Convert all assertion calls to JUnit 5 (patch by gaben, modified)

The modifications are as follows:

  • Merge DomainValidatorTest.testIDN and DomainValidatorTest.testIDNJava6OrLater
  • Update some tests to use @ParameterizedTest (DomainValidatorTest)
  • Replace various exception blocks with assertThrows. These typically looked like
        try {
            // Something that should throw an exception here
            fail("An exception should have been thrown");
        } catch (Exception e) {
            // Verify the exception matches expectations here
        }
    
  • Replace assertTrue(val instanceof Clazz) with assertInstanceOf
  • Replace JUnit 4 @Suite with JUnit 5 @Suite

Both the original patch and the modified patch fix various lint issues.

  • Property svn:eol-style set to native
File size: 19.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.junit.jupiter.api.Assertions.assertEquals;
5import static org.junit.jupiter.api.Assertions.assertFalse;
6import static org.junit.jupiter.api.Assertions.assertInstanceOf;
7import static org.junit.jupiter.api.Assertions.assertNotNull;
8import static org.junit.jupiter.api.Assertions.assertTrue;
9
10import java.io.InputStream;
11import java.io.StringReader;
12import java.util.Collection;
13import java.util.HashSet;
14import java.util.Iterator;
15import java.util.LinkedHashSet;
16import java.util.List;
17import java.util.Set;
18
19import org.junit.jupiter.api.BeforeEach;
20import org.junit.jupiter.api.Test;
21import org.junit.jupiter.api.extension.RegisterExtension;
22import org.openstreetmap.josm.TestUtils;
23import org.openstreetmap.josm.command.ChangePropertyCommand;
24import org.openstreetmap.josm.command.ChangePropertyKeyCommand;
25import org.openstreetmap.josm.command.Command;
26import org.openstreetmap.josm.command.PseudoCommand;
27import org.openstreetmap.josm.command.SequenceCommand;
28import org.openstreetmap.josm.data.coor.LatLon;
29import org.openstreetmap.josm.data.osm.DataSet;
30import org.openstreetmap.josm.data.osm.IPrimitive;
31import org.openstreetmap.josm.data.osm.Node;
32import org.openstreetmap.josm.data.osm.OsmPrimitive;
33import org.openstreetmap.josm.data.osm.OsmUtils;
34import org.openstreetmap.josm.data.preferences.sources.ExtendedSourceEntry;
35import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
36import org.openstreetmap.josm.data.validation.Severity;
37import org.openstreetmap.josm.data.validation.Test.TagTest;
38import org.openstreetmap.josm.data.validation.TestError;
39import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker.ParseResult;
40import org.openstreetmap.josm.gui.mappaint.Environment;
41import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
42import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
43import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
44import org.openstreetmap.josm.io.OsmReader;
45import org.openstreetmap.josm.testutils.JOSMTestRules;
46import org.openstreetmap.josm.tools.Logging;
47
48import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
49
50/**
51 * JUnit Test of {@link MapCSSTagChecker}.
52 */
53class MapCSSTagCheckerTest {
54
55 /**
56 * Setup test.
57 */
58 @RegisterExtension
59 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
60 public JOSMTestRules test = new JOSMTestRules().projection().territories().preferences();
61
62 /**
63 * Setup test.
64 */
65 @BeforeEach
66 public void setUp() {
67 MapCSSTagCheckerAsserts.clear();
68 }
69
70 static MapCSSTagChecker buildTagChecker(String css) throws ParseException {
71 final MapCSSTagChecker test = new MapCSSTagChecker();
72 Set<String> errors = new HashSet<>();
73 test.checks.putAll("test", MapCSSTagCheckerRule.readMapCSS(new StringReader(css), errors::add).parseChecks);
74 assertTrue(errors.isEmpty(), errors::toString);
75 return test;
76 }
77
78 /**
79 * Test {@code natural=marsh}.
80 * @throws ParseException if a parsing error occurs
81 */
82 @Test
83 void testNaturalMarsh() throws ParseException {
84 ParseResult result = MapCSSTagCheckerRule.readMapCSS(new StringReader(
85 "*[natural=marsh] {\n" +
86 " group: tr(\"deprecated\");\n" +
87 " throwWarning: tr(\"{0}={1} is deprecated\", \"{0.key}\", tag(\"natural\"));\n" +
88 " fixRemove: \"{0.key}\";\n" +
89 " fixAdd: \"natural=wetland\";\n" +
90 " fixAdd: \"wetland=marsh\";\n" +
91 "}"));
92 final List<MapCSSTagCheckerRule> checks = result.parseChecks;
93 assertEquals(1, checks.size());
94 assertTrue(result.parseErrors.isEmpty());
95 final MapCSSTagCheckerRule check = checks.get(0);
96 assertNotNull(check);
97 assertEquals("{0.key}=null is deprecated", check.getDescription(null));
98 assertEquals("fixRemove: {0.key}", check.fixCommands.get(0).toString());
99 assertEquals("fixAdd: natural=wetland", check.fixCommands.get(1).toString());
100 assertEquals("fixAdd: wetland=marsh", check.fixCommands.get(2).toString());
101 final OsmPrimitive n1 = OsmUtils.createPrimitive("node natural=marsh");
102 final OsmPrimitive n2 = OsmUtils.createPrimitive("node natural=wood");
103 new DataSet(n1, n2);
104 assertTrue(check.test(n1));
105
106 final Collection<TestError> errors = check.getErrorsForPrimitive(n1, check.whichSelectorMatchesPrimitive(n1), new Environment(), null);
107 assertEquals(1, errors.size());
108 TestError err = errors.iterator().next();
109 assertEquals("deprecated", err.getMessage());
110 assertEquals("natural=marsh is deprecated", err.getDescription());
111 assertEquals(Severity.WARNING, err.getSeverity());
112 assertEquals("Sequence: Fix of natural=marsh is deprecated", check.fixPrimitive(n1).getDescriptionText());
113 assertEquals("{natural=}", ((ChangePropertyCommand) check.fixPrimitive(n1).getChildren().iterator().next()).getTags().toString());
114 assertFalse(check.test(n2));
115 assertEquals("The key is natural and the value is marsh",
116 MapCSSTagCheckerRule.insertArguments(check.rule.selectors.get(0), "The key is {0.key} and the value is {0.value}", null));
117 }
118
119 /**
120 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10913">Bug #10913</a>.
121 * @throws ParseException if a parsing error occurs
122 */
123 @Test
124 void testTicket10913() throws ParseException {
125 final OsmPrimitive p = TestUtils.addFakeDataSet(TestUtils.newWay("highway=tertiary construction=yes"));
126 final MapCSSTagCheckerRule check = MapCSSTagCheckerRule.readMapCSS(new StringReader("way {" +
127 "throwError: \"error\";" +
128 "fixChangeKey: \"highway => construction\";\n" +
129 "fixAdd: \"highway=construction\";\n" +
130 "}")).parseChecks.get(0);
131 final Command command = check.fixPrimitive(p);
132 assertInstanceOf(SequenceCommand.class, command);
133 final Iterator<PseudoCommand> it = command.getChildren().iterator();
134 assertInstanceOf(ChangePropertyKeyCommand.class, it.next());
135 assertInstanceOf(ChangePropertyCommand.class, it.next());
136 }
137
138 /**
139 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/9782">Bug #9782</a>.
140 * @throws ParseException if a parsing error occurs
141 */
142 @Test
143 void testTicket9782() throws ParseException {
144 final MapCSSTagChecker test = buildTagChecker("*[/.+_name/][!name] {" +
145 "throwWarning: tr(\"has {0} but not {1}\", \"{0.key}\", \"{1.key}\");}");
146 final OsmPrimitive p = OsmUtils.createPrimitive("way alt_name=Foo");
147 final Collection<TestError> errors = test.getErrorsForPrimitive(p, false);
148 assertEquals(1, errors.size());
149 assertEquals("has alt_name but not name", errors.iterator().next().getMessage());
150 assertEquals("3000_has alt_name but not name", errors.iterator().next().getIgnoreSubGroup());
151 }
152
153 /**
154 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10859">Bug #10859</a>.
155 * @throws ParseException if a parsing error occurs
156 */
157 @Test
158 void testTicket10859() throws ParseException {
159 final MapCSSTagChecker test = buildTagChecker("way[highway=footway][foot?!] {\n" +
160 " throwWarning: tr(\"{0} used with {1}\", \"{0.value}\", \"{1.tag}\");}");
161 final OsmPrimitive p = OsmUtils.createPrimitive("way highway=footway foot=no");
162 final Collection<TestError> errors = test.getErrorsForPrimitive(p, false);
163 assertEquals(1, errors.size());
164 assertEquals("footway used with foot=no", errors.iterator().next().getMessage());
165 assertEquals("3000_footway used with foot=no", errors.iterator().next().getIgnoreSubGroup());
166 }
167
168 /**
169 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13630">Bug #13630</a>.
170 * @throws ParseException if a parsing error occurs
171 */
172 @Test
173 void testTicket13630() throws ParseException {
174 ParseResult result = MapCSSTagCheckerRule.readMapCSS(new StringReader(
175 "node[crossing=zebra] {fixRemove: \"crossing=zebra\";}"));
176 assertTrue(result.parseChecks.isEmpty());
177 assertEquals(1, result.parseErrors.size());
178 }
179
180 /**
181 * Unit test of {@code min-josm-version} processing.
182 * @throws ParseException if a parsing error occurs
183 */
184 @Test
185 void testPreprocessing() throws ParseException {
186 final MapCSSTagChecker test = buildTagChecker(
187 "@supports (min-josm-version: 0) { *[foo] { throwWarning: \"!\"; } }\n" +
188 "@supports (min-josm-version: 2147483647) { *[bar] { throwWarning: \"!\"; } }");
189 assertEquals(1, test.getErrorsForPrimitive(OsmUtils.createPrimitive("way foo=1"), false).size());
190 assertEquals(0, test.getErrorsForPrimitive(OsmUtils.createPrimitive("way bar=1"), false).size());
191 }
192
193 /**
194 * Unit test of {@link MapCSSTagChecker#initialize}.
195 * @throws Exception if an error occurs
196 */
197 @Test
198 void testInit() throws Exception {
199 Logging.clearLastErrorAndWarnings();
200 MapCSSTagChecker c = new MapCSSTagChecker();
201 c.initialize();
202
203 assertTrue(Logging.getLastErrorAndWarnings().isEmpty(), "no warnings/errors are logged");
204
205 // to trigger MapCSSStyleIndex code
206 Node node = new Node(new LatLon(12, 34));
207 node.put("amenity", "drinking_water");
208 assertTrue(c.getErrorsForPrimitive(node, false).isEmpty());
209 }
210
211 /**
212 * Unit test for all {@link TagTest} assertions.
213 * @throws Exception if an error occurs
214 */
215 @Test
216 void testAssertions() throws Exception {
217 MapCSSTagChecker c = new MapCSSTagChecker();
218 Set<String> assertionErrors = new LinkedHashSet<>();
219
220 // initialize
221 for (ExtendedSourceEntry entry : ValidatorPrefHelper.INSTANCE.getDefault()) {
222 c.addMapCSS(entry.url, assertionErrors::add);
223 }
224
225 for (String msg : assertionErrors) {
226 Logging.error(msg);
227 }
228 assertTrue(assertionErrors.isEmpty(), "not all assertions included in the tests are met");
229 }
230
231 /**
232 * Checks that assertions work for country-specific checks.
233 * @throws ParseException if a parsing error occurs
234 */
235 @Test
236 void testAssertInsideCountry() throws ParseException {
237 final MapCSSTagChecker test = buildTagChecker(
238 "node[amenity=parking][inside(\"BR\")] {\n" +
239 " throwWarning: \"foo\";\n" +
240 " assertMatch: \"node amenity=parking\";\n" +
241 " assertNoMatch: \"node amenity=restaurant\";\n" +
242 "}");
243 assertNotNull(test);
244 }
245
246 /**
247 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17058">Bug #17058</a>.
248 * @throws ParseException if a parsing error occurs
249 */
250 @Test
251 void testTicket17058() throws ParseException {
252 final MapCSSTagChecker test = buildTagChecker(
253 "*[name =~ /(?i).*Straße.*/][inside(\"LI,CH\")] {\n" +
254 " throwError: tr(\"street name contains ß\");\n" +
255 " assertMatch: \"way name=Hauptstraße\";\n" +
256 " assertNoMatch: \"way name=Hauptstrasse\";\n" +
257 "}");
258 assertNotNull(test);
259 }
260
261 /**
262 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13762">Bug #13762</a>.
263 * @throws ParseException if a parsing error occurs
264 */
265 @Test
266 void testTicket13762() throws ParseException {
267 final ParseResult parseResult = MapCSSTagCheckerRule.readMapCSS(new StringReader("" +
268 "meta[lang=de] {\n" +
269 " title: \"Deutschlandspezifische Regeln\";" +
270 "}"));
271 assertTrue(parseResult.parseErrors.isEmpty());
272 }
273
274 /**
275 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/14287">Bug #14287</a>.
276 * @throws Exception if an error occurs
277 */
278 @Test
279 void testTicket14287() throws Exception {
280 final MapCSSTagChecker test = buildTagChecker(
281 "node[amenity=parking] ∈ *[amenity=parking] {" +
282 " throwWarning: tr(\"{0} inside {1}\", \"amenity=parking\", \"amenity=parking\");" +
283 "}");
284 try (InputStream is = TestUtils.getRegressionDataStream(14287, "example.osm")) {
285 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
286 assertEquals(6, test.getErrors().size());
287 }
288 }
289
290 /**
291 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17053">Bug #17053</a>.
292 * @throws ParseException if a parsing error occurs
293 */
294 @Test
295 void testTicket17053() throws ParseException {
296 final MapCSSTagChecker test = buildTagChecker(
297 "way[highway=cycleway][cycleway=track] {\n" +
298 " throwWarning: tr(\"{0} with {1}\", \"{0.tag}\", \"{1.tag}\");\n" +
299 " -osmoseItemClassLevel: \"3032/30328/2\";\n" +
300 " -osmoseTags: list(\"tag\", \"highway\", \"cycleway\");\n" +
301 " fixRemove: \"cycleway\";\n" +
302 "}");
303 assertEquals(1, test.checks.size());
304 MapCSSTagCheckerRule check = test.checks.get("test").iterator().next();
305 assertEquals(1, check.fixCommands.size());
306 assertEquals(2, check.rule.declaration.instructions.size());
307 }
308
309 private void doTestNaturalWood(int ticket, String filename, int errorsCount, int setsCount) throws Exception {
310 final MapCSSTagChecker test = buildTagChecker(
311 "area:closed:areaStyle[tag(\"natural\") = parent_tag(\"natural\")] ⧉ area:closed:areaStyle[natural] {" +
312 " throwWarning: tr(\"Overlapping Identical Natural Areas\");" +
313 "}");
314 final MapCSSStyleSource style = new MapCSSStyleSource(
315 "area[natural=wood] {" +
316 " fill-color: woodarea#008000;" +
317 "}");
318 MapPaintStyles.addStyle(style);
319 try (InputStream is = TestUtils.getRegressionDataStream(ticket, filename)) {
320 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
321 List<TestError> errors = test.getErrors();
322 assertEquals(errorsCount, errors.size());
323 Set<Set<IPrimitive>> primitives = new HashSet<>();
324 for (TestError e : errors) {
325 primitives.add(new HashSet<>(e.getPrimitives()));
326 }
327 assertEquals(setsCount, primitives.size());
328 } finally {
329 MapPaintStyles.removeStyle(style);
330 }
331 }
332
333 /**
334 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/12627">Bug #12627</a>.
335 * @throws Exception if an error occurs
336 */
337 @Test
338 void testTicket12627() throws Exception {
339 doTestNaturalWood(12627, "overlapping.osm", 1, 1);
340 }
341
342 /**
343 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/14289">Bug #14289</a>.
344 * @throws Exception if an error occurs
345 */
346 @Test
347 void testTicket14289() throws Exception {
348 doTestNaturalWood(14289, "example2.osm", 3, 3);
349 }
350
351 /**
352 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/15641">Bug #15641</a>.
353 * @throws ParseException if an error occurs
354 */
355 @Test
356 void testTicket15641() throws ParseException {
357 assertNotNull(buildTagChecker(
358 "relation[type=public_transport][public_transport=stop_area_group] > way {" +
359 " throwWarning: eval(count(parent_tags(public_transport)));" +
360 "}"));
361 }
362
363 /**
364 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17358">Bug #17358</a>.
365 * @throws ParseException if an error occurs
366 */
367 @Test
368 void testTicket17358() throws ParseException {
369 final Collection<TestError> errors = buildTagChecker(
370 "*[/^name/=~/Test/]{" +
371 " throwWarning: \"Key value match\";" +
372 "}").getErrorsForPrimitive(OsmUtils.createPrimitive("way name=Test St"), false);
373 assertEquals(1, errors.size());
374 }
375
376 /**
377 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17695">Bug #17695</a>.
378 * @throws Exception if an error occurs
379 */
380 @Test
381 void testTicket17695() throws Exception {
382 final MapCSSTagChecker test = buildTagChecker(
383 "*[building] ∈ *[building] {" +
384 "throwWarning: tr(\"Building inside building\");" +
385 "}");
386 try (InputStream is = TestUtils.getRegressionDataStream(17695, "bib2.osm")) {
387 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
388 List<TestError> errors = test.getErrors();
389 assertEquals(6, errors.size());
390 }
391 }
392
393 /**
394 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13165">Bug #13165</a>.
395 * @throws Exception if an error occurs
396 */
397 @Test
398 void testTicket13165() throws Exception {
399 final MapCSSTagChecker test = buildTagChecker(
400 "area:closed[tag(\"landuse\") = parent_tag(\"landuse\")] ⧉ area:closed[landuse] {"
401 + "throwWarning: tr(\"Overlapping Identical Landuses\");"
402 + "}");
403 try (InputStream is = TestUtils.getRegressionDataStream(13165, "13165.osm")) {
404 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
405 List<TestError> errors = test.getErrors();
406 assertEquals(3, errors.size());
407 }
408 }
409
410 /**
411 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13165">Bug #13165</a>.
412 * @throws Exception if an error occurs
413 */
414 @Test
415 void testTicket13165IncompleteMP() throws Exception {
416 final MapCSSTagChecker test = buildTagChecker(
417 "area:closed[tag(\"landuse\") = parent_tag(\"landuse\")] ⧉ area:closed[landuse] {"
418 + "throwWarning: tr(\"Overlapping Identical Landuses\");"
419 + "}");
420 try (InputStream is = TestUtils.getRegressionDataStream(13165, "13165-incomplete.osm.bz2")) {
421 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
422 List<TestError> errors = test.getErrors();
423 assertEquals(3, errors.size());
424 }
425 }
426
427 /**
428 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/19053">Bug #19053</a> and
429 * <a href="https://josm.openstreetmap.de/ticket/20957">Bug #20957</a>
430 * - MapCSS rule with group.
431 * - MapCSS functions round, tag, *, /
432 * @throws ParseException if a parsing error occurs
433 */
434 @Test
435 void testTicket19053() throws ParseException {
436 final MapCSSTagChecker test = buildTagChecker(
437 "*[ele][ele =~ /^-?[0-9]+\\.[0-9][0-9][0-9]+$/] {"
438 + "throwWarning: tr(\"{0}\",\"{0.tag}\");"
439 + "fixAdd: concat(\"ele=\", round(tag(\"ele\")*100)/100);"
440 + "group: tr(\"Unnecessary amount of decimal places\");" + "}");
441 final OsmPrimitive p = OsmUtils.createPrimitive("node ele=12.123456");
442 new DataSet(p);
443 final Collection<TestError> errors = test.getErrorsForPrimitive(p, false);
444 assertEquals(1, errors.size());
445 assertEquals("Unnecessary amount of decimal places", errors.iterator().next().getMessage());
446 assertEquals("3000_ele=12.123456", errors.iterator().next().getIgnoreSubGroup());
447 assertEquals("3000_Unnecessary amount of decimal places", errors.iterator().next().getIgnoreGroup());
448 Command fix = errors.iterator().next().getFix();
449 assertNotNull(fix);
450 assertEquals("12.123456", p.get("ele"));
451 fix.executeCommand();
452 assertEquals("12.12", p.get("ele"));
453 }
454
455}
Note: See TracBrowser for help on using the repository browser.