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  
18  package org.apache.commons.jxpath.ri.compiler;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  
24  import org.apache.commons.jxpath.AbstractJXPathTest;
25  import org.apache.commons.jxpath.JXPathContext;
26  import org.apache.commons.jxpath.TestMixedModelBean;
27  import org.apache.commons.jxpath.Variables;
28  import org.junit.jupiter.api.BeforeEach;
29  import org.junit.jupiter.api.Test;
30  
31  /**
32   * Test basic functionality of JXPath - infoset types, operations.
33   */
34  public class VariableTest extends AbstractJXPathTest {
35  
36      private JXPathContext context;
37  
38      @Override
39      @BeforeEach
40      public void setUp() {
41          if (context == null) {
42              context = JXPathContext.newContext(new TestMixedModelBean());
43              context.setFactory(new VariableFactory());
44              final Variables vars = context.getVariables();
45              vars.declareVariable("a", Double.valueOf(1));
46              vars.declareVariable("b", Double.valueOf(1));
47              vars.declareVariable("c", null);
48              vars.declareVariable("d", new String[] { "a", "b" });
49              vars.declareVariable("integer", Integer.valueOf(1));
50              vars.declareVariable("nan", Double.valueOf(Double.NaN));
51              vars.declareVariable("x", null);
52          }
53      }
54  
55      @Test
56      public void testCreateAndSetValuePathDeclareVariableSetCollectionElement() {
57          // Calls factory.declareVariable("stringArray").
58          // The factory needs to create a collection
59          assertXPathCreatePathAndSetValue(context, "$stringArray[2]", "Value2", "$stringArray[2]");
60          // See if the factory populated the first element as well
61          assertEquals("Value1", context.getValue("$stringArray[1]"), "Created <" + "$stringArray[1]" + ">");
62      }
63  
64      @Test
65      public void testCreatePathAndSetValueDeclareVariable() {
66          // Calls factory.declareVariable("string")
67          assertXPathCreatePathAndSetValue(context, "$string", "Value", "$string");
68      }
69  
70      @Test
71      public void testCreatePathAndSetValueDeclareVariableSetProperty() {
72          // Calls factory.declareVariable("test").
73          // The factory should create a TestBean
74          assertXPathCreatePathAndSetValue(context, "$test/boolean", Boolean.TRUE, "$test/boolean");
75      }
76  
77      @Test
78      public void testCreatePathAndSetValueDeclVarSetCollectionElementProperty() {
79          // Calls factory.declareVariable("testArray").
80          // The factory should create a collection of TestBeans.
81          // Then calls factory.createObject(..., collection, "testArray", 1).
82          // That one should produce an instance of TestBean and
83          // put it in the collection at index 1.
84          assertXPathCreatePathAndSetValue(context, "$testArray[2]/boolean", Boolean.TRUE, "$testArray[2]/boolean");
85      }
86  
87      @Test
88      public void testCreatePathAndSetValueExpandCollection() {
89          context.getVariables().declareVariable("array", new String[] { "Value1" });
90          // Does not involve factory at all - just expands the collection
91          assertXPathCreatePathAndSetValue(context, "$array[2]", "Value2", "$array[2]");
92          // Make sure it is still the same array
93          assertEquals("Value1", context.getValue("$array[1]"), "Created <" + "$array[1]" + ">");
94      }
95  
96      @Test
97      public void testCreatePathDeclareVariable() {
98          // Calls factory.declareVariable("string")
99          assertXPathCreatePath(context, "$string", null, "$string");
100     }
101 
102     @Test
103     public void testCreatePathDeclareVariableSetCollectionElement() {
104         // Calls factory.declareVariable("stringArray").
105         // The factory needs to create a collection
106         assertXPathCreatePath(context, "$stringArray[2]", "", "$stringArray[2]");
107         // See if the factory populated the first element as well
108         assertEquals("Value1", context.getValue("$stringArray[1]"), "Created <" + "$stringArray[1]" + ">");
109     }
110 
111     @Test
112     public void testCreatePathDeclareVariableSetCollectionElementProperty() {
113         // Calls factory.declareVariable("testArray").
114         // The factory should create a collection of TestBeans.
115         // Then calls factory.createObject(..., collection, "testArray", 1).
116         // That one should produce an instance of TestBean and
117         // put it in the collection at index 1.
118         assertXPathCreatePath(context, "$testArray[2]/boolean", Boolean.FALSE, "$testArray[2]/boolean");
119     }
120 
121     @Test
122     public void testCreatePathDeclareVariableSetProperty() {
123         // Calls factory.declareVariable("test").
124         // The factory should create a TestBean
125         assertXPathCreatePath(context, "$test/boolean", Boolean.FALSE, "$test/boolean");
126     }
127 
128     @Test
129     public void testCreatePathExpandCollection() {
130         context.getVariables().declareVariable("array", new String[] { "Value1" });
131         // Does not involve factory at all - just expands the collection
132         assertXPathCreatePath(context, "$array[2]", "", "$array[2]");
133         // Make sure it is still the same array
134         assertEquals("Value1", context.getValue("$array[1]"), "Created <" + "$array[1]" + ">");
135     }
136 
137     @Test
138     public void testInvalidVariableName() {
139         assertThrows(Exception.class, () -> context.getValue("$none"), "Evaluating '$none', expected exception - did not get it");
140         assertThrows(Exception.class, () -> context.setValue("$none", Integer.valueOf(1)), "Setting '$none = 1', expected exception - did not get it");
141     }
142 
143     @Test
144     public void testIterateVariable() throws Exception {
145         assertXPathValueIterator(context, "$d", list("a", "b"));
146         assertXPathValue(context, "$d = 'a'", Boolean.TRUE);
147         assertXPathValue(context, "$d = 'b'", Boolean.TRUE);
148     }
149 
150     @Test
151     public void testNestedContext() {
152         final JXPathContext nestedContext = JXPathContext.newContext(context, null);
153         assertXPathValue(nestedContext, "$a", Double.valueOf(1));
154     }
155 
156     @Test
157     public void testRemovePathArrayElement() {
158         // Remove array element - reassigns the new array to the var
159         context.getVariables().declareVariable("temp", new String[] { "temp1", "temp2" });
160         context.removePath("$temp[1]");
161         assertEquals("temp2", context.getValue("$temp[1]"), "Remove array element");
162     }
163 
164     @Test
165     public void testRemovePathCollectionElement() {
166         // Remove list element - does not create a new list
167         context.getVariables().declareVariable("temp", list("temp1", "temp2"));
168         context.removePath("$temp[1]");
169         assertEquals("temp2", context.getValue("$temp[1]"), "Remove collection element");
170     }
171 
172     @Test
173     public void testRemovePathUndeclareVariable() {
174         // Undeclare variable
175         context.getVariables().declareVariable("temp", "temp");
176         context.removePath("$temp");
177         assertFalse(context.getVariables().isDeclaredVariable("temp"), "Undeclare variable");
178     }
179 
180     @Test
181     public void testSetValue() {
182         assertXPathSetValue(context, "$x", Integer.valueOf(1));
183     }
184 
185     @Test
186     public void testUnionOfVariableAndNode() throws Exception {
187         assertXPathValue(context, "count($a | /document/vendor/location)", Double.valueOf(3));
188         assertXPathValue(context, "count($a | /list)", Double.valueOf(7)); // $o + list which contains six discrete values (one is duped, wrapped in a
189                                                                            // Container)
190     }
191 
192     @Test
193     public void testVariables() {
194         // Variables
195         assertXPathValueAndPointer(context, "$a", Double.valueOf(1), "$a");
196     }
197 
198     @Test
199     public void testVariablesInExpressions() {
200         assertXPathValue(context, "$a = $b", Boolean.TRUE);
201         assertXPathValue(context, "$a = $nan", Boolean.FALSE);
202         assertXPathValue(context, "$a + 1", Double.valueOf(2));
203         assertXPathValue(context, "$c", null);
204         assertXPathValue(context, "$d[2]", "b");
205     }
206 }