001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.jxpath.ri.compiler;
018
019import org.apache.commons.jxpath.JXPathContext;
020import org.apache.commons.jxpath.JXPathTestCase;
021import org.apache.commons.jxpath.TestMixedModelBean;
022import org.apache.commons.jxpath.Variables;
023
024/**
025 * Test basic functionality of JXPath - infoset types,
026 * operations.
027 *
028 * @author Dmitri Plotnikov
029 * @version $Revision: 652845 $ $Date: 2008-05-02 13:46:46 -0400 (Fri, 02 May 2008) $
030 */
031public class VariableTest extends JXPathTestCase {
032    private JXPathContext context;
033
034    public void setUp() {
035        if (context == null) {
036            context = JXPathContext.newContext(new TestMixedModelBean());
037            context.setFactory(new VariableFactory());
038
039            Variables vars = context.getVariables();
040            vars.declareVariable("a", new Double(1));
041            vars.declareVariable("b", new Double(1));
042            vars.declareVariable("c", null);
043            vars.declareVariable("d", new String[] { "a", "b" });
044            vars.declareVariable("integer", new Integer(1));
045            vars.declareVariable("nan", new Double(Double.NaN));
046            vars.declareVariable("x", null);
047        }
048    }
049
050    public void testVariables() {
051        // Variables
052        assertXPathValueAndPointer(context, "$a", new Double(1), "$a");
053    }
054
055    public void testVariablesInExpressions() {
056        assertXPathValue(context, "$a = $b", Boolean.TRUE);
057
058        assertXPathValue(context, "$a = $nan", Boolean.FALSE);
059
060        assertXPathValue(context, "$a + 1", new Double(2));
061
062        assertXPathValue(context, "$c", null);
063
064        assertXPathValue(context, "$d[2]", "b");
065    }
066
067    public void testInvalidVariableName() {
068        boolean exception = false;
069        try {
070            context.getValue("$none");
071        }
072        catch (Exception ex) {
073            exception = true;
074        }
075        assertTrue(
076            "Evaluating '$none', expected exception - did not get it",
077            exception);
078        
079        exception = false;
080        try {
081            context.setValue("$none", new Integer(1));
082        }
083        catch (Exception ex) {
084            exception = true;
085        }
086        assertTrue(
087            "Setting '$none = 1', expected exception - did not get it",
088            exception);
089    }
090
091    public void testNestedContext() {
092        JXPathContext nestedContext = JXPathContext.newContext(context, null);
093
094        assertXPathValue(nestedContext, "$a", new Double(1));
095    }
096
097    public void testSetValue() {
098        assertXPathSetValue(context, "$x", new Integer(1));
099    }
100
101    public void testCreatePathDeclareVariable() {
102        // Calls factory.declareVariable("string")
103        assertXPathCreatePath(context, "$string", null, "$string");
104    }
105
106    public void testCreatePathAndSetValueDeclareVariable() {
107        // Calls factory.declareVariable("string")
108        assertXPathCreatePathAndSetValue(
109            context,
110            "$string",
111            "Value",
112            "$string");
113    }
114
115    public void testCreatePathDeclareVariableSetCollectionElement() {
116        // Calls factory.declareVariable("stringArray"). 
117        // The factory needs to create a collection
118        assertXPathCreatePath(
119            context,
120            "$stringArray[2]",
121            "",
122            "$stringArray[2]");
123
124        // See if the factory populated the first element as well
125        assertEquals(
126            "Created <" + "$stringArray[1]" + ">",
127            "Value1",
128            context.getValue("$stringArray[1]"));
129    }
130
131    public void testCreateAndSetValuePathDeclareVariableSetCollectionElement() {
132        // Calls factory.declareVariable("stringArray"). 
133        // The factory needs to create a collection
134        assertXPathCreatePathAndSetValue(
135            context,
136            "$stringArray[2]",
137            "Value2",
138            "$stringArray[2]");
139
140        // See if the factory populated the first element as well
141        assertEquals(
142            "Created <" + "$stringArray[1]" + ">",
143            "Value1",
144            context.getValue("$stringArray[1]"));
145    }
146
147    public void testCreatePathExpandCollection() {
148        context.getVariables().declareVariable(
149            "array",
150            new String[] { "Value1" });
151
152        // Does not involve factory at all - just expands the collection
153        assertXPathCreatePath(context, "$array[2]", "", "$array[2]");
154
155        // Make sure it is still the same array
156        assertEquals(
157            "Created <" + "$array[1]" + ">",
158            "Value1",
159            context.getValue("$array[1]"));
160    }
161
162    public void testCreatePathAndSetValueExpandCollection() {
163        context.getVariables().declareVariable(
164            "array",
165            new String[] { "Value1" });
166
167        // Does not involve factory at all - just expands the collection
168        assertXPathCreatePathAndSetValue(
169            context,
170            "$array[2]",
171            "Value2",
172            "$array[2]");
173
174        // Make sure it is still the same array
175        assertEquals(
176            "Created <" + "$array[1]" + ">",
177            "Value1",
178            context.getValue("$array[1]"));
179    }
180
181    public void testCreatePathDeclareVariableSetProperty() {
182        // Calls factory.declareVariable("test"). 
183        // The factory should create a TestBean
184        assertXPathCreatePath(
185            context,
186            "$test/boolean",
187            Boolean.FALSE,
188            "$test/boolean");
189
190    }
191
192    public void testCreatePathAndSetValueDeclareVariableSetProperty() {
193        // Calls factory.declareVariable("test"). 
194        // The factory should create a TestBean
195        assertXPathCreatePathAndSetValue(
196            context,
197            "$test/boolean",
198            Boolean.TRUE,
199            "$test/boolean");
200
201    }
202
203    public void testCreatePathDeclareVariableSetCollectionElementProperty() {
204        // Calls factory.declareVariable("testArray").
205        // The factory should create a collection of TestBeans.
206        // Then calls factory.createObject(..., collection, "testArray", 1).
207        // That one should produce an instance of TestBean and 
208        // put it in the collection at index 1.
209        assertXPathCreatePath(
210            context,
211            "$testArray[2]/boolean",
212            Boolean.FALSE,
213            "$testArray[2]/boolean");
214    }
215
216    public void testCreatePathAndSetValueDeclVarSetCollectionElementProperty() {
217        // Calls factory.declareVariable("testArray").
218        // The factory should create a collection of TestBeans.
219        // Then calls factory.createObject(..., collection, "testArray", 1).
220        // That one should produce an instance of TestBean and 
221        // put it in the collection at index 1.
222        assertXPathCreatePathAndSetValue(
223            context,
224            "$testArray[2]/boolean",
225            Boolean.TRUE,
226            "$testArray[2]/boolean");
227    }
228
229    public void testRemovePathUndeclareVariable() {
230        // Undeclare variable
231        context.getVariables().declareVariable("temp", "temp");
232        context.removePath("$temp");
233        assertTrue(
234            "Undeclare variable",
235            !context.getVariables().isDeclaredVariable("temp"));
236
237    }
238
239    public void testRemovePathArrayElement() {
240        // Remove array element - reassigns the new array to the var
241        context.getVariables().declareVariable(
242            "temp",
243            new String[] { "temp1", "temp2" });
244        context.removePath("$temp[1]");
245        assertEquals(
246            "Remove array element",
247            "temp2",
248            context.getValue("$temp[1]"));
249    }
250
251    public void testRemovePathCollectionElement() {
252        // Remove list element - does not create a new list
253        context.getVariables().declareVariable("temp", list("temp1", "temp2"));
254        context.removePath("$temp[1]");
255        assertEquals(
256            "Remove collection element",
257            "temp2",
258            context.getValue("$temp[1]"));
259    }
260    
261    public void testUnionOfVariableAndNode() throws Exception {
262        assertXPathValue(context, "count($a | /document/vendor/location)", new Double(3));
263        assertXPathValue(context, "count($a | /list)", new Double(7)); //$o + list which contains six discrete values (one is duped, wrapped in a Container)
264    }
265
266    public void testIterateVariable() throws Exception {
267        assertXPathValueIterator(context, "$d", list("a", "b"));
268        assertXPathValue(context, "$d = 'a'", Boolean.TRUE);
269        assertXPathValue(context, "$d = 'b'", Boolean.TRUE);
270    }
271}