From c5349c1318d23b1f7deb3972b4daf4ea4eded8cd Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Wed, 3 Sep 2014 21:59:56 +0400 Subject: [PATCH] PY-13758 BDD: allow to run several feature files in one run configuration --- .../openapi/util/JDOMExternalizer.java | 27 ++++++++++++++++-- python/helpers/pycharm/_bdd_utils.py | 28 ++++++++++++------- python/helpers/pycharm/behave_runner.py | 19 +++++++------ python/helpers/pycharm/lettuce_runner.py | 9 ++++-- 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java index 909c44db199b..cd5e8630a087 100644 --- a/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java +++ b/platform/util/src/com/intellij/openapi/util/JDOMExternalizer.java @@ -22,7 +22,10 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; public class JDOMExternalizer { private JDOMExternalizer() { @@ -66,7 +69,7 @@ public class JDOMExternalizer { return null; } - public static void writeMap(Element root, Mapmap, @NonNls @Nullable String rootName, @NonNls String entryName) { + public static void writeMap(Element root, Map map, @NonNls @Nullable String rootName, @NonNls String entryName) { Element mapRoot; if (StringUtil.isNotEmpty(rootName)) { mapRoot = new Element(rootName); @@ -106,6 +109,26 @@ public class JDOMExternalizer { } } + /** + * Saves a pack of strings to some attribte. I.e: [tag attr="value"] + * @param parent parent element (where to add newly created tags) + * @param nodeName node name (tag, in our example) + * @param attrName attribute name (attr, in our example) + * @param values a pack of values to add + * @see #loadStringsList(org.jdom.Element, String, String) + */ + public static void saveStringsList(@NotNull final Element parent, + @NotNull final String nodeName, + @NotNull final String attrName, + @NotNull final String... values) { + for (final String value : values) { + final Element node = new Element(nodeName); + node.setAttribute(attrName, value); + parent.addContent(node); + } + } + + @NotNull public static List loadStringsList(Element element, String rootName, String attrName) { final List paths = new LinkedList(); if (element != null) { diff --git a/python/helpers/pycharm/_bdd_utils.py b/python/helpers/pycharm/_bdd_utils.py index eea1bebf1654..9eb90681e127 100644 --- a/python/helpers/pycharm/_bdd_utils.py +++ b/python/helpers/pycharm/_bdd_utils.py @@ -29,19 +29,27 @@ def fix_win_drive(feature_path): os.chdir(feature_disk) -def get_path_by_args(arguments): +def get_path_by_env(environment): """ - :type arguments list - :param arguments: arguments (sys.argv) - :return: tuple (base_dir, what_to_run) where dir is current or first argument from argv, checking it exists - :rtype tuple of str + :type environment dict + :param environment: os.environment (files and folders should be separated with | and passed to PY_STUFF_TO_RUN) + :return: tuple (base_dir, what_to_run(list of feature files or folders))) where dir is current or first argument from env, checking it exists + :rtype tuple of (str, iterable) """ - what_to_run = arguments[1] if len(arguments) > 1 else "." - base_dir = what_to_run - assert os.path.exists(what_to_run), "{} does not exist".format(what_to_run) + if "PY_STUFF_TO_RUN" not in environment: + what_to_run = ["."] + else: + what_to_run = str(environment["PY_STUFF_TO_RUN"]).split("|") - if os.path.isfile(what_to_run): - base_dir = os.path.dirname(what_to_run) # User may point to the file directly + if not what_to_run: + what_to_run = ["."] + + for path in what_to_run: + assert os.path.exists(path), "{} does not exist".format(path) + + base_dir = what_to_run[0] + if os.path.isfile(what_to_run[0]): + base_dir = os.path.dirname(what_to_run[0]) # User may point to the file directly return base_dir, what_to_run diff --git a/python/helpers/pycharm/behave_runner.py b/python/helpers/pycharm/behave_runner.py index 2ec649ea7c1d..51171530ddb4 100644 --- a/python/helpers/pycharm/behave_runner.py +++ b/python/helpers/pycharm/behave_runner.py @@ -1,13 +1,14 @@ # coding=utf-8 """ Behave BDD runner. -*FIRST* param now: folder to search "features" for. -Each "features" folder should have features and "steps" subdir. +See _bdd_utils#get_path_by_env for information how to pass list of features here. +Each feature could be file, folder with feature files or folder with "features" subfolder Other args are tag expressionsin format (--tags=.. --tags=..). See https://pythonhosted.org/behave/behave.html#tag-expression """ import functools +import glob import sys import os import traceback @@ -236,12 +237,14 @@ if __name__ == "__main__": my_config.reporters = [] # To prevent summary to stdout my_config.stdout_capture = False # For test output my_config.stderr_capture = False # For test output - (base_dir, what_to_run) = _bdd_utils.get_path_by_args(sys.argv) - if not my_config.paths: # No path provided, trying to load dit manually - if os.path.isfile(what_to_run): # File is provided, load it - my_config.paths = [what_to_run] - else: # Dir is provided, find subdirs ro run - my_config.paths = _get_dirs_to_run(base_dir) + (base_dir, what_to_run) = _bdd_utils.get_path_by_env(os.environ) + features = set() + for feature in what_to_run: + if os.path.isfile(feature) or glob.glob(os.path.join(feature, "*.feature")): # File of folder with "features" provided, load it + features.add(feature) + elif os.path.isdir(feature): + features |= set(_get_dirs_to_run(feature)) # Find "features" subfolder + my_config.paths = list(features) _BehaveRunner(my_config, base_dir).run() diff --git a/python/helpers/pycharm/lettuce_runner.py b/python/helpers/pycharm/lettuce_runner.py index f0a4b5dbb873..6c4dbb7028a6 100644 --- a/python/helpers/pycharm/lettuce_runner.py +++ b/python/helpers/pycharm/lettuce_runner.py @@ -4,6 +4,7 @@ BDD lettuce framework runner TODO: Support other params (like tags) as well. Supports only 1 param now: folder to search "features" for. """ +import os import _bdd_utils __author__ = 'Ilya.Kazakevich' @@ -108,6 +109,8 @@ class _LettuceRunner(_bdd_utils.BddRunner): if __name__ == "__main__": - (base_dir, what_to_run) = _bdd_utils.get_path_by_args(sys.argv) - _bdd_utils.fix_win_drive(what_to_run) - _LettuceRunner(base_dir, what_to_run).run() \ No newline at end of file + (base_dir, what_to_run) = _bdd_utils.get_path_by_env(os.environ) + if len(what_to_run) > 1: + raise Exception("Lettuce can't run more than one file now") + _bdd_utils.fix_win_drive(what_to_run[0]) + _LettuceRunner(base_dir, what_to_run[0]).run() \ No newline at end of file