source: josm/trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java@ 15275

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

fix #17845 - refactor evaluate code in ExpressionFactory to allow for varargs in functions (patch by taylor.smock)

  • Property svn:eol-style set to native
File size: 26.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.mapcss;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNull;
7import static org.junit.Assert.assertTrue;
8import static org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context.PRIMITIVE;
9
10import java.awt.Color;
11import java.io.StringReader;
12import java.util.List;
13
14import org.junit.Rule;
15import org.junit.Test;
16import org.openstreetmap.josm.TestUtils;
17import org.openstreetmap.josm.data.coor.LatLon;
18import org.openstreetmap.josm.data.osm.DataSet;
19import org.openstreetmap.josm.data.osm.Node;
20import org.openstreetmap.josm.data.osm.OsmUtils;
21import org.openstreetmap.josm.data.osm.Relation;
22import org.openstreetmap.josm.data.osm.RelationMember;
23import org.openstreetmap.josm.data.osm.Way;
24import org.openstreetmap.josm.gui.mappaint.Environment;
25import org.openstreetmap.josm.gui.mappaint.MultiCascade;
26import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition;
27import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyCondition;
28import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType;
29import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyValueCondition;
30import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op;
31import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.PseudoClassCondition;
32import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.RegexpKeyValueRegexpCondition;
33import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition;
34import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector;
35import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
36import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
37import org.openstreetmap.josm.testutils.JOSMTestRules;
38import org.openstreetmap.josm.tools.ColorHelper;
39
40import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
41
42/**
43 * Unit tests of {@link MapCSSParser}.
44 */
45public class MapCSSParserTest {
46
47 protected static Environment getEnvironment(String key, String value) {
48 return new Environment(OsmUtils.createPrimitive("way " + key + "=" + value));
49 }
50
51 protected static MapCSSParser getParser(String stringToParse) {
52 return new MapCSSParser(new StringReader(stringToParse));
53 }
54
55 /**
56 * Setup rule
57 */
58 @Rule
59 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
60 public JOSMTestRules test = new JOSMTestRules().projection();
61
62 @Test
63 public void testDeclarations() throws Exception {
64 getParser("{ opacity: 0.5; color: rgb(1.0, 0.0, 0.0); }").declaration();
65 getParser("{ set tag=value; }").declaration(); //set a tag
66 getParser("{ set tag; }").declaration(); // set a tag to 'yes'
67 getParser("{ opacity: eval(\"tag('population')/100000\"); }").declaration();
68 getParser("{ set width_in_metres=eval(\"tag('lanes')*3\"); }").declaration();
69 }
70
71 @Test
72 public void testClassCondition() throws Exception {
73 List<Condition> conditions = ((Selector.GeneralSelector) getParser("way[name=X].highway:closed").selector()).conds;
74 assertTrue(conditions.get(0) instanceof SimpleKeyValueCondition);
75 assertTrue(conditions.get(0).applies(getEnvironment("name", "X")));
76 assertTrue(conditions.get(1) instanceof ClassCondition);
77 assertTrue(conditions.get(2) instanceof PseudoClassCondition);
78 assertFalse(conditions.get(2).applies(getEnvironment("name", "X")));
79 }
80
81 @Test
82 public void testPseudoClassCondition() throws Exception {
83 Condition c1 = ((Selector.GeneralSelector) getParser("way!:area-style").selector()).conds.get(0);
84 Condition c2 = ((Selector.GeneralSelector) getParser("way!:areaStyle").selector()).conds.get(0);
85 Condition c3 = ((Selector.GeneralSelector) getParser("way!:area_style").selector()).conds.get(0);
86 assertEquals("!:areaStyle", c1.toString());
87 assertEquals("!:areaStyle", c2.toString());
88 assertEquals("!:areaStyle", c3.toString());
89 }
90
91 @Test
92 public void testClassMatching() throws Exception {
93 MapCSSStyleSource css = new MapCSSStyleSource(
94 "way[highway=footway] { set .path; color: #FF6644; width: 2; }\n" +
95 "way[highway=path] { set path; color: brown; width: 2; }\n" +
96 "way[\"set\"=escape] { }\n" +
97 "way.path { text:auto; text-color: green; text-position: line; text-offset: 5; }\n" +
98 "way!.path { color: orange; }\n"
99 );
100 css.loadStyleSource();
101 assertTrue(css.getErrors().isEmpty());
102 MultiCascade mc1 = new MultiCascade();
103 css.apply(mc1, OsmUtils.createPrimitive("way highway=path"), 1, false);
104 assertEquals("green", mc1.getCascade("default").get("text-color", null, String.class));
105 assertEquals("brown", mc1.getCascade("default").get("color", null, String.class));
106 MultiCascade mc2 = new MultiCascade();
107 css.apply(mc2, OsmUtils.createPrimitive("way highway=residential"), 1, false);
108 assertEquals("orange", mc2.getCascade("default").get("color", null, String.class));
109 assertNull(mc2.getCascade("default").get("text-color", null, String.class));
110 MultiCascade mc3 = new MultiCascade();
111 css.apply(mc3, OsmUtils.createPrimitive("way highway=footway"), 1, false);
112 assertEquals(ColorHelper.html2color("#FF6644"), mc3.getCascade("default").get("color", null, Color.class));
113 }
114
115 @Test
116 public void testEqualCondition() throws Exception {
117 Condition condition = getParser("[surface=paved]").condition(PRIMITIVE);
118 assertTrue(condition instanceof SimpleKeyValueCondition);
119 assertEquals("surface", ((SimpleKeyValueCondition) condition).k);
120 assertEquals("paved", ((SimpleKeyValueCondition) condition).v);
121 assertTrue(condition.applies(getEnvironment("surface", "paved")));
122 assertFalse(condition.applies(getEnvironment("surface", "unpaved")));
123 }
124
125 @Test
126 public void testNotEqualCondition() throws Exception {
127 KeyValueCondition condition = (KeyValueCondition) getParser("[surface!=paved]").condition(PRIMITIVE);
128 assertEquals(Op.NEQ, condition.op);
129 assertFalse(condition.applies(getEnvironment("surface", "paved")));
130 assertTrue(condition.applies(getEnvironment("surface", "unpaved")));
131 }
132
133 @Test
134 public void testRegexCondition() throws Exception {
135 KeyValueCondition condition = (KeyValueCondition) getParser("[surface=~/paved|unpaved/]").condition(PRIMITIVE);
136 assertEquals(Op.REGEX, condition.op);
137 assertTrue(condition.applies(getEnvironment("surface", "unpaved")));
138 assertFalse(condition.applies(getEnvironment("surface", "grass")));
139 }
140
141 @Test
142 public void testRegexConditionParenthesis() throws Exception {
143 KeyValueCondition condition = (KeyValueCondition) getParser("[name =~ /^\\(foo\\)/]").condition(PRIMITIVE);
144 assertTrue(condition.applies(getEnvironment("name", "(foo)")));
145 assertFalse(condition.applies(getEnvironment("name", "foo")));
146 assertFalse(condition.applies(getEnvironment("name", "((foo))")));
147 }
148
149 @Test
150 public void testNegatedRegexCondition() throws Exception {
151 KeyValueCondition condition = (KeyValueCondition) getParser("[surface!~/paved|unpaved/]").condition(PRIMITIVE);
152 assertEquals(Op.NREGEX, condition.op);
153 assertFalse(condition.applies(getEnvironment("surface", "unpaved")));
154 assertTrue(condition.applies(getEnvironment("surface", "grass")));
155 }
156
157 @Test
158 public void testBeginsEndsWithCondition() throws Exception {
159 KeyValueCondition condition = (KeyValueCondition) getParser("[foo ^= bar]").condition(PRIMITIVE);
160 assertEquals(Op.BEGINS_WITH, condition.op);
161 assertTrue(condition.applies(getEnvironment("foo", "bar123")));
162 assertFalse(condition.applies(getEnvironment("foo", "123bar")));
163 assertFalse(condition.applies(getEnvironment("foo", "123bar123")));
164 condition = (KeyValueCondition) getParser("[foo $= bar]").condition(PRIMITIVE);
165 assertEquals(Op.ENDS_WITH, condition.op);
166 assertFalse(condition.applies(getEnvironment("foo", "bar123")));
167 assertTrue(condition.applies(getEnvironment("foo", "123bar")));
168 assertFalse(condition.applies(getEnvironment("foo", "123bar123")));
169 }
170
171 @Test
172 public void testOneOfCondition() throws Exception {
173 Condition condition = getParser("[vending~=stamps]").condition(PRIMITIVE);
174 assertTrue(condition.applies(getEnvironment("vending", "stamps")));
175 assertTrue(condition.applies(getEnvironment("vending", "bar;stamps;foo")));
176 assertFalse(condition.applies(getEnvironment("vending", "every;thing;else")));
177 assertFalse(condition.applies(getEnvironment("vending", "or_nothing")));
178 }
179
180 @Test
181 public void testStandardKeyCondition() throws Exception {
182 KeyCondition c1 = (KeyCondition) getParser("[ highway ]").condition(PRIMITIVE);
183 assertEquals(KeyMatchType.EQ, c1.matchType);
184 assertTrue(c1.applies(getEnvironment("highway", "unclassified")));
185 assertFalse(c1.applies(getEnvironment("railway", "rail")));
186 KeyCondition c2 = (KeyCondition) getParser("[\"/slash/\"]").condition(PRIMITIVE);
187 assertEquals(KeyMatchType.EQ, c2.matchType);
188 assertTrue(c2.applies(getEnvironment("/slash/", "yes")));
189 assertFalse(c2.applies(getEnvironment("\"slash\"", "no")));
190 }
191
192 @Test
193 public void testYesNoKeyCondition() throws Exception {
194 KeyCondition c1 = (KeyCondition) getParser("[oneway?]").condition(PRIMITIVE);
195 KeyCondition c2 = (KeyCondition) getParser("[oneway?!]").condition(PRIMITIVE);
196 KeyCondition c3 = (KeyCondition) getParser("[!oneway?]").condition(PRIMITIVE);
197 KeyCondition c4 = (KeyCondition) getParser("[!oneway?!]").condition(PRIMITIVE);
198 Environment yes = getEnvironment("oneway", "yes");
199 Environment no = getEnvironment("oneway", "no");
200 Environment none = getEnvironment("no-oneway", "foo");
201 assertTrue(c1.applies(yes));
202 assertFalse(c1.applies(no));
203 assertFalse(c1.applies(none));
204 assertFalse(c2.applies(yes));
205 assertTrue(c2.applies(no));
206 assertFalse(c2.applies(none));
207 assertFalse(c3.applies(yes));
208 assertTrue(c3.applies(no));
209 assertTrue(c3.applies(none));
210 assertTrue(c4.applies(yes));
211 assertFalse(c4.applies(no));
212 assertTrue(c4.applies(none));
213 }
214
215 @Test
216 public void testRegexKeyCondition() throws Exception {
217 KeyCondition c1 = (KeyCondition) getParser("[/.*:(backward|forward)$/]").condition(PRIMITIVE);
218 assertEquals(KeyMatchType.REGEX, c1.matchType);
219 assertFalse(c1.applies(getEnvironment("lanes", "3")));
220 assertTrue(c1.applies(getEnvironment("lanes:forward", "3")));
221 assertTrue(c1.applies(getEnvironment("lanes:backward", "3")));
222 assertFalse(c1.applies(getEnvironment("lanes:foobar", "3")));
223 }
224
225 @Test
226 public void testRegexKeyValueRegexpCondition() throws Exception {
227 RegexpKeyValueRegexpCondition c1 = (RegexpKeyValueRegexpCondition) getParser("[/^name/=~/Test/]").condition(PRIMITIVE);
228 assertEquals("^name", c1.keyPattern.pattern());
229 assertEquals("Test", c1.pattern.pattern());
230 assertTrue(c1.applies(getEnvironment("name", "Test St")));
231 assertFalse(c1.applies(getEnvironment("alt_name", "Test St")));
232 }
233
234 @Test
235 public void testNRegexKeyConditionSelector() throws Exception {
236 Selector s1 = getParser("*[sport][tourism != hotel]").selector();
237 assertTrue(s1.matches(new Environment(OsmUtils.createPrimitive("node sport=foobar"))));
238 assertFalse(s1.matches(new Environment(OsmUtils.createPrimitive("node sport=foobar tourism=hotel"))));
239 Selector s2 = getParser("*[sport][tourism != hotel][leisure !~ /^(sports_centre|stadium|)$/]").selector();
240 assertTrue(s2.matches(new Environment(OsmUtils.createPrimitive("node sport=foobar"))));
241 assertFalse(s2.matches(new Environment(OsmUtils.createPrimitive("node sport=foobar tourism=hotel"))));
242 assertFalse(s2.matches(new Environment(OsmUtils.createPrimitive("node sport=foobar leisure=stadium"))));
243 }
244
245 @Test
246 public void testKeyKeyCondition() throws Exception {
247 KeyValueCondition c1 = (KeyValueCondition) getParser("[foo = *bar]").condition(PRIMITIVE);
248 Way w1 = new Way();
249 w1.put("foo", "123");
250 w1.put("bar", "456");
251 assertFalse(c1.applies(new Environment(w1)));
252 w1.put("bar", "123");
253 assertTrue(c1.applies(new Environment(w1)));
254 KeyValueCondition c2 = (KeyValueCondition) getParser("[foo =~ */bar/]").condition(PRIMITIVE);
255 Way w2 = new Way(w1);
256 w2.put("bar", "[0-9]{3}");
257 assertTrue(c2.applies(new Environment(w2)));
258 w2.put("bar", "[0-9]");
259 assertTrue(c2.applies(new Environment(w2)));
260 w2.put("bar", "^[0-9]$");
261 assertFalse(c2.applies(new Environment(w2)));
262 }
263
264 @Test
265 public void testParentTag() throws Exception {
266 Selector c1 = getParser("way[foo] > node[tag(\"foo\")=parent_tag(\"foo\")] {}").child_selector();
267 DataSet ds = new DataSet();
268 Way w1 = new Way();
269 Way w2 = new Way();
270 Node n1 = new Node(new LatLon(1, 1));
271 Node n2 = new Node(new LatLon(2, 2));
272 w1.put("foo", "123");
273 w2.put("foo", "123");
274 n1.put("foo", "123");
275 n2.put("foo", "0");
276 ds.addPrimitive(w1);
277 ds.addPrimitive(n1);
278 ds.addPrimitive(n2);
279 w1.addNode(n1);
280 w2.addNode(n2);
281 assertTrue(c1.matches(new Environment(n1)));
282 assertFalse(c1.matches(new Environment(n2)));
283 assertFalse(c1.matches(new Environment(w1)));
284 assertFalse(c1.matches(new Environment(w2)));
285 n1.put("foo", "0");
286 assertFalse(c1.matches(new Environment(n1)));
287 n1.put("foo", "123");
288 assertTrue(c1.matches(new Environment(n1)));
289 }
290
291 @Test
292 public void testTicket8568() throws Exception {
293 MapCSSStyleSource sheet = new MapCSSStyleSource(
294 "way { width: 5; }\n" +
295 "way[keyA], way[keyB] { width: eval(prop(width)+10); }");
296 sheet.loadStyleSource();
297 MultiCascade mc = new MultiCascade();
298 sheet.apply(mc, OsmUtils.createPrimitive("way foo=bar"), 20, false);
299 assertEquals(Float.valueOf(5f), mc.getCascade(Environment.DEFAULT_LAYER).get("width"));
300 sheet.apply(mc, OsmUtils.createPrimitive("way keyA=true"), 20, false);
301 assertEquals(Float.valueOf(15f), mc.getCascade(Environment.DEFAULT_LAYER).get("width"));
302 sheet.apply(mc, OsmUtils.createPrimitive("way keyB=true"), 20, false);
303 assertEquals(Float.valueOf(15f), mc.getCascade(Environment.DEFAULT_LAYER).get("width"));
304 sheet.apply(mc, OsmUtils.createPrimitive("way keyA=true keyB=true"), 20, false);
305 assertEquals(Float.valueOf(15f), mc.getCascade(Environment.DEFAULT_LAYER).get("width"));
306 }
307
308 @Test
309 public void testTicket8071() throws Exception {
310 MapCSSStyleSource sheet = new MapCSSStyleSource(
311 "*[rcn_ref], *[name] {text: concat(tag(rcn_ref), \" \", tag(name)); }");
312 sheet.loadStyleSource();
313 MultiCascade mc = new MultiCascade();
314 sheet.apply(mc, OsmUtils.createPrimitive("way name=Foo"), 20, false);
315 assertEquals(" Foo", mc.getCascade(Environment.DEFAULT_LAYER).get("text"));
316 sheet.apply(mc, OsmUtils.createPrimitive("way rcn_ref=15"), 20, false);
317 assertEquals("15 ", mc.getCascade(Environment.DEFAULT_LAYER).get("text"));
318 sheet.apply(mc, OsmUtils.createPrimitive("way rcn_ref=15 name=Foo"), 20, false);
319 assertEquals("15 Foo", mc.getCascade(Environment.DEFAULT_LAYER).get("text"));
320
321 sheet = new MapCSSStyleSource("" +
322 "*[rcn_ref], *[name] {text: join(\" - \", tag(rcn_ref), tag(ref), tag(name)); }");
323 sheet.loadStyleSource();
324 sheet.apply(mc, OsmUtils.createPrimitive("way rcn_ref=15 ref=1.5 name=Foo"), 20, false);
325 assertEquals("15 - 1.5 - Foo", mc.getCascade(Environment.DEFAULT_LAYER).get("text"));
326 }
327
328 @Test
329 public void testColorNameTicket9191() throws Exception {
330 Environment e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null);
331 getParser("{color: testcolour1#88DD22}").declaration().instructions.get(0).execute(e);
332 Color expected = new Color(0x88DD22);
333 assertEquals(expected, e.getCascade(Environment.DEFAULT_LAYER).get("color"));
334 }
335
336 @Test
337 public void testColorNameTicket9191Alpha() throws Exception {
338 Environment e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null);
339 getParser("{color: testcolour2#12345678}").declaration().instructions.get(0).execute(e);
340 Color expected = new Color(0x12, 0x34, 0x56, 0x78);
341 assertEquals(expected, e.getCascade(Environment.DEFAULT_LAYER).get("color"));
342 }
343
344 @Test
345 public void testColorParsing() throws Exception {
346 assertEquals(new Color(0x12, 0x34, 0x56, 0x78), ColorHelper.html2color("#12345678"));
347 }
348
349 @Test
350 public void testChildSelectorGreaterThanSignIsOptional() throws Exception {
351 assertEquals(
352 getParser("relation[type=route] way[highway]").child_selector().toString(),
353 getParser("relation[type=route] > way[highway]").child_selector().toString());
354 }
355
356 @Test
357 public void testSiblingSelector() throws Exception {
358 ChildOrParentSelector s1 = (Selector.ChildOrParentSelector) getParser(
359 "*[a?][parent_tag(\"highway\")=\"unclassified\"] + *[b?]").child_selector();
360 DataSet ds = new DataSet();
361 Node n1 = new Node(new LatLon(1, 2));
362 n1.put("a", "true");
363 Node n2 = new Node(new LatLon(1.1, 2.2));
364 n2.put("b", "true");
365 Way w = new Way();
366 w.put("highway", "unclassified");
367 ds.addPrimitive(n1);
368 ds.addPrimitive(n2);
369 ds.addPrimitive(w);
370 w.addNode(n1);
371 w.addNode(n2);
372
373 Environment e = new Environment(n2);
374 assertTrue(s1.matches(e));
375 assertEquals(n2, e.osm);
376 assertEquals(n1, e.child);
377 assertEquals(w, e.parent);
378 assertFalse(s1.matches(new Environment(n1)));
379 assertFalse(s1.matches(new Environment(w)));
380 }
381
382 @Test
383 public void testParentTags() throws Exception {
384 DataSet ds = new DataSet();
385 Node n = new Node(new LatLon(1, 2));
386 n.put("foo", "bar");
387 Way w1 = new Way();
388 w1.put("ref", "x10");
389 Way w2 = new Way();
390 w2.put("ref", "x2");
391 Way w3 = new Way();
392 ds.addPrimitive(n);
393 ds.addPrimitive(w1);
394 ds.addPrimitive(w2);
395 ds.addPrimitive(w3);
396 w1.addNode(n);
397 w2.addNode(n);
398 w3.addNode(n);
399
400 MapCSSStyleSource source = new MapCSSStyleSource("node[foo=bar] {refs: join_list(\";\", parent_tags(\"ref\"));}");
401 source.loadStyleSource();
402 assertEquals(1, source.rules.size());
403 Environment e = new Environment(n, new MultiCascade(), Environment.DEFAULT_LAYER, null);
404 assertTrue(source.rules.get(0).selector.matches(e));
405 source.rules.get(0).declaration.execute(e);
406 assertEquals("x2;x10", e.getCascade(Environment.DEFAULT_LAYER).get("refs", null, String.class));
407 }
408
409 @Test
410 public void testCountRoles() throws Exception {
411 DataSet ds = new DataSet();
412 Way way1 = TestUtils.newWay("highway=residential name=1",
413 new Node(new LatLon(0, 0)), new Node((new LatLon(0.001, 0.001))));
414 for (Node node : way1.getNodes()) {
415 ds.addPrimitive(node);
416 }
417 ds.addPrimitive(way1);
418
419 Relation rel1 = TestUtils.newRelation("type=destination_sign", new RelationMember("", way1));
420 ds.addPrimitive(rel1);
421
422 /* Check with empty role and one object */
423 Environment e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
424 assertEquals(1, Functions.count_roles(e, ""));
425
426 /* Check with non-empty role and one object */
427 e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
428 assertEquals(0, Functions.count_roles(e, "from"));
429
430 /* Check with empty role and two objects */
431 Way way2 = TestUtils.newWay("highway=residential name=2", way1.firstNode(), way1.lastNode());
432 ds.addPrimitive(way2);
433 rel1.addMember(new RelationMember("", way2));
434 e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
435 assertEquals(2, Functions.count_roles(e, ""));
436
437 /* Check with non-empty role and two objects */
438 rel1.setMember(0, new RelationMember("from", way1));
439 e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
440 assertEquals(1, Functions.count_roles(e, "from"));
441
442 /* Check with multiple roles */
443 assertEquals(1, Functions.count_roles(e, "from", "to"));
444
445 /* Check with non-relation */
446 e = new Environment(way1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
447 assertEquals(0, Functions.count_roles(e, "from", "to"));
448
449 /* Check with actual call to mapcss functions */
450 MapCSSStyleSource source = new MapCSSStyleSource("relation[type=destination_sign] {roles: count_roles(\"from\");}");
451 source.loadStyleSource();
452 assertEquals(1, source.rules.size());
453 e = new Environment(rel1, new MultiCascade(), Environment.DEFAULT_LAYER, null);
454 assertTrue(source.rules.get(0).selector.matches(e));
455 source.rules.get(0).declaration.execute(e);
456 assertEquals((Integer) 1, e.getCascade(Environment.DEFAULT_LAYER).get("roles", null, Integer.class));
457 }
458
459 @Test
460 public void testSiblingSelectorInterpolation() throws Exception {
461 ChildOrParentSelector s1 = (Selector.ChildOrParentSelector) getParser(
462 "*[tag(\"addr:housenumber\") > child_tag(\"addr:housenumber\")][regexp_test(\"even|odd\", parent_tag(\"addr:interpolation\"))]" +
463 " + *[addr:housenumber]").child_selector();
464 DataSet ds = new DataSet();
465 Node n1 = new Node(new LatLon(1, 2));
466 n1.put("addr:housenumber", "10");
467 Node n2 = new Node(new LatLon(1.1, 2.2));
468 n2.put("addr:housenumber", "100");
469 Node n3 = new Node(new LatLon(1.2, 2.3));
470 n3.put("addr:housenumber", "20");
471 Way w = new Way();
472 w.put("addr:interpolation", "even");
473 ds.addPrimitive(n1);
474 ds.addPrimitive(n2);
475 ds.addPrimitive(n3);
476 ds.addPrimitive(w);
477 w.addNode(n1);
478 w.addNode(n2);
479 w.addNode(n3);
480
481 assertTrue(s1.right.matches(new Environment(n3)));
482 assertTrue(s1.left.matches(new Environment(n2).withChild(n3).withParent(w)));
483 assertTrue(s1.matches(new Environment(n3)));
484 assertFalse(s1.matches(new Environment(n1)));
485 assertFalse(s1.matches(new Environment(n2)));
486 assertFalse(s1.matches(new Environment(w)));
487 }
488
489 @Test
490 public void testInvalidBaseSelector() throws Exception {
491 MapCSSStyleSource css = new MapCSSStyleSource("invalid_base[key=value] {}");
492 css.loadStyleSource();
493 assertFalse(css.getErrors().isEmpty());
494 assertTrue(css.getErrors().iterator().next().toString().contains("Unknown MapCSS base selector invalid_base"));
495 }
496
497 @Test
498 public void testMinMaxFunctions() throws Exception {
499 MapCSSStyleSource sheet = new MapCSSStyleSource("* {" +
500 "min_value: min(tag(x), tag(y), tag(z)); " +
501 "max_value: max(tag(x), tag(y), tag(z)); " +
502 "max_split: max(split(\";\", tag(widths))); " +
503 "}");
504 sheet.loadStyleSource();
505 MultiCascade mc = new MultiCascade();
506
507 sheet.apply(mc, OsmUtils.createPrimitive("way x=4 y=6 z=8 u=100"), 20, false);
508 assertEquals(Float.valueOf(4.0f), mc.getCascade(Environment.DEFAULT_LAYER).get("min_value", Float.NaN, Float.class));
509 assertEquals(Float.valueOf(8.0f), mc.getCascade(Environment.DEFAULT_LAYER).get("max_value", Float.NaN, Float.class));
510
511 sheet.apply(mc, OsmUtils.createPrimitive("way x=4 y=6 widths=1;2;8;56;3;a"), 20, false);
512 assertEquals(Float.valueOf(4f), mc.getCascade(Environment.DEFAULT_LAYER).get("min_value", -777f, Float.class));
513 assertEquals(Float.valueOf(6f), mc.getCascade(Environment.DEFAULT_LAYER).get("max_value", -777f, Float.class));
514 assertEquals(Float.valueOf(56f), mc.getCascade(Environment.DEFAULT_LAYER).get("max_split", -777f, Float.class));
515 }
516
517 /**
518 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/12549">Bug #12549</a>.
519 * @throws ParseException if a parsing error occurs
520 */
521 @Test
522 public void testTicket12549() throws ParseException {
523 Condition condition = getParser("[name =~ /^(?i)(?u)fóo$/]").condition(PRIMITIVE);
524 assertTrue(condition.applies(getEnvironment("name", "fóo")));
525 assertTrue(condition.applies(getEnvironment("name", "fÓo")));
526 condition = getParser("[name =~ /^(\\p{Lower})+$/]").condition(PRIMITIVE);
527 assertFalse(condition.applies(getEnvironment("name", "fóo")));
528 condition = getParser("[name =~ /^(?U)(\\p{Lower})+$/]").condition(PRIMITIVE);
529 assertTrue(condition.applies(getEnvironment("name", "fóo")));
530 assertFalse(condition.applies(getEnvironment("name", "fÓo")));
531 }
532
533 /**
534 * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/17053">Bug #17053</a>.
535 */
536 @Test
537 public void testTicket17053() {
538 MapCSSStyleSource sheet = new MapCSSStyleSource(
539 "way {\n" +
540 " placement_offset: eval(\n" +
541 " cond(prop(\"placement_value\")=\"right_of:1\",eval((prop(lane_width_forward_1)/2)-prop(lane_offset_forward_1)),\n" +
542 " 0\n" +
543 " )\n" +
544 " );\n" +
545 "}");
546 sheet.loadStyleSource();
547 assertTrue(sheet.getErrors().toString(), sheet.getErrors().isEmpty());
548 }
549}
Note: See TracBrowser for help on using the repository browser.