package documentation
Этот коммит содержится в:
родитель
6182dc5d72
коммит
e1d48ef104
10 изменённых файлов: 175 добавлений и 2 удалений
|
@ -1,6 +1,8 @@
|
||||||
|
[](https://travis-ci.org/DATA-DOG/godog)
|
||||||
|
|
||||||
# Godog
|
# Godog
|
||||||
|
|
||||||
**Godog** is an open source behavior-driven development framework for [golang][golang] programming language.
|
**Godog** is an open source behavior-driven development framework for [go][golang] programming language.
|
||||||
What is behavior-driven development, you ask? It’s the idea that you start by writing human-readable sentences that
|
What is behavior-driven development, you ask? It’s the idea that you start by writing human-readable sentences that
|
||||||
describe a feature of your application and how it should work, and only then implement this behavior in software.
|
describe a feature of your application and how it should work, and only then implement this behavior in software.
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ type item struct {
|
||||||
value *lexer.Token
|
value *lexer.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AST is a linked list to store gherkin Tokens
|
||||||
|
// used to insert errors and other details into
|
||||||
|
// the token tree
|
||||||
type AST struct {
|
type AST struct {
|
||||||
head, tail *item
|
head, tail *item
|
||||||
}
|
}
|
||||||
|
|
15
gherkin/example/ls.feature
Обычный файл
15
gherkin/example/ls.feature
Обычный файл
|
@ -0,0 +1,15 @@
|
||||||
|
Feature: ls
|
||||||
|
In order to see the directory structure
|
||||||
|
As a UNIX user
|
||||||
|
I need to be able to list the current directory's contents
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
Given I am in a directory "test"
|
||||||
|
And I have a file named "foo"
|
||||||
|
And I have a file named "bar"
|
||||||
|
When I run "ls"
|
||||||
|
Then I should get:
|
||||||
|
"""
|
||||||
|
bar
|
||||||
|
foo
|
||||||
|
"""
|
21
gherkin/example/main.go
Обычный файл
21
gherkin/example/main.go
Обычный файл
|
@ -0,0 +1,21 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/godog/gherkin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
feature, err := gherkin.Parse("ls.feature")
|
||||||
|
switch {
|
||||||
|
case err == gherkin.ErrEmpty:
|
||||||
|
log.Println("the feature file is empty and does not describe any feature")
|
||||||
|
return
|
||||||
|
case err != nil:
|
||||||
|
log.Println("the feature file is incorrect or could not be read:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Println("have parsed a feature:", feature.Title, "with", len(feature.Scenarios), "scenarios")
|
||||||
|
}
|
|
@ -1,3 +1,61 @@
|
||||||
|
/*
|
||||||
|
Package gherkin is a gherkin language parser based on https://cucumber.io/docs/reference
|
||||||
|
specification. It parses a feature file into the it's structural representation. It also
|
||||||
|
creates an AST tree of gherkin Tokens read from the file.
|
||||||
|
|
||||||
|
With gherkin language you can describe your application behavior as features in
|
||||||
|
human-readable and machine friendly language.
|
||||||
|
|
||||||
|
For example, imagine you’re about to create the famous UNIX ls command.
|
||||||
|
Before you begin, you describe how the feature should work, see the example below..
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Feature: ls
|
||||||
|
In order to see the directory structure
|
||||||
|
As a UNIX user
|
||||||
|
I need to be able to list the current directory's contents
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
Given I am in a directory "test"
|
||||||
|
And I have a file named "foo"
|
||||||
|
And I have a file named "bar"
|
||||||
|
When I run "ls"
|
||||||
|
Then I should get:
|
||||||
|
"""
|
||||||
|
bar
|
||||||
|
foo
|
||||||
|
"""
|
||||||
|
|
||||||
|
As a developer, your work is done as soon as you’ve made the ls command behave as
|
||||||
|
described in the Scenario.
|
||||||
|
|
||||||
|
To read the feature in the example above..
|
||||||
|
|
||||||
|
Example:
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/godog/gherkin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
feature, err := gherkin.Parse("ls.feature")
|
||||||
|
switch {
|
||||||
|
case err == gherkin.ErrEmpty:
|
||||||
|
log.Println("the feature file is empty and does not describe any feature")
|
||||||
|
return
|
||||||
|
case err != nil:
|
||||||
|
log.Println("the feature file is incorrect or could not be read:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Println("have parsed a feature:", feature.Title, "with", len(feature.Scenarios), "scenarios")
|
||||||
|
}
|
||||||
|
|
||||||
|
Now the feature is available in the structure.
|
||||||
|
*/
|
||||||
package gherkin
|
package gherkin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -10,8 +68,15 @@ import (
|
||||||
"github.com/DATA-DOG/godog/gherkin/lexer"
|
"github.com/DATA-DOG/godog/gherkin/lexer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Tag is gherkin feature or scenario tag.
|
||||||
|
// it may be used to filter scenarios.
|
||||||
|
//
|
||||||
|
// tags may be set for a feature, in that case it will
|
||||||
|
// be merged with all scenario tags. or specifically
|
||||||
|
// to a single scenario
|
||||||
type Tag string
|
type Tag string
|
||||||
|
|
||||||
|
// Tags is an array of tags
|
||||||
type Tags []Tag
|
type Tags []Tag
|
||||||
|
|
||||||
func (t Tags) Has(tag Tag) bool {
|
func (t Tags) Has(tag Tag) bool {
|
||||||
|
@ -23,6 +88,7 @@ func (t Tags) Has(tag Tag) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scenario describes the scenario details
|
||||||
type Scenario struct {
|
type Scenario struct {
|
||||||
Title string
|
Title string
|
||||||
Steps []*Step
|
Steps []*Step
|
||||||
|
@ -30,11 +96,13 @@ type Scenario struct {
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Background steps are run before every scenario
|
||||||
type Background struct {
|
type Background struct {
|
||||||
Steps []*Step
|
Steps []*Step
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepType is a general type of step
|
||||||
type StepType string
|
type StepType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -43,6 +111,7 @@ const (
|
||||||
Then StepType = "Then"
|
Then StepType = "Then"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Step describes a Scenario or Background step
|
||||||
type Step struct {
|
type Step struct {
|
||||||
Text string
|
Text string
|
||||||
Comment string
|
Comment string
|
||||||
|
@ -51,6 +120,7 @@ type Step struct {
|
||||||
Table *Table
|
Table *Table
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Feature describes the whole feature
|
||||||
type Feature struct {
|
type Feature struct {
|
||||||
Path string
|
Path string
|
||||||
Tags Tags
|
Tags Tags
|
||||||
|
@ -62,10 +132,12 @@ type Feature struct {
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PyString is a multiline text object used with step definition
|
||||||
type PyString struct {
|
type PyString struct {
|
||||||
Body string
|
Body string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Table is a row group object used with step definition
|
||||||
type Table struct {
|
type Table struct {
|
||||||
rows [][]string
|
rows [][]string
|
||||||
}
|
}
|
||||||
|
@ -78,6 +150,8 @@ var allSteps = []lexer.TokenType{
|
||||||
lexer.BUT,
|
lexer.BUT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrEmpty is returned in case if feature file
|
||||||
|
// is completely empty. May be ignored in some use cases
|
||||||
var ErrEmpty = errors.New("the feature file is empty")
|
var ErrEmpty = errors.New("the feature file is empty")
|
||||||
|
|
||||||
type parser struct {
|
type parser struct {
|
||||||
|
@ -87,6 +161,9 @@ type parser struct {
|
||||||
peeked *lexer.Token
|
peeked *lexer.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the feature file on the given path into
|
||||||
|
// the Feature struct
|
||||||
|
// Returns a Feature struct and error if there is any
|
||||||
func Parse(path string) (*Feature, error) {
|
func Parse(path string) (*Feature, error) {
|
||||||
file, err := os.Open(path)
|
file, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
35
godog.go
Обычный файл
35
godog.go
Обычный файл
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
Package godog is a behavior-driven development framework, a tool to describe your
|
||||||
|
application based on the behavior and run these specifications. The features are
|
||||||
|
described by a human-readable gherkin language.
|
||||||
|
|
||||||
|
For example, imagine you’re about to create the famous UNIX ls command.
|
||||||
|
Before you begin, you describe how the feature should work, see the example below..
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Feature: ls
|
||||||
|
In order to see the directory structure
|
||||||
|
As a UNIX user
|
||||||
|
I need to be able to list the current directory's contents
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
Given I am in a directory "test"
|
||||||
|
And I have a file named "foo"
|
||||||
|
And I have a file named "bar"
|
||||||
|
When I run "ls"
|
||||||
|
Then I should get:
|
||||||
|
"""
|
||||||
|
bar
|
||||||
|
foo
|
||||||
|
"""
|
||||||
|
|
||||||
|
As a developer, your work is done as soon as you’ve made the ls command behave as
|
||||||
|
described in the Scenario.
|
||||||
|
|
||||||
|
Now, wouldn’t it be cool if something could read this sentence and use it to actually
|
||||||
|
run a test against the ls command? Hey, that’s exactly what this package does!
|
||||||
|
As you’ll see, Godog is easy to learn, quick to use, and will put the fun back into tests.
|
||||||
|
|
||||||
|
Godog was inspired by Behat and the above description is taken from it's documentation.
|
||||||
|
*/
|
||||||
|
package godog
|
|
@ -1 +0,0 @@
|
||||||
package godog
|
|
21
steps.go
21
steps.go
|
@ -4,16 +4,37 @@ import "regexp"
|
||||||
|
|
||||||
var stepHandlers map[*regexp.Regexp]StepHandler
|
var stepHandlers map[*regexp.Regexp]StepHandler
|
||||||
|
|
||||||
|
// Objects implementing the StepHandler interface can be
|
||||||
|
// registered as step definitions in godog
|
||||||
|
//
|
||||||
|
// HandleStep method receives all arguments which
|
||||||
|
// will be matched according to the regular expression
|
||||||
|
// which is passed with a step registration.
|
||||||
|
// The error in return - represents a reason of failure.
|
||||||
|
//
|
||||||
|
// Returning signals that the step has finished
|
||||||
|
// and that the feature runner can move on to the next
|
||||||
|
// step.
|
||||||
type StepHandler interface {
|
type StepHandler interface {
|
||||||
HandleStep(args ...interface{}) error
|
HandleStep(args ...interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StepHandlerFunc type is an adapter to allow the use of
|
||||||
|
// ordinary functions as Step handlers. If f is a function
|
||||||
|
// with the appropriate signature, StepHandlerFunc(f) is a
|
||||||
|
// StepHandler object that calls f.
|
||||||
type StepHandlerFunc func(...interface{}) error
|
type StepHandlerFunc func(...interface{}) error
|
||||||
|
|
||||||
|
// HandleStep calls f(step_arguments...).
|
||||||
func (f StepHandlerFunc) HandleStep(args ...interface{}) error {
|
func (f StepHandlerFunc) HandleStep(args ...interface{}) error {
|
||||||
return f(args...)
|
return f(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step registers a StepHandler which will be triggered
|
||||||
|
// if regular expression will match a step from a feature file.
|
||||||
|
//
|
||||||
|
// If none of the StepHandlers are matched, then a pending
|
||||||
|
// step error will be raised.
|
||||||
func Step(exp *regexp.Regexp, h StepHandler) {
|
func Step(exp *regexp.Regexp, h StepHandler) {
|
||||||
stepHandlers[exp] = h
|
stepHandlers[exp] = h
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче