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 22 /* 23 * 24 * StreamSourceAPITest.java 25 * 26 */ 27 package org.apache.qetest.trax.stream; 28 29 import java.io.ByteArrayInputStream; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.FileOutputStream; 33 import java.io.InputStream; 34 import java.io.Reader; 35 import java.io.StringReader; 36 import java.util.Properties; 37 38 import javax.xml.transform.Result; 39 import javax.xml.transform.Source; 40 import javax.xml.transform.Templates; 41 import javax.xml.transform.Transformer; 42 import javax.xml.transform.TransformerFactory; 43 import javax.xml.transform.stream.StreamResult; 44 import javax.xml.transform.stream.StreamSource; 45 46 import org.apache.xml.utils.DefaultErrorHandler; 47 import org.apache.qetest.FileBasedTest; 48 import org.apache.qetest.OutputNameManager; 49 import org.apache.qetest.xsl.XSLTestfileInfo; 50 51 //------------------------------------------------------------------------- 52 53 /** 54 * API Coverage test for the StreamSource class of TRAX.. 55 * @author shane_curcuru@lotus.com 56 * @version $Id$ 57 */ 58 public class StreamSourceAPITest extends FileBasedTest 59 { 60 61 /** 62 * Provides nextName(), currentName() functionality for tests 63 * that may produce any number of output files. 64 */ 65 protected OutputNameManager outNames; 66 67 /** 68 * Information about an xsl/xml file pair for transforming. 69 * Public members include inputName (for xsl); xmlName; goldName; etc. 70 */ 71 protected XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 72 73 /** Subdirectory under test\tests\api for our xsl/xml files. */ 74 public static final String TRAX_STREAM_SUBDIR = "trax" + File.separator + "stream"; 75 76 77 /** Just initialize test name, comment, numTestCases. */ StreamSourceAPITest()78 public StreamSourceAPITest() 79 { 80 numTestCases = 2; // REPLACE_num 81 testName = "StreamSourceAPITest"; 82 testComment = "API Coverage test for the StreamSource class of TRAX."; 83 } 84 85 86 /** 87 * Initialize this test - Set names of xml/xsl test files. 88 * 89 * @param p Properties to initialize from (if needed) 90 * @return false if we should abort the test; true otherwise 91 */ doTestFileInit(Properties p)92 public boolean doTestFileInit(Properties p) 93 { 94 // NOTE: 'reporter' variable is already initialized at this point 95 96 // Used for all tests; just dump files in trax subdir 97 File outSubDir = new File(outputDir + File.separator + TRAX_STREAM_SUBDIR); 98 if (!outSubDir.mkdirs()) 99 reporter.logWarningMsg("Could not create output dir: " + outSubDir); 100 // Initialize an output name manager to that dir with .out extension 101 outNames = new OutputNameManager(outputDir + File.separator + TRAX_STREAM_SUBDIR 102 + File.separator + testName, ".out"); 103 104 String testBasePath = inputDir 105 + File.separator 106 + TRAX_STREAM_SUBDIR 107 + File.separator; 108 String goldBasePath = goldDir 109 + File.separator 110 + TRAX_STREAM_SUBDIR 111 + File.separator; 112 113 testFileInfo.inputName = testBasePath + "StreamImpIncl.xsl"; 114 testFileInfo.xmlName = testBasePath + "StreamImpIncl.xml"; 115 testFileInfo.goldName = goldBasePath + "StreamImpIncl.out"; 116 try 117 { 118 TransformerFactory tf = TransformerFactory.newInstance(); 119 if (!(tf.getFeature(StreamSource.FEATURE) 120 && tf.getFeature(StreamResult.FEATURE))) 121 { // The rest of this test relies on Streams 122 reporter.logErrorMsg("Streams not supported! Some tests may be invalid!"); 123 } 124 } 125 catch (Throwable t) 126 { 127 reporter.checkFail( 128 "Problem creating factory; Some tests may be invalid!"); 129 reporter.logThrowable(reporter.ERRORMSG, t, 130 "Problem creating factory; Some tests may be invalid!"); 131 } 132 133 return true; 134 } 135 136 137 /** 138 * Basic API coverage, constructor and set/get methods. 139 * 140 * @return false if we should abort the test; true otherwise 141 */ testCase1()142 public boolean testCase1() 143 { 144 reporter.testCaseInit("Basic API coverage, constructor and set/get methods"); 145 146 reporter.logWarningMsg("public StreamSource(File f) not yet tested"); 147 reporter.logWarningMsg("public void setSystemId(File f) not yet tested"); 148 149 // Default no-arg ctor sets nothing 150 StreamSource defaultStream = new StreamSource(); 151 reporter.checkObject(defaultStream.getInputStream(), null, "Default StreamSource should have null ByteStream"); 152 reporter.checkObject(defaultStream.getReader(), null, "Default StreamSource should have null CharacterStream"); 153 reporter.check(defaultStream.getPublicId(), null, "Default StreamSource should have null PublicId"); 154 reporter.check(defaultStream.getSystemId(), null, "Default StreamSource should have null SystemId"); 155 156 byte[] bytes = { 0, 0, 0, 0 }; // just a few zeroes, not really needed 157 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 158 StreamSource byteSource1 = new StreamSource(bais); 159 reporter.checkObject(byteSource1.getInputStream(), bais, "StreamSource(is) has ByteStream " + byteSource1.getInputStream()); 160 reporter.checkObject(byteSource1.getReader(), null, "StreamSource(is) should have null CharacterStream"); 161 reporter.check(byteSource1.getPublicId(), null, "StreamSource(is) should have null PublicId"); 162 reporter.check(byteSource1.getSystemId(), null, "StreamSource(is) should have null SystemId"); 163 164 StreamSource byteSource2 = new StreamSource(bais, "some-system-id"); 165 reporter.checkObject(byteSource2.getInputStream(), bais, "StreamSource(is, sysID) has ByteStream " + byteSource2.getInputStream()); 166 reporter.checkObject(byteSource2.getReader(), null, "StreamSource(is, sysID) should have null CharacterStream"); 167 reporter.check(byteSource2.getPublicId(), null, "StreamSource(is, sysID) should have null PublicId"); 168 reporter.check(byteSource2.getSystemId(), "some-system-id", "StreamSource(is, sysID) has SystemId " + byteSource2.getSystemId()); 169 170 StringReader strReader = new StringReader("this is not your parent's XML data"); 171 StreamSource readerSource1 = new StreamSource(strReader); 172 reporter.checkObject(readerSource1.getInputStream(), null, "StreamSource(reader) should have null ByteStream"); 173 reporter.checkObject(readerSource1.getReader(), strReader, "StreamSource(reader) has CharacterStream " + readerSource1.getReader()); 174 reporter.check(readerSource1.getPublicId(), null, "StreamSource(reader) should have null PublicId"); 175 reporter.check(readerSource1.getSystemId(), null, "StreamSource(reader) should have null SystemId"); 176 177 StreamSource readerSource2 = new StreamSource(strReader, "some-system-id"); 178 reporter.checkObject(readerSource2.getInputStream(), null, "StreamSource(reader, sysID) should have null ByteStream"); 179 reporter.checkObject(readerSource2.getReader(), strReader, "StreamSource(reader, sysID) has CharacterStream " + readerSource2.getReader()); 180 reporter.check(readerSource2.getPublicId(), null, "StreamSource(reader, sysID) should have null PublicId"); 181 reporter.check(readerSource2.getSystemId(), "some-system-id", "StreamSource(reader, sysID) has SystemId " + readerSource2.getSystemId()); 182 183 StreamSource sysIDStream = new StreamSource("real-system-id"); 184 reporter.checkObject(sysIDStream.getInputStream(), null, "StreamSource(sysID) should have null ByteStream"); 185 reporter.checkObject(sysIDStream.getReader(), null, "StreamSource(sysID) should have null CharacterStream"); 186 reporter.check(sysIDStream.getPublicId(), null, "StreamSource(sysID) should have null PublicId"); 187 reporter.check(sysIDStream.getSystemId(), "real-system-id", "StreamSource(sysID) has SystemId " + sysIDStream.getSystemId()); 188 189 StreamSource wackyStream = new StreamSource(); 190 wackyStream.setInputStream(bais); 191 InputStream gotStream = wackyStream.getInputStream(); 192 reporter.checkObject(gotStream, bais, "set/getInputStream API coverage"); 193 194 wackyStream.setReader(strReader); 195 Reader gotReader = wackyStream.getReader(); 196 reporter.checkObject(gotReader, strReader, "set/getReader API coverage"); 197 198 wackyStream.setSystemId("new-system-id"); 199 String gotSystemId = wackyStream.getSystemId(); 200 reporter.check(gotSystemId, "new-system-id", "set/getSystemId API coverage"); 201 202 wackyStream.setPublicId("new-public-id"); 203 String gotPublicId = wackyStream.getPublicId(); 204 reporter.check(gotPublicId, "new-public-id", "set/getPublicId API coverage"); 205 206 reporter.testCaseClose(); 207 return true; 208 } 209 210 211 /** 212 * Basic functionality of StreamSources. 213 * 214 * @return false if we should abort the test; true otherwise 215 */ testCase2()216 public boolean testCase2() 217 { 218 reporter.testCaseInit("Basic functionality of StreamSources"); 219 220 TransformerFactory factory = null; 221 String xslID = testFileInfo.inputName; 222 String xmlID = testFileInfo.xmlName; 223 try 224 { 225 factory = TransformerFactory.newInstance(); 226 factory.setErrorListener(new DefaultErrorHandler()); 227 // Create URLs for the filenames 228 // What's the simplest way to do this?!? i.e. as a solution 229 // to the general problem of having a String denoting a 230 // path/filename, that may be absolute or relative, 231 // and may or may not exist, and to get a valid file: URL? 232 reporter.logTraceMsg("Original names xslID=" + xslID + ", xmlID=" + xmlID); 233 xslID = filenameToURI(xslID); 234 xmlID = filenameToURI(xmlID); 235 reporter.logTraceMsg("URL-ized names xslID=" + xslID + ", xmlID=" + xmlID); 236 } 237 catch (Throwable t) 238 { 239 reporter.checkFail("Problem creating factory; can't continue testcase"); 240 reporter.logThrowable(reporter.ERRORMSG, t, 241 "Problem creating factory; can't continue testcase"); 242 return true; 243 } 244 try 245 { 246 // Verify we can do basic transforms with readers/streams 247 reporter.logTraceMsg("Create stream sources and setSystemId separately"); 248 InputStream xslStream1 = new FileInputStream(testFileInfo.inputName); 249 Source xslSource1 = new StreamSource(xslStream1); 250 xslSource1.setSystemId(xslID); 251 InputStream xmlStream1 = new FileInputStream(testFileInfo.xmlName); 252 Source xmlSource1 = new StreamSource(xmlStream1); 253 xmlSource1.setSystemId(xmlID); 254 255 reporter.logTraceMsg("Create FileOutputStream to " + outNames.nextName()); 256 FileOutputStream fos1 = new FileOutputStream(outNames.currentName()); 257 Result result1 = new StreamResult(fos1); 258 Templates templates1 = factory.newTemplates(xslSource1); 259 Transformer transformer1 = templates1.newTransformer(); 260 transformer1.setErrorListener(new DefaultErrorHandler()); 261 reporter.logTraceMsg("about to transform to streams after setSystemId"); 262 transformer1.transform(xmlSource1, result1); 263 fos1.close(); // must close ostreams we own 264 int result = fileChecker.check(reporter, 265 new File(outNames.currentName()), 266 new File(testFileInfo.goldName), 267 "transform to streams after setSystemId into " + outNames.currentName()); 268 if (result == reporter.FAIL_RESULT) 269 reporter.logInfoMsg("transform to streams... failure reason:" + fileChecker.getExtendedInfo()); 270 } 271 catch (Throwable t) 272 { 273 reporter.checkFail("Problem with transform-streams(1)"); 274 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with transform-streams(1)"); 275 } 276 try 277 { 278 reporter.logTraceMsg("Create stream sources with setSystemId in ctor"); 279 InputStream xslStream2 = new FileInputStream(testFileInfo.inputName); 280 Source xslSource2 = new StreamSource(xslStream2, xslID); 281 InputStream xmlStream2 = new FileInputStream(testFileInfo.xmlName); 282 Source xmlSource2 = new StreamSource(xmlStream2, xmlID); 283 FileOutputStream fos2 = new FileOutputStream(outNames.nextName()); 284 Result result2 = new StreamResult(fos2); 285 286 reporter.logInfoMsg("Transform into " + outNames.currentName()); 287 Templates templates2 = factory.newTemplates(xslSource2); 288 Transformer transformer2 = templates2.newTransformer(); 289 transformer2.setErrorListener(new DefaultErrorHandler()); 290 transformer2.transform(xmlSource2, result2); 291 fos2.close(); // must close ostreams we own 292 int result = fileChecker.check(reporter, 293 new File(outNames.currentName()), 294 new File(testFileInfo.goldName), 295 "transform to streams after SystemId in ctor into " + outNames.currentName()); 296 if (result == reporter.FAIL_RESULT) 297 reporter.logInfoMsg("transform to streams... failure reason:" + fileChecker.getExtendedInfo()); 298 } 299 catch (Throwable t) 300 { 301 reporter.checkFail("Problem with transform-streams(2)"); 302 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with transform-streams(2)"); 303 } 304 305 try 306 { 307 // Do a transform without systemId set 308 // Note: is affected by user.dir property; if we're 309 // already in the correct place, this won't be different 310 // But: most people will run from xml-xalan\test, so this should fail 311 try 312 { 313 reporter.logStatusMsg("System.getProperty(user.dir) = " + System.getProperty("user.dir")); 314 } 315 catch (SecurityException e) // in case of Applet context 316 { 317 reporter.logTraceMsg("System.getProperty(user.dir) threw SecurityException"); 318 } 319 reporter.logTraceMsg("Create stream sources without setSystemId set"); 320 InputStream xslStream3 = new FileInputStream(testFileInfo.inputName); 321 Source xslSource3 = new StreamSource(xslStream3); 322 InputStream xmlStream3 = new FileInputStream(testFileInfo.xmlName); 323 Source xmlSource3 = new StreamSource(xmlStream3); 324 FileOutputStream fos3 = new FileOutputStream(outNames.nextName()); 325 Result result3 = new StreamResult(fos3); 326 327 Templates templates3 = factory.newTemplates(xslSource3); 328 Transformer transformer3 = templates3.newTransformer(); 329 transformer3.setErrorListener(new DefaultErrorHandler()); 330 reporter.logStatusMsg("About to transform without systemID; probably throws exception"); 331 transformer3.transform(xmlSource3, result3); 332 reporter.checkFail("The above transform should probably have thrown an exception; into " + outNames.currentName()); 333 } 334 catch (Throwable t) 335 { 336 reporter.checkPass("Transforming with include/import and wrong SystemId throws exception; into " + outNames.currentName()); 337 reporter.logThrowable(reporter.ERRORMSG, t, "Transforming with include/import and wrong SystemId"); 338 } 339 340 reporter.testCaseClose(); 341 return true; 342 } 343 344 345 /** 346 * Worker method to translate String to URI. 347 * Note: Xerces and Crimson appear to handle some URI references 348 * differently - this method needs further work once we figure out 349 * exactly what kind of format each parser wants (esp. considering 350 * relative vs. absolute references). 351 * @param String path\filename of test file 352 * @return URL to pass to SystemId 353 */ filenameToURI(String filename)354 public String filenameToURI(String filename) 355 { 356 File f = new File(filename); 357 String tmp = f.getAbsolutePath(); 358 if (File.separatorChar == '\\') { 359 tmp = tmp.replace('\\', '/'); 360 } 361 return "file:///" + tmp; 362 } 363 364 365 /** 366 * Convenience method to print out usage information - update if needed. 367 * @return String denoting usage of this test class 368 */ usage()369 public String usage() 370 { 371 return ("Common [optional] options supported by StreamSourceAPITest:\n" 372 + "(Note: assumes inputDir=.\\tests\\api)\n" 373 + super.usage()); // Grab our parent classes usage as well 374 } 375 376 377 /** 378 * Main method to run test from the command line - can be left alone. 379 * @param args command line argument array 380 */ main(String[] args)381 public static void main(String[] args) 382 { 383 384 StreamSourceAPITest app = new StreamSourceAPITest(); 385 386 app.doMain(args); 387 } 388 } 389