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

Last change on this file since 6859 was 6859, checked in by simon04, 7 years ago

see #9593 - MapCSS: fix matching of negated regular expressions for missing values

File size: 12.3 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.Preferences
8import org.openstreetmap.josm.data.osm.OsmPrimitive
9import org.openstreetmap.josm.data.osm.Way
10import org.openstreetmap.josm.gui.mappaint.Environment
11import org.openstreetmap.josm.gui.mappaint.MultiCascade
12import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
13import org.openstreetmap.josm.tools.ColorHelper
14import org.openstreetmap.josm.tools.Utils
15
16import java.awt.Color
17
18class MapCSSParserTest {
19
20    protected static OsmPrimitive getPrimitive(String key, String value) {
21        def w = new Way()
22        w.put(key, value)
23        return w
24    }
25
26    protected static Environment getEnvironment(String key, String value) {
27        return new Environment().withPrimitive(getPrimitive(key, value))
28    }
29
30    protected static MapCSSParser getParser(String stringToParse) {
31        return new MapCSSParser(new StringReader(stringToParse));
32    }
33
34    @Before
35    public void setUp() throws Exception {
36        Main.pref = new Preferences()
37    }
38
39    @Test
40    public void testKothicStylesheets() throws Exception {
41        new MapCSSParser(new URL("http://kothic.googlecode.com/hg/src/styles/default.mapcss").openStream(), "UTF-8")
42        new MapCSSParser(new URL("http://kothic.googlecode.com/hg/src/styles/mapink.mapcss").openStream(), "UTF-8")
43    }
44
45    @Test
46    public void testDeclarations() {
47        getParser("{ opacity: 0.5; color: rgb(1.0, 0.0, 0.0); }").declaration()
48        getParser("{ set tag=value; }").declaration() //set a tag
49        getParser("{ set tag; }").declaration() // set a tag to 'yes'
50        getParser("{ opacity: eval(\"tag('population')/100000\"); }").declaration()
51        getParser("{ set width_in_metres=eval(\"tag('lanes')*3\"); }").declaration()
52    }
53
54    @Test
55    public void testClassCondition() throws Exception {
56        def conditions = ((Selector.GeneralSelector) getParser("way[name=X].highway:closed").selector()).conds
57        assert conditions.get(0) instanceof Condition.KeyValueCondition
58        assert conditions.get(0).applies(getEnvironment("name", "X"))
59        assert conditions.get(1) instanceof Condition.ClassCondition
60        assert conditions.get(2) instanceof Condition.PseudoClassCondition
61    }
62
63    @Test
64    public void testClassMatching() throws Exception {
65        def css = new MapCSSStyleSource("")
66        getParser("" +
67                "way[highway=footway] { set .path; color: #FF6644; width: 2; }\n" +
68                "way[highway=path]    { set path; color: brown; width: 2; }\n" +
69                "way[\"set\"=escape]  {  }\n" +
70                "way.path             { text:auto; text-color: green; text-position: line; text-offset: 5; }\n" +
71                "way!.path            { color: orange; }\n"
72        ).sheet(css)
73        assert css.getErrors().isEmpty()
74        def mc1 = new MultiCascade()
75        css.apply(mc1, getPrimitive("highway", "path"), 1, null, false);
76        assert "green".equals(mc1.getCascade("default").get("text-color", null, String.class))
77        assert "brown".equals(mc1.getCascade("default").get("color", null, String.class))
78        def mc2 = new MultiCascade()
79        css.apply(mc2, getPrimitive("highway", "residential"), 1, null, false);
80        assert "orange".equals(mc2.getCascade("default").get("color", null, String.class))
81        assert mc2.getCascade("default").get("text-color", null, String.class) == null
82        def mc3 = new MultiCascade()
83        css.apply(mc3, getPrimitive("highway", "footway"), 1, null, false);
84        assert ColorHelper.html2color("#FF6644").equals(mc3.getCascade("default").get("color", null, Color.class))
85    }
86
87    @Test
88    public void testEqualCondition() throws Exception {
89        def condition = (Condition.KeyValueCondition) getParser("[surface=paved]").condition(Condition.Context.PRIMITIVE)
90        assert condition instanceof Condition.KeyValueCondition
91        assert Condition.Op.EQ.equals(condition.op)
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 testNegatedRegexCondition() throws Exception {
116        def condition = (Condition.KeyValueCondition) getParser("[surface!~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE)
117        assert Condition.Op.NREGEX.equals(condition.op)
118        assert !condition.applies(getEnvironment("surface", "unpaved"))
119        assert condition.applies(getEnvironment("surface", "grass"))
120    }
121
122    @Test
123    public void testStandardKeyCondition() throws Exception {
124        def c1 = (Condition.KeyCondition) getParser("[ highway ]").condition(Condition.Context.PRIMITIVE)
125        assert c1.matchType == null
126        assert c1.applies(getEnvironment("highway", "unclassified"))
127        assert !c1.applies(getEnvironment("railway", "rail"))
128        def c2 = (Condition.KeyCondition) getParser("[\"/slash/\"]").condition(Condition.Context.PRIMITIVE)
129        assert c2.matchType == null
130        assert c2.applies(getEnvironment("/slash/", "yes"))
131        assert !c2.applies(getEnvironment("\"slash\"", "no"))
132    }
133
134    @Test
135    public void testYesNoKeyCondition() throws Exception {
136        def c1 = (Condition.KeyCondition) getParser("[oneway?]").condition(Condition.Context.PRIMITIVE)
137        def c2 = (Condition.KeyCondition) getParser("[oneway?!]").condition(Condition.Context.PRIMITIVE)
138        def c3 = (Condition.KeyCondition) getParser("[!oneway?]").condition(Condition.Context.PRIMITIVE)
139        def c4 = (Condition.KeyCondition) getParser("[!oneway?!]").condition(Condition.Context.PRIMITIVE)
140        def yes = getEnvironment("oneway", "yes")
141        def no = getEnvironment("oneway", "no")
142        def none = getEnvironment("no-oneway", "foo")
143        assert c1.applies(yes)
144        assert !c1.applies(no)
145        assert !c1.applies(none)
146        assert !c2.applies(yes)
147        assert c2.applies(no)
148        assert !c2.applies(none)
149        assert !c3.applies(yes)
150        assert c3.applies(no)
151        assert c3.applies(none)
152        assert c4.applies(yes)
153        assert !c4.applies(no)
154        assert c4.applies(none)
155    }
156
157    @Test
158    public void testRegexKeyCondition() throws Exception {
159        def c1 = (Condition.KeyCondition) getParser("[/.*:(backward|forward)\$/]").condition(Condition.Context.PRIMITIVE)
160        assert Condition.KeyMatchType.REGEX.equals(c1.matchType)
161        assert !c1.applies(getEnvironment("lanes", "3"))
162        assert c1.applies(getEnvironment("lanes:forward", "3"))
163        assert c1.applies(getEnvironment("lanes:backward", "3"))
164        assert !c1.applies(getEnvironment("lanes:foobar", "3"))
165    }
166
167    @Test
168    public void testNRegexKeyConditionSelector() throws Exception {
169        def s1 = getParser("*[sport][tourism != hotel]").selector()
170        assert s1.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar")))
171        assert !s1.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar tourism=hotel")))
172        def s2 = getParser("*[sport][tourism != hotel][leisure !~ /^(sports_centre|stadium|)\$/]").selector()
173        assert s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar")))
174        assert !s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar tourism=hotel")))
175        assert !s2.matches(new Environment().withPrimitive(TestUtils.createPrimitive("node sport=foobar leisure=stadium")))
176    }
177
178    @Test
179    public void testKeyKeyCondition() throws Exception {
180        def c1 = (Condition.KeyValueCondition) getParser("[foo = *bar]").condition(Condition.Context.PRIMITIVE)
181        def w1 = new Way()
182        w1.put("foo", "123")
183        w1.put("bar", "456")
184        assert !c1.applies(new Environment().withPrimitive(w1))
185        w1.put("bar", "123")
186        assert c1.applies(new Environment().withPrimitive(w1))
187        def c2 = (Condition.KeyValueCondition) getParser("[foo =~ */bar/]").condition(Condition.Context.PRIMITIVE)
188        def w2 = new Way(w1)
189        w2.put("bar", "[0-9]{3}")
190        assert c2.applies(new Environment().withPrimitive(w2))
191        w2.put("bar", "[0-9]")
192        assert c2.applies(new Environment().withPrimitive(w2))
193        w2.put("bar", "^[0-9]\$")
194        assert !c2.applies(new Environment().withPrimitive(w2))
195    }
196
197    @Test
198    public void testTicket8568() throws Exception {
199        def sheet = new MapCSSStyleSource("")
200        getParser("" +
201                "way { width: 5; }\n" +
202                "way[keyA], way[keyB] { width: eval(prop(width)+10); }").sheet(sheet)
203        def mc = new MultiCascade()
204        sheet.apply(mc, TestUtils.createPrimitive("way foo=bar"), 20, null, false)
205        assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 5
206        sheet.apply(mc, TestUtils.createPrimitive("way keyA=true"), 20, null, false)
207        assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
208        sheet.apply(mc, TestUtils.createPrimitive("way keyB=true"), 20, null, false)
209        assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
210        sheet.apply(mc, TestUtils.createPrimitive("way keyA=true keyB=true"), 20, null, false)
211        assert mc.getCascade(Environment.DEFAULT_LAYER).get("width") == 15
212    }
213
214    @Test
215    public void testTicket80711() throws Exception {
216        def sheet = new MapCSSStyleSource("")
217        getParser("*[rcn_ref], *[name] {text: concat(tag(rcn_ref), \" \", tag(name)); }").sheet(sheet)
218        def mc = new MultiCascade()
219        sheet.apply(mc, TestUtils.createPrimitive("way name=Foo"), 20, null, false)
220        assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == " Foo"
221        sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15"), 20, null, false)
222        assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 "
223        sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15 name=Foo"), 20, null, false)
224        assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 Foo"
225
226        sheet = new MapCSSStyleSource("")
227        getParser("*[rcn_ref], *[name] {text: join(\" - \", tag(rcn_ref), tag(ref), tag(name)); }").sheet(sheet)
228        sheet.apply(mc, TestUtils.createPrimitive("way rcn_ref=15 ref=1.5 name=Foo"), 20, null, false)
229        assert mc.getCascade(Environment.DEFAULT_LAYER).get("text") == "15 - 1.5 - Foo"
230    }
231
232    @Test
233    public void testColorNameTicket9191() throws Exception {
234        def e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null)
235        getParser("{color: testcolour1#88DD22}").declaration().get(0).execute(e)
236        def expected = new Color(0x88DD22)
237        assert e.getCascade(Environment.DEFAULT_LAYER).get("color") == expected
238        assert Main.pref.getDefaultColor("mappaint.mapcss.testcolour1") == expected
239    }
240
241    @Test
242    public void testColorNameTicket9191Alpha() throws Exception {
243        def e = new Environment(null, new MultiCascade(), Environment.DEFAULT_LAYER, null)
244        getParser("{color: testcolour2#12345678}").declaration().get(0).execute(e)
245        def expected = new Color(0x12, 0x34, 0x56, 0x78)
246        assert e.getCascade(Environment.DEFAULT_LAYER).get("color") == expected
247        assert Main.pref.getDefaultColor("mappaint.mapcss.testcolour2") == expected
248    }
249
250    @Test
251    public void testColorParsing() throws Exception {
252        assert ColorHelper.html2color("#12345678") == new Color(0x12, 0x34, 0x56, 0x78)
253    }
254}
Note: See TracBrowser for help on using the repository browser.