gherkin

package module
v13.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2020 License: MIT Imports: 11 Imported by: 3

README

Gherkin for Go

GoDoc Go Report Card

Gherkin parser/compiler for Go. Please see Gherkin for details.

Building

You need Go installed (obviously). You also need to make sure your PATH points to where Go installs packages:

# Add go bin to path
export PATH=$(go env GOPATH)/bin:${PATH}

Now build it:

make .dist

You should have cross-compiled binaries in ./dist/.

Compress binaries

You need upx installed.

make .dist
make .dist-compressed

Your ./dist_compressed/ directory should now have compressed binaries. Compression fails for some binaries, so you likely won't have a full set.

The build copies the successfully compressed binaries back to ./dist/.

Documentation

Index

Examples

Constants

View Source
const (
	DEFAULT_DIALECT                 = "en"
	COMMENT_PREFIX                  = "#"
	TAG_PREFIX                      = "@"
	TITLE_KEYWORD_SEPARATOR         = ":"
	TABLE_CELL_SEPARATOR            = '|'
	ESCAPE_CHAR                     = '\\'
	ESCAPED_NEWLINE                 = 'n'
	DOCSTRING_SEPARATOR             = "\"\"\""
	DOCSTRING_ALTERNATIVE_SEPARATOR = "```"
)

Variables

This section is empty.

Functions

func Messages

func Messages(
	paths []string,
	sourceStream io.Reader,
	language string,
	includeSource bool,
	includeGherkinDocument bool,
	includePickles bool,
	writer gio.WriteCloser,
	newId func() string,
) ([]messages.Envelope, error)

func ParseGherkinDocument

func ParseGherkinDocument(in io.Reader, newId func() string) (gherkinDocument *messages.GherkinDocument, err error)
Example
input := `Feature: Tagged Examples

  Scenario Outline: minimalistic
    Given the <what>

    @foo
    Examples:
      | what |
      | foo  |

    @bar
    Examples:
      | what |
      | bar  |

  @zap
  Scenario: ha ok
`
r := strings.NewReader(input)

gherkinDocument, err := ParseGherkinDocument(r, (&messages.Incrementing{}).NewId)
if err != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err)
	return
}
feature := gherkinDocument.Feature
//fmt.Fprintf(os.Stdout, "Location: %v\n", feature.Location)
fmt.Fprintf(os.Stdout, "Keyword: %+v\n", feature.Keyword)
fmt.Fprintf(os.Stdout, "Name: %+v\n", feature.Name)
fmt.Fprintf(os.Stdout, "Children: length: %+v\n", len(feature.Children))

scenario1 := feature.Children[0].GetScenario()
//fmt.Fprintf(os.Stdout, " 1: Location: %+v\n", scenario1.Location)
fmt.Fprintf(os.Stdout, "    Keyword: %+v\n", scenario1.Keyword)
fmt.Fprintf(os.Stdout, "    Name: %+v\n", scenario1.Name)
fmt.Fprintf(os.Stdout, "    Steps: length: %+v\n", len(scenario1.Steps))

scenario2 := feature.Children[1].GetScenario()
//fmt.Fprintf(os.Stdout, " 2: Location: %+v\n", scenario2.Location)
fmt.Fprintf(os.Stdout, "    Keyword: %+v\n", scenario2.Keyword)
fmt.Fprintf(os.Stdout, "    Name: %+v\n", scenario2.Name)
fmt.Fprintf(os.Stdout, "    Steps: length: %+v\n", len(scenario2.Steps))
Output:

Keyword: Feature
Name: Tagged Examples
Children: length: 2
    Keyword: Scenario Outline
    Name: minimalistic
    Steps: length: 1
    Keyword: Scenario
    Name: ha ok
    Steps: length: 0
Example (Dialect)
input := "Egenskap: i18n support"
r := strings.NewReader(input)

gherkinDocument, err := ParseGherkinDocumentForLanguage(r, "no", (&messages.Incrementing{}).NewId)
if err != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err)
	return
}
feature := gherkinDocument.Feature
//fmt.Fprintf(os.Stdout, "Location: %+v\n", feature.Location)
fmt.Fprintf(os.Stdout, "Keyword: %+v\n", feature.Keyword)
fmt.Fprintf(os.Stdout, "Name: %+v\n", feature.Name)
fmt.Fprintf(os.Stdout, "Children: length: %+v\n", len(feature.Children))
Output:


Keyword: Egenskap
Name: i18n support
Children: length: 0
Example (Error)
builder := NewAstBuilder((&messages.Incrementing{}).NewId)
parser := NewParser(builder)
parser.StopAtFirstError(false)
matcher := NewMatcher(GherkinDialectsBuildin())

input1 := `# a comment
Feature: Foo
  Scenario: Bar
    Given x
` + "      ```" + `
      unclosed docstring`
r1 := strings.NewReader(input1)

err1 := parser.Parse(NewScanner(r1), matcher)
if err1 != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err1)
}
fmt.Fprintf(os.Stdout, "\n")

input2 := `Feature: Foo
  Scenario: Bar
    Given x
      """
      closed docstring
      """`
r2 := strings.NewReader(input2)

err2 := parser.Parse(NewScanner(r2), matcher)
if err2 != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err2)
	return
}
doc2 := builder.GetGherkinDocument()
fmt.Fprintf(os.Stdout, "Comments: length: %+v\n", len(doc2.Comments))

feature2 := doc2.Feature
//fmt.Fprintf(os.Stdout, "Location: %+v\n", feature2.Location)
fmt.Fprintf(os.Stdout, "Keyword: %+v\n", feature2.Keyword)
fmt.Fprintf(os.Stdout, "Name: %+v\n", feature2.Name)
fmt.Fprintf(os.Stdout, "Children: length: %+v\n", len(feature2.Children))
scenario1 := feature2.Children[0].GetScenario()
//fmt.Fprintf(os.Stdout, " 1: Location: %+v\n", scenario1.Location)
fmt.Fprintf(os.Stdout, "    Keyword: %+v\n", scenario1.Keyword)
fmt.Fprintf(os.Stdout, "    Name: %+v\n", scenario1.Name)
fmt.Fprintf(os.Stdout, "    Steps: length: %+v\n", len(scenario1.Steps))
Output:

Parser errors:
(7:0): unexpected end of file, expected: #DocStringSeparator, #Other

Comments: length: 0
Keyword: Feature
Name: Foo
Children: length: 1
    Keyword: Scenario
    Name: Bar
    Steps: length: 1
Example (Multiple)
builder := NewAstBuilder((&messages.Incrementing{}).NewId)
parser := NewParser(builder)
parser.StopAtFirstError(false)
matcher := NewMatcher(GherkinDialectsBuildin())

input1 := `Feature: Test`
r1 := strings.NewReader(input1)

err1 := parser.Parse(NewScanner(r1), matcher)
if err1 != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err1)
	return
}
doc1 := builder.GetGherkinDocument()
feature1 := doc1.Feature
//fmt.Fprintf(os.Stdout, "Location: %+v\n", feature1.Location)
fmt.Fprintf(os.Stdout, "Keyword: %+v\n", feature1.Keyword)
fmt.Fprintf(os.Stdout, "Name: %+v\n", feature1.Name)
fmt.Fprintf(os.Stdout, "Children: length: %+v\n", len(feature1.Children))
fmt.Fprintf(os.Stdout, "\n")

input2 := `Feature: Test2`
r2 := strings.NewReader(input2)

err2 := parser.Parse(NewScanner(r2), matcher)
if err2 != nil {
	fmt.Fprintf(os.Stdout, "%s\n", err2)
	return
}
doc2 := builder.GetGherkinDocument()
feature2 := doc2.Feature
//fmt.Fprintf(os.Stdout, "Location: %+v\n", feature2.Location)
fmt.Fprintf(os.Stdout, "Keyword: %+v\n", feature2.Keyword)
fmt.Fprintf(os.Stdout, "Name: %+v\n", feature2.Name)
fmt.Fprintf(os.Stdout, "Children: length: %+v\n", len(feature2.Children))
Output:

Keyword: Feature
Name: Test
Children: length: 0

Keyword: Feature
Name: Test2
Children: length: 0

func ParseGherkinDocumentForLanguage

func ParseGherkinDocumentForLanguage(in io.Reader, language string, newId func() string) (gherkinDocument *messages.GherkinDocument, err error)

func Pickles

func Pickles(gherkinDocument messages.GherkinDocument, uri string, newId func() string) []*messages.Pickle

Types

type AstBuilder

type AstBuilder interface {
	Builder
	GetGherkinDocument() *messages.GherkinDocument
}

func NewAstBuilder

func NewAstBuilder(newId func() string) AstBuilder

type Builder

type Builder interface {
	Build(*Token) (bool, error)
	StartRule(RuleType) (bool, error)
	EndRule(RuleType) (bool, error)
	Reset()
}

type GherkinDialect

type GherkinDialect struct {
	Language string
	Name     string
	Native   string
	Keywords map[string][]string
}

func (*GherkinDialect) BackgroundKeywords

func (g *GherkinDialect) BackgroundKeywords() []string

func (*GherkinDialect) ExamplesKeywords

func (g *GherkinDialect) ExamplesKeywords() []string

func (*GherkinDialect) FeatureKeywords

func (g *GherkinDialect) FeatureKeywords() []string

func (*GherkinDialect) RuleKeywords

func (g *GherkinDialect) RuleKeywords() []string

func (*GherkinDialect) ScenarioKeywords

func (g *GherkinDialect) ScenarioKeywords() []string

func (*GherkinDialect) ScenarioOutlineKeywords

func (g *GherkinDialect) ScenarioOutlineKeywords() []string

func (*GherkinDialect) StepKeywords

func (g *GherkinDialect) StepKeywords() []string

type GherkinDialectProvider

type GherkinDialectProvider interface {
	GetDialect(language string) *GherkinDialect
}

func GherkinDialectsBuildin

func GherkinDialectsBuildin() GherkinDialectProvider

Builtin dialects for af (Afrikaans), am (Armenian), an (Aragonese), ar (Arabic), ast (Asturian), az (Azerbaijani), bg (Bulgarian), bm (Malay), bs (Bosnian), ca (Catalan), cs (Czech), cy-GB (Welsh), da (Danish), de (German), el (Greek), em (Emoji), en (English), en-Scouse (Scouse), en-au (Australian), en-lol (LOLCAT), en-old (Old English), en-pirate (Pirate), eo (Esperanto), es (Spanish), et (Estonian), fa (Persian), fi (Finnish), fr (French), ga (Irish), gj (Gujarati), gl (Galician), he (Hebrew), hi (Hindi), hr (Croatian), ht (Creole), hu (Hungarian), id (Indonesian), is (Icelandic), it (Italian), ja (Japanese), jv (Javanese), ka (Georgian), kn (Kannada), ko (Korean), lt (Lithuanian), lu (Luxemburgish), lv (Latvian), mk-Cyrl (Macedonian), mk-Latn (Macedonian (Latin)), mn (Mongolian), ne (Nepali), nl (Dutch), no (Norwegian), pa (Panjabi), pl (Polish), pt (Portuguese), ro (Romanian), ru (Russian), sk (Slovak), sl (Slovenian), sr-Cyrl (Serbian), sr-Latn (Serbian (Latin)), sv (Swedish), ta (Tamil), th (Thai), tl (Telugu), tlh (Klingon), tr (Turkish), tt (Tatar), uk (Ukrainian), ur (Urdu), uz (Uzbek), vi (Vietnamese), zh-CN (Chinese simplified), zh-TW (Chinese traditional), mr (Marathi)

type Line

type Line struct {
	LineText        string
	LineNumber      int
	TrimmedLineText string
	AtEof           bool
}

func (*Line) Indent

func (g *Line) Indent() int

func (*Line) IsEmpty

func (g *Line) IsEmpty() bool

func (*Line) IsEof

func (g *Line) IsEof() bool

func (*Line) StartsWith

func (g *Line) StartsWith(prefix string) bool

type LineSpan

type LineSpan struct {
	Column int
	Text   string
}

func (*LineSpan) String

func (l *LineSpan) String() string

type Location

type Location struct {
	Line   int
	Column int
}

type Matcher

type Matcher interface {
	MatchEOF(line *Line) (bool, *Token, error)
	MatchEmpty(line *Line) (bool, *Token, error)
	MatchComment(line *Line) (bool, *Token, error)
	MatchTagLine(line *Line) (bool, *Token, error)
	MatchFeatureLine(line *Line) (bool, *Token, error)
	MatchRuleLine(line *Line) (bool, *Token, error)
	MatchBackgroundLine(line *Line) (bool, *Token, error)
	MatchScenarioLine(line *Line) (bool, *Token, error)
	MatchExamplesLine(line *Line) (bool, *Token, error)
	MatchStepLine(line *Line) (bool, *Token, error)
	MatchDocStringSeparator(line *Line) (bool, *Token, error)
	MatchTableRow(line *Line) (bool, *Token, error)
	MatchLanguage(line *Line) (bool, *Token, error)
	MatchOther(line *Line) (bool, *Token, error)
	Reset()
}

func NewLanguageMatcher

func NewLanguageMatcher(gdp GherkinDialectProvider, language string) Matcher

func NewMatcher

func NewMatcher(gdp GherkinDialectProvider) Matcher

type Parser

type Parser interface {
	StopAtFirstError(b bool)
	Parse(s Scanner, m Matcher) (err error)
}

func NewParser

func NewParser(b Builder) Parser

type RuleType

type RuleType int
const (
	RuleTypeNone RuleType = iota

	RuleTypeEOF
	RuleTypeEmpty
	RuleTypeComment
	RuleTypeTagLine
	RuleTypeFeatureLine
	RuleTypeRuleLine
	RuleTypeBackgroundLine
	RuleTypeScenarioLine
	RuleTypeExamplesLine
	RuleTypeStepLine
	RuleTypeDocStringSeparator
	RuleTypeTableRow
	RuleTypeLanguage
	RuleTypeOther
	RuleTypeGherkinDocument
	RuleTypeFeature
	RuleTypeFeatureHeader
	RuleTypeRule
	RuleTypeRuleHeader
	RuleTypeBackground
	RuleTypeScenarioDefinition
	RuleTypeScenario
	RuleTypeExamplesDefinition
	RuleTypeExamples
	RuleTypeExamplesTable
	RuleTypeStep
	RuleTypeStepArg
	RuleTypeDataTable
	RuleTypeDocString
	RuleTypeTags
	RuleTypeDescriptionHelper
	RuleTypeDescription
)

func (RuleType) IsEOF

func (t RuleType) IsEOF() bool

func (RuleType) Name

func (t RuleType) Name() string

type Scanner

type Scanner interface {
	Scan() (line *Line, atEof bool, err error)
}

The Scanner reads a gherkin doc (typically read from a .feature file) and creates a token for each line. The tokens are passed to the parser, which outputs an AST (Abstract Syntax Tree).

If the scanner sees a # language header, it will reconfigure itself dynamically to look for Gherkin keywords for the associated language. The keywords are defined in gherkin-languages.json.

func NewScanner

func NewScanner(r io.Reader) Scanner

type Token

type Token struct {
	Type           TokenType
	Keyword        string
	Text           string
	Items          []*LineSpan
	GherkinDialect string
	Indent         string
	Location       *Location
}

func (*Token) IsEOF

func (t *Token) IsEOF() bool

func (*Token) String

func (t *Token) String() string

type TokenType

type TokenType int
const (
	TokenTypeNone TokenType = iota
	TokenTypeEOF
	TokenTypeEmpty
	TokenTypeComment
	TokenTypeTagLine
	TokenTypeFeatureLine
	TokenTypeRuleLine
	TokenTypeBackgroundLine
	TokenTypeScenarioLine
	TokenTypeExamplesLine
	TokenTypeStepLine
	TokenTypeDocStringSeparator
	TokenTypeTableRow
	TokenTypeLanguage
	TokenTypeOther
)

func (TokenType) Name

func (t TokenType) Name() string

func (TokenType) RuleType

func (t TokenType) RuleType() RuleType

Directories

Path Synopsis
This is a console application that prints Cucumber messages to STDOUT.
This is a console application that prints Cucumber messages to STDOUT.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL