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

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

fix #9667 - Verify addresses interpolation range/values via MapCSS (patch by simon04)

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