Save This Page
Home » jakarta-regexp-1.5 » org.apache » regexp » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.regexp;
   19   
   20   import java.io.BufferedReader;
   21   import java.io.ByteArrayInputStream;
   22   import java.io.ByteArrayOutputStream;
   23   import java.io.File;
   24   import java.io.FileReader;
   25   import java.io.IOException;
   26   import java.io.InputStreamReader;
   27   import java.io.ObjectInputStream;
   28   import java.io.ObjectOutputStream;
   29   import java.io.PrintWriter;
   30   import java.io.StringReader;
   31   
   32   /**
   33    * Data driven (and optionally interactive) testing harness to exercise regular
   34    * expression compiler and matching engine.
   35    *
   36    * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a>
   37    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   38    * @author <a href="mailto:gholam@xtra.co.nz">Michael McCallum</a>
   39    * @version $Id: RETest.java 518156 2007-03-14 14:31:26Z vgritsenko $
   40    */
   41   public class RETest
   42   {
   43       // True if we want to see output from success cases
   44       static final boolean showSuccesses = false;
   45   
   46       // A new line character.
   47       static final String NEW_LINE = System.getProperty("line.separator");
   48   
   49       // Construct a debug compiler
   50       final REDebugCompiler compiler = new REDebugCompiler();
   51   
   52       /**
   53        * Main program entrypoint.  If an argument is given, it will be compiled
   54        * and interactive matching will ensue.  If no argument is given, the
   55        * file RETest.txt will be used as automated testing input.
   56        * @param args Command line arguments (optional regular expression)
   57        */
   58       public static void main(String[] args)
   59       {
   60           try
   61           {
   62               if (!test( args )) {
   63                   System.exit(1);
   64               }
   65           }
   66           catch (Exception e)
   67           {
   68               e.printStackTrace();
   69               System.exit(1);
   70           }
   71       }
   72   
   73       /**
   74        * Testing entrypoint.
   75        * @param args Command line arguments
   76        * @exception Exception thrown in case of error
   77        */
   78       public static boolean test( String[] args ) throws Exception
   79       {
   80           RETest test = new RETest();
   81           // Run interactive tests against a single regexp
   82           if (args.length == 2)
   83           {
   84               test.runInteractiveTests(args[1]);
   85           }
   86           else if (args.length == 1)
   87           {
   88               // Run automated tests
   89               test.runAutomatedTests(args[0]);
   90           }
   91           else
   92           {
   93               System.out.println( "Usage: RETest ([-i] [regex]) ([/path/to/testfile.txt])" );
   94               System.out.println( "By Default will run automated tests from file 'docs/RETest.txt' ..." );
   95               System.out.println();
   96               test.runAutomatedTests("docs/RETest.txt");
   97           }
   98           return test.failures == 0;
   99       }
  100   
  101       /**
  102        * Constructor
  103        */
  104       public RETest()
  105       {
  106       }
  107   
  108       /**
  109        * Compile and test matching against a single expression
  110        * @param expr Expression to compile and test
  111        */
  112       void runInteractiveTests(String expr)
  113       {
  114           RE r = new RE();
  115           try
  116           {
  117               // Compile expression
  118               r.setProgram(compiler.compile(expr));
  119   
  120               // Show expression
  121               say("" + NEW_LINE + "" + expr + "" + NEW_LINE + "");
  122   
  123               // Show program for compiled expression
  124               PrintWriter writer = new PrintWriter( System.out );
  125               compiler.dumpProgram( writer );
  126               writer.flush();
  127   
  128               boolean running = true;
  129               // Test matching against compiled expression
  130               while ( running )
  131               {
  132                   // Read from keyboard
  133                   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  134                   System.out.print("> ");
  135                   System.out.flush();
  136                   String match = br.readLine();
  137   
  138                   if ( match != null )
  139                   {
  140                       // Try a match against the keyboard input
  141                       if (r.match(match))
  142                       {
  143                           say("Match successful.");
  144                       }
  145                       else
  146                       {
  147                           say("Match failed.");
  148                       }
  149   
  150                       // Show subparen registers
  151                       showParens(r);
  152                   }
  153                   else
  154                   {
  155                       running = false;
  156                       System.out.println();
  157                   }
  158               }
  159           }
  160           catch (Exception e)
  161           {
  162               say("Error: " + e.toString());
  163               e.printStackTrace();
  164           }
  165       }
  166   
  167       /**
  168        * Exit with a fatal error.
  169        * @param s Last famous words before exiting
  170        */
  171       void die(String s)
  172       {
  173           say("FATAL ERROR: " + s);
  174           System.exit(-1);
  175       }
  176   
  177       /**
  178        * Fail with an error. Will print a big failure message to System.out.
  179        *
  180        * @param log Output before failure
  181        * @param s Failure description
  182        */
  183       void fail(StringBuffer log, String s)
  184       {
  185           System.out.print(log.toString());
  186           fail(s);
  187       }
  188   
  189       /**
  190        * Fail with an error. Will print a big failure message to System.out.
  191        *
  192        * @param s Failure description
  193        */
  194       void fail(String s)
  195       {
  196           failures++;
  197           say("" + NEW_LINE + "");
  198           say("*******************************************************");
  199           say("*********************  FAILURE!  **********************");
  200           say("*******************************************************");
  201           say("" + NEW_LINE + "");
  202           say(s);
  203           say("");
  204           // make sure the writer gets flushed.
  205           compiler.dumpProgram();
  206           say("" + NEW_LINE + "");
  207       }
  208   
  209       /**
  210        * Say something to standard out
  211        * @param s What to say
  212        */
  213       void say(String s)
  214       {
  215           System.out.println(s);
  216       }
  217   
  218       /**
  219        * Dump parenthesized subexpressions found by a regular expression matcher object
  220        * @param r Matcher object with results to show
  221        */
  222       void showParens(RE r)
  223       {
  224           // Loop through each paren
  225           for (int i = 0; i < r.getParenCount(); i++)
  226           {
  227               // Show paren register
  228               say("$" + i + " = " + r.getParen(i));
  229           }
  230       }
  231   
  232       /*
  233        * number in automated test
  234        */
  235       int testCount = 0;
  236   
  237       /*
  238        * Count of failures in automated test
  239        */
  240       int failures = 0;
  241   
  242       /**
  243        * Run automated tests in RETest.txt file (from Perl 4.0 test battery)
  244        * @exception Exception thrown in case of error
  245        */
  246       void runAutomatedTests(String testDocument) throws Exception
  247       {
  248           long ms = System.currentTimeMillis();
  249   
  250           // Some unit tests
  251           testPrecompiledRE();
  252           testSplitAndGrep();
  253           testSubst();
  254           testOther();
  255   
  256           // Test from script file
  257           File testInput = new File(testDocument);
  258           if (! testInput.exists()) {
  259               throw new Exception ("Could not find: " + testDocument);
  260           }
  261   
  262           BufferedReader br = new BufferedReader(new FileReader(testInput));
  263           try
  264           {
  265               // While input is available, parse lines
  266               while (br.ready())
  267               {
  268                   RETestCase testcase = getNextTestCase(br);
  269                   if (testcase != null) {
  270                       testcase.runTest();
  271                   }
  272               }
  273           }
  274           finally
  275           {
  276               br.close();
  277           }
  278   
  279           // Show match time
  280           say(NEW_LINE + NEW_LINE + "Match time = " + (System.currentTimeMillis() - ms) + " ms.");
  281   
  282           // Print final results
  283           if (failures > 0) {
  284               say("*************** THERE ARE FAILURES! *******************");
  285           }
  286           say("Tests complete.  " + testCount + " tests, " + failures + " failure(s).");
  287       }
  288   
  289       /**
  290        * Run automated unit test
  291        * @exception Exception thrown in case of error
  292        */
  293       void testOther() throws Exception
  294       {
  295           // Serialization test 1: Compile regexp and serialize/deserialize it
  296           RE r = new RE("(a*)b");
  297           say("Serialized/deserialized (a*)b");
  298           ByteArrayOutputStream out = new ByteArrayOutputStream(128);
  299           new ObjectOutputStream(out).writeObject(r);
  300           ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
  301           r = (RE)new ObjectInputStream(in).readObject();
  302           if (!r.match("aaab"))
  303           {
  304               fail("Did not match 'aaab' with deserialized RE.");
  305           } else {
  306               say("aaaab = true");
  307               showParens(r);
  308           }
  309   
  310           // Serialization test 2: serialize/deserialize used regexp
  311           out.reset();
  312           say("Deserialized (a*)b");
  313           new ObjectOutputStream(out).writeObject(r);
  314           in = new ByteArrayInputStream(out.toByteArray());
  315           r = (RE)new ObjectInputStream(in).readObject();
  316           if (r.getParenCount() != 0)
  317           {
  318               fail("Has parens after deserialization.");
  319           }
  320           if (!r.match("aaab"))
  321           {
  322               fail("Did not match 'aaab' with deserialized RE.");
  323           } else {
  324               say("aaaab = true");
  325               showParens(r);
  326           }
  327   
  328           // Test MATCH_CASEINDEPENDENT
  329           r = new RE("abc(\\w*)");
  330           say("MATCH_CASEINDEPENDENT abc(\\w*)");
  331           r.setMatchFlags(RE.MATCH_CASEINDEPENDENT);
  332           say("abc(d*)");
  333           if (!r.match("abcddd"))
  334           {
  335               fail("Did not match 'abcddd'.");
  336           } else {
  337               say("abcddd = true");
  338               showParens(r);
  339           }
  340   
  341           if (!r.match("aBcDDdd"))
  342           {
  343               fail("Did not match 'aBcDDdd'.");
  344           } else {
  345               say("aBcDDdd = true");
  346               showParens(r);
  347           }
  348   
  349           if (!r.match("ABCDDDDD"))
  350           {
  351               fail("Did not match 'ABCDDDDD'.");
  352           } else {
  353               say("ABCDDDDD = true");
  354               showParens(r);
  355           }
  356   
  357           r = new RE("(A*)b\\1");
  358           r.setMatchFlags(RE.MATCH_CASEINDEPENDENT);
  359           if (!r.match("AaAaaaBAAAAAA"))
  360           {
  361               fail("Did not match 'AaAaaaBAAAAAA'.");
  362           } else {
  363               say("AaAaaaBAAAAAA = true");
  364               showParens(r);
  365           }
  366   
  367           r = new RE("[A-Z]*");
  368           r.setMatchFlags(RE.MATCH_CASEINDEPENDENT);
  369           if (!r.match("CaBgDe12"))
  370           {
  371               fail("Did not match 'CaBgDe12'.");
  372           } else {
  373               say("CaBgDe12 = true");
  374               showParens(r);
  375           }
  376   
  377           // Test for eol/bol symbols.
  378           r = new RE("^abc$");
  379           if (r.match("\nabc")) {
  380               fail("\"\\nabc\" matches \"^abc$\"");
  381           }
  382   
  383           // Test MATCH_MULTILINE. Test for eol/bol symbols.
  384           r = new RE("^abc$", RE.MATCH_MULTILINE);
  385           if (!r.match("\nabc")) {
  386               fail("\"\\nabc\" doesn't match \"^abc$\"");
  387           }
  388           if (!r.match("\rabc")) {
  389               fail("\"\\rabc\" doesn't match \"^abc$\"");
  390           }
  391           if (!r.match("\r\nabc")) {
  392               fail("\"\\r\\nabc\" doesn't match \"^abc$\"");
  393           }
  394           if (!r.match("\u0085abc")) {
  395               fail("\"\\u0085abc\" doesn't match \"^abc$\"");
  396           }
  397           if (!r.match("\u2028abc")) {
  398               fail("\"\\u2028abc\" doesn't match \"^abc$\"");
  399           }
  400           if (!r.match("\u2029abc")) {
  401               fail("\"\\u2029abc\" doesn't match \"^abc$\"");
  402           }
  403   
  404           // Test MATCH_MULTILINE. Test that '.' does not matches new line.
  405           r = new RE("^a.*b$", RE.MATCH_MULTILINE);
  406           if (r.match("a\nb")) {
  407               fail("\"a\\nb\" matches \"^a.*b$\"");
  408           }
  409           if (r.match("a\rb")) {
  410               fail("\"a\\rb\" matches \"^a.*b$\"");
  411           }
  412           if (r.match("a\r\nb")) {
  413               fail("\"a\\r\\nb\" matches \"^a.*b$\"");
  414           }
  415           if (r.match("a\u0085b")) {
  416               fail("\"a\\u0085b\" matches \"^a.*b$\"");
  417           }
  418           if (r.match("a\u2028b")) {
  419               fail("\"a\\u2028b\" matches \"^a.*b$\"");
  420           }
  421           if (r.match("a\u2029b")) {
  422               fail("\"a\\u2029b\" matches \"^a.*b$\"");
  423           }
  424   
  425           // Bug 38331: Large program
  426           try {
  427               REDebugCompiler c = new REDebugCompiler();
  428               c.compile("(a{8192})?");
  429               fail("(a{8192})? should fail to compile.");
  430               c.dumpProgram();
  431           } catch (RESyntaxException e) {
  432               // expected
  433           }
  434       }
  435   
  436       private void testPrecompiledRE()
  437       {
  438           // Pre-compiled regular expression "a*b"
  439           char[] re1Instructions =
  440           {
  441               0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041,
  442               0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047,
  443               0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000,
  444               0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000,
  445               0x0000,
  446           };
  447   
  448           REProgram re1 = new REProgram(re1Instructions);
  449   
  450           // Simple test of pre-compiled regular expressions
  451           RE r = new RE(re1);
  452           say("a*b");
  453           boolean result = r.match("aaab");
  454           say("aaab = " + result);
  455           showParens(r);
  456           if (!result) {
  457               fail("\"aaab\" doesn't match to precompiled \"a*b\"");
  458           }
  459   
  460           result = r.match("b");
  461           say("b = " + result);
  462           showParens(r);
  463           if (!result) {
  464               fail("\"b\" doesn't match to precompiled \"a*b\"");
  465           }
  466   
  467           result = r.match("c");
  468           say("c = " + result);
  469           showParens(r);
  470           if (result) {
  471               fail("\"c\" matches to precompiled \"a*b\"");
  472           }
  473   
  474           result = r.match("ccccaaaaab");
  475           say("ccccaaaaab = " + result);
  476           showParens(r);
  477           if (!result) {
  478               fail("\"ccccaaaaab\" doesn't match to precompiled \"a*b\"");
  479           }
  480       }
  481   
  482       private void testSplitAndGrep()
  483       {
  484           String[] expected = {"xxxx", "xxxx", "yyyy", "zzz"};
  485           RE r = new RE("a*b");
  486           String[] s = r.split("xxxxaabxxxxbyyyyaaabzzz");
  487           for (int i = 0; i < expected.length && i < s.length; i++) {
  488               assertEquals("Wrong splitted part", expected[i], s[i]);
  489           }
  490           assertEquals("Wrong number of splitted parts", expected.length,
  491                        s.length);
  492   
  493           r = new RE("x+");
  494           expected = new String[] {"xxxx", "xxxx"};
  495           s = r.grep(s);
  496           for (int i = 0; i < s.length; i++)
  497           {
  498               say("s[" + i + "] = " + s[i]);
  499               assertEquals("Grep fails", expected[i], s[i]);
  500           }
  501           assertEquals("Wrong number of string found by grep", expected.length,
  502                        s.length);
  503       }
  504   
  505       private void testSubst()
  506       {
  507           RE r = new RE("a*b");
  508           String expected = "-foo-garply-wacky-";
  509           String actual = r.subst("aaaabfooaaabgarplyaaabwackyb", "-");
  510           assertEquals("Wrong result of substitution in \"a*b\"", expected, actual);
  511   
  512           // Test subst() with backreferences
  513           r = new RE("http://[\\.\\w\\-\\?/~_@&=%]+");
  514           actual = r.subst("visit us: http://www.apache.org!",
  515                            "1234<a href=\"$0\">$0</a>", RE.REPLACE_BACKREFERENCES);
  516           assertEquals("Wrong subst() result", "visit us: 1234<a href=\"http://www.apache.org\">http://www.apache.org</a>!", actual);
  517   
  518           // Test subst() with backreferences without leading characters
  519           // before first backreference
  520           r = new RE("(.*?)=(.*)");
  521           actual = r.subst("variable=value",
  522                            "$1_test_$212", RE.REPLACE_BACKREFERENCES);
  523           assertEquals("Wrong subst() result", "variable_test_value12", actual);
  524   
  525           // Test subst() with NO backreferences
  526           r = new RE("^a$");
  527           actual = r.subst("a",
  528                            "b", RE.REPLACE_BACKREFERENCES);
  529           assertEquals("Wrong subst() result", "b", actual);
  530   
  531           // Test subst() with NO backreferences
  532           r = new RE("^a$", RE.MATCH_MULTILINE);
  533           actual = r.subst("\r\na\r\n",
  534                            "b", RE.REPLACE_BACKREFERENCES);
  535           assertEquals("Wrong subst() result", "\r\nb\r\n", actual);
  536   
  537           // Test for Bug #36106
  538           r = new RE("fo(o)");
  539           actual = r.subst("foo",
  540                            "$1", RE.REPLACE_BACKREFERENCES);
  541           assertEquals("Wrong subst() result", "o", actual);
  542   
  543           // Test for Bug #36405
  544           r = new RE("^(.*?)(x)?$");
  545           actual = r.subst("abc",
  546                            "$1-$2", RE.REPLACE_BACKREFERENCES);
  547           assertEquals("Wrong subst() result", "abc-", actual);
  548   
  549           r = new RE("^(.*?)(x)?$");
  550           actual = r.subst("abcx",
  551                            "$1-$2", RE.REPLACE_BACKREFERENCES);
  552           assertEquals("Wrong subst() result", "abc-x", actual);
  553   
  554           r = new RE("([a-b]+?)([c-d]+)");
  555           actual = r.subst("zzabcdzz",
  556                            "$1-$2", RE.REPLACE_BACKREFERENCES);
  557           assertEquals("Wrong subst() result", "zzab-cdzz", actual);
  558       }
  559   
  560       public void assertEquals(String message, String expected, String actual)
  561       {
  562           if (expected != null && !expected.equals(actual)
  563               || actual != null && !actual.equals(expected))
  564           {
  565               fail(message + " (expected \"" + expected
  566                    + "\", actual \"" + actual + "\")");
  567           }
  568       }
  569   
  570       public void assertEquals(String message, int expected, int actual)
  571       {
  572           if (expected != actual) {
  573               fail(message + " (expected \"" + expected
  574                    + "\", actual \"" + actual + "\")");
  575           }
  576       }
  577   
  578       /**
  579        * Converts yesno string to boolean.
  580        * @param yesno string representation of expected result
  581        * @return true if yesno is "YES", false if yesno is "NO"
  582        *         stops program otherwise.
  583        */
  584       private boolean getExpectedResult(String yesno)
  585       {
  586           if ("NO".equals(yesno))
  587           {
  588               return false;
  589           }
  590           else if ("YES".equals(yesno))
  591           {
  592               return true;
  593           }
  594           else
  595           {
  596               // Bad test script
  597               die("Test script error!");
  598               return false; //to please javac
  599           }
  600       }
  601   
  602       /**
  603        * Finds next test description in a given script.
  604        * @param br <code>BufferedReader</code> for a script file
  605        * @return strign tag for next test description
  606        * @exception IOException if some io problems occured
  607        */
  608       private String findNextTest(BufferedReader br) throws IOException
  609       {
  610           String number = "";
  611   
  612           while (br.ready())
  613           {
  614               number = br.readLine();
  615               if (number == null)
  616               {
  617                   break;
  618               }
  619               number = number.trim();
  620               if (number.startsWith("##"))
  621               {
  622                   continue;
  623               }
  624               if (number.startsWith("#"))
  625               {
  626                   break;
  627               }
  628               if (!number.equals(""))
  629               {
  630                   say("Script error.  Line = " + number);
  631                   System.exit(-1);
  632               }
  633           }
  634           return number;
  635       }
  636   
  637       /**
  638        * Creates testcase for the next test description in the script file.
  639        * @param br <code>BufferedReader</code> for script file.
  640        * @return a new tescase or null.
  641        * @exception IOException if some io problems occured
  642        */
  643       private RETestCase getNextTestCase(BufferedReader br) throws IOException
  644       {
  645           // Find next re test case
  646           final String tag = findNextTest(br);
  647   
  648           // Are we done?
  649           if (!br.ready())
  650           {
  651               return null;
  652           }
  653   
  654           // Get expression
  655           final String expr = br.readLine();
  656   
  657           // Get test information
  658           final String matchAgainst = br.readLine();
  659           final boolean badPattern = "ERR".equals(matchAgainst);
  660           boolean shouldMatch = false;
  661           int expectedParenCount;
  662           String[] expectedParens = null;
  663   
  664           if (!badPattern) {
  665               shouldMatch = getExpectedResult(br.readLine().trim());
  666               if (shouldMatch) {
  667                   expectedParenCount = Integer.parseInt(br.readLine().trim());
  668                   expectedParens = new String[expectedParenCount];
  669                   for (int i = 0; i < expectedParenCount; i++) {
  670                       expectedParens[i] = br.readLine();
  671                   }
  672               }
  673           }
  674   
  675           return new RETestCase(this, tag, expr, matchAgainst, badPattern,
  676                                 shouldMatch, expectedParens);
  677       }
  678   }
  679   
  680   final class RETestCase
  681   {
  682       final private StringBuffer log = new StringBuffer();
  683       final private int number;
  684       final private String tag; // number from script file
  685       final private String pattern;
  686       final private String toMatch;
  687       final private boolean badPattern;
  688       final private boolean shouldMatch;
  689       final private String[] parens;
  690       final private RETest test;
  691       private RE regexp;
  692   
  693       public RETestCase(RETest test, String tag, String pattern,
  694                         String toMatch, boolean badPattern,
  695                         boolean shouldMatch, String[] parens)
  696       {
  697           this.number = ++test.testCount;
  698           this.test = test;
  699           this.tag = tag;
  700           this.pattern = pattern;
  701           this.toMatch = toMatch;
  702           this.badPattern = badPattern;
  703           this.shouldMatch = shouldMatch;
  704           if (parens != null) {
  705               this.parens = new String[parens.length];
  706               System.arraycopy(parens, 0, this.parens, 0, parens.length);
  707           } else {
  708               this.parens = null;
  709           }
  710       }
  711   
  712       public void runTest()
  713       {
  714           test.say(tag + "(" + number + "): " + pattern);
  715           if (testCreation()) {
  716               testMatch();
  717           }
  718       }
  719   
  720       boolean testCreation()
  721       {
  722           try
  723           {
  724               // Compile it
  725               regexp = new RE();
  726               regexp.setProgram(test.compiler.compile(pattern));
  727               // Expression didn't cause an expected error
  728               if (badPattern)
  729               {
  730                   test.fail(log, "Was expected to be an error, but wasn't.");
  731                   return false;
  732               }
  733   
  734               return true;
  735           }
  736           // Some expressions *should* cause exceptions to be thrown
  737           catch (Exception e)
  738           {
  739               // If it was supposed to be an error, report success and continue
  740               if (badPattern)
  741               {
  742                   log.append("   Match: ERR\n");
  743                   success("Produces an error (" + e.toString() + "), as expected.");
  744                   return false;
  745               }
  746   
  747               // Wasn't supposed to be an error
  748               String message = (e.getMessage() == null) ? e.toString() : e.getMessage();
  749               test.fail(log, "Produces an unexpected exception \"" + message + "\"");
  750               e.printStackTrace();
  751           }
  752           catch (Error e)
  753           {
  754               // Internal error happened
  755               test.fail(log, "Compiler threw fatal error \"" + e.getMessage() + "\"");
  756               e.printStackTrace();
  757           }
  758   
  759           return false;
  760       }
  761   
  762       private void testMatch()
  763       {
  764           log.append("   Match against: '").append(toMatch).append("'\n");
  765           // Try regular matching
  766           try
  767           {
  768               // Match against the string
  769               boolean result = regexp.match(toMatch);
  770               log.append("   Matched: ").append(result ? "YES" : "NO").append("\n");
  771   
  772               // Check result, parens, and iterators
  773               if (checkResult(result) && (!shouldMatch || checkParens()))
  774               {
  775                   // test match(CharacterIterator, int)
  776                   // for every CharacterIterator implementation.
  777                   log.append("   Match using StringCharacterIterator\n");
  778                   if (!tryMatchUsingCI(new StringCharacterIterator(toMatch)))
  779                       return;
  780   
  781                   log.append("   Match using CharacterArrayCharacterIterator\n");
  782                   if (!tryMatchUsingCI(new CharacterArrayCharacterIterator(toMatch.toCharArray(), 0, toMatch.length())))
  783                       return;
  784   
  785                   log.append("   Match using StreamCharacterIterator\n");
  786                   if (!tryMatchUsingCI(new StreamCharacterIterator(new ByteArrayInputStream(toMatch.getBytes()))))
  787                       return;
  788   
  789                   log.append("   Match using ReaderCharacterIterator\n");
  790                   if (!tryMatchUsingCI(new ReaderCharacterIterator(new StringReader(toMatch))))
  791                       return;
  792               }
  793           }
  794           // Matcher blew it
  795           catch(Exception e)
  796           {
  797               test.fail(log, "Matcher threw exception: " + e.toString());
  798               e.printStackTrace();
  799           }
  800           // Internal error
  801           catch(Error e)
  802           {
  803               test.fail(log, "Matcher threw fatal error \"" + e.getMessage() + "\"");
  804               e.printStackTrace();
  805           }
  806       }
  807   
  808       private boolean checkResult(boolean result)
  809       {
  810           // Write status
  811           if (result == shouldMatch) {
  812               success((shouldMatch ? "Matched" : "Did not match")
  813                       + " \"" + toMatch + "\", as expected:");
  814               return true;
  815           } else {
  816               if (shouldMatch) {
  817                   test.fail(log, "Did not match \"" + toMatch + "\", when expected to.");
  818               } else {
  819                   test.fail(log, "Matched \"" + toMatch + "\", when not expected to.");
  820               }
  821               return false;
  822           }
  823       }
  824   
  825       private boolean checkParens()
  826       {
  827           // Show subexpression registers
  828           if (RETest.showSuccesses)
  829           {
  830               test.showParens(regexp);
  831           }
  832   
  833           log.append("   Paren count: ").append(regexp.getParenCount()).append("\n");
  834           if (!assertEquals(log, "Wrong number of parens", parens.length, regexp.getParenCount()))
  835           {
  836               return false;
  837           }
  838   
  839           // Check registers against expected contents
  840           for (int p = 0; p < regexp.getParenCount(); p++)
  841           {
  842               log.append("   Paren ").append(p).append(": ").append(regexp.getParen(p)).append("\n");
  843   
  844               // Compare expected result with actual
  845               if ("null".equals(parens[p]) && regexp.getParen(p) == null)
  846               {
  847                   // Consider "null" in test file equal to null
  848                   continue;
  849               }
  850               if (!assertEquals(log, "Wrong register " + p, parens[p], regexp.getParen(p)))
  851               {
  852                   return false;
  853               }
  854           }
  855   
  856           return true;
  857       }
  858   
  859       boolean tryMatchUsingCI(CharacterIterator matchAgainst)
  860       {
  861           try {
  862               boolean result = regexp.match(matchAgainst, 0);
  863               log.append("   Match: ").append(result ? "YES" : "NO").append("\n");
  864               return checkResult(result) && (!shouldMatch || checkParens());
  865           }
  866           // Matcher blew it
  867           catch(Exception e)
  868           {
  869               test.fail(log, "Matcher threw exception: " + e.toString());
  870               e.printStackTrace();
  871           }
  872           // Internal error
  873           catch(Error e)
  874           {
  875               test.fail(log, "Matcher threw fatal error \"" + e.getMessage() + "\"");
  876               e.printStackTrace();
  877           }
  878           return false;
  879       }
  880   
  881       public boolean assertEquals(StringBuffer log, String message, String expected, String actual)
  882       {
  883           if (expected != null && !expected.equals(actual)
  884               || actual != null && !actual.equals(expected))
  885           {
  886               test.fail(log, message + " (expected \"" + expected
  887                         + "\", actual \"" + actual + "\")");
  888               return false;
  889           }
  890           return true;
  891       }
  892   
  893       public boolean assertEquals(StringBuffer log, String message, int expected, int actual)
  894       {
  895           if (expected != actual) {
  896               test.fail(log, message + " (expected \"" + expected
  897                         + "\", actual \"" + actual + "\")");
  898               return false;
  899           }
  900           return true;
  901       }
  902   
  903       /**
  904        * Show a success
  905        * @param s Success story
  906        */
  907       void success(String s)
  908       {
  909           if (RETest.showSuccesses)
  910           {
  911               test.say("" + RETest.NEW_LINE + "-----------------------" + RETest.NEW_LINE + "");
  912               test.say("Expression #" + (number) + " \"" + pattern + "\" ");
  913               test.say("Success: " + s);
  914           }
  915       }
  916   }

Save This Page
Home » jakarta-regexp-1.5 » org.apache » regexp » [javadoc | source]