source: josm/trunk/test/unit/org/openstreetmap/josm/tools/template_engine/TemplateParserTest.java@ 12656

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

see #15182 - move SearchCompiler from actions.search to data.osm.search

  • Property svn:eol-style set to native
File size: 13.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools.template_engine;
3
4import java.util.Arrays;
5import java.util.List;
6
7import org.junit.Assert;
8import org.junit.BeforeClass;
9import org.junit.Test;
10import org.openstreetmap.josm.JOSMFixture;
11import org.openstreetmap.josm.data.osm.Node;
12import org.openstreetmap.josm.data.osm.Relation;
13import org.openstreetmap.josm.data.osm.RelationMember;
14import org.openstreetmap.josm.data.osm.search.SearchCompiler;
15import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match;
16import org.openstreetmap.josm.data.osm.search.SearchParseError;
17import org.openstreetmap.josm.testutils.DatasetFactory;
18import org.unitils.reflectionassert.ReflectionAssert;
19
20/**
21 * Unit tests of {@link TemplateParser} class.
22 */
23public class TemplateParserTest {
24
25 /**
26 * Setup test.
27 */
28 @BeforeClass
29 public static void setUp() {
30 JOSMFixture.createUnitTestFixture().init();
31 }
32
33 /**
34 * Test to parse an empty string.
35 * @throws ParseError if the template cannot be parsed
36 */
37 @Test
38 public void testEmpty() throws ParseError {
39 TemplateParser parser = new TemplateParser("");
40 ReflectionAssert.assertReflectionEquals(new StaticText(""), parser.parse());
41 }
42
43 /**
44 * Test to parse a variable.
45 * @throws ParseError if the template cannot be parsed
46 */
47 @Test
48 public void testVariable() throws ParseError {
49 TemplateParser parser = new TemplateParser("abc{var}\\{ef\\$\\{g");
50 ReflectionAssert.assertReflectionEquals(CompoundTemplateEntry.fromArray(new StaticText("abc"),
51 new Variable("var"), new StaticText("{ef${g")), parser.parse());
52 }
53
54 /**
55 * Test to parse a condition with whitespaces.
56 * @throws ParseError if the template cannot be parsed
57 */
58 @Test
59 public void testConditionWhitespace() throws ParseError {
60 TemplateParser parser = new TemplateParser("?{ '{name} {desc}' | '{name}' | '{desc}' }");
61 Condition condition = new Condition();
62 condition.getEntries().add(CompoundTemplateEntry.fromArray(new Variable("name"), new StaticText(" "), new Variable("desc")));
63 condition.getEntries().add(new Variable("name"));
64 condition.getEntries().add(new Variable("desc"));
65 ReflectionAssert.assertReflectionEquals(condition, parser.parse());
66 }
67
68 /**
69 * Test to parse a condition without whitespace.
70 * @throws ParseError if the template cannot be parsed
71 */
72 @Test
73 public void testConditionNoWhitespace() throws ParseError {
74 TemplateParser parser = new TemplateParser("?{'{name} {desc}'|'{name}'|'{desc}'}");
75 Condition condition = new Condition();
76 condition.getEntries().add(CompoundTemplateEntry.fromArray(new Variable("name"), new StaticText(" "), new Variable("desc")));
77 condition.getEntries().add(new Variable("name"));
78 condition.getEntries().add(new Variable("desc"));
79 ReflectionAssert.assertReflectionEquals(condition, parser.parse());
80 }
81
82 private static Match compile(String expression) throws SearchParseError {
83 return SearchCompiler.compile(expression);
84 }
85
86 /**
87 * Test to parse a search expression condition.
88 * @throws ParseError if the template cannot be parsed
89 * @throws SearchParseError if an error has been encountered while compiling
90 */
91 @Test
92 public void testConditionSearchExpression() throws ParseError, SearchParseError {
93 TemplateParser parser = new TemplateParser("?{ admin_level = 2 'NUTS 1' | admin_level = 4 'NUTS 2' | '{admin_level}'}");
94 Condition condition = new Condition();
95 condition.getEntries().add(new SearchExpressionCondition(compile("admin_level = 2"), new StaticText("NUTS 1")));
96 condition.getEntries().add(new SearchExpressionCondition(compile("admin_level = 4"), new StaticText("NUTS 2")));
97 condition.getEntries().add(new Variable("admin_level"));
98 ReflectionAssert.assertReflectionEquals(condition, parser.parse());
99 }
100
101 TemplateEngineDataProvider dataProvider = new TemplateEngineDataProvider() {
102 @Override
103 public Object getTemplateValue(String name, boolean special) {
104 if (special) {
105 if ("localName".equals(name))
106 return "localName";
107 else
108 return null;
109 } else {
110 switch (name) {
111 case "name":
112 return "waypointName";
113 case "number":
114 return 10;
115 case "special:key":
116 return "specialKey";
117 default:
118 return null;
119 }
120 }
121 }
122
123 @Override
124 public boolean evaluateCondition(Match condition) {
125 return true;
126 }
127
128 @Override
129 public List<String> getTemplateKeys() {
130 return Arrays.asList("name", "number");
131 }
132 };
133
134 /**
135 * Test to fill a template.
136 * @throws ParseError if the template cannot be parsed
137 */
138 @Test
139 public void testFilling() throws ParseError {
140 TemplateParser parser = new TemplateParser("{name} u{unknown}u i{number}i");
141 TemplateEntry entry = parser.parse();
142 StringBuilder sb = new StringBuilder();
143 entry.appendText(sb, dataProvider);
144 Assert.assertEquals("waypointName uu i10i", sb.toString());
145 }
146
147 /**
148 * Test to parse a search expression.
149 * @throws ParseError if the template cannot be parsed
150 */
151 @Test
152 public void testFillingSearchExpression() throws ParseError {
153 TemplateParser parser = new TemplateParser("?{ admin_level = 2 'NUTS 1' | admin_level = 4 'NUTS 2' | '{admin_level}'}");
154 TemplateEntry templateEntry = parser.parse();
155
156 StringBuilder sb = new StringBuilder();
157 Relation r = new Relation();
158 r.put("admin_level", "2");
159 templateEntry.appendText(sb, r);
160 Assert.assertEquals("NUTS 1", sb.toString());
161
162 sb.setLength(0);
163 r.put("admin_level", "5");
164 templateEntry.appendText(sb, r);
165 Assert.assertEquals("5", sb.toString());
166 }
167
168 /**
169 * Test to print all.
170 * @throws ParseError if the template cannot be parsed
171 */
172 @Test
173 public void testPrintAll() throws ParseError {
174 TemplateParser parser = new TemplateParser("{special:everything}");
175 TemplateEntry entry = parser.parse();
176 StringBuilder sb = new StringBuilder();
177 entry.appendText(sb, dataProvider);
178 Assert.assertEquals("name=waypointName, number=10", sb.toString());
179 Assert.assertEquals("{special:everything}", entry.toString());
180 }
181
182 /**
183 * Test to print on several lines.
184 * @throws ParseError if the template cannot be parsed
185 */
186 @Test
187 public void testPrintMultiline() throws ParseError {
188 TemplateParser parser = new TemplateParser("{name}\\n{number}");
189 TemplateEntry entry = parser.parse();
190 StringBuilder sb = new StringBuilder();
191 entry.appendText(sb, dataProvider);
192 Assert.assertEquals("waypointName\n10", sb.toString());
193 }
194
195 /**
196 * Test to print special variables.
197 * @throws ParseError if the template cannot be parsed
198 */
199 @Test
200 public void testSpecialVariable() throws ParseError {
201 TemplateParser parser = new TemplateParser("{name}u{special:localName}u{special:special:key}");
202 TemplateEntry templateEntry = parser.parse();
203
204 StringBuilder sb = new StringBuilder();
205 templateEntry.appendText(sb, dataProvider);
206 Assert.assertEquals("waypointNameulocalNameuspecialKey", sb.toString());
207 }
208
209 @Test
210 public void testSearchExpression() throws Exception {
211 compile("(parent type=type1 type=parent1) | (parent type=type2 type=parent2)");
212 //"parent(type=type1,type=parent1) | (parent(type=type2,type=parent2)"
213 //TODO
214 }
215
216 /**
217 * Test to switch context.
218 * @throws ParseError if the template cannot be parsed
219 */
220 @Test
221 public void testSwitchContext() throws ParseError {
222 TemplateParser parser = new TemplateParser("!{parent() type=parent2 '{name}'}");
223 DatasetFactory ds = new DatasetFactory();
224 Relation parent1 = ds.addRelation(1);
225 parent1.put("type", "parent1");
226 parent1.put("name", "name_parent1");
227 Relation parent2 = ds.addRelation(2);
228 parent2.put("type", "parent2");
229 parent2.put("name", "name_parent2");
230 Node child = ds.addNode(1);
231 parent1.addMember(new RelationMember("", child));
232 parent2.addMember(new RelationMember("", child));
233
234 StringBuilder sb = new StringBuilder();
235 TemplateEntry entry = parser.parse();
236 entry.appendText(sb, child);
237
238 Assert.assertEquals("name_parent2", sb.toString());
239 }
240
241 @Test
242 public void testSetAnd() throws ParseError {
243 TemplateParser parser = new TemplateParser("!{(parent(type=child) type=parent) & (parent type=child subtype=parent) '{name}'}");
244 DatasetFactory ds = new DatasetFactory();
245 Relation parent1 = ds.addRelation(1);
246 parent1.put("type", "parent");
247 parent1.put("subtype", "parent");
248 parent1.put("name", "name_parent1");
249 Node child = ds.addNode(1);
250 child.put("type", "child");
251 parent1.addMember(new RelationMember("", child));
252
253 StringBuilder sb = new StringBuilder();
254 TemplateEntry entry = parser.parse();
255 entry.appendText(sb, child);
256
257 Assert.assertEquals("name_parent1", sb.toString());
258 }
259
260 @Test
261 public void testSetOr() throws ParseError {
262 TemplateParser parser = new TemplateParser("!{(parent(type=type1) type=parent1) | (parent type=type2 type=parent2) '{name}'}");
263 DatasetFactory ds = new DatasetFactory();
264 Relation parent1 = ds.addRelation(1);
265 parent1.put("type", "parent1");
266 parent1.put("name", "name_parent1");
267 Relation parent2 = ds.addRelation(2);
268 parent2.put("type", "parent2");
269 parent2.put("name", "name_parent2");
270 Node child1 = ds.addNode(1);
271 child1.put("type", "type1");
272 parent1.addMember(new RelationMember("", child1));
273 parent2.addMember(new RelationMember("", child1));
274 Node child2 = ds.addNode(2);
275 child2.put("type", "type2");
276 parent1.addMember(new RelationMember("", child2));
277 parent2.addMember(new RelationMember("", child2));
278
279 StringBuilder sb = new StringBuilder();
280 TemplateEntry entry = parser.parse();
281 entry.appendText(sb, child1);
282 entry.appendText(sb, child2);
283
284 Assert.assertEquals("name_parent1name_parent2", sb.toString());
285 }
286
287 @Test
288 public void testMultilevel() throws ParseError {
289 TemplateParser parser = new TemplateParser(
290 "!{(parent(parent(type=type1)) type=grandparent) | (parent type=type2 type=parent2) '{name}'}");
291 DatasetFactory ds = new DatasetFactory();
292 Relation parent1 = ds.addRelation(1);
293 parent1.put("type", "parent1");
294 parent1.put("name", "name_parent1");
295 Relation parent2 = ds.addRelation(2);
296 parent2.put("type", "parent2");
297 parent2.put("name", "name_parent2");
298 Node child1 = ds.addNode(1);
299 child1.put("type", "type1");
300 parent1.addMember(new RelationMember("", child1));
301 parent2.addMember(new RelationMember("", child1));
302 Node child2 = ds.addNode(2);
303 child2.put("type", "type2");
304 parent1.addMember(new RelationMember("", child2));
305 parent2.addMember(new RelationMember("", child2));
306 Relation grandParent = ds.addRelation(3);
307 grandParent.put("type", "grandparent");
308 grandParent.put("name", "grandparent_name");
309 grandParent.addMember(new RelationMember("", parent1));
310
311
312 StringBuilder sb = new StringBuilder();
313 TemplateEntry entry = parser.parse();
314 entry.appendText(sb, child1);
315 entry.appendText(sb, child2);
316
317 Assert.assertEquals("grandparent_namename_parent2", sb.toString());
318 }
319
320 @Test(expected = ParseError.class)
321 public void testErrorsNot() throws ParseError {
322 TemplateParser parser = new TemplateParser("!{-parent() '{name}'}");
323 parser.parse();
324 }
325
326 @Test(expected = ParseError.class)
327 public void testErrorOr() throws ParseError {
328 TemplateParser parser = new TemplateParser("!{parent() | type=type1 '{name}'}");
329 parser.parse();
330 }
331
332 @Test
333 public void testChild() throws ParseError {
334 TemplateParser parser = new TemplateParser("!{((child(type=type1) type=child1) | (child type=type2 type=child2)) type=child2 '{name}'}");
335 DatasetFactory ds = new DatasetFactory();
336 Relation parent1 = ds.addRelation(1);
337 parent1.put("type", "type1");
338 Relation parent2 = ds.addRelation(2);
339 parent2.put("type", "type2");
340 Node child1 = ds.addNode(1);
341 child1.put("type", "child1");
342 child1.put("name", "child1");
343 parent1.addMember(new RelationMember("", child1));
344 parent2.addMember(new RelationMember("", child1));
345 Node child2 = ds.addNode(2);
346 child2.put("type", "child2");
347 child2.put("name", "child2");
348 parent1.addMember(new RelationMember("", child2));
349 parent2.addMember(new RelationMember("", child2));
350
351
352 StringBuilder sb = new StringBuilder();
353 TemplateEntry entry = parser.parse();
354 entry.appendText(sb, parent2);
355
356 Assert.assertEquals("child2", sb.toString());
357 }
358
359 @Test
360 public void testToStringCanBeParsedAgain() throws Exception {
361 final String s1 = "?{ '{name} ({desc})' | '{name} ({cmt})' | '{name}' | '{desc}' | '{cmt}' }";
362 final String s2 = new TemplateParser(s1).parse().toString();
363 final String s3 = new TemplateParser(s2).parse().toString();
364 Assert.assertEquals(s1, s2);
365 Assert.assertEquals(s2, s3);
366 }
367}
Note: See TracBrowser for help on using the repository browser.