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

Last change on this file since 14481 was 14481, checked in by Don-vip, 5 years ago

fix #17053 - ignore MapCSS declarations starting with "-" to allow external extensions (used by osmose)

  • Property svn:eol-style set to native
File size: 13.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNotNull;
7import static org.junit.Assert.assertTrue;
8
9import java.io.InputStream;
10import java.io.StringReader;
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Iterator;
14import java.util.LinkedHashSet;
15import java.util.List;
16import java.util.Set;
17
18import org.junit.Ignore;
19import org.junit.Rule;
20import org.junit.Test;
21import org.openstreetmap.josm.TestUtils;
22import org.openstreetmap.josm.command.ChangePropertyCommand;
23import org.openstreetmap.josm.command.ChangePropertyKeyCommand;
24import org.openstreetmap.josm.command.Command;
25import org.openstreetmap.josm.command.PseudoCommand;
26import org.openstreetmap.josm.command.SequenceCommand;
27import org.openstreetmap.josm.data.osm.DataSet;
28import org.openstreetmap.josm.data.osm.IPrimitive;
29import org.openstreetmap.josm.data.osm.OsmPrimitive;
30import org.openstreetmap.josm.data.osm.OsmUtils;
31import org.openstreetmap.josm.data.validation.Severity;
32import org.openstreetmap.josm.data.validation.TestError;
33import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker.ParseResult;
34import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker.TagCheck;
35import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
36import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
37import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
38import org.openstreetmap.josm.io.OsmReader;
39import org.openstreetmap.josm.testutils.JOSMTestRules;
40import org.openstreetmap.josm.tools.Logging;
41
42import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
43
44/**
45 * JUnit Test of {@link MapCSSTagChecker}.
46 */
47public class MapCSSTagCheckerTest {
48
49 /**
50 * Setup test.
51 */
52 @Rule
53 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
54 public JOSMTestRules test = new JOSMTestRules().projection();
55
56 static MapCSSTagChecker buildTagChecker(String css) throws ParseException {
57 final MapCSSTagChecker test = new MapCSSTagChecker();
58 test.checks.putAll("test", TagCheck.readMapCSS(new StringReader(css)).parseChecks);
59 return test;
60 }
61
62 /**
63 * Test {@code natural=marsh}.
64 * @throws ParseException if a parsing error occurs
65 */
66 @Test
67 public void testNaturalMarsh() throws ParseException {
68 ParseResult result = TagCheck.readMapCSS(new StringReader(
69 "*[natural=marsh] {\n" +
70 " group: tr(\"deprecated\");\n" +
71 " throwWarning: tr(\"{0}={1} is deprecated\", \"{0.key}\", tag(\"natural\"));\n" +
72 " fixRemove: \"{0.key}\";\n" +
73 " fixAdd: \"natural=wetland\";\n" +
74 " fixAdd: \"wetland=marsh\";\n" +
75 "}"));
76 final List<TagCheck> checks = result.parseChecks;
77 assertEquals(1, checks.size());
78 assertTrue(result.parseErrors.isEmpty());
79 final TagCheck check = checks.get(0);
80 assertNotNull(check);
81 assertEquals("{0.key}=null is deprecated", check.getDescription(null));
82 assertEquals("fixRemove: {0.key}", check.fixCommands.get(0).toString());
83 assertEquals("fixAdd: natural=wetland", check.fixCommands.get(1).toString());
84 assertEquals("fixAdd: wetland=marsh", check.fixCommands.get(2).toString());
85 final OsmPrimitive n1 = OsmUtils.createPrimitive("node natural=marsh");
86 final OsmPrimitive n2 = OsmUtils.createPrimitive("node natural=wood");
87 new DataSet(n1, n2);
88 assertTrue(check.test(n1));
89 assertEquals("deprecated", check.getErrorForPrimitive(n1).getMessage());
90 assertEquals("natural=marsh is deprecated", check.getErrorForPrimitive(n1).getDescription());
91 assertEquals(Severity.WARNING, check.getErrorForPrimitive(n1).getSeverity());
92 assertEquals("Sequence: Fix of natural=marsh is deprecated", check.fixPrimitive(n1).getDescriptionText());
93 assertEquals("{natural=}", ((ChangePropertyCommand) check.fixPrimitive(n1).getChildren().iterator().next()).getTags().toString());
94 assertFalse(check.test(n2));
95 assertEquals("The key is natural and the value is marsh",
96 TagCheck.insertArguments(check.rule.selectors.get(0), "The key is {0.key} and the value is {0.value}", null));
97 }
98
99 /**
100 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10913">Bug #10913</a>.
101 * @throws ParseException if a parsing error occurs
102 */
103 @Test
104 public void testTicket10913() throws ParseException {
105 final OsmPrimitive p = TestUtils.addFakeDataSet(TestUtils.newWay("highway=tertiary construction=yes"));
106 final TagCheck check = TagCheck.readMapCSS(new StringReader("way {" +
107 "throwError: \"error\";" +
108 "fixChangeKey: \"highway => construction\";\n" +
109 "fixAdd: \"highway=construction\";\n" +
110 "}")).parseChecks.get(0);
111 final Command command = check.fixPrimitive(p);
112 assertTrue(command instanceof SequenceCommand);
113 final Iterator<PseudoCommand> it = command.getChildren().iterator();
114 assertTrue(it.next() instanceof ChangePropertyKeyCommand);
115 assertTrue(it.next() instanceof ChangePropertyCommand);
116 }
117
118 /**
119 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/9782">Bug #9782</a>.
120 * @throws ParseException if a parsing error occurs
121 */
122 @Test
123 public void testTicket9782() throws ParseException {
124 final MapCSSTagChecker test = buildTagChecker("*[/.+_name/][!name] {" +
125 "throwWarning: tr(\"has {0} but not {1}\", \"{0.key}\", \"{1.key}\");}");
126 final OsmPrimitive p = OsmUtils.createPrimitive("way alt_name=Foo");
127 final Collection<TestError> errors = test.getErrorsForPrimitive(p, false);
128 assertEquals(1, errors.size());
129 assertEquals("has alt_name but not name", errors.iterator().next().getMessage());
130 assertEquals("3000_*[.+_name][!name]", errors.iterator().next().getIgnoreSubGroup());
131 }
132
133 /**
134 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10859">Bug #10859</a>.
135 * @throws ParseException if a parsing error occurs
136 */
137 @Test
138 public void testTicket10859() throws ParseException {
139 final MapCSSTagChecker test = buildTagChecker("way[highway=footway][foot?!] {\n" +
140 " throwWarning: tr(\"{0} used with {1}\", \"{0.value}\", \"{1.tag}\");}");
141 final OsmPrimitive p = OsmUtils.createPrimitive("way highway=footway foot=no");
142 final Collection<TestError> errors = test.getErrorsForPrimitive(p, false);
143 assertEquals(1, errors.size());
144 assertEquals("footway used with foot=no", errors.iterator().next().getMessage());
145 assertEquals("3000_way[highway=footway][foot]", errors.iterator().next().getIgnoreSubGroup());
146 }
147
148 /**
149 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13630">Bug #13630</a>.
150 * @throws ParseException if a parsing error occurs
151 */
152 @Test
153 public void testTicket13630() throws ParseException {
154 ParseResult result = TagCheck.readMapCSS(new StringReader(
155 "node[crossing=zebra] {fixRemove: \"crossing=zebra\";}"));
156 assertTrue(result.parseChecks.isEmpty());
157 assertEquals(1, result.parseErrors.size());
158 }
159
160 /**
161 * Unit test of {@code min-josm-version} processing.
162 * @throws ParseException if a parsing error occurs
163 */
164 @Test
165 public void testPreprocessing() throws ParseException {
166 final MapCSSTagChecker test = buildTagChecker("" +
167 "@supports (min-josm-version: 1) { *[foo] { throwWarning: \"!\"; } }\n" +
168 "@supports (min-josm-version: 2147483647) { *[bar] { throwWarning: \"!\"; } }\n");
169 assertEquals(1, test.getErrorsForPrimitive(OsmUtils.createPrimitive("way foo=1"), false).size());
170 assertEquals(0, test.getErrorsForPrimitive(OsmUtils.createPrimitive("way bar=1"), false).size());
171 }
172
173 /**
174 * Unit test of {@link MapCSSTagChecker#initialize}.
175 * @throws Exception if an error occurs
176 */
177 @Test
178 public void testInit() throws Exception {
179 MapCSSTagChecker c = new MapCSSTagChecker();
180 c.initialize();
181
182 Set<String> assertionErrors = new LinkedHashSet<>();
183 for (Set<TagCheck> schecks : c.checks.values()) {
184 assertionErrors.addAll(c.checkAsserts(schecks));
185 }
186 for (String msg : assertionErrors) {
187 Logging.error(msg);
188 }
189 assertTrue("not all assertions included in the tests are met", assertionErrors.isEmpty());
190 }
191
192 /**
193 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13762">Bug #13762</a>.
194 * @throws ParseException if a parsing error occurs
195 */
196 @Test
197 public void testTicket13762() throws ParseException {
198 final ParseResult parseResult = TagCheck.readMapCSS(new StringReader("" +
199 "meta[lang=de] {\n" +
200 " title: \"Deutschlandspezifische Regeln\";" +
201 "}"));
202 assertTrue(parseResult.parseErrors.isEmpty());
203 }
204
205 /**
206 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/14287">Bug #14287</a>.
207 * @throws Exception if an error occurs
208 */
209 @Test
210 @Ignore("not fixed yet")
211 public void testTicket14287() throws Exception {
212 final MapCSSTagChecker test = buildTagChecker(
213 "node[amenity=parking] ∈ *[amenity=parking] {" +
214 " throwWarning: tr(\"{0} inside {1}\", \"amenity=parking\", \"amenity=parking\");" +
215 "}");
216 try (InputStream is = TestUtils.getRegressionDataStream(14287, "example.osm")) {
217 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
218 assertEquals(6, test.getErrors().size());
219 }
220 }
221
222 /**
223 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17053">Bug #17053</a>.
224 * @throws ParseException if a parsing error occurs
225 */
226 @Test
227 public void testTicket17053() throws ParseException {
228 final MapCSSTagChecker test = buildTagChecker(
229 "way[highway=cycleway][cycleway=track] {\n" +
230 " throwWarning: tr(\"{0} with {1}\", \"{0.tag}\", \"{1.tag}\");\n" +
231 " -osmoseItemClassLevel: \"3032/30328/2\";\n" +
232 " -osmoseTags: list(\"tag\", \"highway\", \"cycleway\");\n" +
233 " fixRemove: \"cycleway\";\n" +
234 "}");
235 assertEquals(1, test.checks.size());
236 TagCheck check = test.checks.get("test").iterator().next();
237 assertEquals(1, check.fixCommands.size());
238 assertEquals(2, check.rule.declaration.instructions.size());
239 }
240
241 private void doTestNaturalWood(int ticket, String filename, int errorsCount, int setsCount) throws Exception {
242 final MapCSSTagChecker test = buildTagChecker(
243 "area:closed:areaStyle[tag(\"natural\") = parent_tag(\"natural\")] ⧉ area:closed:areaStyle[natural] {" +
244 " throwWarning: tr(\"Overlapping Identical Natural Areas\");" +
245 "}");
246 final MapCSSStyleSource style = new MapCSSStyleSource(
247 "area[natural=wood] {" +
248 " fill-color: woodarea#008000;" +
249 "}");
250 MapPaintStyles.addStyle(style);
251 try (InputStream is = TestUtils.getRegressionDataStream(ticket, filename)) {
252 test.visit(OsmReader.parseDataSet(is, null).allPrimitives());
253 List<TestError> errors = test.getErrors();
254 assertEquals(errorsCount, errors.size());
255 Set<Set<IPrimitive>> primitives = new HashSet<>();
256 for (TestError e : errors) {
257 primitives.add(new HashSet<>(e.getPrimitives()));
258 }
259 assertEquals(setsCount, primitives.size());
260 } finally {
261 MapPaintStyles.removeStyle(style);
262 }
263 }
264
265 /**
266 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/12627">Bug #12627</a>.
267 * @throws Exception if an error occurs
268 */
269 @Test
270 @Ignore("not fixed yet")
271 public void testTicket12627() throws Exception {
272 doTestNaturalWood(12627, "overlapping.osm", 1, 1);
273 }
274
275 /**
276 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/14289">Bug #14289</a>.
277 * @throws Exception if an error occurs
278 */
279 @Test
280 @Ignore("not fixed yet")
281 public void testTicket14289() throws Exception {
282 doTestNaturalWood(14289, "example2.osm", 3, 3);
283 }
284
285 /**
286 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/15641">Bug #15641</a>.
287 * @throws ParseException if an error occurs
288 */
289 @Test
290 public void testTicket15641() throws ParseException {
291 assertNotNull(buildTagChecker(
292 "relation[type=public_transport][public_transport=stop_area_group] > way {" +
293 " throwWarning: eval(count(parent_tags(public_transport)));" +
294 "}"));
295 }
296}
Note: See TracBrowser for help on using the repository browser.