• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id$
20  */
21 // This file uses 2 space indents, no tabs.
22 
23 /*
24  *
25  * TestXPathAPI.java
26  *
27  */
28 package org.apache.qetest.xalanj2;
29 
30 import android.platform.test.annotations.FlakyTest;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.util.Properties;
34 
35 import javax.xml.parsers.DocumentBuilderFactory;
36 import javax.xml.transform.OutputKeys;
37 import javax.xml.transform.Transformer;
38 import javax.xml.transform.TransformerException;
39 import javax.xml.transform.TransformerFactory;
40 import javax.xml.transform.dom.DOMSource;
41 import javax.xml.transform.stream.StreamResult;
42 
43 import org.apache.qetest.FileBasedTest;
44 import org.apache.qetest.OutputNameManager;
45 import org.apache.qetest.xsl.XSLTestfileInfo;
46 import org.apache.test.android.AndroidFileUtils;
47 import org.apache.xml.dtm.DTM;
48 import org.apache.xml.dtm.DTMIterator;
49 import org.apache.xml.dtm.DTMManager;
50 import org.apache.xml.utils.PrefixResolverDefault;
51 import org.apache.xpath.XPathAPI;
52 import org.apache.xpath.objects.XObject;
53 import org.junit.Test;
54 import org.w3c.dom.Document;
55 import org.w3c.dom.DocumentFragment;
56 import org.w3c.dom.Node;
57 import org.w3c.dom.NodeList;
58 import org.w3c.dom.traversal.NodeIterator;
59 import org.xml.sax.InputSource;
60 
61 /**
62  * Basic functionality test of the public XPathAPI methods.
63  *
64  * Very basic coverage/smoketest level test.
65  * Applies a number of XPaths to some sample documents
66  * and checks output from the various public XPathAPI mehods.
67  * @see XPathAPI
68  * @author myriam_midy@lotus.com
69  * @author shane_curcuru@lotus.com
70  */
71 public class TestXPathAPI extends FileBasedTest
72 {
73   /** Array of sample XPaths to test.  */
74   protected String[] xpath;
75 
76   /** Base path/name of all output files.  */
77   protected String baseOutName = null;
78 
79   protected XSLTestfileInfo testFileInfo1 = new XSLTestfileInfo();
80   protected XSLTestfileInfo testFileInfo2 = new XSLTestfileInfo();
81   protected XSLTestfileInfo testFileInfo3 = new XSLTestfileInfo();
82   protected XSLTestfileInfo testFileInfo4 = new XSLTestfileInfo();
83   protected XSLTestfileInfo testFileInfo5 = new XSLTestfileInfo();
84   protected XSLTestfileInfo testFileInfo6 = new XSLTestfileInfo();
85   protected XSLTestfileInfo testFileInfo7 = new XSLTestfileInfo();
86 
87 
88   /** Provides nextName(), currentName() functionality.  */
89   protected OutputNameManager outNames;
90 
91   /** Subdirectory under test\tests\api for our xsl/xml files.  */
92     public static final String X2J_SUBDIR = "xalanj2";
93 
94     /** Just initialize test name, comment, numTestCases. */
TestXPathAPI()95     public TestXPathAPI()
96     {
97         numTestCases = 7;  // REPLACE_num
98         testName = "TestXPathAPI";
99         testComment = "API coverage testing of XPathAPI";
100     }
101 
102     /**
103      * Initialize this test - Set names of xml/xsl test files etc.
104      * Also initializes an array of sample xpaths to test.
105      *
106      * @param p Properties to initialize from (if needed)
107      * @return false if we should abort the test; true otherwise
108      */
doTestFileInit(Properties p)109     public boolean doTestFileInit(Properties p)
110     {
111         // Used for all tests; just dump files in trax subdir
112         File outSubDir = new File(outputDir + File.separator + X2J_SUBDIR);
113         if (!outSubDir.mkdirs())
114             reporter.logWarningMsg("Could not create output dir: " + outSubDir);
115         // Output name manager initialized in each testCase
116         baseOutName = outputDir + File.separator + X2J_SUBDIR + File.separator + testName;
117 
118         String testBasePath = inputDir
119                               + File.separator
120                               + X2J_SUBDIR
121                               + File.separator;
122         String goldBasePath = goldDir
123                               + File.separator
124                               + X2J_SUBDIR
125                               + File.separator;
126 
127         // Gold names are appended onto for each test
128         testFileInfo1.xmlName = testBasePath + "testXPath.xml";
129         testFileInfo1.goldName = goldBasePath;
130 
131         testFileInfo2.xmlName = testBasePath + "testXPath.xml";
132         testFileInfo2.goldName = goldBasePath;
133 
134         testFileInfo3.xmlName = testBasePath + "testXPath.xml";
135         testFileInfo3.goldName = goldBasePath;
136 
137         testFileInfo4.xmlName = testBasePath + "testXPath.xml";
138         testFileInfo4.goldName = goldBasePath;
139 
140         testFileInfo5.xmlName = testBasePath + "testXPath.xml";
141         testFileInfo5.goldName = goldBasePath;
142 
143         testFileInfo6.xmlName = testBasePath + "testXPath2.xml";
144         testFileInfo6.goldName = goldBasePath;
145 
146         testFileInfo7.xmlName = testBasePath + "testXPath3.xml";
147         testFileInfo7.goldName = goldBasePath;
148 
149         // Initialize xpath test data
150         // Note: when adding new xpaths, update array ctor and
151         //  also need to update each testCase's gold files
152         xpath = new String[25];
153         xpath[0] = "/doc/a/@test";
154         xpath[1] = "//.";
155         xpath[2] = "/doc";
156         xpath[3] = "/doc/a";
157         xpath[4] = "//@*";
158         xpath[5] = ".";
159         xpath[6] = "//ancestor-or-self::*";
160         xpath[7] = "./child::*[1]";
161         xpath[8] = "//descendant-or-self::*/@*[1]";
162         xpath[9] = "//@* | * | node()";
163         xpath[10] = "//*";
164         xpath[11] = "/doc/namespace::*";
165         xpath[12] = "//descendant::comment()";
166         xpath[13] = "//*[local-name()='a']";
167         xpath[14] = "//*[current()]/@*";
168         xpath[15] = "//*[last()]";
169         xpath[16] = "doc/*[last()]";
170         xpath[17] = "/doc/a/*[current()]/@*";
171         xpath[18] = "doc/descendant::node()";
172         xpath[19] = "doc/a/@*";
173         xpath[20] = "doc/b/a/ancestor-or-self::*";
174         xpath[21] = "doc/b/a/preceding::*";
175         xpath[22] = "doc/a/following::*";
176         xpath[23] = "/doc/b/preceding-sibling::*";
177         xpath[24] = "/doc/a/following-sibling::*";
178 
179         return true;
180     }
181 
182 
183 
184   /** Quick test of XPathAPI.selectNodeIterator().  */
testCase1()185   public boolean testCase1()
186     throws Exception
187   {
188     reporter.testCaseInit("Quick test of XPathAPI.selectNodeIterator()");
189     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
190 
191     Document doc = parseToDOM(testFileInfo1.xmlName);
192     Transformer serializer = getSerializer();
193 
194     for (int i=0;i<xpath.length; i++)
195     {
196       // Use the simple XPath API to select a nodeIterator.
197       NodeIterator nl = XPathAPI.selectNodeIterator(doc, xpath[i]);
198 
199       Node n;
200       while ((n = nl.nextNode())!= null)
201       {
202         serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
203         File f = new File(outNames.currentName());
204         fileChecker.check(reporter,
205                            f,
206                            new File(testFileInfo1.goldName + f.getName()),
207                           "selectNodeIterator() of "+xpath[i] + " into " + outNames.currentName());
208       }
209     } // of for...
210     reporter.testCaseClose();
211     return true;
212   }
213 
214   /** Quick test of XPathAPI.selectNodeList().  */
testCase2()215   public boolean testCase2()
216     throws Exception
217   {
218     reporter.testCaseInit("Quick test of XPathAPI.selectNodeList()");
219     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
220 
221     // Note: parsed file and gold file don't match - why? 10-Oct-01 -sc
222     Document doc = parseToDOM(testFileInfo1.xmlName);
223     Transformer serializer = getSerializer();
224 
225     for (int i=0;i<xpath.length; i++)
226     {
227       NodeList nl = XPathAPI.selectNodeList(doc, xpath[i]);
228 
229       Node n;
230       int j = 0;
231       while (j < nl.getLength())
232       {
233         n = nl.item(j++);
234         serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
235         File f = new File(outNames.currentName());
236         fileChecker.check(reporter,
237                           f,
238                           new File(testFileInfo2.goldName + f.getName()),
239                           "selectNodeList() of "+xpath[i] + " into " + outNames.currentName());
240       }
241     } // of for...
242     reporter.testCaseClose();
243     return true;
244   }
245 
246   /** Quick test of XPathAPI.selectSingleNode().  */
testCase3()247   public boolean testCase3()
248     throws Exception
249   {
250     reporter.testCaseInit("Quick test of XPathAPI.selectSingleNode()");
251     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
252 
253     // Note: parsed file and gold file don't match - why? 10-Oct-01 -sc
254     Document doc = parseToDOM(testFileInfo1.xmlName);
255     Transformer serializer = getSerializer();
256 
257     for (int i=0;i<xpath.length; i++)
258     {
259       Node n = XPathAPI.selectSingleNode(doc, xpath[i]);
260 
261       if (n != null)
262       {
263         serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
264         File f = new File(outNames.currentName());
265         fileChecker.check(reporter,
266                            f,
267                            new File(testFileInfo3.goldName + f.getName()),
268                           "selectSingleNode() of "+xpath[i] + " into " + outNames.currentName());
269       }
270       else
271       {
272         reporter.logWarningMsg("No node found with selectSingleNode() of "+xpath[i]);
273       }
274     } // of for...
275     reporter.testCaseClose();
276     return true;
277   }
278 
279 
280   /** Quick test of XPathAPI.eval().  */
testCase4()281   public boolean testCase4()
282     throws Exception
283   {
284     reporter.testCaseInit("Quick test of XPathAPI.eval()");
285     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
286 
287     // Note: parsed file and gold file don't match - why? 10-Oct-01 -sc
288     Document doc = parseToDOM(testFileInfo1.xmlName);
289     Transformer serializer = getSerializer();
290 
291     //Document d1 =(Document) doc.getDocumentElement();
292     // Node d = (doc.getNodeType() == Node.DOCUMENT_NODE)
293     // ? (Document) doc.getDocumentElement() : doc;
294     reporter.logInfoMsg("Creating a PrefixResolverDefault(...)");
295     PrefixResolverDefault prefixResolver =
296                new PrefixResolverDefault(doc.getDocumentElement());
297 
298     for (int i=0;i<xpath.length; i++)
299     {
300       XObject list = XPathAPI.eval(doc, xpath[i], prefixResolver);
301 
302       int n;
303       DTMIterator nl = list.iter();
304       DTMManager dtmManager = nl.getDTMManager();
305       while ((n = nl.nextNode())!= DTM.NULL)
306       {
307         Node node = dtmManager.getDTM(n).getNode(n);
308         serializer.transform(new DOMSource(node), new StreamResult(outNames.nextName()));
309         File f = new File(outNames.currentName());
310         fileChecker.check(reporter,
311                            f,
312                            new File(testFileInfo4.goldName + f.getName()),
313                           "eval() of "+xpath[i] + " into " + outNames.currentName());
314       }
315     } // of for...
316     reporter.testCaseClose();
317     return true;
318   }
319 
320   /** Quick test of XPathAPI.selectNodeList() and doc.getFirstChild().  */
testCase5()321   public boolean testCase5()
322     throws Exception
323   {
324     reporter.testCaseInit("Quick test of XPathAPI.selectNodeList() and doc.getFirstChild()");
325     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
326 
327     Document doc = parseToDOM(testFileInfo5.xmlName);
328     Transformer serializer = getSerializer();
329 
330     // Use the simple XPath API to select a nodeIterator.
331     reporter.logStatusMsg("Querying DOM using selectNodeList(doc.getFirstChild(), 'a')");
332     NodeList nl = XPathAPI.selectNodeList(doc.getFirstChild(), "a");
333 
334     Node n;
335     int j = 0;
336     while (j < nl.getLength())
337     {
338       n = nl.item(j++);
339       serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
340       File f = new File(outNames.currentName());
341       fileChecker.check(reporter,
342                         f,
343                         new File(testFileInfo5.goldName + f.getName()),
344                         "selectNodeList(doc.getFirstChild(), 'a') into " + outNames.currentName());
345     }
346     reporter.testCaseClose();
347     return true;
348   }
349 
350   /** Quick test of XPathAPI.selectNodeIterator() and non-document node.  */
testCase6()351   public boolean testCase6()
352     throws Exception
353   {
354     reporter.testCaseInit("Quick test of XPathAPI.selectNodeIterator() and non-document node");
355     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
356     String filename = testFileInfo6.xmlName;
357     String xpathStr = "*[local-name()='sitemap' and namespace-uri()='http://apache.org/xalan/test/sitemap']";
358 
359     // Set up a DOM tree to query.
360     reporter.logInfoMsg("Parsing input file "+filename);
361     // Android-added: Look up the file in the java resources.
362     // InputSource in = new InputSource(new FileInputStream(filename));
363     InputSource in = new InputSource(AndroidFileUtils.getInputFileUrl(filename).openStream());
364     DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
365     dfactory.setNamespaceAware(true);
366     Document doc = dfactory.newDocumentBuilder().parse(in);
367 
368     Transformer serializer = getSerializer();
369 
370     // Create DocumentFragment
371     DocumentFragment frag = doc.createDocumentFragment();
372     frag.appendChild(doc.getFirstChild());
373 
374     // Use the simple XPath API to select a nodeIterator.
375     reporter.logStatusMsg("selectNodeIterator(" + xpathStr + ") and a non document node");
376     NodeIterator nl = XPathAPI.selectNodeIterator(frag, xpathStr);
377 
378     Node n;
379     while ((n = nl.nextNode())!= null)
380     {
381       serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
382       File f = new File(outNames.currentName());
383       fileChecker.check(reporter,
384                         f,
385                         new File(testFileInfo6.goldName + f.getName()),
386                         "selectNodeIterator(...) into " + outNames.currentName());
387     }
388     reporter.testCaseClose();
389     return true;
390   }
391 
392   /** Quick test of XPathAPI.selectNodeList using 'id(a)'.  */
testCase7()393   public boolean testCase7()
394     throws Exception
395   {
396     reporter.testCaseInit("Quick test of XPathAPI.selectNodeList using 'id(a)'");
397     outNames = new OutputNameManager(baseOutName + reporter.getCurrentCaseNum(), ".out");
398 
399     // Note: parsed file and gold file don't match - why? 10-Oct-01 -sc
400     Document doc = parseToDOM(testFileInfo7.xmlName);
401     Transformer serializer = getSerializer();
402 
403     // Use the simple XPath API to select a nodeIterator.
404     reporter.logStatusMsg("selectNodeList using 'id(a)' ");
405     NodeList nl = XPathAPI.selectNodeList(doc, "id('a')");
406 
407     Node n;
408     int j = 0;
409     while (j < nl.getLength())
410     {
411       n = nl.item(j++);
412       serializer.transform(new DOMSource(n), new StreamResult(outNames.nextName()));
413       File f = new File(outNames.currentName());
414       fileChecker.check(reporter,
415                         f,
416                         new File(testFileInfo5.goldName + f.getName()),
417                         "selectNodeList using 'id(a)' into " + outNames.currentName());
418     }
419     reporter.testCaseClose();
420     return true;
421   }
422 
423   /** Worker method to return a transformer for serializing.  */
getSerializer()424   protected Transformer getSerializer() throws TransformerException
425   {
426     // Set up an identity transformer to use as serializer.
427     Transformer serializer = TransformerFactory.newInstance().newTransformer();
428     serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
429     return serializer;
430   }
431 
432   /** Worker method to parse file into a DOM.  */
parseToDOM(String filename)433   protected Document parseToDOM(String filename) throws Exception
434   {
435     reporter.logInfoMsg("Parsing input file "+filename);
436 
437     // Set up a DOM tree to query.
438     // Android-added: Look up the file in the java resources.
439     // InputSource in = new InputSource(new FileInputStream(filename));
440     InputSource in = new InputSource(AndroidFileUtils.getInputFileUrl(filename).openStream());
441     DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
442     Document doc = dfactory.newDocumentBuilder().parse(in);
443     return doc;
444   }
445 
446   //-----------------------------------------------------------
447   //---- Basic XSLProcessorTestBase utility methods
448   //-----------------------------------------------------------
449   /**
450    * Convenience method to print out usage information - update if needed.
451    * @return String denoting usage of this test class
452    */
usage()453   public String usage()
454   {
455     return ("Common [optional] options supported by TestXPathAPI:\n"
456             + "(Note: assumes inputDir=.\\tests\\api)\n"
457             + super.usage());   // Grab our parent classes usage as well
458   }
459 
460 
461   /** Main method to run from the command line.    */
main(String[] args)462   public static void main (String[] args)
463   {
464     TestXPathAPI app = new TestXPathAPI();
465     app.doMain(args);
466   }
467 
468   // Android-added: Run main method as a JUnit test case.
469   @FlakyTest(bugId = 292520220)
470   @Test
main()471   public void main() {
472     main(new String[0]);
473   }
474 } // end of class ApplyXPath
475 
476