KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > htmlparser > tests > ParserTestCase


1 // HTMLParser Library $Name: v1_5_20050313 $ - A java-based parser for HTML
2
// http://sourceforge.org/projects/htmlparser
3
// Copyright (C) 2004 Somik Raha
4
//
5
// Revision Control Information
6
//
7
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/tests/ParserTestCase.java,v $
8
// $Author: derrickoswald $
9
// $Date: 2004/07/31 16:42:33 $
10
// $Revision: 1.52 $
11
//
12
// This library is free software; you can redistribute it and/or
13
// modify it under the terms of the GNU Lesser General Public
14
// License as published by the Free Software Foundation; either
15
// version 2.1 of the License, or (at your option) any later version.
16
//
17
// This library is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
// Lesser General Public License for more details.
21
//
22
// You should have received a copy of the GNU Lesser General Public
23
// License along with this library; if not, write to the Free Software
24
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
//
26

27 package org.htmlparser.tests;
28
29 import java.util.Enumeration JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import junit.framework.TestCase;
34 import org.htmlparser.Attribute;
35
36 import org.htmlparser.Node;
37 import org.htmlparser.Parser;
38 import org.htmlparser.Tag;
39 import org.htmlparser.Text;
40 import org.htmlparser.lexer.Lexer;
41 import org.htmlparser.lexer.Page;
42 import org.htmlparser.nodes.TagNode;
43 import org.htmlparser.tags.FormTag;
44 import org.htmlparser.tags.InputTag;
45 import org.htmlparser.util.DefaultParserFeedback;
46 import org.htmlparser.util.NodeIterator;
47 import org.htmlparser.util.ParserException;
48 import org.htmlparser.util.ParserUtils;
49
50 public class ParserTestCase extends TestCase {
51
52     static boolean mCaseInsensitiveComparisons = false;
53     protected Parser parser;
54     protected Node node [];
55     protected int nodeCount;
56     protected Lexer mLexer;
57
58     public ParserTestCase(String JavaDoc name) {
59         super(name);
60     }
61
62     protected void parse(String JavaDoc response) throws ParserException {
63         createParser(response,10000);
64         parseNodes();
65     }
66
67     protected void createParser(String JavaDoc inputHTML) {
68         mLexer = new Lexer (new Page (inputHTML));
69         parser = new Parser(mLexer, new DefaultParserFeedback(DefaultParserFeedback.QUIET));
70         node = new Node[40];
71     }
72
73     protected void createParser(String JavaDoc inputHTML,int numNodes)
74     {
75         Lexer lexer = new Lexer (inputHTML);
76         parser = new Parser (lexer, new DefaultParserFeedback(DefaultParserFeedback.QUIET));
77         node = new Node[numNodes];
78     }
79
80     protected void createParser(String JavaDoc inputHTML, String JavaDoc url) {
81         Lexer lexer = new Lexer (inputHTML);
82         lexer.getPage ().setUrl (url);
83         parser = new Parser (lexer, new DefaultParserFeedback(DefaultParserFeedback.QUIET));
84         node = new Node[40];
85     }
86
87     protected void createParser(String JavaDoc inputHTML, String JavaDoc url,int numNodes) {
88         Lexer lexer = new Lexer (inputHTML);
89         lexer.getPage ().setUrl (url);
90         parser = new Parser (lexer, new DefaultParserFeedback(DefaultParserFeedback.QUIET));
91         node = new Node[numNodes];
92     }
93
94     public Parser getParser ()
95     {
96         return (parser);
97     }
98
99     public void setParser (Parser parser)
100     {
101         this.parser = parser;
102     }
103
104     public void assertStringEquals(String JavaDoc message, String JavaDoc expected,
105                                       String JavaDoc actual) {
106         String JavaDoc mismatchInfo = "";
107
108         if (expected.length() < actual.length()) {
109             mismatchInfo = "\n\nACTUAL result has "+(actual.length()-expected.length())+" extra characters at the end. They are :";
110             int limit = Math.min (expected.length() + 10, actual.length());
111             for (int i = expected.length(); i < limit; i++)
112                 mismatchInfo += ("\nPosition : " + i + " , Code = " + (int) actual.charAt(i));
113             if (limit != actual.length())
114                 mismatchInfo += "\netc.";
115         } else if(expected.length() > actual.length()) {
116             mismatchInfo = "\n\nEXPECTED result has "+(expected.length()-actual.length())+" extra characters at the end. They are :";
117             int limit = Math.min (actual.length() + 10, expected.length());
118             for (int i = actual.length(); i < expected.length(); i++)
119                 mismatchInfo += ("\nPosition : " + i + " , Code = " + (int) expected.charAt(i));
120             if (limit != expected.length ())
121                 mismatchInfo += "\netc.";
122         }
123         for (int i = 0; i < expected.length(); i++) {
124             if (
125                     (expected.length() != actual.length() &&
126                         (
127                             i >= (expected.length()-1 ) ||
128                             i >= (actual.length()-1 )
129                         )
130                     ) ||
131                     (mCaseInsensitiveComparisons && Character.toUpperCase (actual.charAt(i)) != Character.toUpperCase (expected.charAt(i))) ||
132                     (!mCaseInsensitiveComparisons && (actual.charAt(i) != expected.charAt(i)))
133                 ) {
134                     StringBuffer JavaDoc errorMsg = new StringBuffer JavaDoc();
135                     errorMsg.append(
136                         message +mismatchInfo + " \nMismatch of strings at char posn " + i +
137                         " \n\nString Expected upto mismatch = " +
138                         expected.substring(0, i) +
139                         " \n\nString Actual upto mismatch = " +
140                         actual.substring(0, i)
141                     );
142                     if (i<expected.length())
143                        errorMsg.append(
144                             " \n\nString Expected MISMATCH CHARACTER = "+
145                             expected.charAt(i) + ", code = " +
146                             (int) expected.charAt(i)
147                         );
148
149                     if (i<actual.length())
150                         errorMsg.append(
151                             " \n\nString Actual MISMATCH CHARACTER = " +
152                             actual.charAt(i) + ", code = " +
153                             (int) actual.charAt(i)
154                         );
155
156                     errorMsg.append(
157                         " \n\n**** COMPLETE STRING EXPECTED ****\n" +
158                         expected +
159                         " \n\n**** COMPLETE STRING ACTUAL***\n" + actual
160                     );
161                     System.out.println ("string differs, expected \"" + expected + "\", actual \"" + actual + "\"");
162                     failWithMessage(errorMsg.toString());
163             }
164
165         }
166     }
167
168     public void failWithMessage(String JavaDoc message) {
169         fail(message);
170     }
171
172     public void parseNodes() throws ParserException{
173         nodeCount = 0;
174         for (NodeIterator e = parser.elements();e.hasMoreNodes();)
175         {
176             node[nodeCount++] = e.nextNode();
177         }
178     }
179
180     public void assertNodeCount(int nodeCountExpected) {
181         StringBuffer JavaDoc msg = new StringBuffer JavaDoc();
182         for (int i=0;i<nodeCount;i++) {
183             msg.append(node[i].getClass().getName());
184             msg.append("-->\n").append(node[i].toHtml()).append("\n");
185         }
186         if (nodeCountExpected != nodeCount)
187             System.out.println ("node count differs, expected " + nodeCountExpected + ", actual " + nodeCount);
188         assertEquals("Number of nodes parsed didn't match, nodes found were :\n"+msg.toString(),nodeCountExpected,nodeCount);
189     }
190
191     public void parseAndAssertNodeCount(int nodeCountExpected) throws ParserException {
192         parseNodes();
193         assertNodeCount(nodeCountExpected);
194     }
195
196     public void assertSameType(String JavaDoc displayMessage, Node expected, Node actual) {
197         String JavaDoc expectedNodeName = expected.getClass().getName();
198         String JavaDoc actualNodeName = actual.getClass().getName();
199         displayMessage =
200             "The types did not match: Expected "+
201             expectedNodeName+" \nbut was "+
202             actualNodeName+"\nEXPECTED XML:"+expected.toHtml()+"\n"+
203             "ACTUAL XML:"+actual.toHtml()+displayMessage;
204         assertStringEquals(displayMessage, expectedNodeName, actualNodeName);
205     }
206
207     public void assertTagEquals(String JavaDoc displayMessage, Node expected, Node actual) {
208         if (expected instanceof Tag) {
209             Tag expectedTag = (Tag)expected;
210             Tag actualTag = (Tag)actual;
211             assertTagNameMatches(displayMessage, expectedTag, actualTag);
212             assertAttributesMatch(displayMessage, expectedTag, actualTag);
213         }
214     }
215
216     private void assertTagNameMatches(
217         String JavaDoc displayMessage,
218         Tag nextExpectedTag,
219         Tag nextActualTag) {
220         String JavaDoc expectedTagName = nextExpectedTag.getTagName();
221         String JavaDoc actualTagName = nextActualTag.getTagName();
222         displayMessage = "The tag names did not match: Expected "+expectedTagName+" \nbut was "+actualTagName+displayMessage;
223         assertStringEquals(displayMessage, expectedTagName, actualTagName);
224     }
225
226     public void assertXmlEquals(String JavaDoc displayMessage, String JavaDoc expected, String JavaDoc actual) throws Exception JavaDoc
227     {
228         Node nextExpectedNode;
229         Node nextActualNode;
230         Tag tag1;
231         Tag tag2;
232
233         expected = removeEscapeCharacters(expected);
234         actual = removeEscapeCharacters(actual);
235
236         Parser expectedParser = Parser.createParser(expected, null);
237         Parser resultParser = Parser.createParser(actual, null);
238
239         NodeIterator expectedIterator = expectedParser.elements();
240         NodeIterator actualIterator = resultParser.elements();
241         displayMessage = createGenericFailureMessage(displayMessage, expected, actual);
242
243         nextExpectedNode = null;
244         nextActualNode = null;
245         tag1 = null;
246         tag2 = null;
247         do {
248             if (null != tag1)
249                 nextExpectedNode = tag1;
250             else
251                 nextExpectedNode = getNextNodeUsing (expectedIterator);
252             if (null != tag2)
253                 nextActualNode = tag2;
254             else
255                 nextActualNode = getNextNodeUsing (actualIterator);
256             assertNotNull (nextActualNode);
257             tag1 = fixIfXmlEndTag (expectedParser.getLexer ().getPage (), nextExpectedNode);
258             tag2 = fixIfXmlEndTag (resultParser.getLexer ().getPage (), nextActualNode);
259             assertStringValueMatches(
260                 displayMessage,
261                 nextExpectedNode,
262                 nextActualNode
263             );
264             assertSameType(displayMessage, nextExpectedNode, nextActualNode);
265             assertTagEquals(displayMessage, nextExpectedNode, nextActualNode);
266         }
267         while (expectedIterator.hasMoreNodes() || (null != tag1));
268         assertActualXmlHasNoMoreNodes(displayMessage, actualIterator);
269     }
270
271     private Node getNextNodeUsing(NodeIterator nodeIterator)
272         throws ParserException {
273         Node nextNode;
274         String JavaDoc text=null;
275         do {
276             nextNode = nodeIterator.nextNode();
277             if (nextNode instanceof Text) {
278                 text = nextNode.toPlainTextString().trim();
279             } else text = null;
280         }
281         while (text!=null && text.length()==0);
282         return nextNode;
283     }
284
285     private void assertStringValueMatches(
286         String JavaDoc displayMessage, Node expectedNode,Node actualNode) {
287
288         String JavaDoc expected = expectedNode.toPlainTextString().trim();
289         String JavaDoc actual = actualNode.toPlainTextString().trim();
290         expected = expected.replace('\n', ' ');
291         actual = actual.replace('\n',' ');
292         displayMessage = "String value mismatch\nEXPECTED:"+expected+"\nACTUAL:"+actual+displayMessage;
293         assertStringEquals(displayMessage,expected,actual);
294
295     }
296
297     private void assertActualXmlHasNoMoreNodes(
298         String JavaDoc displayMessage,
299         NodeIterator actualIterator)
300         throws ParserException {
301         if (actualIterator.hasMoreNodes()) {
302             String JavaDoc extraTags = "\nExtra Tags\n**********\n";
303             do {
304                 extraTags += actualIterator.nextNode().toHtml();
305             }
306             while (actualIterator.hasMoreNodes());
307
308             displayMessage = "Actual had more data than expected\n"+extraTags+displayMessage;
309             fail(displayMessage);
310         }
311     }
312
313     private String JavaDoc createGenericFailureMessage(
314         String JavaDoc displayMessage,
315         String JavaDoc expected,
316         String JavaDoc actual) {
317         return "\n\n"+displayMessage+"\n\nComplete Xml\n************\nEXPECTED:\n"+expected+"\nACTUAL:\n"+actual;
318     }
319
320     /**
321      * Return a following tag if node is an empty XML tag.
322      */

323     private Tag fixIfXmlEndTag (Page page, Node node)
324     {
325         Tag ret;
326
327         ret = null;
328         if (node instanceof Tag)
329         {
330             Tag tag = (Tag)node;
331             if (tag.isEmptyXmlTag())
332             {
333                 tag.setEmptyXmlTag (false);
334                 ret = new TagNode (page, tag.getStartPosition (), tag.getEndPosition (), tag.getAttributesEx ());
335             }
336         }
337         
338         return (ret);
339     }
340
341     private void assertAttributesMatch(String JavaDoc displayMessage, Tag expectedTag, Tag actualTag)
342     {
343         assertAllExpectedTagAttributesFoundInActualTag(
344             displayMessage,
345             expectedTag,
346             actualTag);
347         if (expectedTag.getAttributesEx().size() != actualTag.getAttributesEx().size())
348             assertActualTagHasNoExtraAttributes(displayMessage, expectedTag, actualTag);
349     }
350
351     private void assertActualTagHasNoExtraAttributes(String JavaDoc displayMessage, Tag expectedTag, Tag actualTag)
352     {
353         assertStringEquals (displayMessage+"\ntag name", expectedTag.getTagName (), actualTag.getTagName ());
354         Vector JavaDoc v = actualTag.getAttributesEx ();
355         for (int i = 1; i < v.size (); i++)
356         {
357             Attribute a = (Attribute)v.elementAt (i);
358             if (a.isWhitespace ())
359                 continue;
360             String JavaDoc expectedValue = expectedTag.getAttribute (a.getName ());
361             if (null == expectedValue)
362                 fail("\nActual tag had extra attribute: " + a.getName () + displayMessage);
363         }
364     }
365
366     private void assertAllExpectedTagAttributesFoundInActualTag(
367         String JavaDoc displayMessage,
368         Tag expectedTag,
369         Tag actualTag)
370     {
371         assertStringEquals (displayMessage+"\ntag name", expectedTag.getTagName (), actualTag.getTagName ());
372         Vector JavaDoc v = actualTag.getAttributesEx ();
373         for (int i = 1; i < v.size (); i++)
374         {
375             Attribute a = (Attribute)v.elementAt (i);
376             if (a.isWhitespace ())
377                 continue;
378             String JavaDoc actualValue = actualTag.getAttribute (a.getName ());
379             String JavaDoc expectedValue = expectedTag.getAttribute (a.getName ());
380
381             assertStringEquals(
382                 "\nvalue for attribute " + a.getName () + " in tag "+expectedTag.getTagName()+" expected="+expectedValue+" but was "+actualValue+
383                 "\n\nComplete Tag expected:\n"+expectedTag.toHtml()+
384                 "\n\nComplete Tag actual:\n"+actualTag.toHtml()+
385                 displayMessage,
386                 expectedValue,
387                 actualValue
388             );
389         }
390     }
391
392     public static String JavaDoc removeEscapeCharacters(String JavaDoc inputString) {
393         inputString = ParserUtils.removeChars(inputString,'\r');
394         inputString = inputString.replace ('\n',' ');
395         inputString = ParserUtils.removeChars(inputString,'\t');
396         return inputString;
397     }
398
399     public void assertSuperType(
400         String JavaDoc message,
401         Class JavaDoc expectedType,
402         Object JavaDoc object)
403     {
404         String JavaDoc expectedTypeName = expectedType.getName();
405         String JavaDoc actualTypeName = object.getClass().getName();
406         if (!expectedType.isAssignableFrom (object.getClass ()))
407             fail(
408                 message+" should have been of type\n"+
409                 expectedTypeName+
410                 " but was of type \n"+
411                 actualTypeName+"\n and is :"+((Node)object).toHtml()
412             );
413     }
414
415     public void assertType(
416         String JavaDoc message,
417         Class JavaDoc expectedType,
418         Object JavaDoc object)
419     {
420         if (!expectedType.isAssignableFrom (object.getClass ()))
421         {
422             String JavaDoc expectedTypeName = expectedType.getName ();
423             String JavaDoc actualTypeName = object.getClass ().getName ();
424             if (!actualTypeName.equals (expectedTypeName))
425                 fail(
426                     message + " should have been of type "+
427                     expectedTypeName
428                     + " but was of type "
429                     + actualTypeName
430                     + " and is:"
431                     + ((Node)object).toHtml()
432                 );
433         }
434     }
435
436     protected void assertHiddenIDTagPresent(FormTag formTag, String JavaDoc name, String JavaDoc inputTagValue) {
437         InputTag inputTag = formTag.getInputTag(name);
438         assertNotNull("Hidden Tag "+name+" should have been there", inputTag);
439         assertStringEquals("Hidden Tag Contents", inputTagValue, inputTag.getAttribute("VALUE"));
440         assertStringEquals("Hidden Tag Type", "hidden", inputTag.getAttribute("TYPE"));
441     }
442
443     protected void assertNodeCount(String JavaDoc message, int expectedLength, Node[] nodes) {
444         if (expectedLength!=nodes.length) {
445             StringBuffer JavaDoc failMsg = new StringBuffer JavaDoc(message);
446             failMsg.append("\n");
447             failMsg.append("Number of nodes expected ").append(expectedLength).append(" \n");
448             failMsg.append("but was : ");
449             failMsg.append(nodes.length).append("\n");
450             failMsg.append("Nodes found are:\n");
451             for (int i=0;i<nodes.length;i++) {
452                 failMsg.append("Node ").append(i).append(" : ");
453                 failMsg.append(nodes[i].getClass().getName()).append("\n");
454                 failMsg.append(nodes[i].toString()).append("\n\n");
455             }
456             fail(failMsg.toString());
457         }
458     }
459
460     /**
461      * Mainline for individual test cases.
462      * @param args Command line arguments. The following options
463      * are understood:
464      * <pre>
465      * -text -- use junit.textui.TestRunner
466      * -awt -- use junit.awtui.TestRunner
467      * -swing -- use junit.swingui.TestRunner (default)
468      * </pre>
469      * All other options are passed on to the junit framework.
470      * Decides the test class by examiing the system properties looking
471      * for a property that starts with "org.htmlparser.tests.", this is
472      * used as the name of the class (the value is ignored).
473      * Each class that subclasses ParserTestCase can inherit this mainline
474      * by adding a static block in their class similar to:
475      * <pre>
476      * static
477      * {
478      * System.setProperty ("org.htmlparser.tests.ParserTest", "ParserTest");
479      * }
480      * </pre>
481      */

482     public static void main(String JavaDoc[] args)
483     {
484         String JavaDoc runner;
485         int i;
486         String JavaDoc arguments[];
487         Properties JavaDoc properties;
488         Enumeration JavaDoc enumeration;
489         String JavaDoc name;
490         Class JavaDoc cls;
491
492         runner = null;
493         for (i = 0; (i < args.length) && (null == runner); i++)
494         {
495             if (args[i].equalsIgnoreCase ("-text"))
496                 runner = "junit.textui.TestRunner";
497             else if (args[i].equalsIgnoreCase ("-awt"))
498                 runner = "junit.awtui.TestRunner";
499             else if (args[i].equalsIgnoreCase ("-swing"))
500                 runner = "junit.swingui.TestRunner";
501         }
502         if (null != runner)
503         {
504             // remove it from the arguments
505
arguments = new String JavaDoc[args.length - 1];
506             System.arraycopy (args, 0, arguments, 0, i - 1);
507             System.arraycopy (args, i, arguments, i - 1, args.length - i);
508             args = arguments;
509         }
510         else
511             runner = "junit.swingui.TestRunner";
512
513         // find the test class that has registered in the system properties
514
arguments = args; // default of no class name, works in GUI mode
515
properties = System.getProperties ();
516         enumeration = properties.propertyNames ();
517         while (enumeration.hasMoreElements ())
518         {
519             name = (String JavaDoc)enumeration.nextElement ();
520             if (name.startsWith ("org.htmlparser.tests."))
521             {
522                 // from http://www.mail-archive.com/commons-user%40jakarta.apache.org/msg02958.html
523
//
524
// The problem is within the UI test runners of JUnit. They bring
525
// with them a custom classloader, which causes the
526
// LogConfigurationException. Unfortunately Log4j doesn't work
527
// either.
528
//
529
// Solution: Disable "Reload classes every run" or start JUnit with
530
// command line option -noloading before the name of the Testsuite.
531
if (true)
532                 {
533                     // append the test class
534
arguments = new String JavaDoc[args.length + 2];
535                     System.arraycopy (args, 0, arguments, 0, args.length);
536                     arguments[arguments.length - 2] = "-noloading";
537                     arguments[arguments.length - 1] = name;
538                 }
539                 else
540                 {
541                     // append the test class
542
arguments = new String JavaDoc[args.length + 1];
543                     System.arraycopy (args, 0, arguments, 0, args.length);
544                     arguments[args.length] = name;
545                 }
546                 break; // JUnit only handles one class on the command line
547
}
548         }
549
550         // invoke main() of the test runner
551
try
552         {
553             cls = Class.forName (runner);
554             java.lang.reflect.Method JavaDoc method = cls.getDeclaredMethod (
555                 "main", new Class JavaDoc[] { String JavaDoc[].class });
556             method.invoke (
557                 null,
558                 new Object JavaDoc[] { arguments });
559         }
560         catch (Throwable JavaDoc t)
561         {
562             System.err.println (
563                 "cannot run unit test ("
564                 + t.getMessage ()
565                 + ")");
566         }
567     }
568 }
569
Popular Tags