You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by cu...@apache.org on 2002/06/06 19:17:12 UTC

cvs commit: xml-xalan/test/java/src/org/apache/qetest/xsl XHTComparator.java

curcuru     2002/06/06 10:17:11

  Modified:    test/java/src/org/apache/qetest/xsl XHTComparator.java
  Log:
  Update parse() for text mode to parse line-by-line and then
  construct a <line> element for each line (request: pdick);
  also update comments and minor text output improvements;
  please let me know if you think this changes how any compares are done!
  
  Revision  Changes    Path
  1.9       +116 -83   xml-xalan/test/java/src/org/apache/qetest/xsl/XHTComparator.java
  
  Index: XHTComparator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/test/java/src/org/apache/qetest/xsl/XHTComparator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XHTComparator.java	16 Apr 2002 16:22:38 -0000	1.8
  +++ XHTComparator.java	6 Jun 2002 17:17:11 -0000	1.9
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2000 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -64,10 +64,6 @@
   import java.io.File;
   import java.io.FileReader;
   import java.io.BufferedReader;
  -
  -import java.net.URL;
  -import java.net.MalformedURLException;
  -
   import java.util.Properties;
   import java.util.StringTokenizer;
   
  @@ -82,7 +78,6 @@
   // Needed JAXP classes
   import javax.xml.parsers.DocumentBuilder;
   import javax.xml.parsers.DocumentBuilderFactory;
  -import javax.xml.parsers.ParserConfigurationException;
   
   // SAX2 imports
   import org.xml.sax.ErrorHandler;
  @@ -95,20 +90,29 @@
    * <p>Given two files, an actual test result and a known good or 'gold'
    * test result, diff the two files to see if they are equal; if not, provide
    * some very basic info on where they differ.</p>
  + *
    * <p>Attempts to parse each file as an XML document using Xerces;
    * if that fails, attempt to parse each as an HTML document using
    * <i>NEED NEW HTML PARSER</i>; if that fails, pretend to parse each
  - * doc as a single text node.</p>
  + * doc as text and construct a faux document node; then do 
  + * readLine() and construct a &lt;line> element for each line.</p>
  + *
  + * <p>The comparison routine then recursively compares the two 
  + * documents node-by-node; see the code for exactly how each 
  + * node type is handled.  Note that some node types are currently 
  + * ignored.</p>
  + *
    * //@todo document whitespace difference handling better -sc
  - * //@todo check how namespaces are handled and diff'd -sc
    * //@todo check how XML decls are handled (or not) -sc
  - * //@todo check how files of different encodings are handled in each parse type -sc
    * //@todo Allow param to define the type of parse we do (i.e. if a
    * testwriter knows their output file will be XML, we should only
    * attempt to parse it as XML, not other types)
  + * @see XHTComparatorXSLTC for an alternate implementation of 
  + * diff() which tests some things as QNames (which checks for the 
  + * true namespace, instead of just the prefix)
    * @author Scott_Boag@lotus.com
    * @author Shane_Curcuru@lotus.com
  - * @version $Id: XHTComparator.java,v 1.8 2002/04/16 16:22:38 santiagopg Exp $
  + * @version $Id: XHTComparator.java,v 1.9 2002/06/06 17:17:11 curcuru Exp $
    */
   public class XHTComparator
   {
  @@ -192,11 +196,19 @@
   
       /**
        * Compare two files by parsing into DOMs and comparing trees.
  +     *
  +     * <p>Parses the goldFileName by using the 
  +     * {@link #parse(String, PrintWriter, String, Properties) parse worker method}
  +     * - if null, we bail and return false.  If non-null, we parse the 
  +     * testFileName into a Document as well.  Then we call 
  +     * {@link #diff(Node, Node, PrintWriter, boolean[]) diff worker method} 
  +     * to do the real work of comparing.</p>
  +     *
        * @param goldFileName expected file
        * @param testFileName actual file
        * @param reporter PrintWriter to dump status info to
  -     * @param array of warning flags (for whitespace diffs, I think?)
  -     * NEEDSDOC @param warning
  +     * @param warning array of warning flags (for whitespace diffs, 
  +     * item[0] is set to true if we find whitespace-only diffs)
        * @param attributes to attempt to set onto parsers
        * @return true if they match, false otherwise
        */
  @@ -209,6 +221,10 @@
           Document goldDoc = parse(goldFileName, reporter, GOLD, attributes);
   
           // parse the test doc only if gold doc was parsed OK
  +        //@todo Jun-02 -sc Note the logic here might be improveable to 
  +        //  actually report file missing problems better: i.e. 
  +        //  in theory, if the actual is missing, it's a fail; if 
  +        //  the gold (only) is missing, it's ambiguous
           Document testDoc = (null != goldDoc)
                              ? parse(testFileName, reporter, TEST, attributes) : null;
   
  @@ -234,11 +250,17 @@
       // REASON_CONSTANT;gold val;test val;reason description
   
       /**
  -     * The contract is: when you enter here the gold and test nodes are the same type,
  +     * Diff two Nodes recursively and report true if equal.  
  +     *
  +     * <p>The contract is: when you enter here the gold and test nodes are the same type,
        * both non-null, and both in the same basic position in the tree.
  -     * //@todo verify caller really performs for the contract -sc
  +     * //@todo verify caller really performs for the contract -sc</p>
        *
  -     * @param gold gold or expected node
  +     * <p>See the code for how it's done; note that not all node 
  +     * types are actually compared currently.  Also see 
  +     * {@link XHTComparatorXSLTC} for an alternate implementation.</p>
  +     *
  +     * @param gold or expected node
        * @param test actual node
        * @param reporter PrintWriter to dump status info to
        * @param warning[] if any whitespace diffs found
  @@ -286,20 +308,8 @@
               reporter.println(MISMATCH_VALUE + nodeTypeString(gold) + "len="
                              + value1.length() + SEPARATOR
                              + nodeTypeString(test) + "len=" + value2.length()
  -                           + SEPARATOR + "lengths do not match");
  -
  -            // Limit length we output to logs; extremely long values 
  -            //  are more hassle than they're worth (at that point, 
  -            //  it's either obvious what the problem is, or it's 
  -            //  such a small problem that you'll need to manually
  -            //  compare the files separately
  -            if (value1.length() > maxDisplayLen)
  -                value1 = value1.substring(0, maxDisplayLen);
  -            if (value2.length() > maxDisplayLen)
  -                value2 = value2.substring(0, maxDisplayLen);
  -            reporter.println(MISMATCH_VALUE_GOLD + nodeTypeString(gold) + SEPARATOR + "\n" + value1);
  -            reporter.println(MISMATCH_VALUE_TEXT + nodeTypeString(test) + SEPARATOR + "\n" + value2);
  -
  +                           + SEPARATOR + "values do not match");
  +            printNodeDiff(gold, test, reporter);
               return false;
           }
           else if ((null != value1) && (null == value2))
  @@ -462,13 +472,17 @@
        * NEEDSDOC Method tryToAdvancePastWhitespace 
        *
        *
  -     * NEEDSDOC @param n
  +     * @param n node to check if it's whitespace
        * @param reporter PrintWriter to dump status info to
  -     * NEEDSDOC @param warning
  -     * NEEDSDOC @param next
  -     * NEEDSDOC @param which
  +     * @param warning set to true if we advance past a 
  +     * whitespace node; note that this logic isn't quite 
  +     * correct, I think (it should only be set if 
  +     * we advance past whitespace that isn't equal in 
  +     * both trees or something like that)
  +     * @param next array of nodes to continue thru
  +     * @param which index into next array
        *
  -     * NEEDSDOC (tryToAdvancePastWhitespace) @return
  +     * @return Node we should be at after advancing
        */
       Node tryToAdvancePastWhitespace(Node n, PrintWriter reporter,
                                       boolean[] warning, Node next[], int which)
  @@ -572,6 +586,7 @@
                   reporter.println(MISMATCH_NODE + nodeTypeString(gold)
                                  + SEPARATOR + nodeTypeString(test) + SEPARATOR
                                  + "node type mismatch");
  +                printNodeDiff(gold, test, reporter);
   
                   return false;
               }
  @@ -583,60 +598,79 @@
       /**
        * Cheap-o text printout of a node.  By Scott.  
        *
  -     * NEEDSDOC @param n
  -     *
  -     * NEEDSDOC ($objectName$) @return
  +     * @param n node to print info for
  +     * @return String of getNodeType plus getNodeName
        */
  -    String nodeTypeString(Node n)
  +    public static String nodeTypeString(Node n)
       {
  -
  -        String s;
  -
           switch (n.getNodeType())
           {
           case Node.DOCUMENT_NODE :
  -            s = "DOCUMENT_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "DOCUMENT(" + n.getNodeName() + ")";
           case Node.ELEMENT_NODE :
  -            s = "ELEMENT_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "ELEMENT(" + n.getNodeName() + ")";
           case Node.CDATA_SECTION_NODE :
  -            s = "CDATA_SECTION_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "CDATA_SECTION(" + n.getNodeName() + ")";
           case Node.ENTITY_REFERENCE_NODE :
  -            s = "ENTITY_REFERENCE_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "ENTITY_REFERENCE(" + n.getNodeName() + ")";
           case Node.ATTRIBUTE_NODE :
  -            s = "ATTRIBUTE_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "ATTRIBUTE(" + n.getNodeName() + ")";
           case Node.COMMENT_NODE :
  -            s = "COMMENT_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "COMMENT(" + n.getNodeName() + ")";
           case Node.ENTITY_NODE :
  -            s = "ENTITY_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "ENTITY(" + n.getNodeName() + ")";
           case Node.NOTATION_NODE :
  -            s = "NOTATION_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "NOTATION(" + n.getNodeName() + ")";
           case Node.PROCESSING_INSTRUCTION_NODE :
  -            s = "PROCESSING_INSTRUCTION_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "PROCESSING_INSTRUCTION(" + n.getNodeName() + ")";
           case Node.TEXT_NODE :
  -            s = "TEXT_NODE(" + n.getNodeName() + ")";
  -            break;
  +            return "TEXT()"; // #text is all that's ever printed out, so skip it
           default :
  -            s = "UNKNOWN_NODE(" + n.getNodeName() + ")";
  +            return "UNKNOWN(" + n.getNodeName() + ")";
           }
  -
  -        return s;
       }  // end of nodeTypeString()
   
   
       /**
  +     * Cheap-o text printout of two different nodes.  
  +     *
  +     * @param goldNode or expected node to print info
  +     * @param testNode or actual node to print info
  +     * @param n node to print info for
  +     * @param reporter PrintWriter to dump status info to
  +     */
  +    public void printNodeDiff(Node goldNode, Node testNode, PrintWriter reporter)
  +    {
  +        String goldValue = goldNode.getNodeValue();
  +        String testValue = testNode.getNodeValue();
  +        if (null == goldValue)
  +            goldValue = "null";
  +        if (null == testValue)
  +            testValue = "null";
  +
  +        // Limit length we output to logs; extremely long values 
  +        //  are more hassle than they're worth (at that point, 
  +        //  it's either obvious what the problem is, or it's 
  +        //  such a small problem that you'll need to manually
  +        //  compare the files separately
  +        if (goldValue.length() > maxDisplayLen)
  +            goldValue = goldValue.substring(0, maxDisplayLen);
  +        if (testValue.length() > maxDisplayLen)
  +            testValue = testValue.substring(0, maxDisplayLen);
  +        reporter.println(MISMATCH_VALUE_GOLD + nodeTypeString(goldNode) + SEPARATOR + "\n" + goldValue);
  +        reporter.println(MISMATCH_VALUE_TEXT + nodeTypeString(testNode) + SEPARATOR + "\n" + testValue);
  +    }
  +
  +
  +    /**
        * Simple worker method to parse filename to a Document.  
        *
  -     * Attempts XML parse, then HTML parse (when parser available), 
  -     * then just parses as text and sticks into a text node.
  +     * <p>Attempts XML parse, if that throws an exception, then 
  +     * we attempt an HTML parse (when parser available), if 
  +     * that throws an exception, then we parse as text: 
  +     * we construct a faux document element to hold it all, 
  +     * and then parse by readLine() and put each line of 
  +     * text into a &lt;line> element.</p>
        *
        * @param filename to parse as a local path
        * @param reporter PrintWriter to dump status info to
  @@ -660,7 +694,8 @@
           applyAttributes(dfactory, attributes);
           
           // Local class: cheap non-printing ErrorHandler
  -        // This is used to suppress validation warnings
  +        // This is used to suppress validation warnings which 
  +        //  would otherwise clutter up the console
           ErrorHandler nullHandler = new ErrorHandler() {
               public void warning(SAXParseException e) throws SAXException {}
               public void error(SAXParseException e) throws SAXException {}
  @@ -699,12 +734,16 @@
                       reporter.println(WARNING + e.toString());
                       parseType = which + PARSE_TYPE + "[text];";
   
  +                    // First build a faux document with parent element
  +                    DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
  +                    doc = docBuilder.newDocument();
  +                    Element outElem = doc.createElement("out");
  +
                       // Parse as text, line by line
                       //   Since we already know it should be text, this should 
                       //   work better than parsing by bytes.
                       FileReader fr = new FileReader(filename);
                       BufferedReader br = new BufferedReader(fr);
  -                    StringBuffer buffer = new StringBuffer();
                       for (;;)
                       {
                           String tmp = br.readLine();
  @@ -713,28 +752,22 @@
                           {
                               break;
                           }
  -
  -                        buffer.append(tmp);
  -                        buffer.append("\n");  // Put in the newlines as well
  +                        // An additional thing we could do would 
  +                        //  be to put in the line number in the 
  +                        //  file in here somehow, so when users 
  +                        //  view reports, they get that info
  +                        Element lineElem = doc.createElement("line");
  +                        outElem.appendChild(lineElem);
  +                        Text textNode = doc.createTextNode(tmp);
  +                        lineElem.appendChild(textNode);
                       }
  -
  -                    DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
  -                    doc = docBuilder.newDocument();
  -                    Element outElem = doc.createElement("out");
  -                    Text textNode = doc.createTextNode(buffer.toString());
  -
  -                    // Note: will this always be a valid node?  If we're parsing 
  -                    //    in as text, will there ever be cases where the diff that's 
  -                    //    done later on will fail becuase some really garbage-like 
  -                    //    text has been put into a node?
  -                    outElem.appendChild(textNode);
  +                    // Now stick the whole element into the document to return
                       doc.appendChild(outElem);
                   }
                   catch (Throwable throwable)
                   {
                       reporter.println(OTHER_ERROR + filename + SEPARATOR
                                      + "threw:" + throwable.toString());
  -                    // throwable.printStackTrace();
                   }
               }
           }
  
  
  

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