KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > regexp > RETest


1 package org.apache.regexp;
2
3 /*
4  * ====================================================================
5  *
6  * The Apache Software License, Version 1.1
7  *
8  * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
9  * reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution, if
24  * any, must include the following acknowlegement:
25  * "This product includes software developed by the
26  * Apache Software Foundation (http://www.apache.org/)."
27  * Alternately, this acknowlegement may appear in the software itself,
28  * if and wherever such third-party acknowlegements normally appear.
29  *
30  * 4. The names "The Jakarta Project", "Jakarta-Regexp", and "Apache Software
31  * Foundation" must not be used to endorse or promote products derived
32  * from this software without prior written permission. For written
33  * permission, please contact apache@apache.org.
34  *
35  * 5. Products derived from this software may not be called "Apache"
36  * nor may "Apache" appear in their names without prior written
37  * permission of the Apache Group.
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This software consists of voluntary contributions made by many
54  * individuals on behalf of the Apache Software Foundation. For more
55  * information on the Apache Software Foundation, please see
56  * <http://www.apache.org/>.
57  *
58  */

59
60 import java.io.BufferedReader JavaDoc;
61 import java.io.FileReader JavaDoc;
62 import java.io.InputStreamReader JavaDoc;
63 import java.io.PrintWriter JavaDoc;
64 import java.io.File JavaDoc;
65 import java.io.ByteArrayOutputStream JavaDoc;
66 import java.io.ObjectOutputStream JavaDoc;
67 import java.io.ByteArrayInputStream JavaDoc;
68 import java.io.ObjectInputStream JavaDoc;
69
70 /**
71  * Data driven (and optionally interactive) testing harness to exercise regular
72  * expression compiler and matching engine.
73  *
74  * @author <a HREF="mailto:jonl@muppetlabs.com">Jonathan Locke</a>
75  * @author <a HREF="mailto:jon@latchkey.com">Jon S. Stevens</a>
76  * @author <a HREF="mailto:gholam@xtra.co.nz">Michael McCallum</a>
77  * @version $Id: RETest.java,v 1.5 2003/05/02 01:03:47 vgritsenko Exp $
78  */

79 public class RETest
80 {
81     // True if we want to see output from success cases
82
static final boolean showSuccesses = false;
83
84     // A new line character.
85
static final String JavaDoc NEW_LINE = System.getProperty( "line.separator" );
86
87     // Construct a matcher and a debug compiler
88
RE r = new RE();
89     REDebugCompiler compiler = new REDebugCompiler();
90
91     /**
92      * Main program entrypoint. If an argument is given, it will be compiled
93      * and interactive matching will ensue. If no argument is given, the
94      * file RETest.txt will be used as automated testing input.
95      * @param args Command line arguments (optional regular expression)
96      */

97     public static void main(String JavaDoc[] args)
98     {
99         try
100         {
101             test( args );
102         }
103         catch (Exception JavaDoc e)
104         {
105             e.printStackTrace();
106         }
107     }
108
109     /**
110      * Testing entrypoint.
111      * @param args Command line arguments
112      * @exception Exception thrown in case of error
113      */

114     public static boolean test( String JavaDoc[] args ) throws Exception JavaDoc
115     {
116         RETest test = new RETest();
117         // Run interactive tests against a single regexp
118
if (args.length == 2)
119         {
120             test.runInteractiveTests(args[1]);
121         }
122         else if (args.length == 1)
123         {
124             // Run automated tests
125
test.runAutomatedTests(args[0]);
126         }
127         else
128         {
129             System.out.println( "Usage: RETest ([-i] [regex]) ([/path/to/testfile.txt])" );
130             System.out.println( "By Default will run automated tests from file 'docs/RETest.txt' ..." );
131             System.out.println();
132             test.runAutomatedTests("docs/RETest.txt");
133         }
134         return test.failures == 0;
135     }
136
137     /**
138      * Constructor
139      */

140     public RETest()
141     {
142     }
143
144     /**
145      * Compile and test matching against a single expression
146      * @param expr Expression to compile and test
147      */

148     void runInteractiveTests(String JavaDoc expr)
149     {
150         try
151         {
152             // Compile expression
153
r.setProgram(compiler.compile(expr));
154
155             // Show expression
156
say("" + NEW_LINE + "" + expr + "" + NEW_LINE + "");
157
158             // Show program for compiled expression
159
PrintWriter JavaDoc writer = new PrintWriter JavaDoc( System.out );
160             compiler.dumpProgram( writer );
161             writer.flush();
162
163             boolean running = true;
164             // Test matching against compiled expression
165
while ( running )
166             {
167                 // Read from keyboard
168
BufferedReader JavaDoc br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(System.in));
169                 System.out.print("> ");
170                 System.out.flush();
171                 String JavaDoc match = br.readLine();
172
173                 if ( match != null )
174                 {
175                     // Try a match against the keyboard input
176
if (r.match(match))
177                     {
178                         say("Match successful.");
179                     }
180                     else
181                     {
182                         say("Match failed.");
183                     }
184
185                     // Show subparen registers
186
showParens(r);
187                 }
188                 else
189                 {
190                     running = false;
191                     System.out.println();
192                 }
193             }
194         }
195         catch (Exception JavaDoc e)
196         {
197             say("Error: " + e.toString());
198             e.printStackTrace();
199         }
200     }
201
202     /**
203      * Exit with a fatal error.
204      * @param s Last famous words before exiting
205      */

206     void die(String JavaDoc s)
207     {
208         say("FATAL ERROR: " + s);
209         System.exit(0);
210     }
211
212     /**
213     * Fail with an error.
214     * Will print a big failure message to System.out.
215     * @param s Failure description
216     */

217     void fail(String JavaDoc s)
218     {
219         failures++;
220         say("" + NEW_LINE + "");
221         say("*******************************************************");
222         say("********************* FAILURE! **********************");
223         say("*******************************************************");
224         say("" + NEW_LINE + "");
225         say(s);
226         say("");
227         // make sure the writer gets flushed.
228
PrintWriter JavaDoc writer = new PrintWriter JavaDoc( System.out );
229         compiler.dumpProgram( writer );
230         writer.flush();
231         say("" + NEW_LINE + "");
232     }
233
234     /**
235      * Show a success
236      * @param s Success story
237      */

238     void success(String JavaDoc s)
239     {
240         if (showSuccesses)
241         {
242             show();
243             say("Success: " + s);
244         }
245     }
246
247     /**
248      * Say something to standard out
249      * @param s What to say
250      */

251     void say(String JavaDoc s)
252     {
253         System.out.println (s);
254     }
255
256     /**
257      * Show an expression
258      */

259     void show()
260     {
261         say("" + NEW_LINE + "-----------------------" + NEW_LINE + "");
262         say("Expression #" + (n) + " \"" + expr + "\" ");
263     }
264
265     /**
266      * Dump parenthesized subexpressions found by a regular expression matcher object
267      * @param r Matcher object with results to show
268      */

269     void showParens(RE r)
270     {
271         // Loop through each paren
272
for (int i = 0; i < r.getParenCount(); i++)
273         {
274             // Show paren register
275
say("$" + i + " = " + r.getParen(i));
276         }
277     }
278
279     // Pre-compiled regular expression "a*b"
280
char[] re1Instructions =
281     {
282         0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041,
283         0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047,
284         0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000,
285         0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000,
286         0x0000,
287     };
288
289     REProgram re1 = new REProgram(re1Instructions);
290
291     /*
292      * Current expression and number in automated test
293     */

294     String JavaDoc expr;
295     int n = 0;
296
297     /*
298      * Count of failures in automated test
299      */

300     int failures = 0;
301
302     /**
303      * Run automated tests in RETest.txt file (from Perl 4.0 test battery)
304      * @exception Exception thrown in case of error
305      */

306     void runAutomatedTests(String JavaDoc testDocument) throws Exception JavaDoc
307     {
308         long ms = System.currentTimeMillis();
309
310         // Simple test of pre-compiled regular expressions
311
RE r = new RE(re1);
312         say("a*b");
313         say("aaaab = " + r.match("aaab"));
314         showParens(r);
315         say("b = " + r.match("b"));
316         showParens(r);
317         say("c = " + r.match("c"));
318         showParens(r);
319         say("ccccaaaaab = " + r.match("ccccaaaaab"));
320         showParens(r);
321
322         r = new RE("a*b");
323         String JavaDoc[] s = r.split("xxxxaabxxxxbyyyyaaabzzz");
324         r = new RE("x+");
325         s = r.grep(s);
326         for (int i = 0; i < s.length; i++)
327         {
328             System.out.println ("s[" + i + "] = " + s[i]);
329         }
330
331         r = new RE("a*b");
332         String JavaDoc s1 = r.subst("aaaabfooaaabgarplyaaabwackyb", "-");
333         System.out.println ("s = " + s1);
334
335         // Some unit tests
336
runAutomatedTests();
337
338         // Test from script file
339
File JavaDoc testInput = new File JavaDoc(testDocument);
340         if (! testInput.exists())
341             throw new Exception JavaDoc ("Could not find: " + testDocument);
342         BufferedReader JavaDoc br = new BufferedReader JavaDoc(new FileReader JavaDoc(testInput));
343         try
344         {
345             // While input is available, parse lines
346
while (br.ready())
347             {
348                 // Find next re test case
349
String JavaDoc number = "";
350                 String JavaDoc yesno;
351                 while (br.ready())
352                 {
353                     number = br.readLine();
354                     if (number == null)
355                     {
356                         break;
357                     }
358                     number = number.trim();
359                     if (number.startsWith("#"))
360                     {
361                         break;
362                     }
363                     if (!number.equals(""))
364                     {
365                         System.out.println ("Script error. Line = " + number);
366                         System.exit(0);
367                     }
368                 }
369
370                 // Are we done?
371
if (!br.ready())
372                 {
373                     break;
374                 }
375
376                 // Get expression
377
expr = br.readLine();
378                 n++;
379                 say("");
380                 say(n + ". " + expr);
381                 say("");
382
383                 // Compile it
384
try
385                 {
386                     r.setProgram(compiler.compile(expr));
387                 }
388
389                 // Some expressions *should* cause exceptions to be thrown
390
catch (Exception JavaDoc e)
391                 {
392                     // Get expected result
393
yesno = br.readLine().trim();
394
395                     // If it was supposed to be an error, report success and continue
396
if (yesno.equals("ERR"))
397                     {
398                         say(" Match: ERR");
399                         success("Produces an error (" + e.toString() + "), as expected.");
400                         continue;
401                     }
402
403                     // Wasn't supposed to be an error
404
String JavaDoc message = e.getMessage() == null ? e.toString() : e.getMessage();
405                     fail("Produces an unexpected exception \"" + message + "\"");
406                     e.printStackTrace();
407                 }
408                 catch (Error JavaDoc e)
409                 {
410                     // Internal error happened
411
fail("Compiler threw fatal error \"" + e.getMessage() + "\"");
412                     e.printStackTrace();
413                 }
414
415                 // Get string to match against
416
String JavaDoc matchAgainst = br.readLine().trim();
417                 say(" Match against: '" + matchAgainst + "'");
418
419                 // Expression didn't cause an expected error
420
if (matchAgainst.equals("ERR"))
421                 {
422                     fail("Was expected to be an error, but wasn't.");
423                     continue;
424                 }
425
426                 // Try matching
427
try
428                 {
429                     // Match against the string
430
boolean b = r.match(matchAgainst);
431
432                     // Get expected result
433
yesno = br.readLine().trim();
434
435                     // If match succeeded
436
if (b)
437                     {
438                         // Status
439
say(" Match: YES");
440
441                         // Match wasn't supposed to succeed
442
if (yesno.equals("NO"))
443                         {
444                             fail("Matched \"" + matchAgainst + "\", when not expected to.");
445                         }
446                         else
447                         if (yesno.equals("YES"))
448                         {
449                             // Match succeeded as expected
450
success("Matched \"" + matchAgainst + "\", as expected:");
451
452                             // Show subexpression registers
453
if (showSuccesses)
454                             {
455                                 showParens(r);
456                             }
457
458                             say(" Paren count: " + r.getParenCount());
459
460                             // Check registers against expected contents
461
for (int p = 0; p < r.getParenCount(); p++)
462                             {
463                                 // Get next register
464
String JavaDoc register = br.readLine().trim();
465                                 say(" Paren " + p + " : " + r.getParen(p));
466
467                                 // Compare expected result with actual
468
if (register.length() == 0 && r.getParen(p) == null)
469                                 {
470                                     // Consider "" in test file equal to null
471
} else
472                                 if (!register.equals(r.getParen(p)))
473                                 {
474                                     // Register isn't what it was supposed to be
475
fail("Register " + p + " should be = \"" + register + "\", but is \"" + r.getParen(p) + "\" instead.");
476                                 }
477                             }
478                         }
479                         else
480                         {
481                             // Bad test script
482
die("Test script error!");
483                         }
484                     }
485                     else
486                     {
487                         // Status
488
say(" Match: NO");
489
490                         // Match failed
491
if (yesno.equals("YES"))
492                         {
493                             // Should have failed
494
fail("Did not match \"" + matchAgainst + "\", when expected to.");
495                         }
496                         else
497                         if (yesno.equals("NO"))
498                         {
499                             // Should have failed
500
success("Did not match \"" + matchAgainst + "\", as expected.");
501                         }
502                         else
503                         {
504                             // Bad test script
505
die("Test script error!");
506                         }
507                     }
508                 }
509
510                 // Matcher blew it
511
catch(Exception JavaDoc e)
512                 {
513                     fail("Matcher threw exception: " + e.toString());
514                     e.printStackTrace();
515                 }
516
517                 // Internal error
518
catch(Error JavaDoc e)
519                 {
520                     fail("Matcher threw fatal error \"" + e.getMessage() + "\"");
521                     e.printStackTrace();
522                 }
523             }
524         }
525         finally
526         {
527             br.close();
528         }
529
530         // Show match time
531
System.out.println( NEW_LINE + NEW_LINE + "Match time = " + (System.currentTimeMillis() - ms) + " ms.");
532
533         // Print final results
534
System.out.println( NEW_LINE + "Tests complete. " + n + " tests, " + failures + " failure(s).");
535     }
536
537     /**
538      * Run automated unit test
539      * @exception Exception thrown in case of error
540      */

541     void runAutomatedTests() throws Exception JavaDoc
542     {
543         // Serialization test 1: Compile regexp and serialize/deserialize it
544
RE r = new RE("(a*)b");
545         say("Serialized/deserialized (a*)b");
546         ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc(128);
547         new ObjectOutputStream JavaDoc(out).writeObject(r);
548         ByteArrayInputStream JavaDoc in = new ByteArrayInputStream JavaDoc(out.toByteArray());
549         r = (RE)new ObjectInputStream JavaDoc(in).readObject();
550         if (!r.match("aaab")) {
551             fail("Did not match 'aaab' with deserialized RE.");
552         }
553         say("aaaab = true");
554         showParens(r);
555
556         // Serialization test 2: serialize/deserialize used regexp
557
out.reset();
558         say("Deserialized (a*)b");
559         new ObjectOutputStream JavaDoc(out).writeObject(r);
560         in = new ByteArrayInputStream JavaDoc(out.toByteArray());
561         r = (RE)new ObjectInputStream JavaDoc(in).readObject();
562         if (r.getParenCount() != 0) {
563             fail("Has parens after deserialization.");
564         }
565         if (!r.match("aaab")) {
566             fail("Did not match 'aaab' with deserialized RE.");
567         }
568         say("aaaab = true");
569         showParens(r);
570
571         // Test MATCH_CASEINDEPENDENT
572
r = new RE("abc(\\w*)");
573         say("MATCH_CASEINDEPENDENT abc(\\w*)");
574         r.setMatchFlags(RE.MATCH_CASEINDEPENDENT);
575         say("abc(d*)");
576         if (!r.match("abcddd")) {
577             fail("Did not match 'abcddd'.");
578         }
579         say("abcddd = true");
580         showParens(r);
581
582         if (!r.match("aBcDDdd")) {
583             fail("Did not match 'aBcDDdd'.");
584         }
585         say("aBcDDdd = true");
586         showParens(r);
587
588         if (!r.match("ABCDDDDD")) {
589             fail("Did not match 'ABCDDDDD'.");
590         }
591         say("ABCDDDDD = true");
592         showParens(r);
593     }
594 }
595
Popular Tags