package net.thucydides.core.reports.adaptors.specflow;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import net.thucydides.core.ThucydidesSystemProperty;
import net.thucydides.core.guice.Injectors;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.util.Inflector;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
public class SpecflowScenarioTitleLine {
public static final String START_ARGUMENT = "(";
public static final char ESCAPE_CHAR = '\\';
public static final char STRING_SEP = '"';
public static final char ARG_SEP = ',';
public static final char END_ARGUMENT = ')';
public static final String NULL = "null";
private final String scenarioTitle;
private final String storyTitle;
private final String storyPath;
private final List<String> parameters;
private final Inflector inflector = new Inflector();
private final EnvironmentVariables environmentVariables;
public SpecflowScenarioTitleLine(String titleLine, EnvironmentVariables environmentVariables) {
List<String> titleElements = elementsFrom(stripLead(titleLine));
this.environmentVariables = environmentVariables;
scenarioTitle = scenarioTitleIn(Lists.reverse(titleElements).get(0));
storyTitle = storyTitleIn(titleElements);
storyPath = pathFrom(titleElements);
parameters = argumentsFrom(titleLine);
}
/**
* From a title line that looks like:
* ***** ESD.Epp.RegularPaymentCapture.SpecFlow.Features.RegularPaymentGroupServiceCallsFeature.PopulateBusinessTransactionAndPaymentTypeDropDownLists("Inputter","Funds Transfer between Own Accounts","N/A","Funds Transfer",null)
* returns a list of string: ["Inputter","Funds Transfer between Own Accounts","N/A","Funds Transfer",""]
* It assumes that the escape character is '\' and it replaces null by an empty string
* @param titleLine the title line
* @return a list of argumenents
*/
private List<String> argumentsFrom(String titleLine) {
if(!titleLine.contains(START_ARGUMENT)) {
return Lists.newArrayList();
}
String argumentString = titleLine.substring(titleLine.indexOf(START_ARGUMENT) + 1, titleLine.lastIndexOf(END_ARGUMENT));
List<String> result = Lists.newArrayList();
StringBuilder currentResult = new StringBuilder();
boolean inString = false;
for (int i = 0; i < argumentString.length(); i++) {
Character c = argumentString.charAt(i);
if(c == ESCAPE_CHAR) {
i++;
currentResult.append(argumentString.charAt(i));
} else if(c == STRING_SEP){//this should happen only while parsing string
inString = !inString;
} else if(c == ARG_SEP && !inString) {
addResult(result, currentResult);
currentResult = new StringBuilder();
} else {
currentResult.append(c);
}
}
if(currentResult.length() != 0) {
addResult(result, currentResult);
}
return result;
}
private void addResult(List<String> result, StringBuilder currentResult) {
String s = currentResult.toString();
if(s.equals(NULL)) {
s = "";
}
result.add(s);
}
public SpecflowScenarioTitleLine(String titleLine) {
this(titleLine, Injectors.getInjector().getProvider(EnvironmentVariables.class).get() );
}
private String pathFrom(List<String> titleElements) {
List<String> pathElements = Lists.newArrayList(titleElements);
pathElements.remove(pathElements.size() - 1);
pathElements = removeExcludedElementsFrom(pathElements);
return Joiner.on(".").join(pathElements);
}
private List<String> removeExcludedElementsFrom(List<String> pathElements) {
List<String> purgedPathElements = Lists.newArrayList(pathElements);
String excludedElementConfiguration
= environmentVariables.getProperty(ThucydidesSystemProperty.THUCYDIDES_REQUIREMENT_EXCLUSIONS,"");
List<String> excludedElements
= Lists.newArrayList(Splitter.on(",")
.trimResults()
.omitEmptyStrings()
.split(excludedElementConfiguration));
purgedPathElements.removeAll(excludedElements);
return purgedPathElements;
}
private String storyTitleIn(List<String> titleElements) {
List<String> reverseTitleElements = Lists.reverse(titleElements);
return inflector.of(reverseTitleElements.get(1)).inHumanReadableForm().toString();
}
private String scenarioTitleIn(String titleElement) {
return Splitter.on("(").split(titleElement).iterator().next();
}
private List<String> elementsFrom(String titleElements) {
return Lists.newCopyOnWriteArrayList(Splitter.on(".").split(titleElements));
}
private String stripLead(String titleLine) {
return StringUtils.strip(titleLine, "* ");
}
public String getScenarioTitle() {
return scenarioTitle;
}
public String getStoryTitle() {
return storyTitle;
}
public String getStoryPath() {
return storyPath;
}
public String getTitleName() {
return storyPath + "." + scenarioTitle;
}
public List getArguments() {
return parameters;
}
public String getRowTitle() {
return scenarioTitle + "[" + getArguments() + "]";
}
}