source: josm/trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy@ 7115

Last change on this file since 7115 was 7115, checked in by simon04, 12 years ago

fix #9783 - MapCSS: allow to regexp-match name=(foo) by [name =~ /\(foo\)/]

File size: 15.0 KB
Line 
1package org.openstreetmap.josm.gui.mappaint.mapcss
2
3import java.awt.Color
4
5import org.junit.Before
6import org.junit.Test
7import org.openstreetmap.josm.JOSMFixture
8import org.openstreetmap.josm.Main
9import org.openstreetmap.josm.TestUtils
10import org.openstreetmap.josm.data.coor.LatLon
11import org.openstreetmap.josm.data.osm.DataSet
12import org.openstreetmap.josm.data.osm.OsmPrimitive
13import org.openstreetmap.josm.data.osm.Way
14import org.openstreetmap.josm.gui.mappaint.Environment
15import org.openstreetmap.josm.gui.mappaint.MultiCascade
16import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
17import org.openstreetmap.josm.tools.ColorHelper
18
19class MapCSSParserTest {
20
21 protected static OsmPrimitive getPrimitive(String key, String value) {
22 def w = new Way()
23 w.put(key, value)
24 return w
25 }
26
27 protected static Environment getEnvironment(String key, String value) {
28 return new Environment().withPrimitive(getPrimitive(key, value))
29 }
30
31 protected static MapCSSParser getParser(String stringToParse) {
32 return new MapCSSParser(new StringReader(stringToParse));
33 }
34
35 @Before
36 public void setUp() throws Exception {
37 JOSMFixture.createUnitTestFixture().init();
38 }
39
40 @Test
41 public void testKothicStylesheets() throws Exception {
42 new MapCSSParser(new URL("http://kothic.googlecode.com/hg/src/styles/default.mapcss").openStream(), "UTF-8")
43 new MapCSSParser(new URL("http://kothic.googlecode.com/hg/src/styles/mapink.mapcss").openStream(), "UTF-8")
44 }
45
46 @Test
47 public void testDeclarations() {
48 getParser("{ opacity: 0.5; color: rgb(1.0, 0.0, 0.0); }").declaration()
49 getParser("{ set tag=value; }").declaration() //set a tag
50 getParser("{ set tag; }").declaration() // set a tag to 'yes'
51 getParser("{ opacity: eval(\"tag('population')/100000\"); }").declaration()
52 getParser("{ set width_in_metres=eval(\"tag('lanes')*3\"); }").declaration()
53 }
54
55 @Test
56 public void testClassCondition() throws Exception {
57 def conditions = ((Selector.GeneralSelector) getParser("way[name=X].highway:closed").selector()).conds
58 assert conditions.get(0) instanceof Condition.SimpleKeyValueCondition
59 assert conditions.get(0).applies(getEnvironment("name", "X"))
60 assert conditions.get(1) instanceof Condition.ClassCondition
61 assert conditions.get(2) instanceof Condition.PseudoClassCondition
62 }
63
64 @Test
65 public void testClassMatching() throws Exception {
66 def css = new MapCSSStyleSource("")
67 getParser("" +
68 "way[highway=footway] { set .path; color: #FF6644; width: 2; }\n" +
69 "way[highway=path] { set path; color: brown; width: 2; }\n" +
70 "way[\"set\"=escape] { }\n" +
71 "way.path { text:auto; text-color: green; text-position: line; text-offset: 5; }\n" +
72 "way!.path { color: orange; }\n"
73 ).sheet(css)
74 assert css.getErrors().isEmpty()
75 def mc1 = new MultiCascade()
76 css.apply(mc1, getPrimitive("highway", "path"), 1, null, false);
77 assert "green".equals(mc1.getCascade("default").get("text-color", null, String.class))
78 assert "brown".equals(mc1.getCascade("default").get("color", null, String.class))
79 def mc2 = new MultiCascade()
80 css.apply(mc2, getPrimitive("highway", "residential"), 1, null, false);
81 assert "orange".equals(mc2.getCascade("default").get("color", null, String.class))
82 assert mc2.getCascade("default").get("text-color", null, String.class) == null
83 def mc3 = new MultiCascade()
84 css.apply(mc3, getPrimitive("highway", "footway"), 1, null, false);
85 assert ColorHelper.html2color("#FF6644").equals(mc3.getCascade("default").get("color", null, Color.class))
86 }
87
88 @Test
89 public void testEqualCondition() throws Exception {
90 def condition = (Condition.SimpleKeyValueCondition) getParser("[surface=paved]").condition(Condition.Context.PRIMITIVE)
91 assert condition instanceof Condition.SimpleKeyValueCondition
92 assert "surface".equals(condition.k)
93 assert "paved".equals(condition.v)
94 assert condition.applies(getEnvironment("surface", "paved"))
95 assert !condition.applies(getEnvironment("surface", "unpaved"))
96 }
97
98 @Test
99 public void testNotEqualCondition() throws Exception {
100 def condition = (Condition.KeyValueCondition) getParser("[surface!=paved]").condition(Condition.Context.PRIMITIVE)
101 assert Condition.Op.NEQ.equals(condition.op)
102 assert !condition.applies(getEnvironment("surface", "paved"))
103 assert condition.applies(getEnvironment("surface", "unpaved"))
104 }
105
106 @Test
107 public void testRegexCondition() throws Exception {
108 def condition = (Condition.KeyValueCondition) getParser("[surface=~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE)
109 assert Condition.Op.REGEX.equals(condition.op)
110 assert condition.applies(getEnvironment("surface", "unpaved"))
111 assert !condition.applies(getEnvironment("surface", "grass"))
112 }
113
114 @Test
115 public void testRegexConditionParenthesis() throws Exception {
116 def condition = (Condition.KeyValueCondition) getParser("[name =~ /^\\(foo\\)/]").condition(Condition.Context.PRIMITIVE)
117 assert condition.applies(getEnvironment("name", "(foo)"))
118 assert !condition.applies(getEnvironment("name", "foo"))
119 assert !condition.applies(getEnvironment("name", "((foo))"))
120 }
121
122 @Test
123 public void testNegatedRegexCondition() throws Exception {
124 def condition = (Condition.KeyValueCondition) getParser("[surface!~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE)
125 assert Condition.Op.NREGEX.equals(condition.op)
126 assert !condition.applies(getEnvironment("surface", "unpaved"))
127 assert condition.applies(getEnvironment("surface", "grass"))
128 }
129
130 @Test
131 public void testStandardKeyCondition() throws Exception {
132 def c1 = (Condition.KeyCondition) getParser("[ highway ]").condition(Condition.Context.PRIMITIVE)
133 assert c1.matchType == null
134 assert c1.applies(getEnvironment("highway", "unclassified"))
135 assert !c1.applies(getEnvironment("railway", "rail"))
136 def c2 = (Condition.KeyCondition) getParser("[\"/slash/\"]").condition(Condition.Context.PRIMITIVE)
137 assert c2.matchType == null
138 assert c2.applies(getEnvironment("/slash/", "yes"))
139 assert !c2.applies(getEnvironment("\"slash\"", "no"))
140 }
141
142 @Test
143 public void testYesNoKeyCondition() throws Exception {
144 def c1 = (Condition.KeyCondition) getParser("[oneway?]").condition(Condition.Context.PRIMITIVE)
145 def c2 = (Condition.KeyCondition) getParser("[oneway?!]").condition(Condition.Context.PRIMITIVE)
146 def c3 = (Condition.KeyCondition) getParser("[!oneway?]").condition(Condition.Context.PRIMITIVE)
147 def c4 = (Condition.KeyCondition) getParser("[!oneway?!]").condition(Condition.Context.PRIMITIVE)
148 def yes = getEnvironment("oneway", "yes")
149 def no = getEnvironment("oneway", "no")
150 def none = getEnvironment("no-oneway", "foo")
151 assert c1.applies(yes)
152 assert !c1.applies(no)
153 assert !c1.applies(none)
154 assert !c2.applies(yes)
155 assert c2.applies(no)
156 assert !c2.applies(none)
157 assert !c3.applies(yes)
158 assert c3.applies(no)
159 assert c3.applies(none)
160 assert c4.applies(yes)
161 assert !c4.applies(no)
162 assert c4.applies(none)
163 }
164
165 @Test
166 public void testRegexKeyCondition() throws Exception {
167 def c1 = (Condition.KeyCondition) getParser("[/.*:(backward|forward)\$/]").condition(Condition.Context.PRIMITIVE)
168 assert Condition.KeyMatchType.REGEX.equals(c1.matchType)
169 assert !c1.applies(getEnvironment("lanes", "3"))
170 assert c1.applies(getEnvironment("lanes:forward", "3"))
171 assert c1.applies(getEnvironment("lanes:backward", "3"))
172 assert !c1.applies(getEnvironment("lanes:foobar", "3"))
173 }
174
175 @Test
176 public void testNRegexKeyConditionSelector() throws Exception {
177 def s1 = getParser("*[sport][tourism != hotel]").selector()
178 assert s1.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar")))
179 assert !s1.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar tourism=hotel")))
180 def s2 = getParser("*[sport][tourism != hotel][leisure !~ /^(sports_centre|stadium|)\$/]").selector()
181 assert s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar")))
182 assert !s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar tourism=hotel")))
183 assert !s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar leisure=stadium")))
184 }
185
186 @Test
187 public void testKeyKeyCondition() throws Exception {
188 def c1 = (Condition.KeyValueCondition) getParser("[foo = *bar]").condition(Condition.Context.PRIMITIVE)
189 def w1 = new Way()
190 w1.put("foo", "123")
191 w1.put("bar", "456")
192 assert !c1.applies(new Environment().withPrimitive(w1))
193 w1.put("bar", "123")
194 assert c1.applies(new Environment().withPrimitive(w1))
195 def c2 = (Condition.KeyValueCondition) getParser("[foo =~ */bar/]").condition(Condition.Context.PRIMITIVE)
196 def w2 = new Way(w1)
197 w2.put("bar", "[0-9]{3}")
198 assert c2.applies(new Environment().withPrimitive(w2))
199 w2.put("bar", "[0-9]")
200 assert c2.applies(new Environment().withPrimitive(w2))
201 w2.put("bar", "^[0-9]\$")
202 assert !c2.applies(new Environment().withPrimitive(w2))
203 }
204
205 @Test
206 public void testTicket8568() throws Exception {
207 def sheet = new MapCSSStyleSource("")
208 getParser("" +
209 "way { width: 5; }\n" +
210 "way[keyA], way[keyB] { width: eval(prop(width)+10); }").sheet(sheet)
211 def mc = new MultiCascade()
212 sheet.apply(mc, TestUtils.createPrimitive("way foo=bar"), 20, null, false)
213 assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 5
214 sheet.apply(mc, TestUtils.createPrimitive("way keyA=true"), 20, null, false)
215 assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
216 sheet.apply(mc, TestUtils.createPrimitive("way keyB=true"), 20, null, false)
217 assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
218 sheet.apply(mc, TestUtils.createPrimitive("way keyA=true keyB=true"), 20, null, false)
219 assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
220 }
221
222 @Test
223 public void testTicket8071() throws Exception {
224 def sheet = new MapCSSStyleSource("")
225 getParser("*[rcn_ref], *[name] {text: concat(tag(rcn_ref), \" \", tag(name)); }").sheet(sheet)
226 def mc = new MultiCascade()
227 sheet.apply(mc, TestUtils.createPrimitive("way name=Foo"), 20, null, false)
228 assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == " Foo"
229 sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15"), 20, null, false)
230 assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 "
231 sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15 name=Foo"), 20, null, false)
232 assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 Foo"
233
234 sheet = new MapCSSStyleSource("")
235 getParser("*[rcn_ref], *[name] {text: join(\" - \", tag(rcn_ref), tag(ref), tag(name)); }").sheet(sheet)
236 sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15 ref=1.5 name=Foo"), 20, null, false)
237 assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 - 1.5 - Foo"
238 }
239
240 @Test
241 public void testColorNameTicket9191() throws Exception {
242 def e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null)
243 getParser("{color: testcolour1#88DD22}").declaration().instructions.get(0).execute(e)
244 def expected = new Color(0x88DD22)
245 assert e.getCascade(Environment.DEFAULT_LAYER).get("color") == expected
246 assert Main.pref.getDefaultColor("mappaint.mapcss.testcolour1") == expected
247 }
248
249 @Test
250 public void testColorNameTicket9191Alpha() throws Exception {
251 def e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null)
252 getParser("{color: testcolour2#12345678}").declaration().instructions.get(0).execute(e)
253 def expected = new Color(0x12, 0x34, 0x56, 0x78)
254 assert e.getCascade(Environment.DEFAULT_LAYER).get("color") == expected
255 assert Main.pref.getDefaultColor("mappaint.mapcss.testcolour2") == expected
256 }
257
258 @Test
259 public void testColorParsing() throws Exception {
260 assert ColorHelper.html2color("#12345678") == new Color(0x12, 0x34, 0x56, 0x78)
261 }
262
263 @Test
264 public void testSiblingSelector() throws Exception {
265 def s1 = (Selector.ChildOrParentSelector) getParser("*[a?][parent_tag(\"highway\")=\"unclassified\"] + *[b?]").child_selector()
266 def ds = new DataSet()
267 def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
268 n1.put("a", "true")
269 def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
270 n2.put("b", "true")
271 def w = new Way()
272 w.put("highway", "unclassified")
273 ds.addPrimitive(n1)
274 ds.addPrimitive(n2)
275 ds.addPrimitive(w)
276 w.addNode(n1)
277 w.addNode(n2)
278
279 def e = new Environment().withPrimitive(n2)
280 assert s1.matches(e)
281 assert e.osm == n2
282 assert e.child == n1
283 assert e.parent == w
284 assert !s1.matches(new Environment().withPrimitive(n1))
285 assert !s1.matches(new Environment().withPrimitive(w))
286 }
287
288 @Test
289 public void testSiblingSelectorInterpolation() throws Exception {
290 def s1 = (Selector.ChildOrParentSelector) getParser(
291 "*[tag(\"addr:housenumber\") > child_tag(\"addr:housenumber\")][regexp_test(\"even|odd\", parent_tag(\"addr:interpolation\"))]" +
292 " + *[addr:housenumber]").child_selector()
293 def ds = new DataSet()
294 def n1 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
295 n1.put("addr:housenumber", "10")
296 def n2 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.1, 2.2))
297 n2.put("addr:housenumber", "100")
298 def n3 = new org.openstreetmap.josm.data.osm.Node(new LatLon(1.2, 2.3))
299 n3.put("addr:housenumber", "20")
300 def w = new Way()
301 w.put("addr:interpolation", "even")
302 ds.addPrimitive(n1)
303 ds.addPrimitive(n2)
304 ds.addPrimitive(n3)
305 ds.addPrimitive(w)
306 w.addNode(n1)
307 w.addNode(n2)
308 w.addNode(n3)
309
310 assert s1.right.matches(new Environment().withPrimitive(n3))
311 assert s1.left.matches(new Environment().withPrimitive(n2).withChild(n3).withParent(w))
312 assert s1.matches(new Environment().withPrimitive(n3))
313 assert !s1.matches(new Environment().withPrimitive(n1))
314 assert !s1.matches(new Environment().withPrimitive(n2))
315 assert !s1.matches(new Environment().withPrimitive(w))
316 }
317}
Note: See TracBrowser for help on using the repository browser.