You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by vh...@apache.org on 2001/04/13 23:17:03 UTC

cvs commit: xml-batik/test-sources/org/apache/batik/test/xml XSLXMLReportConsumer.java XMLTestReportProcessor.java XMLTestSuiteRunner.java

vhardy      01/04/13 14:17:03

  Modified:    test-sources/org/apache/batik/test/svg
                        SVGRenderingAccuracyTest.java
               test-sources/org/apache/batik/test/xml
                        XMLTestReportProcessor.java XMLTestSuiteRunner.java
  Added:       test-sources/org/apache/batik/test/xml
                        XSLXMLReportConsumer.java
  Log:
  Improved SVGRenderingAccuracyTest, XMLTestSuiteRunner and
  XMLTestReportProcessor. Now can generate HTML report with
  XSL stylesheet.
  
  Revision  Changes    Path
  1.4       +139 -14   xml-batik/test-sources/org/apache/batik/test/svg/SVGRenderingAccuracyTest.java
  
  Index: SVGRenderingAccuracyTest.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/test-sources/org/apache/batik/test/svg/SVGRenderingAccuracyTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SVGRenderingAccuracyTest.java	2001/04/12 21:40:05	1.3
  +++ SVGRenderingAccuracyTest.java	2001/04/13 21:17:02	1.4
  @@ -14,12 +14,28 @@
   import java.io.FileOutputStream;
   import java.io.InputStream;
   import java.io.IOException;
  +import java.io.StringWriter;
  +import java.io.PrintWriter;
   
   import java.net.URL;
   
   import java.util.Locale;
   import java.util.ResourceBundle;
  +import java.util.Vector;
   
  +import java.awt.Color;
  +import java.awt.Graphics2D;
  +import java.awt.image.BufferedImage;
  +
  +import org.apache.batik.ext.awt.image.CompositeRule;
  +import org.apache.batik.ext.awt.image.rendered.CompositeRed;
  +import org.apache.batik.ext.awt.image.rendered.BufferedImageCachableRed;
  +
  +import org.apache.batik.ext.awt.image.ImageLoader;
  +
  +import org.apache.batik.ext.awt.image.codec.PNGImageEncoder;
  +import org.apache.batik.ext.awt.image.codec.PNGEncodeParam;
  +
   import org.apache.batik.transcoder.TranscoderException;
   import org.apache.batik.transcoder.TranscoderInput;
   import org.apache.batik.transcoder.TranscoderOutput;
  @@ -40,7 +56,7 @@
    * all pixel values are the same).
    *
    * @author <a href="mailto:vhardy@apache.lorg">Vincent Hardy</a>
  - * @version $Id: SVGRenderingAccuracyTest.java,v 1.3 2001/04/12 21:40:05 vhardy Exp $
  + * @version $Id: SVGRenderingAccuracyTest.java,v 1.4 2001/04/13 21:17:02 vhardy Exp $
    */
   public class SVGRenderingAccuracyTest implements Test{
       /**
  @@ -106,17 +122,34 @@
       public static final String ENTRY_KEY_ERROR_DESCRIPTION 
           = "SVGRenderingAccuracyTest.entry.key.error.description";
   
  +    /**
  +     * Entry describing the reference/generated image file
  +     */
  +    public static final String ENTRY_KEY_REFERENCE_GENERATED_IMAGE_URI
  +        = "SVGRenderingAccuracyTest.entry.key.reference.generated.image.file";
  +
  +    /**
  +     * Entry describing the generated difference image
  +     */
  +    public static final String ENTRY_KEY_DIFFERENCE_IMAGE
  +        = "SVGRenderingAccuracyTest.entry.key.difference.image";
  +
       /**
  -     * Entry describing the reference image URL
  +     * Entry describing that an internal error occured while
  +     * generating the test failure description
        */
  -    public static final String ENTRY_KEY_REFERENCE_IMAGE_URI
  -        = "SVGRenderingAccuracyTest.entry.key.reference.image.uri";
  +    public static final String ENTRY_KEY_INTERNAL_ERROR
  +        = "SVGRenderingAccuracyTest.entry.key.internal.error";
   
       /**
  -     * Entry describing the generated image 
  +     * Messages expressing that comparison images could not be
  +     * created:
  +     * {0} : exception class
  +     * {1} : exception message
  +     * {2} : exception stack trace.
        */
  -    public static final String ENTRY_KEY_TEMPORARY_FILE
  -        = "SVGRenderingAccuracyTest.entry.key.temporary.file";
  +    public static final String COULD_NOT_GENERATE_COMPARISON_IMAGES
  +        = "SVGRenderingAccuracyTest.message.error.could.not.generate.comparison.images";
   
       /**
        * The gui resources file name
  @@ -325,14 +358,35 @@
           // If the files differ, return an error
           //
           if(!accurate){
  +            // Build two images:
  +            // a. One with the reference image and the newly generated image
  +            // b. One with the difference between the two images and the set of 
  +            //    different pixels.
               report.setErrorCode(ERROR_SVG_RENDERING_NOT_ACCURATE);
  -            report.setDescription(new TestReport.Entry[]{
  -                new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_ERROR_DESCRIPTION, null),
  -                                     Messages.formatMessage(ERROR_SVG_RENDERING_NOT_ACCURATE, null)),
  -                new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_REFERENCE_IMAGE_URI, null),
  -                                     refImgURL),
  -                new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_TEMPORARY_FILE, null),
  -                                     tmpFile) });
  +            try{
  +                File cmpDiffFile[] = buildCompareAndDiffImages(refImgURL, tmpFile);
  +                
  +                report.setDescription(new TestReport.Entry[]{
  +                    new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_ERROR_DESCRIPTION, null),
  +                                         Messages.formatMessage(ERROR_SVG_RENDERING_NOT_ACCURATE, null)),
  +                    new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_REFERENCE_GENERATED_IMAGE_URI, null),
  +                                         cmpDiffFile[0]),
  +                    new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_DIFFERENCE_IMAGE, null),
  +                                         cmpDiffFile[1]) });
  +            }catch(IOException e){
  +                StringWriter trace = new StringWriter();
  +                e.printStackTrace(new PrintWriter(trace));
  +                
  +                report.setDescription(new TestReport.Entry[]{
  +                    new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_ERROR_DESCRIPTION, null),
  +                                         Messages.formatMessage(ERROR_SVG_RENDERING_NOT_ACCURATE, null)),
  +                    new TestReport.Entry(Messages.formatMessage(ENTRY_KEY_INTERNAL_ERROR, null),
  +                                         Messages.formatMessage(COULD_NOT_GENERATE_COMPARISON_IMAGES, 
  +                                                                new Object[]{e.getClass().getName(),
  +                                                                             e.getMessage(),
  +                                                                             trace.toString()})) });
  +            }
  +            
               report.setPassed(false);
               return report;
           }
  @@ -343,6 +397,77 @@
           //
           report.setPassed(true);
           return report;
  +    }
  +
  +    /**
  +     * This method builds two images from the two input images:
  +     * + One with the 2 input images side by side
  +     * + One with the differences between the two images.
  +     */
  +    protected File[] buildCompareAndDiffImages(URL refImgURL,
  +                                               File generatedFile) 
  +        throws IOException 
  +    {
  +        BufferedImage ref = ImageLoader.loadImage(refImgURL,
  +                                                  BufferedImage.TYPE_INT_ARGB);
  +
  +        BufferedImage gen = ImageLoader.loadImage(generatedFile,
  +                                                  BufferedImage.TYPE_INT_ARGB);
  +
  +        BufferedImage cmp = new BufferedImage(ref.getWidth()*2,
  +                                              ref.getHeight(),
  +                                              BufferedImage.TYPE_INT_ARGB);
  +
  +        Graphics2D g = cmp.createGraphics();
  +        g.setPaint(Color.white);
  +        g.fillRect(0, 0, cmp.getWidth(), cmp.getHeight());
  +        g.drawImage(ref, 0, 0, null);
  +        g.translate(ref.getWidth(), 0);
  +        g.drawImage(gen, 0, 0, null);
  +        g.dispose();
  +
  +        BufferedImage diff = new BufferedImage(ref.getWidth(),
  +                                               ref.getHeight(),
  +                                               BufferedImage.TYPE_INT_ARGB);
  +
  +        Vector src = new Vector();
  +        src.addElement(new BufferedImageCachableRed(ref));
  +        src.addElement(new BufferedImageCachableRed(gen));
  +
  +        CompositeRed cr = new CompositeRed(src,
  +                                            new CompositeRule(0, 1, -1, 0));
  +        /*g = diff.createGraphics();
  +        g.setPaint(Color.white);
  +        g.fillRect(0, 0, diff.getWidth(), diff.getHeight());
  +        g.drawImage(ref, 0, 0, null);
  +        g.setXORMode(Color.white);
  +        g.drawImage(gen, 0, 0, null);*/
  +        cr.copyToRaster(diff.getRaster());
  +
  +        return new File[] { imageToFile(cmp),
  +                            imageToFile(diff) };
  +    }
  +
  +    /**
  +     * Creates a temporary File into which the input image is
  +     * saved.
  +     */
  +    protected File imageToFile(BufferedImage img)
  +        throws IOException {
  +
  +        File imgFile 
  +            = File.createTempFile(TEMP_FILE_PREFIX,
  +                                  TEMP_FILE_SUFFIX,
  +                                  null);
  +        imgFile.deleteOnExit();
  +
  +        PNGImageEncoder encoder 
  +            = new PNGImageEncoder(new FileOutputStream(imgFile),
  +                             PNGEncodeParam.getDefaultEncodeParam(img));
  +
  +        encoder.encode(img);
  +
  +        return imgFile;
       }
   
       /**
  
  
  
  1.3       +50 -10    xml-batik/test-sources/org/apache/batik/test/xml/XMLTestReportProcessor.java
  
  Index: XMLTestReportProcessor.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/test-sources/org/apache/batik/test/xml/XMLTestReportProcessor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLTestReportProcessor.java	2001/04/10 23:27:42	1.2
  +++ XMLTestReportProcessor.java	2001/04/13 21:17:02	1.3
  @@ -42,14 +42,28 @@
    * converts the <tt>TestReports</tt> it processes into an 
    * XML document that it outputs in a directory. The directory
    * used by the object can be configured at creation time.
  + * <br />
  + * The <tt>XMLTestReportProcessor</tt> can optionally notify a 
  + * report consumer of the XML file it created.
    *
    * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
  - * @version $Id: XMLTestReportProcessor.java,v 1.2 2001/04/10 23:27:42 vhardy Exp $
  + * @version $Id: XMLTestReportProcessor.java,v 1.3 2001/04/13 21:17:02 vhardy Exp $
    */
   public class XMLTestReportProcessor 
       implements TestReportProcessor,
                  XTRConstants {
       /**
  +     * An <tt>XMLReportConsumer</tt> is notified every time a 
  +     * new report is generated by an <tt>XMLTestReportProcessor</tt>
  +     */
  +    public static interface XMLReportConsumer {
  +        /**
  +         * Invoked when new report has been generated.
  +         */
  +        public void onNewReport(File xmlReport) throws Exception ;
  +    }
  +
  +    /**
        * Prefix for the files created by this processor
        */
       public static final String XML_TEST_REPORT_PREFIX
  @@ -88,6 +102,26 @@
   								 
   
       /**
  +     * The XMLReportConsumer instance is notified whenever 
  +     * this object generates a new report.
  +     */
  +    protected XMLReportConsumer consumer;
  +
  +    /**
  +     * Default constructor
  +     */
  +    public XMLTestReportProcessor(){
  +    }
  +
  +    /**
  +     * @param reportConsumer consumer for the XML report generated
  +     *        by this object. May be null.
  +     */
  +    public XMLTestReportProcessor(XMLTestReportProcessor.XMLReportConsumer consumer){
  +        this.consumer = consumer;
  +    }
  +
  +    /**
        * Recursively processes the input <tt>TestReport</tt> and
        * any of its children.
        */
  @@ -110,7 +144,11 @@
               
               processReport(report, root, document);
               
  -            serializeReport(root);
  +            File xmlReport = serializeReport(root);
  +
  +            if(consumer != null){
  +                consumer.onNewReport(xmlReport);
  +            }
   
           } catch(Exception e) {
               StringWriter sw = new StringWriter();
  @@ -131,12 +169,12 @@
       public File getReportDirectory()
           throws IOException {
           File file = new File(XML_TEST_REPORT_DEFAULT_DIRECTORY);
  -				if( !file.exists() ){
  -					throw new IOException(Messages.formatMessage(REPORT_DIRECTORY_DOES_NOT_EXIST, 
  -																											new Object[]{XML_TEST_REPORT_DEFAULT_DIRECTORY}));
  -				}
  -
  -				return file;
  +        if( !file.exists() ){
  +            throw new IOException(Messages.formatMessage(REPORT_DIRECTORY_DOES_NOT_EXIST, 
  +                                                         new Object[]{XML_TEST_REPORT_DEFAULT_DIRECTORY}));
  +        }
  +        
  +        return file;
       }
   
       /**
  @@ -255,7 +293,7 @@
               
               entryElement.setAttributeNS(null, 
                                           XTR_VALUE_ATTRIBUTE,
  -                                        tmpFileCopy.getAbsolutePath());
  +                                        tmpFileCopy.toURL().toString());
   
           }
           else {
  @@ -297,7 +335,7 @@
       /**
        * Saves the XML document into a file
        */
  -    protected void serializeReport(Element reportElement) throws IOException {
  +    protected File serializeReport(Element reportElement) throws IOException {
           //
           // First, create a new File
           //
  @@ -313,6 +351,8 @@
                            fw);
   
           fw.close();
  +
  +        return tmpFile;
       }
   
       
  
  
  
  1.3       +45 -13    xml-batik/test-sources/org/apache/batik/test/xml/XMLTestSuiteRunner.java
  
  Index: XMLTestSuiteRunner.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/test-sources/org/apache/batik/test/xml/XMLTestSuiteRunner.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLTestSuiteRunner.java	2001/04/11 01:33:12	1.2
  +++ XMLTestSuiteRunner.java	2001/04/13 21:17:02	1.3
  @@ -48,7 +48,7 @@
    * <tt>Test</tt> and <tt>TestSuite</tt> objects.
    *
    * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
  - * @version $Id: XMLTestSuiteRunner.java,v 1.2 2001/04/11 01:33:12 vhardy Exp $
  + * @version $Id: XMLTestSuiteRunner.java,v 1.3 2001/04/13 21:17:02 vhardy Exp $
    */
   public class XMLTestSuiteRunner implements XTSConstants{
       /**
  @@ -248,28 +248,60 @@
           }
           
           Constructor constructor 
  -            = cl.getDeclaredConstructor(argsClasses);
  +            = getDeclaredConstructor(cl, argsClasses);
           
           return constructor.newInstance(argsArray);
       }
   
       /**
  +     * Returns a constructor that has can be used for the input class
  +     * types.
  +     */
  +    protected Constructor getDeclaredConstructor(Class cl,
  +                                                 Class[] argClasses){
  +        Constructor[] cs = cl.getDeclaredConstructors();
  +        for(int i=0; i<cs.length; i++){
  +            Class[] reqArgClasses = cs[i].getParameterTypes();
  +            if(reqArgClasses.length == argClasses.length){
  +                int j=0;
  +                for(; j<argClasses.length; j++){
  +                    if(!reqArgClasses[j].isAssignableFrom(argClasses[j])){
  +                        break;
  +                    }
  +                }
  +                if(j == argClasses.length){
  +                    return cs[i];
  +                }
  +            }
  +        }
  +
  +        return null;
  +    }
  +
  +    /**
        * Limitation: Arguments *must* have a String based
  -     * constructor.
  +     * constructor. Or be an object that takes a set of string
  +     * based arguments.
        */
       public Object buildArgument(Element element) throws Exception {
  -        String type = element.getAttributeNS(null,
  +        String classAttr = element.getAttributeNS(null,
                                                XTS_CLASS_ATTRIBUTE);
   
  -        String value = element.getAttributeNS(null,
  -                                              XTS_VALUE_ATTRIBUTE);
  -
  -        Class cl = Class.forName(type);
  -        
  -        Constructor constructor 
  -            = cl.getDeclaredConstructor(new Class[] { String.class });
  -
  -        return constructor.newInstance(new Object[] {value});
  +        if(!element.hasChildNodes()){
  +            String value = element.getAttributeNS(null,
  +                                                  XTS_VALUE_ATTRIBUTE);
  +            
  +            // String based argument
  +            Class cl = Class.forName(classAttr);
  +            
  +            Constructor constructor 
  +                = cl.getDeclaredConstructor(new Class[] { String.class });
  +            
  +            return constructor.newInstance(new Object[] {value});
  +        }
  +        else{
  +            return buildObject(classAttr, element);
  +        }
       }
   
       /**
  
  
  
  1.1                  xml-batik/test-sources/org/apache/batik/test/xml/XSLXMLReportConsumer.java
  
  Index: XSLXMLReportConsumer.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.test.xml;
  
  import java.io.File;
  import java.io.IOException;
  
  import org.apache.xalan.xslt.XSLTProcessorFactory;
  import org.apache.xalan.xslt.XSLTInputSource;
  import org.apache.xalan.xslt.XSLTResultTarget;
  import org.apache.xalan.xslt.XSLTProcessor;
  
  /**
   * This implementation of the <tt>XMLTestReportProcessor.XMLReportConsumer</tt>
   * interface simply applies an XSL transformation to the input
   * XML file and stores the result in a configurable directory.
   *
   * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
   * @version $Id: XSLXMLReportConsumer.java,v 1.1 2001/04/13 21:17:03 vhardy Exp $
   */
  public class XSLXMLReportConsumer 
      implements XMLTestReportProcessor.XMLReportConsumer {
      /**
       * Stylesheet URI
       */
      private String stylesheet;
  
      /**
       * Output directory, i.e., the directory where the result
       * of the XSL transformation will be stored.
       */
      private String outputDirectory;
  
      /**
       * Prefix for the output file names
       */
      private String outputPrefix;
  
      /**
       * Suffix for the output file names.
       */
      private String outputSuffix;
  
      /**
       * Constructor
       * @param stylesheet URI for the stylesheet to apply to the XML report
       * @param outputDirectory directory where the result of the XSL transformation
       *                  should be written
       * @param outputPrefix prefix for the output file name
       * @param outputSuffic suffic for the output file name.
       */
      public XSLXMLReportConsumer(String stylesheet,
                                  String outputDirectory,
                                  String outputPrefix,
                                  String outputSuffix){
          this.stylesheet = stylesheet;
          this.outputDirectory = outputDirectory;
          this.outputPrefix = outputPrefix;
          this.outputSuffix = outputSuffix;
      }
  
      /**
       * When a new report has been generated, this consumer
       * applies the same stylesheet to the input XML document
       */
      public void onNewReport(File xmlReport)
          throws Exception{
          XSLTProcessor processor = XSLTProcessorFactory.getProcessor();
          
          processor.process(new XSLTInputSource(xmlReport.toURL().toString()),
                            new XSLTInputSource(stylesheet),
                            new XSLTResultTarget(createNewReportOutput().getAbsolutePath()));
      }
      
      /**
       * Returns a new file in the outputDirectory, with 
       * the requested prefix/suffix
       */
      public File createNewReportOutput() throws IOException{
          File dir = new File(outputDirectory);
          System.out.println("outputDirectory : " + outputDirectory);
          System.out.println("outputPrefix    : " + outputPrefix);
          System.out.println("outputSuffix    : " + outputSuffix);
          return File.createTempFile(outputPrefix,
                                     outputSuffix,
                                     dir);
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org