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.assertNotNull;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.StringTokenizer;
31  
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * Tests for the foreach statement
36   */
37  @SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
38  class ForEachTest extends JexlTestCase {
39  
40      /** Create a named test */
41      public ForEachTest() {
42          super("ForEachTest");
43      }
44  
45      @Test
46      void testForEachBreakBroken() throws Exception {
47          final JexlException.Parsing xparse = assertThrows(JexlException.Parsing.class, () -> JEXL.createScript("if (true) { break; }"),
48                  "break is out of loop!");
49          assertTrue(xparse.detailedMessage().contains("break"));
50  
51      }
52  
53      @Test
54      void testForEachBreakMethod() throws Exception {
55          final JexlScript e = JEXL.createScript(
56                  "var rr = -1; for (var item : [1, 2, 3 ,4 ,5, 6]) { if (item == 3) { rr = item; break; }} rr"
57          );
58          final JexlContext jc = new MapContext();
59          jc.set("list", new Foo());
60          final Object o = e.execute(jc);
61          assertEquals(3, o, "Result is not last evaluated expression");
62      }
63  
64      @Test
65      void testForEachContinueBroken() throws Exception {
66          final JexlException.Parsing xparse = assertThrows(JexlException.Parsing.class, () -> JEXL.createScript("var rr = 0; continue;"),
67                  "continue is out of loop!");
68          assertTrue(xparse.detailedMessage().contains("continue"));
69      }
70  
71      @Test
72      void testForEachContinueMethod() throws Exception {
73          final JexlScript e = JEXL.createScript(
74                  "var rr = 0; for (var item : [1, 2, 3 ,4 ,5, 6]) { if (item <= 3) continue; rr = rr + item;}"
75          );
76          final JexlContext jc = new MapContext();
77          jc.set("list", new Foo());
78          final Object o = e.execute(jc);
79          assertEquals(15, o, "Result is not last evaluated expression");
80      }
81  
82      @Test
83      void testForEachWithArray() throws Exception {
84          final JexlScript e = JEXL.createScript("for (item : list) item");
85          final JexlContext jc = new MapContext();
86          jc.set("list", new Object[]{"Hello", "World"});
87          final Object o = e.execute(jc);
88          assertEquals("World", o, "Result is not last evaluated expression");
89      }
90  
91      @Test
92      void testForEachWithBlock() throws Exception {
93          final JexlScript exs0 = JEXL.createScript("for (var in : list) { x = x + in; }");
94          final JexlContext jc = new MapContext();
95          jc.set("list", new Object[]{2, 3});
96              jc.set("x", Integer.valueOf(1));
97          final Object o = exs0.execute(jc);
98              assertEquals(Integer.valueOf(6), o, "Result is wrong");
99              assertEquals(Integer.valueOf(6), jc.get("x"), "x is wrong");
100         }
101 
102     @Test
103     void testForEachWithCollection() throws Exception {
104         final JexlScript e = JEXL.createScript("for (var item : list) item");
105         final JexlContext jc = new MapContext();
106         jc.set("list", Arrays.asList("Hello", "World"));
107         final Object o = e.execute(jc);
108         assertEquals("World", o, "Result is not last evaluated expression");
109     }
110 
111     @Test
112     void testForEachWithEmptyList() throws Exception {
113         final JexlScript e = JEXL.createScript("for (item : list) 1+1");
114         final JexlContext jc = new MapContext();
115         jc.set("list", Collections.emptyList());
116 
117         final Object o = e.execute(jc);
118         assertNull(o);
119     }
120 
121     @Test
122     void testForEachWithEmptyStatement() throws Exception {
123         final JexlScript e = JEXL.createScript("for (item : list) ;");
124         final JexlContext jc = new MapContext();
125         jc.set("list", Collections.emptyList());
126 
127         final Object o = e.execute(jc);
128         assertNull(o);
129     }
130 
131     @Test
132     void testForEachWithEnumeration() throws Exception {
133         final JexlScript e = JEXL.createScript("for (var item : list) item");
134         final JexlContext jc = new MapContext();
135         jc.set("list", new StringTokenizer("Hello,World", ","));
136         final Object o = e.execute(jc);
137         assertEquals("World", o, "Result is not last evaluated expression");
138     }
139 
140     @Test
141     void testForEachWithIterator() throws Exception {
142         final JexlScript e = JEXL.createScript("for (var item : list) item");
143         final JexlContext jc = new MapContext();
144         jc.set("list", Arrays.asList("Hello", "World").iterator());
145         final Object o = e.execute(jc);
146         assertEquals("World", o, "Result is not last evaluated expression");
147     }
148 
149     @Test
150     void testForEachWithIteratorMethod() throws Exception {
151         final JexlScript e = JEXL.createScript("for (var item : list.cheezy) item");
152         final JexlContext jc = new MapContext();
153         jc.set("list", new Foo());
154         final Object o = e.execute(jc);
155         assertEquals("brie", o, "Result is not last evaluated expression");
156     }
157 
158     @Test
159     void testForEachWithListExpression() throws Exception {
160         final JexlScript e = JEXL.createScript("for (var item : list.keySet()) item");
161         final JexlContext jc = new MapContext();
162         final Map<?, ?> map = System.getProperties();
163         final String lastKey = (String) new ArrayList<Object>(map.keySet()).get(System.getProperties().size() - 1);
164         jc.set("list", map);
165         final Object o = e.execute(jc);
166         assertEquals(lastKey, o, "Result is not last evaluated expression");
167     }
168 
169     @Test
170     void testForEachWithMap() throws Exception {
171         final JexlScript e = JEXL.createScript("for(item : list) item");
172         final JexlContext jc = new MapContext();
173         final Map<?, ?> map = System.getProperties();
174         final String lastProperty = (String) new ArrayList<Object>(map.values()).get(System.getProperties().size() - 1);
175         jc.set("list", map);
176         final Object o = e.execute(jc);
177         assertEquals(lastProperty, o, "Result is not last evaluated expression");
178     }
179 
180     @Test
181     void testForEachWithProperty() throws Exception {
182         final JexlScript e = JEXL.createScript("for(var item : list.cheeseList) item");
183         final JexlContext jc = new MapContext();
184         jc.set("list", new Foo());
185         final Object o = e.execute(jc);
186         assertEquals("brie", o, "Result is not last evaluated expression");
187     }
188 
189     @Test void testForLoop0a() {
190         final String src = "(l)->{ for (let x = 0; x < 4; ++x) { l.add(x); } }";
191         final JexlEngine jexl = new JexlBuilder().safe(false).create();
192         final JexlScript script = jexl.createScript(src);
193         final List<Integer> l = new ArrayList<>();
194         final Object result = script.execute(null, l);
195         assertNotNull(result);
196         assertEquals(Arrays.asList(0, 1, 2, 3), l);
197         final String resrc = toString(script);
198         assertEquals(src, resrc);
199     }
200 
201     @Test void testForLoop0b0() {
202         final String src = "(l)->{ for (let x = 0, y = 0; x < 4; ++x) l.add(x) }";
203         final JexlEngine jexl = new JexlBuilder().safe(false).create();
204         final JexlScript script = jexl.createScript(src);
205         final List<Integer> l = new ArrayList<>();
206         final Object result = script.execute(null, l);
207         assertNotNull(result);
208         assertEquals(Arrays.asList(0, 1, 2, 3), l);
209         final String resrc = toString(script);
210         assertEquals(src, resrc);
211     }
212 }