(pattern-matcher)= # Matching Step Expression To match gherkin steps into python code, we used a [pattern matcher](#tursu.pattern_matcher). The default pattern matcher is based on curly brace to discover variable, and it match a single world. But if it is enclosed by `"`, then it can be a sentence (that can't contains `"` at the moment, there is no way to escape it). :::{list-table} :widths: 20 40 40 :header-rows: 1 - - matcher - Python decorator example - Gherkin usage example - - ```python {username} ``` - ```python @given('a user {username}') ``` - ```Gherkin Given a user Alice ``` - - ```python "{username}" ``` - ```python @then('I see the text "{expected}"') ``` - ```Gherkin I see the text "Welcome Alice" ``` ::: ## Typing support The default matcher does not enforce the type in the text of the decorator, **it use the function signature**. Supported types are: `bool`, `date`, `datetime`, `float`, `int`, `str`, `Enum` and `Literal[...]`: ### boolean **Python signature:** ```python @given('Given the feature flag "{feature_flag}" is set to {ff_toggle}') def toggle_feature_flag(feature_flag: str, ff_toggle: bool): ... ``` **Gherkin example:** ```Gherkin Given the feature flag "DARK_MODE" is set to true Then the system status should be off ``` ```{note} * True values are `true`, `1`, `yes`, `on` * False values are `false`, `0`, `no`, `off` Those values are case insensitive. Everything else will raise a value error. ``` ### date **Python signature:** ```python @given("the user's subscription expires on {expires_on}") def given_expires_on_subscription(expires_on: date): ... ``` **Gherkin example:** ```Gherkin Given the user's subscription expires on 2025-12-31 ``` ### datetime **Python signature:** ```python @given("the user's subscription expires at {expires_at}") def given_expires_at_subscription(expires_at: date): ... ``` **Gherkin example:** ```Gherkin Given the user's subscription expires at 2025-12-31T08:00:00Z ``` ### float **Python signature:** ```python @given("the account balance is {account_balance}") def toggle_feature_flag(account_balance: float): ... ``` **Gherkin example:** ```Gherkin Given the account balance is 99.99 ``` ### int **Python signature:** ```python @then("the cart should contain {items_count} items") def assert_cart_items_count(feature_flag: int): ... ``` **Gherkin example:** ```Gherkin Then the cart should contain 3 items ``` ### str **Python signature:** ```python @given('Given the user role {role} protected by passphrase "{passphrase}"') def given_role(role: str, passphrase: str): ... ``` **Gherkin example:** ```Gherkin Given the user role admin protected by passphrase "I am feeling lucky" ``` ### Enum **Python signature:** ```python from enum import Enum class OrderStatus(Enum): PENDING = "Pending" PROCESSING = "Processing" CANCELLED = "Cancelled" REFUNDED = "Refunded" COMPLETED = "Completed" @given("Given the order status is {order_status}") def toggle_feature_flag(order_status: OrderSatus): ... ``` **Gherkin example:** ```Gherkin Given the order status is PROCESSING ``` ```{note} For enum, the key must be passed, not the value. ``` ### Literal **Python signature:** ```python from typing import Literal FeatureFlagName = Literal["dark_mode", "light_mode", "beta_feature"] @given("the feature flag {feature} is set to {status}") def set_feature_flag(feature: FeatureFlagName, status: bool): ... ``` **Gherkin example:** ```Gherkin Given the feature flag dark_mode is set to on ``` ## Complex types and more about Gherkin To provide long text or data set, gherkin supports 2 things, doc strings, and data tables. It allow to multiline step, and we will start with the docstring for json support. ### Json ```python @given("the user provides the following profile data:") def create_user_from_json(doc_string: dict[str, Any]): ... ``` ```Gherkin Given the user provides the following profile data: """json { "username": "johndoe", "email": "johndoe@example.com", "address": { "street": "123 Main St", "city": "Anytown", "postal_code": "12345" } } """ ``` ```{note} When a media type is set to `json` (`"""json` in gherkin docstring) then tursu will parse the json and return it as a list or a dict. Otherwise, a plain string will be returned. ``` ### List of dict from a data table ```python @given("the user provides the following login credentials:") def fill_user_table(data_table: list[dict[str, str]]): ... ``` ```Gherkin Given the user provides the following login credentials: | username | password | | johndoe | secret123 | | janedoe | password1 | ``` ````{note} data_table looks like ```python [ {"username": "johndoe", "password": "secret123"}, {"username": "janedoe", "password": "password1"}, ] ``` ````