1   /*
2    * $Header$
3    * $Revision$
4    * $Date$
5    *
6    * ====================================================================
7    *
8    * Copyright 2005 Elliotte Rusty Harold
9    * All rights reserved.
10   *
11   * Redistribution and use in source and binary forms, with or without
12   * modification, are permitted provided that the following conditions are
13   * met:
14   * 
15   *   * Redistributions of source code must retain the above copyright
16   *     notice, this list of conditions and the following disclaimer.
17   * 
18   *   * Redistributions in binary form must reproduce the above copyright
19   *     notice, this list of conditions and the following disclaimer in the
20   *     documentation and/or other materials provided with the distribution.
21   * 
22   *   * Neither the name of the Jaxen Project nor the names of its
23   *     contributors may be used to endorse or promote products derived 
24   *     from this software without specific prior written permission.
25   * 
26   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
29   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
30   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   *
38   * ====================================================================
39   * This software consists of voluntary contributions made by many 
40   * individuals on behalf of the Jaxen Project and was originally 
41   * created by bob mcwhirter <bob@werken.com> and 
42   * James Strachan <jstrachan@apache.org>.  For more information on the 
43   * Jaxen Project, please see <http://www.jaxen.org/>.
44   * 
45   * $Id$
46   */
47  
48  package org.jaxen.test;
49  
50  import java.util.List;
51  
52  import javax.xml.parsers.DocumentBuilder;
53  import javax.xml.parsers.DocumentBuilderFactory;
54  import javax.xml.parsers.ParserConfigurationException;
55  
56  import junit.framework.TestCase;
57  
58  import org.jaxen.BaseXPath;
59  import org.jaxen.FunctionCallException;
60  import org.jaxen.JaxenException;
61  import org.jaxen.dom.DOMXPath;
62  import org.w3c.dom.Document;
63  import org.w3c.dom.Element;
64  
65  /***
66   * @author Elliotte Rusty Harold
67   *
68   */
69  public class LangTest extends TestCase {
70  
71      private Document doc;
72      private DocumentBuilder builder;
73      
74      public void setUp() throws ParserConfigurationException
75      {
76          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
77          factory.setNamespaceAware(true);
78          builder = factory.newDocumentBuilder();
79          doc = builder.newDocument();
80      }
81  
82      public LangTest(String name) {
83          super(name);
84      }
85  
86      public void testLangFunction() 
87        throws JaxenException {
88          
89          BaseXPath xpath = new DOMXPath("//*[lang('en')]");
90          Element a = doc.createElementNS("", "a");
91          Element b = doc.createElementNS("", "b");
92          b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en");
93          doc.appendChild(a);
94          a.appendChild(b);
95          Element x2 = doc.createElementNS("", "x");
96          Element x3 = doc.createElementNS("", "x");
97          Element x4 = doc.createElementNS("", "x");
98          a.appendChild(x4);
99          b.appendChild(x2);
100         b.appendChild(x3);
101         x2.appendChild(doc.createTextNode("2"));
102         x3.appendChild(doc.createTextNode("3"));
103         x4.appendChild(doc.createTextNode("4"));
104         
105         List result = xpath.selectNodes(doc);
106         assertEquals(3, result.size());
107         assertEquals(b, result.get(0));
108         assertEquals(x2, result.get(1));
109         assertEquals(x3, result.get(2));
110         
111     }    
112 
113     public void testLangFunctionSelectsNothing() 
114       throws JaxenException {
115         
116         BaseXPath xpath = new DOMXPath("//*[lang('fr')]");
117         Element a = doc.createElementNS("", "a");
118         Element b = doc.createElementNS("", "b");
119         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en");
120         doc.appendChild(a);
121         a.appendChild(b);
122         Element x2 = doc.createElementNS("", "x");
123         Element x3 = doc.createElementNS("", "x");
124         Element x4 = doc.createElementNS("", "x");
125         a.appendChild(x4);
126         b.appendChild(x2);
127         b.appendChild(x3);
128         x2.appendChild(doc.createTextNode("2"));
129         x3.appendChild(doc.createTextNode("3"));
130         x4.appendChild(doc.createTextNode("4"));
131         
132         List result = xpath.selectNodes(doc);
133         assertEquals(0, result.size());
134         
135     }    
136 
137     public void testLangFunctionSelectsSubcode() 
138       throws JaxenException {
139         
140         BaseXPath xpath = new DOMXPath("//*[lang('fr')]");
141         Element a = doc.createElementNS("", "a");
142         Element b = doc.createElementNS("", "b");
143         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
144         doc.appendChild(a);
145         a.appendChild(b);
146         Element x2 = doc.createElementNS("", "x");
147         Element x3 = doc.createElementNS("", "x");
148         Element x4 = doc.createElementNS("", "x");
149         a.appendChild(x4);
150         b.appendChild(x2);
151         b.appendChild(x3);
152         x2.appendChild(doc.createTextNode("2"));
153         x3.appendChild(doc.createTextNode("3"));
154         x4.appendChild(doc.createTextNode("4"));
155         
156         List result = xpath.selectNodes(doc);
157         assertEquals(3, result.size());
158         assertEquals(b, result.get(0));
159         assertEquals(x2, result.get(1));
160         assertEquals(x3, result.get(2));
161         
162     }    
163 
164     public void testHyphenRequiredAtEnd() 
165       throws JaxenException {
166         
167         BaseXPath xpath = new DOMXPath("//*[lang('f')]");
168         Element a = doc.createElementNS("", "a");
169         Element b = doc.createElementNS("", "b");
170         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
171         doc.appendChild(a);
172         a.appendChild(b);
173         Element x2 = doc.createElementNS("", "x");
174         Element x3 = doc.createElementNS("", "x");
175         Element x4 = doc.createElementNS("", "x");
176         a.appendChild(x4);
177         b.appendChild(x2);
178         b.appendChild(x3);
179         x2.appendChild(doc.createTextNode("2"));
180         x3.appendChild(doc.createTextNode("3"));
181         x4.appendChild(doc.createTextNode("4"));
182         
183         List result = xpath.selectNodes(doc);
184         assertEquals(0, result.size());
185         
186     }    
187 
188     public void testLangFunctionSelectsEmptyNodeSet() 
189       throws JaxenException {
190         
191         BaseXPath xpath = new DOMXPath("//*[lang(d)]");
192         // This node-set will be empty. Therefore it's the same as the
193         // empty string. Therefore it matches all languages.
194         Element a = doc.createElementNS("", "a");
195         Element b = doc.createElementNS("", "b");
196         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
197         doc.appendChild(a);
198         a.appendChild(b);
199         Element x2 = doc.createElementNS("", "x");
200         Element x3 = doc.createElementNS("", "x");
201         Element x4 = doc.createElementNS("", "x");
202         a.appendChild(x4);
203         b.appendChild(x2);
204         b.appendChild(x3);
205         x2.appendChild(doc.createTextNode("2"));
206         x3.appendChild(doc.createTextNode("3"));
207         x4.appendChild(doc.createTextNode("4"));
208         
209         List result = xpath.selectNodes(doc);
210         assertEquals(0, result.size());
211         
212     }    
213 
214     public void testLangFunctionSelectsNonEmptyNodeSet() 
215       throws JaxenException {
216         
217         BaseXPath xpath = new DOMXPath("//*[lang(x)]");
218         Element a = doc.createElementNS("", "a");
219         Element b = doc.createElementNS("", "b");
220         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
221         doc.appendChild(a);
222         a.appendChild(b);
223         Element x2 = doc.createElementNS("", "x");
224         Element x3 = doc.createElementNS("", "x");
225         Element x4 = doc.createElementNS("", "x");
226         a.appendChild(x4);
227         b.appendChild(x2);
228         b.appendChild(x3);
229         x2.appendChild(doc.createTextNode("fr"));
230         x3.appendChild(doc.createTextNode("3"));
231         x4.appendChild(doc.createTextNode("4"));
232         
233         List result = xpath.selectNodes(doc);
234         assertEquals(1, result.size());
235         assertEquals(b, result.get(0));
236         
237     }    
238 
239     public void testLangFunctionAppliedToNonElement() 
240       throws JaxenException {
241         
242         BaseXPath xpath = new DOMXPath("//text()[lang('fr')]");
243         Element a = doc.createElementNS("", "a");
244         Element b = doc.createElementNS("", "b");
245         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
246         doc.appendChild(a);
247         a.appendChild(b);
248         Element x2 = doc.createElementNS("", "x");
249         Element x3 = doc.createElementNS("", "x");
250         Element x4 = doc.createElementNS("", "x");
251         a.appendChild(x4);
252         b.appendChild(x2);
253         b.appendChild(x3);
254         x2.appendChild(doc.createTextNode("fr"));
255         x3.appendChild(doc.createTextNode("3"));
256         x4.appendChild(doc.createTextNode("4"));
257         
258         List result = xpath.selectNodes(doc);
259         assertEquals(2, result.size());
260         assertEquals(x2.getFirstChild(), result.get(0));
261         assertEquals(x3.getFirstChild(), result.get(1));
262         
263     }    
264 
265     public void testLangFunctionAppliedToDocument() 
266       throws JaxenException {
267         
268         BaseXPath xpath = new DOMXPath("lang('fr')");
269         Element a = doc.createElementNS("", "a");
270         Element b = doc.createElementNS("", "b");
271         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
272         doc.appendChild(a);
273         a.appendChild(b);
274         Element x2 = doc.createElementNS("", "x");
275         Element x3 = doc.createElementNS("", "x");
276         Element x4 = doc.createElementNS("", "x");
277         a.appendChild(x4);
278         b.appendChild(x2);
279         b.appendChild(x3);
280         x2.appendChild(doc.createTextNode("fr"));
281         x3.appendChild(doc.createTextNode("3"));
282         x4.appendChild(doc.createTextNode("4"));
283         
284         Boolean result = (Boolean) xpath.evaluate(doc);
285         assertEquals(Boolean.FALSE, result);
286         
287     }    
288 
289     public void testLangFunctionSelectsNumber() 
290       throws JaxenException {
291         
292         BaseXPath xpath = new DOMXPath("//*[lang(3)]");
293         
294         Element a = doc.createElementNS("", "a");
295         Element b = doc.createElementNS("", "b");
296         b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
297         doc.appendChild(a);
298         a.appendChild(b);
299         Element x2 = doc.createElementNS("", "x");
300         Element x3 = doc.createElementNS("", "x");
301         Element x4 = doc.createElementNS("", "x");
302         a.appendChild(x4);
303         b.appendChild(x2);
304         b.appendChild(x3);
305         x2.appendChild(doc.createTextNode("2"));
306         x3.appendChild(doc.createTextNode("3"));
307         x4.appendChild(doc.createTextNode("4"));
308         
309         List result = xpath.selectNodes(doc);
310         assertEquals(0, result.size());
311         
312     }    
313 
314     public void testLangFunctionRequiresOneArgument() 
315       throws JaxenException {
316         
317         try {
318             BaseXPath xpath = new DOMXPath("lang()");
319             org.w3c.dom.Element a = doc.createElementNS("", "a");
320             doc.appendChild(a);
321             xpath.selectNodes(doc);
322             fail("Allowed empty lang() function");
323         }
324         catch (FunctionCallException success) {
325             assertNotNull(success.getMessage());
326         }
327         
328     }    
329 
330     public void testLangFunctionRequiresAtMostOneArgument() 
331       throws JaxenException {
332         
333         try {
334             BaseXPath xpath = new DOMXPath("lang('en', 'fr')");
335             org.w3c.dom.Element a = doc.createElementNS("", "a");
336             doc.appendChild(a);
337             xpath.selectNodes(doc);
338             fail("Allowed empty lang() function");
339         }
340         catch (FunctionCallException success) {
341             assertNotNull(success.getMessage());
342         }
343         
344     }    
345 
346 
347 }