
io.github.carousell.testrails.FeatureParser Maven / Gradle / Ivy
package io.github.carousell.testrails;
import io.github.carousell.testrails.model.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.assertj.core.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Parser for feature files. */
public class FeatureParser {
private static final Logger LOG = LoggerFactory.getLogger(FeatureParser.class);
private static List caseIdList = new ArrayList<>();
/**
* Parse features from a given directory. Only scenarios which have at least one of the specified
* tags will be included. Scenarios "inherit" the tags of the feature they are defined in.
*
* @param path directory containing the feature files
* @param tags {@link List} of tags to include
* @return {@link List} of {@link Feature}s
*/
public List parseFeatures(String path, String... tags) {
List features = new ArrayList();
LOG.debug("Recursively parsing feature files from {}", path);
try (Stream paths = Files.walk(Paths.get(path))) {
paths
.filter(Files::isRegularFile)
.forEach(x -> parseFeature(x, Paths.get(path), features, tags));
} catch (IOException e) {
LOG.error("Couldn't load feature files from directory {}", path);
}
return features;
}
static List parseFeature(
Path path, Path rootPath, List features, String... tags) {
LOG.debug("Processing feature file {}", path);
try (BufferedReader reader = new BufferedReader(new FileReader(path.toFile()))) {
List scenarios = new ArrayList();
List featureTags = new ArrayList();
String featureName = "";
String line = "";
String previousLine = "";
int lineNumber = 1;
while ((line = reader.readLine()) != null) {
if (line.trim().startsWith("Feature")) {
featureTags = parseTags(previousLine);
featureName = parseFeatureName(line);
}
if (line.trim().startsWith("Scenario")) {
Scenario scenario = parseScenario(line, previousLine, lineNumber);
List allTags = new ArrayList(featureTags);
allTags.addAll(scenario.getTags());
LOG.debug("Scenario tags: {}, required tags: {}", allTags, tags);
if (tags.length == 0
|| (Arrays.asList(tags).stream().allMatch(allTags::contains))) {
LOG.info("Adding scenario {}", scenario);
scenarios.add(scenario);
parseCaseId(allTags);
} else {
LOG.debug("Skipping scenario {}", scenario);
}
}
previousLine = line;
lineNumber++;
}
if (!scenarios.isEmpty()) {
features.add(
new Feature(featureName, rootPath.relativize(path).toString(), scenarios, featureTags));
}
} catch (IOException e) {
LOG.warn("Error reading feature file {}. Skipping!");
}
return features;
}
static String parseFeatureName(String line) {
return line.replaceAll("Feature: ", "").trim();
}
static String parseScenarioName(String line) {
return line.replaceAll("Scenario( Outline)?: ", "").trim();
}
static Scenario parseScenario(String line, String previousLine, int lineNumber) {
return new Scenario(lineNumber, parseScenarioName(line), parseTags(previousLine));
}
static List parseTags(String line) {
List tags = new ArrayList();
if (line.isEmpty()) {
return Collections.emptyList();
} else {
String[] tagsArray = line.trim().replaceAll(" +", " ").split(" ");
for (String tag : tagsArray) {
if (!tag.isEmpty()) {
tags.add(tag.trim().replaceAll("@", ""));
}
}
return tags;
}
}
static void parseCaseId(List alltags) {
for(String tag : alltags){
if (tag.startsWith("case")) {
int startindex = tag.indexOf("(");
int endindex = tag.indexOf(")");
if ((startindex == -1) || (endindex == -1)) {
LOG.error("Something wrong on case tag format : {}", alltags);
throw new IndexOutOfBoundsException("Find one of index is -1");
}
String[] ids = tag.substring(startindex+1, endindex).split(",");
for (String id : ids) {
caseIdList.add(Integer.parseInt(id));
}
LOG.debug("Show Current Test Case Id List : {}", caseIdList);
}
}
}
static List getCaseIdList() {
return caseIdList.stream().distinct().collect(Collectors.toList());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy