Fix many types
This commit is contained in:
parent
33729841eb
commit
78cf86af32
|
@ -18,5 +18,5 @@ warn_unused_configs = true
|
||||||
files = "pytest_bdd/**/*.py"
|
files = "pytest_bdd/**/*.py"
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = ["parse", "parse_type"]
|
module = ["parse", "parse_type", "glob2"]
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
|
|
@ -49,7 +49,7 @@ class LogBDDCucumberJSON:
|
||||||
def __init__(self, logfile: str) -> None:
|
def __init__(self, logfile: str) -> None:
|
||||||
logfile = os.path.expanduser(os.path.expandvars(logfile))
|
logfile = os.path.expanduser(os.path.expandvars(logfile))
|
||||||
self.logfile = os.path.normpath(os.path.abspath(logfile))
|
self.logfile = os.path.normpath(os.path.abspath(logfile))
|
||||||
self.features = {}
|
self.features: Dict[str, Dict] = {}
|
||||||
|
|
||||||
# TODO: Unused method?
|
# TODO: Unused method?
|
||||||
def append(self, obj):
|
def append(self, obj):
|
||||||
|
@ -62,7 +62,7 @@ class LogBDDCucumberJSON:
|
||||||
:param report: pytest `Report` object
|
:param report: pytest `Report` object
|
||||||
:return: `dict` in form {"status": "<passed|failed|skipped>", ["error_message": "<error_message>"]}
|
:return: `dict` in form {"status": "<passed|failed|skipped>", ["error_message": "<error_message>"]}
|
||||||
"""
|
"""
|
||||||
result = {}
|
result: Dict[str, Any] = {}
|
||||||
if report.passed or not step["failed"]: # ignore setup/teardown
|
if report.passed or not step["failed"]: # ignore setup/teardown
|
||||||
result = {"status": "passed"}
|
result = {"status": "passed"}
|
||||||
elif report.failed and step["failed"]:
|
elif report.failed and step["failed"]:
|
||||||
|
|
|
@ -48,7 +48,7 @@ class GherkinTerminalReporter(TerminalReporter):
|
||||||
|
|
||||||
if not letter and not word:
|
if not letter and not word:
|
||||||
# probably passed setup/teardown
|
# probably passed setup/teardown
|
||||||
return
|
return None
|
||||||
|
|
||||||
if isinstance(word, tuple):
|
if isinstance(word, tuple):
|
||||||
word, word_markup = word
|
word, word_markup = word
|
||||||
|
@ -93,3 +93,4 @@ class GherkinTerminalReporter(TerminalReporter):
|
||||||
else:
|
else:
|
||||||
return super().pytest_runtest_logreport(rep)
|
return super().pytest_runtest_logreport(rep)
|
||||||
self.stats.setdefault(cat, []).append(rep)
|
self.stats.setdefault(cat, []).append(rep)
|
||||||
|
return None
|
||||||
|
|
|
@ -3,7 +3,7 @@ import re
|
||||||
import textwrap
|
import textwrap
|
||||||
import typing
|
import typing
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Any, List, Optional, Set, Tuple
|
from typing import Any, List, Optional, Set, Tuple, cast
|
||||||
|
|
||||||
from . import exceptions, types
|
from . import exceptions, types
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ def get_step_type(line: str) -> Optional[str]:
|
||||||
for prefix, _type in STEP_PREFIXES:
|
for prefix, _type in STEP_PREFIXES:
|
||||||
if line.startswith(prefix):
|
if line.startswith(prefix):
|
||||||
return _type
|
return _type
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feature":
|
def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feature":
|
||||||
|
@ -96,7 +97,7 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feat
|
||||||
description="",
|
description="",
|
||||||
)
|
)
|
||||||
scenario: typing.Optional[ScenarioTemplate] = None
|
scenario: typing.Optional[ScenarioTemplate] = None
|
||||||
mode = None
|
mode: Optional[str] = None
|
||||||
prev_mode = None
|
prev_mode = None
|
||||||
description: typing.List[str] = []
|
description: typing.List[str] = []
|
||||||
step = None
|
step = None
|
||||||
|
@ -188,11 +189,11 @@ def parse_feature(basedir: str, filename: str, encoding: str = "utf-8") -> "Feat
|
||||||
)
|
)
|
||||||
elif mode and mode not in (types.FEATURE, types.TAG):
|
elif mode and mode not in (types.FEATURE, types.TAG):
|
||||||
step = Step(name=parsed_line, type=mode, indent=line_indent, line_number=line_number, keyword=keyword)
|
step = Step(name=parsed_line, type=mode, indent=line_indent, line_number=line_number, keyword=keyword)
|
||||||
if feature.background and not scenario:
|
if feature.background and scenario:
|
||||||
target = feature.background
|
feature.background.add_step(step)
|
||||||
else:
|
else:
|
||||||
target = scenario
|
scenario = cast(ScenarioTemplate, scenario)
|
||||||
target.add_step(step)
|
scenario.add_step(step)
|
||||||
prev_line = clean_line
|
prev_line = clean_line
|
||||||
|
|
||||||
feature.description = "\n".join(description).strip()
|
feature.description = "\n".join(description).strip()
|
||||||
|
@ -207,22 +208,22 @@ class Feature:
|
||||||
scenarios: OrderedDict,
|
scenarios: OrderedDict,
|
||||||
filename: str,
|
filename: str,
|
||||||
rel_filename: str,
|
rel_filename: str,
|
||||||
name: Optional[Any],
|
name: Optional[str],
|
||||||
tags: Set,
|
tags: Set,
|
||||||
examples: "Examples",
|
examples: "Examples",
|
||||||
background: Optional[Any],
|
background: "Optional[Background]",
|
||||||
line_number: int,
|
line_number: int,
|
||||||
description: str,
|
description: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.scenarios: typing.Dict[str, ScenarioTemplate] = scenarios
|
self.scenarios: typing.Dict[str, ScenarioTemplate] = scenarios
|
||||||
self.rel_filename = rel_filename
|
self.rel_filename: str = rel_filename
|
||||||
self.filename = filename
|
self.filename: str = filename
|
||||||
self.tags = tags
|
self.tags: Set = tags
|
||||||
self.examples = examples
|
self.examples: "Examples" = examples
|
||||||
self.name = name
|
self.name: Optional[str] = name
|
||||||
self.line_number = line_number
|
self.line_number: int = line_number
|
||||||
self.description = description
|
self.description: str = description
|
||||||
self.background = background
|
self.background: "Optional[Background]" = background
|
||||||
|
|
||||||
|
|
||||||
class ScenarioTemplate:
|
class ScenarioTemplate:
|
||||||
|
@ -319,17 +320,17 @@ class Step:
|
||||||
:param int line_number: line number.
|
:param int line_number: line number.
|
||||||
:param str keyword: step keyword.
|
:param str keyword: step keyword.
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name: str = name
|
||||||
self.keyword = keyword
|
self.keyword: str = keyword
|
||||||
self.lines = []
|
self.lines: List[str] = []
|
||||||
self.indent = indent
|
self.indent: int = indent
|
||||||
self.type = type
|
self.type: str = type
|
||||||
self.line_number = line_number
|
self.line_number: int = line_number
|
||||||
self.failed = False
|
self.failed: bool = False
|
||||||
self.start = 0
|
self.start: int = 0 # TODO: Unused
|
||||||
self.stop = 0
|
self.stop: int = 0 # TODO: Unused
|
||||||
self.scenario: "Optional[Scenario]" = None
|
self.scenario: "Optional[ScenarioTemplate]" = None
|
||||||
self.background = None
|
self.background: "Optional[Background]" = None
|
||||||
|
|
||||||
def add_line(self, line: str) -> None:
|
def add_line(self, line: str) -> None:
|
||||||
"""Add line to the multiple step.
|
"""Add line to the multiple step.
|
||||||
|
@ -386,9 +387,9 @@ class Background:
|
||||||
:param pytest_bdd.parser.Feature feature: Feature.
|
:param pytest_bdd.parser.Feature feature: Feature.
|
||||||
:param int line_number: Line number.
|
:param int line_number: Line number.
|
||||||
"""
|
"""
|
||||||
self.feature = feature
|
self.feature: "Feature" = feature
|
||||||
self.line_number = line_number
|
self.line_number: int = line_number
|
||||||
self.steps = []
|
self.steps: "typing.List[Step]" = []
|
||||||
|
|
||||||
def add_step(self, step: "Step") -> None:
|
def add_step(self, step: "Step") -> None:
|
||||||
"""Add step to the background."""
|
"""Add step to the background."""
|
||||||
|
@ -402,10 +403,10 @@ class Examples:
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize examples instance."""
|
"""Initialize examples instance."""
|
||||||
self.example_params = []
|
self.example_params: List[str] = []
|
||||||
self.examples = []
|
self.examples: List[List[str]] = []
|
||||||
self.vertical_examples = []
|
self.vertical_examples: List[List[str]] = []
|
||||||
self.line_number = None
|
self.line_number: Optional[int] = None
|
||||||
self.name = None
|
self.name = None
|
||||||
|
|
||||||
def set_param_names(self, keys: List[str]) -> None:
|
def set_param_names(self, keys: List[str]) -> None:
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
import re as base_re
|
import re as base_re
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, cast
|
||||||
|
|
||||||
import parse as base_parse
|
import parse as base_parse
|
||||||
from parse_type import cfparse as base_cfparse
|
from parse_type import cfparse as base_cfparse
|
||||||
|
@ -40,6 +40,7 @@ class re(StepParser):
|
||||||
|
|
||||||
:return: `dict` of step arguments
|
:return: `dict` of step arguments
|
||||||
"""
|
"""
|
||||||
|
# TODO: This is a potential bug, as groupdict can return None (found with typing)
|
||||||
return self.regex.match(name).groupdict()
|
return self.regex.match(name).groupdict()
|
||||||
|
|
||||||
def is_matching(self, name: str) -> bool:
|
def is_matching(self, name: str) -> bool:
|
||||||
|
@ -60,7 +61,7 @@ class parse(StepParser):
|
||||||
|
|
||||||
:return: `dict` of step arguments
|
:return: `dict` of step arguments
|
||||||
"""
|
"""
|
||||||
return self.parser.parse(name).named
|
return cast(Dict[str, Any], self.parser.parse(name).named)
|
||||||
|
|
||||||
def is_matching(self, name: str) -> bool:
|
def is_matching(self, name: str) -> bool:
|
||||||
"""Match given name with the step name."""
|
"""Match given name with the step name."""
|
||||||
|
|
|
@ -62,9 +62,10 @@ def find_argumented_step_fixture_name(
|
||||||
except FixtureLookupError:
|
except FixtureLookupError:
|
||||||
continue
|
continue
|
||||||
return parser_name
|
return parser_name
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _find_step_function(request: FixtureRequest, step: "Step", scenario: "Scenario") -> Callable:
|
def _find_step_function(request: FixtureRequest, step: "Step", scenario: "Scenario") -> Any:
|
||||||
"""Match the step defined by the regular expression pattern.
|
"""Match the step defined by the regular expression pattern.
|
||||||
|
|
||||||
:param request: PyTest request object.
|
:param request: PyTest request object.
|
||||||
|
@ -81,9 +82,9 @@ def _find_step_function(request: FixtureRequest, step: "Step", scenario: "Scenar
|
||||||
except FixtureLookupError:
|
except FixtureLookupError:
|
||||||
try:
|
try:
|
||||||
# Could not find a fixture with the same name, let's see if there is a parser involved
|
# Could not find a fixture with the same name, let's see if there is a parser involved
|
||||||
name = find_argumented_step_fixture_name(name, step.type, request._fixturemanager, request)
|
argumented_name = find_argumented_step_fixture_name(name, step.type, request._fixturemanager, request)
|
||||||
if name:
|
if argumented_name:
|
||||||
return request.getfixturevalue(name)
|
return request.getfixturevalue(argumented_name)
|
||||||
raise
|
raise
|
||||||
except FixtureLookupError:
|
except FixtureLookupError:
|
||||||
raise exceptions.StepDefinitionNotFoundError(
|
raise exceptions.StepDefinitionNotFoundError(
|
||||||
|
@ -167,15 +168,15 @@ def _get_scenario_decorator(
|
||||||
"scenario function can only be used as a decorator. Refer to the documentation."
|
"scenario function can only be used as a decorator. Refer to the documentation."
|
||||||
)
|
)
|
||||||
[fn] = args
|
[fn] = args
|
||||||
args = get_args(fn)
|
func_args = get_args(fn)
|
||||||
|
|
||||||
# We need to tell pytest that the original function requires its fixtures,
|
# We need to tell pytest that the original function requires its fixtures,
|
||||||
# otherwise indirect fixtures would not work.
|
# otherwise indirect fixtures would not work.
|
||||||
@pytest.mark.usefixtures(*args)
|
@pytest.mark.usefixtures(*func_args)
|
||||||
def scenario_wrapper(request: FixtureRequest, _pytest_bdd_example: Dict[str, str]) -> Optional[Any]:
|
def scenario_wrapper(request: FixtureRequest, _pytest_bdd_example: Dict[str, str]) -> Optional[Any]:
|
||||||
scenario = templated_scenario.render(_pytest_bdd_example)
|
scenario = templated_scenario.render(_pytest_bdd_example)
|
||||||
_execute_scenario(feature, scenario, request)
|
_execute_scenario(feature, scenario, request)
|
||||||
fixture_values = [request.getfixturevalue(arg) for arg in args]
|
fixture_values = [request.getfixturevalue(arg) for arg in func_args]
|
||||||
return fn(*fixture_values)
|
return fn(*fixture_values)
|
||||||
|
|
||||||
example_parametrizations = collect_example_parametrizations(templated_scenario)
|
example_parametrizations = collect_example_parametrizations(templated_scenario)
|
||||||
|
|
|
@ -8,9 +8,10 @@ from sys import _getframe
|
||||||
from typing import Any, Callable, Dict, List
|
from typing import Any, Callable, Dict, List
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
|
from _pytest.config import Config
|
||||||
from _pytest.pytester import RunResult
|
from _pytest.pytester import RunResult
|
||||||
|
|
||||||
CONFIG_STACK = []
|
CONFIG_STACK: "List[Config]" = []
|
||||||
|
|
||||||
|
|
||||||
def get_args(func: Callable) -> List[str]:
|
def get_args(func: Callable) -> List[str]:
|
||||||
|
|
Loading…
Reference in New Issue