code: package freemarker.eclipse.test;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import junit.framework.TestCase;
  
  import org.eclipse.jface.text.rules.IRule;
  import org.eclipse.jface.text.rules.IToken;
  import org.eclipse.jface.text.rules.Token;
  
  import freemarker.eclipse.test.util.MockCharacterScanner;
  
  /**
   * Superclass for all rule tests. A subclass can add tests by invoking
   * {@link #addMatchingTest addMatchingTest} or
   * {@link #addNonMatchingTest addNonMatchingTest}.
   *
   * Matching tests evaluate to a token (which is checked) and a position
   * after the analysis (which is checked as well).
   *
   * Non-matching tests should evaluate to Token.UNDEFINED and the
   * position after the analysis should be 0.
   *
   * @author <a href="mailto:stephan&#64;chaquotay.net">Stephan Mueller</a>
   * @version $Id: AbstractRuleTestCase.java,v 1.1 2004/02/05 00:17:52 stephanmueller Exp $
   */
  public abstract class AbstractRuleTestCase extends TestCase {
  
      protected List<RuleTestInfo> tests = new ArrayList<RuleTestInfo>();
      protected IRule rule = null;
  
      public static final IToken NO_MATCH = new Token(null) {
          public boolean isUndefined() {
              return (true);
          }
          public String toString() {
              return "no match";
          }
      };
  
      public static final IToken MATCH = new Token(null) {
          public String toString() {
              return "match";
          }
      };
  
      public AbstractRuleTestCase(String name) {
          super(name);
      }
  
      public void runTest() {
          if (null == rule) {
              throw new RuntimeException("rule == null");
          }
          for (int i = 0; i < tests.size(); i++) {
              RuleTestInfo info = tests.get(i);
              MockCharacterScanner scanner =
                  new MockCharacterScanner(info.text);
              IToken result = rule.evaluate(scanner);
  
              // we use our own 'UNDEFINED' token which looks nicer
              if (result.equals(Token.UNDEFINED))
                  result = NO_MATCH;
  
              assertEquals(info.message, info.expected, result);
              assertEquals(info.message, info.pos, scanner.getPos());
          }
      }
  
      public void addMatchingTest(String text, int pos, String message) {
          tests.add(new RuleTestInfo(text, MATCH, pos, message));
      }
  
      public void addNonMatchingTest(String text, String message) {
          tests.add(new RuleTestInfo(text, NO_MATCH, 0, message));
      }
  
      private class RuleTestInfo {
  
          public int pos;
          public IToken expected;
          public String text;
          public String message;
  
          public RuleTestInfo(String text, IToken exp, int pos, String msg) {
              this.pos = pos;
              this.expected = exp;
              this.message = msg;
              this.text = text;
          }
      }
  
  }
  