Merge pull request #539 from pytest-dev/re-fullmatch
Fix `parsers.re` doing only partial string match
This commit is contained in:
commit
adcc48ffa2
|
@ -5,6 +5,7 @@ Unreleased
|
||||||
----------
|
----------
|
||||||
- Fix bug where steps without parsers would take precedence over steps with parsers. `#534 <https://github.com/pytest-dev/pytest-bdd/pull/534>`_
|
- Fix bug where steps without parsers would take precedence over steps with parsers. `#534 <https://github.com/pytest-dev/pytest-bdd/pull/534>`_
|
||||||
- Step functions can now be decorated multiple times with @given, @when, @then. Previously every decorator would override ``converters`` and ``target_fixture`` every at every application. `#534 <https://github.com/pytest-dev/pytest-bdd/pull/534>`_ `#525 <https://github.com/pytest-dev/pytest-bdd/issues/525>`_
|
- Step functions can now be decorated multiple times with @given, @when, @then. Previously every decorator would override ``converters`` and ``target_fixture`` every at every application. `#534 <https://github.com/pytest-dev/pytest-bdd/pull/534>`_ `#525 <https://github.com/pytest-dev/pytest-bdd/issues/525>`_
|
||||||
|
- ``parsers.re`` now does a `fullmatch <https://docs.python.org/3/library/re.html#re.fullmatch>`_ instead of a partial match. This is to make it work just like the other parsers, since they don't ignore non-matching characters at the end of the string. `#539 <https://github.com/pytest-dev/pytest-bdd/pull/539>`_
|
||||||
|
|
||||||
6.0.1
|
6.0.1
|
||||||
-----
|
-----
|
||||||
|
|
|
@ -42,14 +42,14 @@ class re(StepParser):
|
||||||
|
|
||||||
:return: `dict` of step arguments
|
:return: `dict` of step arguments
|
||||||
"""
|
"""
|
||||||
match = self.regex.match(name)
|
match = self.regex.fullmatch(name)
|
||||||
if match is None:
|
if match is None:
|
||||||
return None
|
return None
|
||||||
return match.groupdict()
|
return match.groupdict()
|
||||||
|
|
||||||
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."""
|
||||||
return bool(self.regex.match(name))
|
return bool(self.regex.fullmatch(name))
|
||||||
|
|
||||||
|
|
||||||
class parse(StepParser):
|
class parse(StepParser):
|
||||||
|
|
|
@ -14,7 +14,7 @@ def test_every_steps_takes_param_with_the_same_name(testdir):
|
||||||
When I pay 2 Euro
|
When I pay 2 Euro
|
||||||
And I pay 1 Euro
|
And I pay 1 Euro
|
||||||
Then I should have 0 Euro
|
Then I should have 0 Euro
|
||||||
And I should have 999999 Euro # In my dream...
|
And I should have 999999 Euro
|
||||||
|
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
|
@ -55,6 +55,59 @@ def test_every_steps_takes_param_with_the_same_name(testdir):
|
||||||
result.assert_outcomes(passed=1)
|
result.assert_outcomes(passed=1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_exact_match(testdir):
|
||||||
|
"""Test that parsers.re does an exact match (fullmatch) of the whole string.
|
||||||
|
|
||||||
|
This tests exists because in the past we only used re.match, which only finds a match at the beginning
|
||||||
|
of the string, so if there were any more characters not matching at the end, they were ignored"""
|
||||||
|
|
||||||
|
testdir.makefile(
|
||||||
|
".feature",
|
||||||
|
arguments=textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
Feature: Step arguments
|
||||||
|
Scenario: Every step takes a parameter with the same name
|
||||||
|
Given I have 2 Euro
|
||||||
|
# Step that should not be found:
|
||||||
|
When I pay 1 Euro by mistake
|
||||||
|
Then I should have 1 Euro left
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
testdir.makepyfile(
|
||||||
|
textwrap.dedent(
|
||||||
|
r"""
|
||||||
|
import pytest
|
||||||
|
from pytest_bdd import parsers, given, when, then, scenarios
|
||||||
|
|
||||||
|
scenarios("arguments.feature")
|
||||||
|
|
||||||
|
@given(parsers.re(r"I have (?P<amount>\d+) Euro"), converters={"amount": int}, target_fixture="wallet")
|
||||||
|
def _(amount):
|
||||||
|
return {"EUR": amount}
|
||||||
|
|
||||||
|
|
||||||
|
# Purposefully using a re that will not match the step "When I pay 1 Euro and 50 cents"
|
||||||
|
@when(parsers.re(r"I pay (?P<amount>\d+) Euro"), converters={"amount": int})
|
||||||
|
def _(amount, wallet):
|
||||||
|
wallet["EUR"] -= amount
|
||||||
|
|
||||||
|
|
||||||
|
@then(parsers.re(r"I should have (?P<amount>\d+) Euro left"), converters={"amount": int})
|
||||||
|
def _(amount, wallet):
|
||||||
|
assert wallet["EUR"] == amount
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.assert_outcomes(failed=1)
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
'*StepDefinitionNotFoundError: Step definition is not found: When "I pay 1 Euro by mistake"*'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_argument_in_when(testdir):
|
def test_argument_in_when(testdir):
|
||||||
testdir.makefile(
|
testdir.makefile(
|
||||||
".feature",
|
".feature",
|
||||||
|
|
Loading…
Reference in New Issue