/**
* Copyright AdScale GmbH, Germany, 2009
*/
package fitnesse.responders.run;
import util.StringUtil;
import fitnesse.http.Request;
import fitnesse.wiki.PageCrawler;
import fitnesse.wiki.PageData;
import fitnesse.wiki.WikiPage;
import fitnesse.wiki.WikiPagePath;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class SuiteFilter {
final private SuiteTagMatcher notMatchTags;
final private SuiteTagMatcher matchTags;
final private String startWithTest;
public static SuiteFilter NO_MATCHING = new SuiteFilter(null, null, null) {
public boolean isMatchingTest(WikiPage testPage) {
return false;
}
};
public static SuiteFilter MATCH_ALL = new SuiteFilter(null, null, null);
SuiteFilter(String matchingTags, String mustNotMatchTags, String startWithTest) {
this.startWithTest = (!"".equals(startWithTest)) ? startWithTest : null;
matchTags = new SuiteTagMatcher(matchingTags, true);
notMatchTags = new SuiteTagMatcher(mustNotMatchTags, false);
}
public SuiteFilter(Request request, String suitePath) {
this(getSuiteTagFilter(request),
getNotSuiteFilter(request),
getSuiteFirstTest(request, suitePath));
}
private static String getSuiteTagFilter(Request request) {
return request != null ? (String) request.getInput("suiteFilter") : null;
}
private static String getNotSuiteFilter(Request request) {
return request != null ? (String) request.getInput("excludeSuiteFilter") : null;
}
private static String getSuiteFirstTest(Request request, String suiteName) {
String startTest = null;
if (request != null) {
startTest = (String) request.getInput("firstTest");
}
if (startTest != null) {
if (startTest.indexOf(suiteName) != 0) {
startTest = suiteName + "." + startTest;
}
}
return startTest;
}
public boolean isMatchingTest(WikiPage testPage) {
PageData data = testPage.getData();
boolean pruned = data.hasAttribute(PageData.PropertyPRUNE);
boolean isTest = data.hasAttribute("Test");
return !pruned &&
isTest &&
matchTags.matches(testPage) &&
!notMatchTags.matches(testPage) &&
afterStartingTest(testPage);
}
private boolean afterStartingTest(WikiPage testPage) {
if (startWithTest == null) {
return true;
}
PageCrawler crawler = testPage.getPageCrawler();
WikiPagePath pageName = crawler.getFullPath(testPage);
return (pageName.toString().compareTo(startWithTest) >= 0);
}
public boolean hasMatchingTests() {
return (this != NO_MATCHING);
}
public SuiteFilter getFilterForTestsInSuite(WikiPage suitePage) {
if (suitePage.getData().hasAttribute(PageData.PropertyPRUNE)) {
return NO_MATCHING;
}
PageData pageData = suitePage.getData();
if (pageData.hasAttribute("Suite") && matchTags.isFiltering() && matchTags.matches(suitePage)) {
return new SuiteFilter(null, notMatchTags.tagString, startWithTest).getFilterForTestsInSuite(suitePage);
}
if (notMatchTags.matches(suitePage)) {
return NO_MATCHING;
}
return this;
}
@Override
public String toString() {
List<String> criterias = new LinkedList<String>();
if (matchTags.isFiltering()) {
criterias.add("matches '" + matchTags.tagString + "'");
}
if (notMatchTags.isFiltering()) {
criterias.add("doesn't match '" + notMatchTags.tagString + "'");
}
if (startWithTest != null) {
criterias.add("starts with test '" + startWithTest + "'");
}
return StringUtil.join(criterias, " & ");
}
private class SuiteTagMatcher {
private static final String LIST_SEPARATOR = "\\s*,\\s*";
final private List<String> tags;
final String tagString;
final private boolean matchIfNoTags;
public SuiteTagMatcher(String suiteTags, boolean matchIfNoTags) {
tagString = suiteTags;
if (suiteTags != null) {
tags = new LinkedList<String>(Arrays.asList(suiteTags.split(LIST_SEPARATOR)));
}
else {
tags = null;
}
this.matchIfNoTags = matchIfNoTags;
}
boolean isFiltering() {
return (tags != null);
}
boolean matches(WikiPage wikiPage) {
return (tags == null) ? matchIfNoTags : testMatchesQuery(wikiPage);
}
private boolean testMatchesQuery(WikiPage wikiPage) {
String testTagString = getTestTags(wikiPage);
return (testTagString != null && testTagsMatchQueryTags(testTagString));
}
private String getTestTags(WikiPage context) {
try {
return context.getData().getAttribute(PageData.PropertySUITES);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private boolean testTagsMatchQueryTags(String testTagString) {
String testTags[] = testTagString.trim().split(LIST_SEPARATOR);
for (String testTag : testTags) {
for (String queryTag : tags) {
if (testTag.equalsIgnoreCase(queryTag)) {
return true;
}
}
}
return false;
}
}
}