From 18320bbefc93df8cb9b453f018adfd358d005ff3 Mon Sep 17 00:00:00 2001 From: Alessio Bogon <778703+youtux@users.noreply.github.com> Date: Tue, 12 Jul 2022 18:56:52 +0200 Subject: [PATCH 1/2] `parsers.re` now does fullmatch. This makes it work the same way other parsers work (they don't ignore non-matching characters at the end of the string) --- CHANGES.rst | 1 + pytest_bdd/parsers.py | 4 +-- tests/args/regex/test_args.py | 55 ++++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 30959bc..474b0d9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Unreleased ---------- - Fix bug where steps without parsers would take precedence over steps with parsers. `#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 `_ `#525 `_ +- ``parsers.re`` now does a `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. 6.0.1 ----- diff --git a/pytest_bdd/parsers.py b/pytest_bdd/parsers.py index 77e3e1a..0ae1670 100644 --- a/pytest_bdd/parsers.py +++ b/pytest_bdd/parsers.py @@ -42,14 +42,14 @@ class re(StepParser): :return: `dict` of step arguments """ - match = self.regex.match(name) + match = self.regex.fullmatch(name) if match is None: return None return match.groupdict() def is_matching(self, name: str) -> bool: """Match given name with the step name.""" - return bool(self.regex.match(name)) + return bool(self.regex.fullmatch(name)) class parse(StepParser): diff --git a/tests/args/regex/test_args.py b/tests/args/regex/test_args.py index 1c429cf..77a667e 100644 --- a/tests/args/regex/test_args.py +++ b/tests/args/regex/test_args.py @@ -14,7 +14,7 @@ def test_every_steps_takes_param_with_the_same_name(testdir): When I pay 2 Euro And I pay 1 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) +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\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\d+) Euro"), converters={"amount": int}) + def _(amount, wallet): + wallet["EUR"] -= amount + + + @then(parsers.re(r"I should have (?P\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): testdir.makefile( ".feature", From cc1180d158b89a261f9bc41bb2fb77662c73f815 Mon Sep 17 00:00:00 2001 From: Alessio Bogon <778703+youtux@users.noreply.github.com> Date: Tue, 12 Jul 2022 18:58:57 +0200 Subject: [PATCH 2/2] Add reference to the PR --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 474b0d9..974b218 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Unreleased ---------- - Fix bug where steps without parsers would take precedence over steps with parsers. `#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 `_ `#525 `_ -- ``parsers.re`` now does a `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. +- ``parsers.re`` now does a `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 `_ 6.0.1 -----