Skip to content

Commit

Permalink
Merge pull request #393 from radish-bdd/feature/parser-cli
Browse files Browse the repository at this point in the history
Implement radish-parser cli
  • Loading branch information
timofurrer committed Feb 14, 2020
2 parents 7cd1576 + 0d24d06 commit f9a7426
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 6 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def get_meta(meta, metafile):
"console_scripts": [
"radish = radish.__main__:cli",
"radish-test = radish.step_testing.__main__:cli",
"radish-parser = radish.parser.__main__:cli",
]
},
keywords=KEYWORDS,
Expand Down
111 changes: 111 additions & 0 deletions src/radish/parser/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""
radish
~~~~~~
The root from red to green. BDD tooling for Python.
:copyright: (c) 2019 by Timo Furrer <tuxtimo@gmail.com>
:license: MIT, see LICENSE for more details.
"""

import sys
from pathlib import Path

import click
import colorful as cf

from radish.config import Config
from radish.terrain import world
from radish.parser.core import FeatureFileParser
from radish.errors import RadishError
from radish.logger import enable_radish_debug_mode_click_hook, logger


def expand_feature_files(ctx, param, feature_files):
"""Expand the given feature files
Expanding directories recursively for Feature Files
"""
expanded_feature_files = []
for feature_file_location in (Path(f) for f in feature_files):
if feature_file_location.is_dir():
expanded_feature_files.extend(
list(feature_file_location.glob("**/*.feature"))
)
else:
expanded_feature_files.append(feature_file_location)

return expanded_feature_files


@click.command()
@click.version_option()
@click.help_option("--help", "-h")
@click.option(
"--debug",
"-d",
"enable_debug_mode",
is_flag=True,
help="Enable debug mode for radish itself",
callback=enable_radish_debug_mode_click_hook,
)
@click.option(
"--no-ansi",
"no_ansi",
is_flag=True,
help=(
"Turn off all ANSI sequences (colors, line rewrites) ."
"This option is mainly used by the formatters"
),
)
@click.option(
"--resolve-preconditions",
"resolve_preconditions",
is_flag=True,
help="Resolve @preconditions when parsing the Feature Files",
)
@click.argument(
"feature_files",
nargs=-1,
type=click.Path(exists=True),
callback=expand_feature_files,
)
def cli(**kwargs):
"""radish - The root from red to green. BDD tooling for Python.
Parse and Pretty Print the raw radish AST for the given Feature Files
Provide the Feature Files to run in FEATURE_FILES.
"""
config = Config(kwargs)
world.config = config

# turn of ANSI colors if requested
if config.no_ansi:
cf.disable()

parser = FeatureFileParser(
ast_transformer=None,
resolve_preconditions=config.resolve_preconditions
)

for feature_file in config.feature_files:
logger.info("Parsing Feature File %s", feature_file)
try:
feature_ast = parser.parse(feature_file)
if feature_ast:
print(feature_ast.pretty())
except RadishError as exc:
print("", flush=True)
print(
"An error occured while parsing the Feature File {}:".format(
feature_file
),
flush=True,
)
print(exc, flush=True)
sys.exit(1)


if __name__ == "__main__":
cli()
20 changes: 14 additions & 6 deletions src/radish/parser/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
RadishStepDocStringNotClosed,
RadishStepDoesNotStartWithKeyword,
)
from radish.parser.transformer import RadishGherkinTransformer
from radish.parser.transformer import RadishGherkinTransformer, Transformer


class LanguageSpec:
Expand Down Expand Up @@ -63,15 +63,22 @@ class FeatureFileParser:
"""Radish Feature File Parser responsible to parse a single Feature File"""

def __init__(
self, grammerfile: Path = None, resolve_preconditions: bool = True
self,
grammerfile: Path = None,
ast_transformer: Transformer = RadishGherkinTransformer,
resolve_preconditions: bool = True,
) -> None:
if grammerfile is None:
grammerfile = Path(__file__).parent / "grammer.g"

self.grammerfile = grammerfile
self.resolve_preconditions = resolve_preconditions

self._transformer = RadishGherkinTransformer()
if ast_transformer is not None:
self._transformer = ast_transformer()
else:
self._transformer = None

self._current_feature_id = 1

self._parsers = {}
Expand Down Expand Up @@ -111,9 +118,10 @@ def parse_contents(
language_spec = self._detect_language(featurefile_contents)

# prepare the transformer for the Feature File
self._transformer.prepare(
language_spec, featurefile_path, featurefile_contents, feature_id
)
if self._transformer is not None:
self._transformer.prepare(
language_spec, featurefile_path, featurefile_contents, feature_id
)

# get a parser
parser = self._get_parser(language_spec)
Expand Down
36 changes: 36 additions & 0 deletions tests/integration/features/Radish-Parser-Helpers.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Feature: Expose the Radish Parser via cli
In order to debug and inspect the
radish AST radish provides a CLI
to pretty print the AST of parsed
Feature Files.

Scenario: Print the AST of a simple single Scenario Feature File
Given the Feature File "some.feature"
"""
Feature: Some Feature
Scenario: Some Scenario
When the setup is done
Then the setup has been done
"""
When the "some.feature" is parsed
Then the output to match:
"""
start
feature
Feature
Some Feature
feature_body
description
scenario
Scenario
Some Scenario
step
When
the setup is done
step_arguments
step
Then
the setup has been done
step_arguments
"""
26 changes: 26 additions & 0 deletions tests/integration/radish/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,29 @@ def run_matching_config_with_options(step, matching_config_filename, radish_opti
step.context.exit_code = proc.returncode
step.context.stdout = stdout
step.context.command = radish_command


@when(
"the {feature_filename:QuotedString} is parsed"
)
def run_parser(step, feature_filename):
"""Run the given Feature File"""
feature_path = os.path.join(
step.context.features_dir, feature_filename
)
radish_command = [
"coverage",
"run",
"-p",
"-m",
"radish.parser",
feature_path,
]
proc = subprocess.Popen(
radish_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
stdout, _ = proc.communicate()

step.context.exit_code = proc.returncode
step.context.stdout = stdout
step.context.command = radish_command

0 comments on commit f9a7426

Please sign in to comment.