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    *      https://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;
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.assertInstanceOf;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * Tests for map literals
35   */
36  @SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
37  class MapLiteralTest extends JexlTestCase {
38      public MapLiteralTest() {
39          super("MapLiteralTest");
40      }
41  
42      @Test
43      void testCallingMethodsOnNewMapLiteral() throws Exception {
44          final JexlExpression e = JEXL.createExpression("size({ 'foo' : 'bar' }.values())");
45          final JexlContext jc = new MapContext();
46  
47          final Object o = e.evaluate(jc);
48          assertEquals(Integer.valueOf(1), o);
49      }
50  
51      @Test
52      void testEmptyMap() throws Exception {
53          final JexlScript script = JEXL.createScript("map['']", "map");
54          final Object result = script.execute(null, Collections.singletonMap("", 42));
55          assertEquals(42, result);
56      }
57  
58      @Test
59      void testLiteralWithMultipleEntries() throws Exception {
60          final Map<String, String> expected = new HashMap<>();
61          expected.put("foo", "bar");
62          expected.put("eat", "food");
63          final List<String> sources = Arrays.asList("{ 'foo' : 'bar', 'eat' : 'food' }", "{ 'foo' : 'bar', 'eat' : 'food', }");
64          for(final String src : sources) {
65              final JexlExpression e = JEXL.createExpression("{ 'foo' : 'bar', 'eat' : 'food' }");
66              final Object o = e.evaluate(null);
67              assertEquals(expected, o);
68          }
69      }
70  
71      @Test
72      void testLiteralWithNumbers() throws Exception {
73          JexlExpression e = JEXL.createExpression("{ 5 : 10 }");
74          final JexlContext jc = new MapContext();
75  
76          Object o = e.evaluate(jc);
77          assertEquals(Collections.singletonMap(Integer.valueOf(5), Integer.valueOf(10)), o);
78  
79          e = JEXL.createExpression("m = { 3 : 30, 4 : 40, 5 : 'fifty', '7' : 'seven', 7 : 'SEVEN' }");
80          e.evaluate(jc);
81  
82          e = JEXL.createExpression("m.3");
83          o = e.evaluate(jc);
84          assertEquals(Integer.valueOf(30), o);
85  
86          e = JEXL.createExpression("m[4]");
87          o = e.evaluate(jc);
88          assertEquals(Integer.valueOf(40), o);
89  
90          jc.set("i", Integer.valueOf(5));
91          e = JEXL.createExpression("m[i]");
92          o = e.evaluate(jc);
93          assertEquals("fifty", o);
94  
95          e = JEXL.createExpression("m.3 = 'thirty'");
96          e.evaluate(jc);
97          e = JEXL.createExpression("m.3");
98          o = e.evaluate(jc);
99          assertEquals("thirty", o);
100 
101         e = JEXL.createExpression("m['7']");
102         o = e.evaluate(jc);
103         assertEquals("seven", o);
104 
105         e = JEXL.createExpression("m.7");
106         o = e.evaluate(jc);
107         assertEquals("SEVEN", o);
108 
109         jc.set("k", Integer.valueOf(7));
110         e = JEXL.createExpression("m[k]");
111         o = e.evaluate(jc);
112         assertEquals("SEVEN", o);
113 
114         jc.set("k", "7");
115         e = JEXL.createExpression("m[k]");
116         o = e.evaluate(jc);
117         assertEquals("seven", o);
118     }
119 
120     @Test
121     void testLiteralWithStrings() throws Exception {
122         final List<String> sources = Arrays.asList("{ 'foo' : 'bar' }", "{ 'foo' : 'bar', }");
123         for(final String src : sources) {
124             final JexlExpression e = JEXL.createExpression(src);
125             final Object o = e.evaluate(null);
126             assertEquals(Collections.singletonMap("foo", "bar"), o);
127         }
128         assertThrows(JexlException.Parsing.class, () -> JEXL.createExpression("{  : , }"));
129     }
130 
131     @Test
132     void testMapArrayLiteral() throws Exception {
133         JexlExpression e = JEXL.createExpression("{'foo' : [ 'inner' , 'bar' ]}");
134         final JexlContext jc = new MapContext();
135         Object o = e.evaluate(jc);
136         assertNotNull(o);
137 
138         jc.set("outer", o);
139         e = JEXL.createExpression("outer.foo.1");
140         o = e.evaluate(jc);
141         assertEquals("bar", o);
142     }
143 
144     @Test
145     void testMapMapLiteral() throws Exception {
146         JexlExpression e = JEXL.createExpression("{'foo' : { 'inner' : 'bar' }}");
147         final JexlContext jc = new MapContext();
148         Object o = e.evaluate(jc);
149         assertNotNull(o);
150 
151         jc.set("outer", o);
152         e = JEXL.createExpression("outer.foo.inner");
153         o = e.evaluate(jc);
154         assertEquals("bar", o);
155     }
156 
157     @Test
158     void testNotEmptySimpleMapLiteral() throws Exception {
159         final JexlExpression e = JEXL.createExpression("empty({ 'foo' : 'bar' })");
160         final JexlContext jc = new MapContext();
161 
162         final Object o = e.evaluate(jc);
163         assertFalse((Boolean) o);
164     }
165 
166     @Test
167     void testSizeOfSimpleMapLiteral() throws Exception {
168         final JexlExpression e = JEXL.createExpression("size({ 'foo' : 'bar' })");
169         final JexlContext jc = new MapContext();
170 
171         final Object o = e.evaluate(jc);
172         assertEquals(Integer.valueOf(1), o);
173     }
174 
175     @Test
176     void testVariableMap() throws Exception {
177         final JexlScript script = JEXL.createScript("{ ['1', '2'.toString()] : someValue }", "someValue");
178         final Object result = script.execute(null, 42);
179         assertInstanceOf(Map.class, result);
180         Object key = null;
181         Object value = null;
182         for(final Map.Entry<?,?> e : ((Map<?,?>) result).entrySet()) {
183             key = e.getKey();
184             value = e.getValue();
185             break;
186         }
187         final Object gg = ((Map) result).get(key);
188         assertEquals(42, ((Number) gg).intValue());
189         assertEquals(value, ((Number) gg).intValue());
190     }
191 }