View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3.parser;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  
24  import org.apache.commons.jexl3.JexlException;
25  import org.apache.commons.jexl3.JexlFeatures;
26  import org.junit.jupiter.api.Test;
27  
28  /**
29   */
30  public class ParserTest {
31      static final JexlFeatures FEATURES = new JexlFeatures();
32      public ParserTest() {}
33  
34      /**
35       * Test the escaped control characters.
36       */
37      @Test
38      public void testControlCharacters() {
39          // Both '' and "" are valid JEXL string
40          // The array of tuples where the first element is an expected result and the second element is a test string.
41          final String[][] strings = {
42              new String[] {"a\nb\tc", "'a\nb\tc'"}, // we still honor the actual characters
43              new String[] {"a\nb\tc", "'a\\nb\\tc'"},
44              new String[] {"a\nb\tc", "\"a\\nb\\tc\""},
45              new String[] {"\b\t\n\f\r", "'\\b\\t\\n\\f\\r'"},
46              new String[] {"'hi'", "'\\'hi\\''"},
47              new String[] {"\"hi\"", "'\"hi\"'"},
48              new String[] {"\"hi\"", "'\"hi\"'"},
49          };
50          for(final String[] pair: strings) {
51              final String output = StringParser.buildString(pair[1], true);
52              assertEquals(pair[0], output);
53          }
54      }
55  
56      @Test
57      public void testErrorAmbiguous() throws Exception {
58          final Parser parser = new Parser(";");
59          assertThrows(JexlException.Ambiguous.class, () -> parser.parse(null, FEATURES, "x = 1 y = 5", null), "should have failed on ambiguous statement");
60      }
61  
62      @Test
63      public void testErrorAssign() throws Exception {
64          final String[] ops = { "=", "+=", "-=", "/=", "*=", "^=", "&=", "|=" };
65          for (final String op : ops) {
66              final Parser parser = new Parser(";");
67              final JexlException.Parsing xparse = assertThrows(JexlException.Parsing.class, () -> parser.parse(null, FEATURES, "foo() " + op + " 1;", null),
68                      () -> "should have failed on invalid assignment " + op);
69              assertNotNull(xparse.getDetail());
70              assertNotNull(xparse.toString());
71          }
72      }
73  
74      @Test
75      public void testIdentifierEscape() {
76          final String[] ids = {"a\\ b", "a\\ b\\ c", "a\\'b\\\"c", "a\\ \\ c"};
77          for(final String id : ids) {
78              final String esc0 = StringParser.unescapeIdentifier(id);
79              assertFalse(esc0.contains("\\"));
80              final String esc1 = StringParser.escapeIdentifier(esc0);
81              assertEquals(id, esc1);
82          }
83      }
84  
85      /**
86       * See if we can parse simple scripts
87       */
88      @Test
89      public void testParse() throws Exception {
90          final Parser parser = new Parser(";");
91          JexlNode sn;
92          sn = parser.parse(null, FEATURES, "foo = 1;", null);
93          assertNotNull(sn, "parsed node is null");
94  
95          sn = parser.parse(null, FEATURES, "foo = \"bar\";", null);
96          assertNotNull(sn, "parsed node is null");
97  
98          sn = parser.parse(null, FEATURES, "foo = 'bar';", null);
99          assertNotNull(sn, "parsed node is null");
100     }
101 }