Package fitnesse.testsystems.slim.tables

Source Code of fitnesse.testsystems.slim.tables.ScenarioTable

// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.testsystems.slim.tables;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fitnesse.slim.instructions.Instruction;
import fitnesse.testsystems.ExecutionResult;
import fitnesse.testsystems.TestResult;
import fitnesse.testsystems.TestSummary;
import fitnesse.testsystems.slim.SlimTestContext;
import fitnesse.testsystems.slim.Table;
import fitnesse.testsystems.slim.results.SlimTestResult;
import org.apache.commons.lang.StringUtils;


public class ScenarioTable extends SlimTable {
  private static final String instancePrefix = "scenarioTable";
  private static final String underscorePattern = "\\W_(?=\\W|$)";
  private String name;
  private List<String> inputs = new ArrayList<String>();
  private Set<String> outputs = new HashSet<String>();
  private final int colsInHeader = table.getColumnCountInRow(0);
  private boolean parameterized = false;

  public ScenarioTable(Table table, String tableId,
                       SlimTestContext testContext) {
    super(table, tableId, testContext);
  }

  protected String getTableType() {
    return instancePrefix;
  }

  @Override
  public List<SlimAssertion> getAssertions() throws SyntaxError {
    parseTable();

    // Note: scenario's only add instructions when needed to,
    // since they might need parameters.
    return Collections.emptyList();
  }

  private void parseTable() throws SyntaxError {
    validateHeader();

    parameterized = determineParameterized();
    name = getScenarioName();
    getTestContext().addScenario(name, this);
    getScenarioArguments();
  }

  protected boolean determineParameterized() {
    String firstNameCell = table.getCellContents(1, 0);
    return isNameParameterized(firstNameCell);
  }

    protected void getScenarioArguments() {
    if (parameterized) {
      getArgumentsForParameterizedName();
    } else {
      getArgumentsForAlternatingName();
    }
  }

  private void getArgumentsForAlternatingName() {
    for (int inputCol = 2; inputCol < colsInHeader; inputCol += 2) {
      String argName = table.getCellContents(inputCol, 0);

      splitInputAndOutputArguments(argName);
    }
  }

private void splitInputAndOutputArguments(String argName) {
  argName = argName.trim();
  if (argName.endsWith("?")) {
        String disgracedArgName = Disgracer.disgraceMethodName(argName);
        outputs.add(disgracedArgName);
      } else {
        String disgracedArgName = Disgracer.disgraceMethodName(argName);
        inputs.add(disgracedArgName);
      }
}

  private void getArgumentsForParameterizedName() {
    String argumentString = table.getCellContents(2, 0);
    String[] arguments = argumentString.split(",");

    for (String argument : arguments) {
        splitInputAndOutputArguments(argument);
    }
  }

  protected void addInput(String argument) {
    inputs.add(argument);
  }

  public String getScenarioName() {
    if (parameterized) {
      String parameterizedName = table.getCellContents(1, 0);

      return unparameterize(parameterizedName);
    } else {
      return getNameFromAlternatingCells();
    }
  }

  public static boolean isNameParameterized(String firstNameCell) {
    Pattern regPat = Pattern.compile(underscorePattern);
    Matcher underscoreMatcher = regPat.matcher(firstNameCell);

    return underscoreMatcher.find();
  }

  public static String unparameterize(String firstNameCell) {
    String name = firstNameCell.replaceAll(underscorePattern, " ").trim();

    return Disgracer.disgraceClassName(name);
  }

  private String getNameFromAlternatingCells() {
    StringBuffer nameBuffer = new StringBuffer();

    for (int nameCol = 1; nameCol < colsInHeader; nameCol += 2)
      nameBuffer.append(table.getCellContents(nameCol, 0)).append(" ");

    return Disgracer.disgraceClassName(nameBuffer.toString().trim());
  }

  private void validateHeader() throws SyntaxError {
    if (colsInHeader <= 1) {
      throw new SyntaxError("Scenario tables must have a name.");
    }
  }

  public String getName() {
    return name;
  }

  public Set<String> getInputs() {
    return new HashSet<String>(inputs);
  }

  public Set<String> getOutputs() {
    return outputs;
  }

  public List<SlimAssertion> call(final Map<String, String> scenarioArguments,
                   SlimTable parentTable, int row) throws SyntaxError {
    Table newTable = getTable().asTemplate(new Table.CellContentSubstitution() {
      @Override
      public String substitute(String content) throws SyntaxError {
        for (Map.Entry<String, String> scenarioArgument : scenarioArguments.entrySet()) {
          String arg = scenarioArgument.getKey();
          if (getInputs().contains(arg)) {
            String argument = scenarioArguments.get(arg);
            content = StringUtils.replace(content, "@" + arg, argument);
            content = StringUtils.replace(content, "@{" + arg + "}", argument);
          } else {
            throw new SyntaxError(String.format("The argument %s is not an input to the scenario.", arg));
          }
        }
        return content;
      }
    });
    ScenarioTestContext testContext = new ScenarioTestContext(parentTable.getTestContext());
    ScriptTable t = createChild(testContext, parentTable, newTable);
    parentTable.addChildTable(t, row);
    List<SlimAssertion> assertions = t.getAssertions();
    assertions.add(makeAssertion(Instruction.NOOP_INSTRUCTION, new ScenarioExpectation(t, row)));
    return assertions;
  }

  protected ScriptTable createChild(ScenarioTestContext testContext, SlimTable parentTable, Table newTable) {
    ScriptTable scriptTable;
    if (parentTable instanceof ScriptTable && !parentTable.getClass().equals(ScriptTable.class)) {
      scriptTable = createChild((ScriptTable) parentTable, newTable, testContext);
    } else {
      scriptTable = new ScriptTable(newTable, id, testContext);
    }
    scriptTable.setCustomComparatorRegistry(customComparatorRegistry);
    return scriptTable;
  }

  protected ScriptTable createChild(ScriptTable parentScriptTable, Table newTable, SlimTestContext testContext) {
    Class<? extends ScriptTable> parentTableClass = parentScriptTable.getClass();
    try {
      return SlimTableFactory.createTable(parentTableClass, newTable, id, testContext);
    } catch (Exception e) {
      throw new RuntimeException("Unable to create child table of type: " + parentTableClass.getName(), e);
    }
  }

  public List<SlimAssertion> call(String[] args, ScriptTable parentTable, int row) throws SyntaxError {
    Map<String, String> scenarioArguments = new HashMap<String, String>();

    for (int i = 0; (i < inputs.size()) && (i < args.length); i++)
      scenarioArguments.put(inputs.get(i), args[i]);

    return call(scenarioArguments, parentTable, row);
  }

  public boolean isParameterized() {
    return parameterized;
  }

///// scriptTable matcher logic:
  public String[] matchParameters(String invokingString) {
    String parameterizedName;

    if (parameterized) {
      parameterizedName = table.getCellContents(1, 0);
    } else if (this.inputs.size() > 0) {
      StringBuilder nameBuffer = new StringBuilder();

      for (int nameCol = 1; nameCol < colsInHeader; nameCol += 2)
        nameBuffer.append(table.getCellContents(nameCol, 0))
          .append(" _ ");

      parameterizedName = nameBuffer.toString().trim();
    } else {
      return null;
    }

    return getArgumentsMatchingParameterizedName(parameterizedName,
      invokingString);
  }

  private String[] getArgumentsMatchingParameterizedName(
    String parameterizedName, String invokingString) {
    Matcher matcher = makeParameterizedNameMatcher(parameterizedName,
      invokingString);

    if (matcher.matches()) {
      return extractNamesFromMatcher(matcher);
    } else {
      return null;
    }
  }

  private Matcher makeParameterizedNameMatcher(String parameterizedName,
                                               String invokingString) {
    String patternString = parameterizedName.replaceAll("_", "(.*)");
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(invokingString);

    return matcher;
  }

  private String[] extractNamesFromMatcher(Matcher matcher) {
    String[] arguments = new String[matcher.groupCount()];

    for (int i = 0; i < arguments.length; i++) {
      arguments[i] = matcher.group(i + 1);
    }

    return arguments;
  }
//// till here

  private final class ScenarioExpectation extends RowExpectation {
    private ScriptTable scriptTable;

    private ScenarioExpectation(ScriptTable scriptTable, int row) {
      super(-1, row); // We don't care about anything but the row.
      this.scriptTable = scriptTable;
    }

    @Override
    public TestResult evaluateExpectation(Object returnValue) {
      SlimTable parent = scriptTable.getParent();
      ExecutionResult testStatus = ((ScenarioTestContext) scriptTable.getTestContext()).getExecutionResult();
      if (outputs.isEmpty() || testStatus != ExecutionResult.PASS){
        // if the scenario has no output parameters
        // or the scenario failed
        // then the whole line should be flagged
        parent.getTable().updateContent(getRow(), new SlimTestResult(testStatus));
      }
      return null;
    }

    @Override
    protected SlimTestResult createEvaluationMessage(String actual, String expected) {
      return null;
    }
  }

  // This context is mainly used to determine if the scenario table evaluated successfully
  // This determines the execution result for the "calling" table row.
  protected final class ScenarioTestContext implements SlimTestContext {

    private final SlimTestContext testContext;
    private final TestSummary testSummary = new TestSummary();

    public ScenarioTestContext(SlimTestContext testContext) {
      this.testContext = testContext;
    }

    @Override
    public String getSymbol(String symbolName) {
      return testContext.getSymbol(symbolName);
    }

    @Override
    public void setSymbol(String symbolName, String value) {
      testContext.setSymbol(symbolName, value);
    }

    @Override
    public void addScenario(String scenarioName, ScenarioTable scenarioTable) {
      testContext.addScenario(scenarioName, scenarioTable);
    }

    @Override
    public ScenarioTable getScenario(String scenarioName) {
      return testContext.getScenario(scenarioName);
    }

    @Override
    public Collection<ScenarioTable> getScenarios() {
      return testContext.getScenarios();
    }

    @Override
    public void incrementPassedTestsCount() {
      increment(ExecutionResult.PASS);
    }

    @Override
    public void incrementFailedTestsCount() {
      increment(ExecutionResult.FAIL);
    }

    @Override
    public void incrementErroredTestsCount() {
      increment(ExecutionResult.ERROR);
    }

    @Override
    public void incrementIgnoredTestsCount() {
      increment(ExecutionResult.IGNORE);
    }

    @Override
    public void increment(ExecutionResult result) {
      testContext.increment(result);
      testSummary.add(result);
    }

    @Override
    public void increment(TestSummary summary) {
      testContext.increment(summary);
      testSummary.add(summary);
    }

    ExecutionResult getExecutionResult() {
      return ExecutionResult.getExecutionResult(testSummary);
    }
  }
}
TOP

Related Classes of fitnesse.testsystems.slim.tables.ScenarioTable

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.