# Gherkin for Exlir

This Gherkin Parser is meant to parse gherkin files. In order to provide an official parser that can be maintained by the Cucumber community, the parser is generated by the Berp parser generator, which takes the gherkin grammar file. This way, when new gherkin syntax is supported, it is only a matter of generating a new parser (and making slight changes to the code base).

## Usage tokenizer

For now the Gherkin Parser is meant to be used internally and not as a command line tool. There are 2 main functionalities, tokenizing and actually parsing to an AST. Sample usage:

```elixir
# For the tokenizer
iex> CucumberGherkin.tokenize("testdata/good/background.feature") |> IO.puts
(1:1)FeatureLine:Feature/Background/
(2:1)Empty://
(3:3)BackgroundLine:Background/a simple background/
...
```

## Usage parser

The other functionality is parsing feature files to an actual AST / envelopes. You can specify the following options:

* `:no_source`
* `:no_ast`
* `:no_pickles`

You always get a list back with the non-ignored elements. Keep in mind that there can be more than one executable pickle!

```elixir
# You can parse path(s) that export Cucumber Envelopes
#   The second parameter are options, supported options are listed below
CucumberGherkin.parse_path("testdata/good/background.feature", [:no_ast, :no_pickles])
[
  %CucumberMessages.Envelope{
    __uf__: [],
    message: {:source,
     %CucumberMessages.Source{
       # ...
     }}
  }
]
# or only the executable pickles
CucumberGherkin.parse_path("testdata/good/background.feature", [:no_ast, :no_source])
[
  %CucumberMessages.Envelope{
    __uf__: [],
    message: {:pickle,
     %CucumberMessages.Pickle{
       # ...
    }}
  },
  %CucumberMessages.Envelope{
    __uf__: [],
    message: {:pickle,
     %CucumberMessages.Pickle{
       # ...
    }}
  }
]
# Or the AST
CucumberGherkin.parse_path("testdata/good/background.feature", [:no_pickles, :no_source])
[
  %CucumberMessages.Envelope{
    __uf__: [],
    message: {:gherkin_document,
     %CucumberMessages.GherkinDocument{
       # ...
    }}
  }
]
```

As you've probably already surmised, the structs that you get back are from the [cucumber messages](https://hex.pm/packages/cucumber_messages) library.

## Pretty printing to ndjson

If you want the ndjson output, you can print this with:

```elixir
CucumberGherkin.parse_path("testdata/good/background.feature", []) |> CucumberGherkin.print_messages(:ndjson) |> IO.puts
{"source":{"data": .......... }}
{"gherkinDocument":{"feature": ........... }}
{"pickle":{ .......... }}
{"pickle":{ .......... }}
```

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `cucumber_gherkin` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:cucumber_gherkin, "~>"}
  ]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/cucumber_gherkin](https://hexdocs.pm/cucumber_gherkin).

## Extra info

testdata from cucumber gherkin monorepo commit hash 27e0b8a7d9102b83f7f2100cd85f46ef211133a4

## Tests

You can manually run the tests:

```bash
# Run all the tests
mix test

# Use good/bad testdata only
mix test --only good
mix test --only bad

# Test specific functionalities
mix test --only tokens
mix test --only ast
mix test --only source
mix test --only pickles
```

## Credits

This library is originally funded by [UCLL](https://www.ucll.be) its "First Time Right" research project.
