All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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.info("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.info("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.info("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.info("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")) {
        LOG.info("{}", tag);
        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.info("Show Current Test Case Id List : {}", caseIdList);
      }
    }
  }

  static List getCaseIdList() {
    return caseIdList.stream().distinct().collect(Collectors.toList());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy