Package fitnesse.fit.anubhava

Source Code of fitnesse.fit.anubhava.DSLAdapter

package fitnesse.fit.anubhava;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fit.Fixture;
import fit.Parse;
import fit.exception.FitFailureException;

/**
* Modified or written by Anubhava Srivastava for use with FitNesse.
* Copyright (c) 2008 Anubhava Srivastava
* Released under the terms of the GNU General Public License version 2
*
* DSL (Domain Specific Language) Adapter is an optional add-on for
* Generic Fixture. DSLAdapter lets testers write their GenerixFixture
* test tables in customer-centric language rather than in core Java.
*
* @author Anubhava Srivastava
* @see http://anubhava.wordpress.com/
*/
public class DSLAdapter extends Fixture {
  public static final String cellDelim = "``";
  public static final char paramDelim = ',';
  public static Pattern backsp = Pattern.compile("\\\\");
  public static Pattern none = Pattern.compile("");
  public static Pattern d = Pattern.compile("\\\\?\\{(\\d+)\\}");

  public static class InvalidParamSequence extends Exception {
    private static final long serialVersionUID = 1L;
    public InvalidParamSequence(String mesg)
    {
      super(mesg);
    }
  }

  public static class CommandRow {
    protected String methodName = null;
    protected Pattern regexp = null;
    protected Matcher matcher = null;
    protected String paramSequence = null;

    public CommandRow(String expression, String methodName, String seq)
    {
      super();
      this.regexp = Pattern.compile(expression);
      this.methodName = methodName;
      this.paramSequence = seq;
    }

    @Override
    public String toString()
    {
      StringBuffer sb = new StringBuffer();
      sb.append("Method Name: " + methodName);
      List<String> params = getParameters();
      if (params != null && params.size() > 0)
        sb.append("\nMethod Parameters: " + getParameters());
      if (matcher != null)
        sb.append("\nMatcher: " + matcher.pattern());
      return sb.toString();
    }

    private String matchIt(String s)
    {
      return matchIt(s, false);
    }

    private String matchIt(String s, boolean isMethod)
    {
      //System.err.println("s is: " + s);
      Matcher m = d.matcher(s);

      StringBuffer sb = new StringBuffer();
      while (m.find()) {
        int start = m.start();
        if (s.charAt(start) == '\\')
          continue;
        else
        {
          int argNo = Integer.parseInt(m.group(1));
          if (argNo <= matcher.groupCount())
          {
            String str = matcher.group(argNo);
            //System.err.println("* group is: " + str);
            if (str.charAt(0) == '\\')
              sb.append('\\');
            else if (!isMethod) {
              Object v = GenericFixture.fetchVariable( str );
              // resolve variables only for String type
              if ( v != null && !v.getClass().isArray()
                  && ( v.getClass().equals(String.class) ||
                    v.getClass().getGenericSuperclass().equals(String.class) )
                 )
                str = v.toString();
            }
            m.appendReplacement(sb, str);
            //System.err.println("* sb is: " + sb);
          }
        }

      }
      m.appendTail(sb);

      //strip all escape characters now
      if (s.charAt(0) != '\\')
        m = none.matcher(sb.toString());
      else
        m = backsp.matcher(sb.toString());
      String param = m.replaceAll("");
      //System.err.println("* param is: " + param);
      return  param ;
    }

    public String getMethodName() {
      //System.err.println("Finding match for methodName: " + methodName);
      String m = matchIt(methodName, true);
      return m;
    }

    public String getExpression() {
      return regexp.pattern();
    }

    public List<String> getParameters() {
      //split params on , ignoring \,
      List<String> parameters = new ArrayList<String>();
      if (paramSequence.length() > 0 && this.matcher != null)
      {
        ArrayList<String> items = new ArrayList<String>();
        int prev=0;
        // special case for bean shell
        if ( !methodName.equals("GenericFixture.bsh") )
        {
          for(int i=0; i<paramSequence.length(); i++)
          {
            if (paramSequence.charAt(i) == paramDelim &&
                (i==0 || paramSequence.charAt(i-1) != '\\'))
            {
              items.add(paramSequence.substring(prev, i).replace("\\,", ",").trim());
              prev=i+1;
            }
          }
        }
        //System.err.println("paramSequence: " + paramSequence + " - " + prev + " - " + paramSequence.substring(prev));
        items.add( paramSequence.substring(prev).replace("\\,", ",").trim() );
        //System.err.println("items: " + items);
        // now replace all $1, $2 etc
        for(String s: items)
        {
          parameters.add( matchIt(s) );
        }
      }
      return parameters;
    }

    public boolean matches(String record) {
      matcher = regexp.matcher(record);
      return matcher.matches();
    }
  }

  public void readRow(Parse row) throws InvalidParamSequence
  {
    int c=0;
    String key = null;
    List<String> values = new ArrayList<String>();
    for (Parse cells = row.parts; cells != null; c++, cells=cells.more)
    {
      String text = Parse.unescape(Parse.unformat(cells.body).trim());
      if (c==0)
      {
        key = text;
      }
      values.add(text.trim());
    }

    if (c<2)
      throw new InvalidParamSequence("Invalid DSL syntax: " + values);

    StringBuffer expression = new StringBuffer(key);
    for(c=1; c<values.size()-2; c++)
    {
      expression.append(cellDelim);
      String val = values.get(c);
      if (val.equals("%"))
        expression.append("(\\p{Print}+)");
      else
        expression.append(val);
    }
    this.add(key, expression.toString(), values.get(c), values.get(c+1));
  }

  /*
   * overriding doRows() method of Fixture class
   */
  @Override
  public void doRows(Parse rows) throws FitFailureException
  {
    try {
      for ( int r=0; rows != null; r++, rows=rows.more )
      {
        readRow(rows);
      }
      //System.out.println("Map is: " + commandMap);
    }
    catch (InvalidParamSequence ips)
    {
      throw new FitFailureException(ips.toString());
    }
  }

  private static Map<String, List<CommandRow>> commandMap =
    new HashMap<String, List<CommandRow>>();

  public static CommandRow findMatch(String key, String... items) {
    StringBuffer record = new StringBuffer(items.length);
    record.append(key);
    for(String s: items) {
      record.append(cellDelim);
      record.append(s);
    }

    CommandRow cr = null;
    List<CommandRow> rows = commandMap.get(camel(key));
    if (rows != null)
    {
      for (CommandRow cRow: rows) {
        //System.err.println("Comparing [" + record + "] with [" +
        //cRow.getExpression() + "]");
        if (cRow.matches(record.toString()))
        {
          cr = cRow;
          //System.err.println("Matched: [" + cr + "]");
          break;
        }
      }
    }
    return cr;
  }

  public void add(String key, String value, String methodName, String seq)
  {
    key = camel(key);
    List<CommandRow> l = commandMap.get(key);
    if (l == null)
      commandMap.put(key, l=new ArrayList<CommandRow>());
    l.add(new CommandRow(value, methodName, seq));
  }

  public static void main(String[] args)
  throws InvalidParamSequence
  {
    DSLAdapter dp = new DSLAdapter();
    dp.add("user types", "user types``(\\p{Print}+)``into``(\\p{Print}+)``field",
        "type", "xpath={2},id={1},[{1}=\\{3}]");
    dp.add("user types", "user types``(\\p{Print}+)", "myMethod", "{1}");
    dp.add("user starts the app", "user starts the app", "start", "");

    CommandRow cr = DSLAdapter.findMatch("user types", "ilog_123", "into", "username", "field");
    if (cr != null)
      System.out.println("Found a matching command: " + cr.methodName + " "
          + cr.getParameters());
    else
      System.out.println("Did Not Find a matching command");

    cr = DSLAdapter.findMatch("user starts the app");
    if (cr != null)
      System.out.println("Found a matching command: " + cr.methodName + " "
          + cr.getParameters());
    else
      System.out.println("Did Not Find a matching command");
  }
}
TOP

Related Classes of fitnesse.fit.anubhava.DSLAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.