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;
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.assertNotSame;
22  
23  import java.util.Map;
24  import java.util.Set;
25  import java.util.concurrent.atomic.AtomicInteger;
26  
27  import org.apache.commons.jexl3.internal.ArrayBuilder;
28  import org.apache.commons.jexl3.internal.MapBuilder;
29  import org.apache.commons.jexl3.internal.SetBuilder;
30  import org.junit.jupiter.api.Test;
31  /**
32   * Counting the number of times map,sets,array literals are created.
33   * <p>
34   * Originally intended to prove one could cache results of constant map literals when used to create
35   * libraries (a map of lamba).
36   * However, those literals must be newly instantiated since their result may be modified; there is
37   * thus no point in trying to cache them. (Think harder and nod, don't try again.)
38   * These pointless tests as a reminder of 'why' those behave the way they do.
39   * </p>
40   */
41  public class CollectionLiteralTest extends JexlTestCase {
42      public static class Arithmetic363 extends JexlArithmetic {
43          final AtomicInteger maps = new AtomicInteger();
44          final AtomicInteger sets = new AtomicInteger();
45          final AtomicInteger arrays = new AtomicInteger();
46  
47          public Arithmetic363(final boolean strict) {
48              super(strict);
49          }
50  
51          @Override public ArrayBuilder arrayBuilder(final int size, final boolean extended) {
52              return new CountingArrayBuilder(arrays, size, extended);
53          }
54          @Override public MapBuilder mapBuilder(final int size, final boolean extended) {
55              return new CountingMapBuilder(maps, size, extended);
56          }
57          @Override public SetBuilder setBuilder(final int size, final boolean extended) {
58              return new CountingSetBuilder(sets, size, extended);
59          }
60      }
61  
62      static class CountingArrayBuilder extends ArrayBuilder {
63          final AtomicInteger count;
64  
65          public CountingArrayBuilder(final AtomicInteger ai, final int size, final boolean extended) {
66              super(size, extended);
67              count = ai;
68          }
69  
70          @Override public Object create(final boolean extended) {
71              final Object array = super.create(extended);
72              count.incrementAndGet();
73              return array;
74          }
75      }
76  
77      static class CountingMapBuilder extends MapBuilder {
78          final AtomicInteger count;
79          public CountingMapBuilder(final AtomicInteger ai, final int size, final boolean extended) {
80              super(size, extended);
81              count = ai;
82          }
83          @Override public Map<Object, Object> create() {
84              final Map<Object, Object> map = super.create();
85              count.incrementAndGet();
86              return map;
87          }
88      }
89  
90      static class CountingSetBuilder extends SetBuilder {
91          final AtomicInteger count;
92          public CountingSetBuilder(final AtomicInteger ai, final int size, final boolean extended) {
93              super(size, extended);
94              count = ai;
95          }
96          @Override public Set<?> create() {
97              final Set<?> set = super.create();
98              count.incrementAndGet();
99              return set;
100         }
101     }
102 
103     public CollectionLiteralTest() {
104         super("CollectionLiteralTest");
105     }
106 
107     @Test
108     public void testArrayBuilder() {
109         final Arithmetic363 jc = new Arithmetic363(true);
110         final JexlEngine jexl = new JexlBuilder().cache(4).arithmetic(jc).create();
111         JexlScript script;
112         Object result;
113 
114         script = jexl.createScript("[ (x)->{ 1 + x; }, (y)->{ y - 1; } ]");
115         Object previous = null;
116         for(int i = 0; i < 4; ++i) {
117             result = script.execute(null);
118             assertNotNull(result);
119             assertNotSame(previous, result);
120             previous = result;
121             assertEquals( 1 + i, jc.arrays.get());
122         }
123     }
124 
125     @Test
126     public void testMapLBuilder() {
127         final Arithmetic363 jc = new Arithmetic363(true);
128         final JexlEngine jexl = new JexlBuilder().cache(4).arithmetic(jc).create();
129         JexlScript script;
130         Object result;
131 
132         script = jexl.createScript("{ 'x':(x)->{ 1 + x; }, 'y' : (y)->{ y - 1; } }");
133         Object previous = null;
134         for(int i = 0; i < 4; ++i) {
135             result = script.execute(null);
136             assertNotNull(result);
137             assertNotSame(previous, result);
138             previous = result;
139             assertEquals(1 + i, jc.maps.get());
140         }
141     }
142 
143     @Test
144     public void testSetBuilder() {
145         final Arithmetic363 jc = new Arithmetic363(true);
146         final JexlEngine jexl = new JexlBuilder().cache(4).arithmetic(jc).create();
147         JexlScript script;
148         Object result;
149 
150         script = jexl.createScript("{ (x)->{ 1 + x; }, (y)->{ y - 1; } }");
151         Object previous = null;
152         for(int i = 0; i < 4; ++i) {
153             result = script.execute(null);
154             assertNotNull(result);
155             assertNotSame(previous, result);
156             previous = result;
157             assertEquals(1 + i, jc.sets.get());
158         }
159     }
160 
161 }