# `Cucumber.StepRegistry`
[🔗](https://github.com/huddlz-hq/cucumber/blob/main/lib/cucumber/step_registry.ex#L1)

The complete set of step definitions and parameter types for a run, and
the one place step text is matched against them.

A registry is built once from step definition modules (see
`Cucumber.StepDefinition`) and parameter type modules (see
`Cucumber.ParameterTypes`). Building it:

  * merges the parameter types, raising if two modules register the same
    name
  * compiles every pattern once, so matching never compiles
  * raises on a step definition registered twice (identical expressions,
    or identical regexes with identical flags)
  * drops, with a warning, any definition whose expression references an
    undefined parameter type — mirroring reference Cucumber, steps that
    would have matched it are reported as undefined
  * orders definitions by file and line, so `definitions/1` is stable
    across runs

## Examples

    registry = Cucumber.StepRegistry.new([MyApp.Steps], [MyApp.ParameterTypes])

    case Cucumber.StepRegistry.match(registry, "I have 3 cukes") do
      {:ok, definition, args} -> {definition.module, definition.function, args}
      :undefined -> :undefined
      {:ambiguous, matches} -> Enum.map(matches, fn {definition, _args} -> definition end)
    end

# `match_result`

```elixir
@type match_result() ::
  {:ok, Cucumber.StepRegistry.Definition.t(), [term()]}
  | :undefined
  | {:ambiguous, [{Cucumber.StepRegistry.Definition.t(), [term()]}]}
```

# `t`

```elixir
@opaque t()
```

# `definitions`

```elixir
@spec definitions(t()) :: [Cucumber.StepRegistry.Definition.t()]
```

Returns every definition, ordered by file and line.

## Examples

    Cucumber.StepRegistry.definitions(registry)
    # => [%Cucumber.StepRegistry.Definition{position: 0, ...}, ...]

# `match`

```elixir
@spec match(t(), String.t()) :: match_result()
```

Matches step text against every definition.

Returns `{:ok, definition, args}` for exactly one match, `:undefined` for
none, and `{:ambiguous, matches}` — every match, in definition order — for
more than one. Expression args are converted by their parameter types;
regex args are the captured strings, `nil` for unmatched optional groups.

## Examples

    Cucumber.StepRegistry.match(registry, "I have 3 cukes")
    # => {:ok, %Cucumber.StepRegistry.Definition{source: "I have {int} cukes"}, [3]}

# `new`

```elixir
@spec new([module()], [module()]) :: t()
```

Builds a registry from step definition modules and parameter type modules.

Raises on duplicate step definitions or duplicate parameter types; see the
module documentation for everything building checks.

## Examples

    Cucumber.StepRegistry.new([MyApp.Steps])
    Cucumber.StepRegistry.new([MyApp.Steps], [MyApp.ParameterTypes])

# `parameter_types`

```elixir
@spec parameter_types(t()) :: Cucumber.Expression.custom_types()
```

Returns the parameter types the registry was built with, keyed by name.

## Examples

    Cucumber.StepRegistry.parameter_types(registry)
    # => %{"color" => %{name: "color", regexp: ~r/red|blue/, transform: nil}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
