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 * StreamResultAPITest.java 25 * 26 */ 27 package org.apache.qetest.trax.stream; 28 29 import java.io.ByteArrayOutputStream; 30 import java.io.CharArrayWriter; 31 import java.io.File; 32 import java.io.FileInputStream; 33 import java.io.FileOutputStream; 34 import java.io.OutputStream; 35 import java.io.OutputStreamWriter; 36 import java.io.PrintStream; 37 import java.io.StringWriter; 38 import java.io.Writer; 39 import java.util.Properties; 40 41 import javax.xml.transform.Result; 42 import javax.xml.transform.Source; 43 import javax.xml.transform.Templates; 44 import javax.xml.transform.Transformer; 45 import javax.xml.transform.TransformerFactory; 46 import javax.xml.transform.stream.StreamResult; 47 import javax.xml.transform.stream.StreamSource; 48 49 import org.apache.xml.utils.DefaultErrorHandler; 50 import org.apache.qetest.FileBasedTest; 51 import org.apache.qetest.OutputNameManager; 52 import org.apache.qetest.Reporter; 53 import org.apache.qetest.xsl.XHTFileCheckService; 54 import org.apache.qetest.xsl.XSLTestfileInfo; 55 56 //------------------------------------------------------------------------- 57 58 /** 59 * API Coverage test for the StreamResult class of TRAX.. 60 * @author shane_curcuru@lotus.com 61 * @version $Id$ 62 */ 63 public class StreamResultAPITest extends FileBasedTest 64 { 65 66 /** 67 * Provides nextName(), currentName() functionality for tests 68 * that may produce any number of output files. 69 */ 70 protected OutputNameManager outNames; 71 72 /** StreamImpIncl for testing systemId stuff. */ 73 protected XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); 74 75 /** StreamOutputFormat for testing types of output streams. */ 76 protected XSLTestfileInfo outputFileInfo = new XSLTestfileInfo(); 77 78 /** Subdirectory under test\tests\api for our xsl/xml files. */ 79 public static final String TRAX_STREAM_SUBDIR = "trax" + File.separator + "stream"; 80 81 82 /** Just initialize test name, comment, numTestCases. */ StreamResultAPITest()83 public StreamResultAPITest() 84 { 85 numTestCases = 2; // REPLACE_num 86 testName = "StreamResultAPITest"; 87 testComment = "API Coverage test for the StreamResult class of TRAX."; 88 } 89 90 91 /** 92 * Initialize this test - Set names of xml/xsl test files. 93 * 94 * @param p Properties to initialize from (if needed) 95 * @return false if we should abort the test; true otherwise 96 */ doTestFileInit(Properties p)97 public boolean doTestFileInit(Properties p) 98 { 99 // NOTE: 'reporter' variable is already initialized at this point 100 101 // Used for all tests; just dump files in trax subdir 102 File outSubDir = new File(outputDir + File.separator + TRAX_STREAM_SUBDIR); 103 if (!outSubDir.mkdirs()) 104 reporter.logWarningMsg("Could not create output dir: " + outSubDir); 105 // Initialize an output name manager to that dir with .out extension 106 outNames = new OutputNameManager(outputDir + File.separator + TRAX_STREAM_SUBDIR 107 + File.separator + testName, ".out"); 108 109 String testBasePath = inputDir 110 + File.separator 111 + TRAX_STREAM_SUBDIR 112 + File.separator; 113 String goldBasePath = goldDir 114 + File.separator 115 + TRAX_STREAM_SUBDIR 116 + File.separator; 117 118 testFileInfo.inputName = testBasePath + "StreamImpIncl.xsl"; 119 testFileInfo.xmlName = testBasePath + "StreamImpIncl.xml"; 120 testFileInfo.goldName = goldBasePath + "StreamImpIncl.out"; 121 outputFileInfo.inputName = testBasePath + "StreamOutputFormat.xsl"; 122 outputFileInfo.xmlName = testBasePath + "StreamOutputFormat.xml"; 123 outputFileInfo.goldName = goldBasePath + "StreamOutputFormat.out"; 124 try 125 { 126 TransformerFactory tf = TransformerFactory.newInstance(); 127 if (!(tf.getFeature(StreamSource.FEATURE) 128 && tf.getFeature(StreamResult.FEATURE))) 129 { // The rest of this test relies on Streams 130 reporter.logErrorMsg("Streams not supported! Some tests may be invalid!"); 131 } 132 } 133 catch (Throwable t) 134 { 135 reporter.checkFail( 136 "Problem creating factory; Some tests may be invalid!"); 137 reporter.logThrowable(reporter.ERRORMSG, t, 138 "Problem creating factory; Some tests may be invalid!"); 139 } 140 141 return true; 142 } 143 144 145 /** 146 * Basic API coverage, constructor and set/get methods. 147 * 148 * @return false if we should abort the test; true otherwise 149 */ testCase1()150 public boolean testCase1() 151 { 152 reporter.testCaseInit("Basic API coverage, constructor and set/get methods"); 153 154 reporter.logWarningMsg("public StreamResult(File f) not yet tested"); 155 156 // Default no-arg ctor sets nothing 157 StreamResult defaultStream = new StreamResult(); 158 reporter.checkObject(defaultStream.getOutputStream(), null, "Default StreamResult should have null ByteStream"); 159 reporter.checkObject(defaultStream.getWriter(), null, "Default StreamResult should have null CharacterStream"); 160 reporter.check(defaultStream.getSystemId(), null, "Default StreamResult should have null SystemId"); 161 162 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 163 StreamResult byteResult1 = new StreamResult(baos); 164 reporter.checkObject(byteResult1.getOutputStream(), baos, "StreamResult(os) has ByteStream " + byteResult1.getOutputStream()); 165 reporter.checkObject(byteResult1.getWriter(), null, "StreamResult(os) should have null CharacterStream"); 166 reporter.check(byteResult1.getSystemId(), null, "StreamResult(os) should have null SystemId"); 167 168 StringWriter strWriter = new StringWriter(); 169 StreamResult readerResult1 = new StreamResult(strWriter); 170 reporter.checkObject(readerResult1.getOutputStream(), null, "StreamResult(writer) should have null ByteStream"); 171 reporter.checkObject(readerResult1.getWriter(), strWriter, "StreamResult(writer) has CharacterStream " + readerResult1.getWriter()); 172 reporter.check(readerResult1.getSystemId(), null, "StreamResult(writer) should have null SystemId"); 173 174 StreamResult wackyStream = new StreamResult(); 175 wackyStream.setOutputStream(baos); 176 OutputStream gotStream = wackyStream.getOutputStream(); 177 reporter.checkObject(gotStream, baos, "set/getOutputStream API coverage"); 178 179 wackyStream.setWriter(strWriter); 180 Writer gotWriter = wackyStream.getWriter(); 181 reporter.checkObject(gotWriter, strWriter, "set/getWriter API coverage"); 182 183 wackyStream.setSystemId("new-system-id"); 184 String gotSystemId = wackyStream.getSystemId(); 185 reporter.check(gotSystemId, "new-system-id", "set/getSystemId API coverage"); 186 187 reporter.testCaseClose(); 188 return true; 189 } 190 191 192 /** 193 * Basic functionality of StreamResults. 194 * 195 * @return false if we should abort the test; true otherwise 196 */ testCase2()197 public boolean testCase2() 198 { 199 reporter.testCaseInit("Basic functionality of StreamResults"); 200 201 TransformerFactory factory = null; 202 Source xslSource = null; 203 Source xmlSource = null; 204 Templates templates = null; 205 try 206 { 207 factory = TransformerFactory.newInstance(); 208 factory.setErrorListener(new DefaultErrorHandler()); 209 // Create re-useable sources 210 xslSource = new StreamSource(new FileInputStream(outputFileInfo.inputName)); 211 reporter.logTraceMsg("Create stream sources, templates"); 212 templates = factory.newTemplates(xslSource); 213 } 214 catch (Throwable t) 215 { 216 reporter.checkFail("Problem creating factory; can't continue testcase"); 217 reporter.logThrowable(reporter.ERRORMSG, t, 218 "Problem creating factory; can't continue testcase"); 219 return true; 220 } 221 222 try 223 { 224 // Test some OutputStreams 225 // Simple FileOutputStream is tested in numerous other tests 226 Transformer transformer = templates.newTransformer(); 227 transformer.setErrorListener(new DefaultErrorHandler()); 228 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 229 Result result1 = new StreamResult(baos); 230 reporter.logTraceMsg("About to Transform into ByteArrayOutputStream"); 231 232 // Note: must get a new xmlSource for each transform 233 // Should this really be necessary? I suppose 234 // FileInputStreams don't just get 'reset' for you, 235 // but it would be nice to reuse the StreamSources 236 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 237 transformer.transform(xmlSource, result1); 238 reporter.logTraceMsg("baos.size() is: " + baos.size()); 239 240 ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); 241 PrintStream ps = new PrintStream(baos2); 242 Result result2 = new StreamResult(ps); 243 reporter.logTraceMsg("About to Transform into PrintStream"); 244 245 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 246 transformer.transform(xmlSource, result2); 247 reporter.logTraceMsg("ps(baos2).size() is: " + baos2.size()); 248 249 if (!reporter.checkString(baos.toString(), baos2.toString(), "BAOS and PS output comparison")) 250 { 251 reporter.logArbitrary(reporter.TRACEMSG, "baos was: " + baos.toString()); 252 reporter.logArbitrary(reporter.TRACEMSG, "ps(baos2) was: " + baos2.toString()); 253 } 254 writeFileAndValidate(baos.toString("UTF-8"), outputFileInfo.goldName); 255 } 256 catch (Throwable t) 257 { 258 reporter.checkFail("Problem with transform-streams(1)"); 259 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with transform-streams(1)"); 260 } 261 262 try 263 { 264 // Test some Writers 265 Transformer transformer = templates.newTransformer(); 266 transformer.setErrorListener(new DefaultErrorHandler()); 267 StringWriter sw = new StringWriter(); 268 Result result1 = new StreamResult(sw); 269 reporter.logTraceMsg("About to Transform into StringWriter"); 270 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 271 transformer.transform(xmlSource, result1); 272 273 CharArrayWriter cw = new CharArrayWriter(); 274 Result result2 = new StreamResult(cw); 275 reporter.logTraceMsg("About to Transform into CharArrayWriter"); 276 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 277 transformer.transform(xmlSource, result2); 278 279 if (!reporter.checkString(sw.toString(), cw.toString(), "SW and CW output comparison")) 280 { 281 reporter.logArbitrary(reporter.TRACEMSG, "sw was: " + sw.toString()); 282 reporter.logArbitrary(reporter.TRACEMSG, "cw was: " + cw.toString()); 283 } 284 writeFileAndValidate(sw.toString(), outputFileInfo.goldName); 285 } 286 catch (Throwable t) 287 { 288 reporter.checkFail("Problem with transform-streams(2)"); 289 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with transform-streams(2)"); 290 } 291 292 try 293 { 294 // Test with systemId set 295 // Note: may be affected by user.dir property; if we're 296 // already in the correct place, this won't be different 297 try 298 { 299 reporter.logTraceMsg("System.getProperty(user.dir) = " + System.getProperty("user.dir")); 300 } 301 catch (SecurityException e) // in case of Applet context 302 { 303 reporter.logTraceMsg("System.getProperty(user.dir) threw SecurityException"); 304 } 305 Transformer transformer = templates.newTransformer(); 306 transformer.setErrorListener(new DefaultErrorHandler()); 307 StringWriter sw1 = new StringWriter(); 308 Result result1 = new StreamResult(sw1); 309 reporter.logTraceMsg("About to Transform into StringWriter w/out systemId set"); 310 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 311 transformer.transform(xmlSource, result1); 312 313 StringWriter sw2 = new StringWriter(); 314 Result result2 = new StreamResult(sw2); 315 result2.setSystemId("random-system-id"); 316 reporter.logTraceMsg("About to Transform into StringWriter w/ systemId set"); 317 xmlSource = new StreamSource(new FileInputStream(outputFileInfo.xmlName)); 318 transformer.transform(xmlSource, result2); 319 reporter.check(result2.getSystemId(), "random-system-id", "systemId remains set after transform"); 320 321 if (!reporter.checkString(sw1.toString(), sw2.toString(), "Output comparison, with/without systemId")) 322 { 323 reporter.logArbitrary(reporter.TRACEMSG, "sw1 w/out systemId was: " + sw1.toString()); 324 reporter.logArbitrary(reporter.TRACEMSG, "sw2 w/ systemId was: " + sw2.toString()); 325 } 326 writeFileAndValidate(sw1.toString(), outputFileInfo.goldName); 327 reporter.logInfoMsg("@todo we should update XHTComparator for bogus systemId's like we have in this test"); 328 // @todo we should update XHTComparator for bogus systemId's like we have in this test 329 // Note that using XHTFileCheckService, it always compares our 330 // outputs using [text] since the XML parser usually throws: 331 // warning;org.xml.sax.SAXParseException: File "file:/E:/builds/xml-xalan/test/tests/api-gold/trax/stream/this-is-doctype-system" not found. 332 if (reporter.getLoggingLevel() >= Reporter.TRACEMSG) 333 { 334 reporter.logArbitrary(reporter.TRACEMSG, fileChecker.getExtendedInfo()); 335 } 336 } 337 catch (Throwable t) 338 { 339 reporter.checkFail("Problem with transform-streams(3)"); 340 reporter.logThrowable(reporter.ERRORMSG, t, "Problem with transform-streams(3)"); 341 } 342 343 reporter.testCaseClose(); 344 return true; 345 } 346 347 348 /** 349 * Worker method to dump a string to a file and validate it. 350 * @return true if OK, false otherwise 351 */ writeFileAndValidate(String data, String goldFile)352 public void writeFileAndValidate(String data, String goldFile) 353 { 354 try 355 { 356 FileOutputStream fos = new FileOutputStream(outNames.nextName()); 357 OutputStreamWriter fw = new OutputStreamWriter(fos, "UTF-8"); 358 fw.write(data); 359 fw.close(); 360 // Explicitly ask that Validation be turned off, since 361 // we use bogus systemids 362 fileChecker.setAttribute(XHTFileCheckService.SETVALIDATING, "false"); 363 fileChecker.check(reporter, 364 new File(outNames.currentName()), 365 new File(goldFile), 366 "writeStringToFile() checking: " + outNames.currentName()); 367 } 368 catch (Exception e) 369 { 370 reporter.checkFail("writeStringToFile() threw: " + e.toString()); 371 reporter.logThrowable(Reporter.ERRORMSG, e, "writeStringToFile() threw"); 372 } 373 } 374 375 376 /** 377 * Convenience method to print out usage information - update if needed. 378 * @return String denoting usage of this test class 379 */ usage()380 public String usage() 381 { 382 return ("Common [optional] options supported by StreamResultAPITest:\n" 383 + "(Note: assumes inputDir=.\\tests\\api)\n" 384 + "REPLACE_any_new_test_arguments\n" 385 + super.usage()); // Grab our parent classes usage as well 386 } 387 388 389 /** 390 * Main method to run test from the command line - can be left alone. 391 * @param args command line argument array 392 */ main(String[] args)393 public static void main(String[] args) 394 { 395 396 StreamResultAPITest app = new StreamResultAPITest(); 397 398 app.doMain(args); 399 } 400 } 401