From 3bff8cebc2fcf4d32637aa605357b94e71c32c60 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 17 May 2017 12:21:53 -0400 Subject: [PATCH] FAB-3976 remove unused vendored dependency more to come... Change-Id: Ic12d877bf1f8a3c6feb1e2276e4ab7112e752e1b Signed-off-by: Christopher Ferris --- vendor/github.com/DATA-DOG/godog/CHANGELOG.md | 42 -- vendor/github.com/DATA-DOG/godog/LICENSE | 28 - vendor/github.com/DATA-DOG/godog/Makefile | 27 - vendor/github.com/DATA-DOG/godog/README.md | 277 --------- vendor/github.com/DATA-DOG/godog/ast.go | 31 - vendor/github.com/DATA-DOG/godog/builder.go | 332 ----------- vendor/github.com/DATA-DOG/godog/flags.go | 133 ----- vendor/github.com/DATA-DOG/godog/fmt.go | 387 ------------- vendor/github.com/DATA-DOG/godog/fmt_junit.go | 185 ------ .../github.com/DATA-DOG/godog/fmt_pretty.go | 395 ------------- .../github.com/DATA-DOG/godog/fmt_progress.go | 114 ---- vendor/github.com/DATA-DOG/godog/gherkin.go | 11 - vendor/github.com/DATA-DOG/godog/godog.go | 45 -- vendor/github.com/DATA-DOG/godog/logo.png | Bin 48144 -> 0 bytes vendor/github.com/DATA-DOG/godog/run.go | 124 ---- vendor/github.com/DATA-DOG/godog/stepdef.go | 189 ------- vendor/github.com/DATA-DOG/godog/suite.go | 535 ------------------ vendor/github.com/DATA-DOG/godog/utils.go | 50 -- vendor/vendor.json | 6 - 19 files changed, 2911 deletions(-) delete mode 100644 vendor/github.com/DATA-DOG/godog/CHANGELOG.md delete mode 100644 vendor/github.com/DATA-DOG/godog/LICENSE delete mode 100644 vendor/github.com/DATA-DOG/godog/Makefile delete mode 100644 vendor/github.com/DATA-DOG/godog/README.md delete mode 100644 vendor/github.com/DATA-DOG/godog/ast.go delete mode 100644 vendor/github.com/DATA-DOG/godog/builder.go delete mode 100644 vendor/github.com/DATA-DOG/godog/flags.go delete mode 100644 vendor/github.com/DATA-DOG/godog/fmt.go delete mode 100644 vendor/github.com/DATA-DOG/godog/fmt_junit.go delete mode 100644 vendor/github.com/DATA-DOG/godog/fmt_pretty.go delete mode 100644 vendor/github.com/DATA-DOG/godog/fmt_progress.go delete mode 100644 vendor/github.com/DATA-DOG/godog/gherkin.go delete mode 100644 vendor/github.com/DATA-DOG/godog/godog.go delete mode 100644 vendor/github.com/DATA-DOG/godog/logo.png delete mode 100644 vendor/github.com/DATA-DOG/godog/run.go delete mode 100644 vendor/github.com/DATA-DOG/godog/stepdef.go delete mode 100644 vendor/github.com/DATA-DOG/godog/suite.go delete mode 100644 vendor/github.com/DATA-DOG/godog/utils.go diff --git a/vendor/github.com/DATA-DOG/godog/CHANGELOG.md b/vendor/github.com/DATA-DOG/godog/CHANGELOG.md deleted file mode 100644 index 7ff33be69e1..00000000000 --- a/vendor/github.com/DATA-DOG/godog/CHANGELOG.md +++ /dev/null @@ -1,42 +0,0 @@ -# Change LOG - -**2016-06-14** - **v0.5.0** -- godog now uses **go tool compile** and **go tool link** to support - vendor directory dependencies. It also compiles test executable the same - way as standard **go test** utility. With this change, only go - versions from **1.5** are now supported. - -**2016-06-01** -- parse flags in main command, to show version and help without needing - to compile test package and buildable go sources. - -**2016-05-28** -- show nicely formatted called step func name and file path - -**2016-05-26** -- pack gherkin dependency in a subpackage to prevent compatibility - conflicts in the future. If recently upgraded, probably you will need to - reference gherkin as `github.com/DATA-DOG/godog/gherkin` instead. - -**2016-05-25** -- refactored test suite build tooling in order to use standard **go test** - tool. Which allows to compile package with godog runner script in **go** - idiomatic way. It also supports all build environment options as usual. -- **godog.Run** now returns an **int** exit status. It was not returning - anything before, so there is no compatibility breaks. - -**2016-03-04** -- added **junit** compatible output formatter, which prints **xml** - results to **os.Stdout** -- fixed #14 which skipped printing background steps when there was - scenario outline in feature. - -**2015-07-03** -- changed **godog.Suite** from interface to struct. Context registration should be updated accordingly. The reason -for change: since it exports the same methods and there is no need to mock a function in tests, there is no -obvious reason to keep an interface. -- in order to support running suite concurrently, needed to refactor an entry point of application. The **Run** method -now is a func of godog package which initializes and run the suite (or more suites). Method **New** is removed. This -change made godog a little cleaner. -- renamed **RegisterFormatter** func to **Format** to be more consistent. - diff --git a/vendor/github.com/DATA-DOG/godog/LICENSE b/vendor/github.com/DATA-DOG/godog/LICENSE deleted file mode 100644 index 3da144716dd..00000000000 --- a/vendor/github.com/DATA-DOG/godog/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -The three clause BSD license (http://en.wikipedia.org/wiki/BSD_licenses) - -Copyright (c) 2015-2016, DataDog.lt team -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* The name DataDog.lt may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/DATA-DOG/godog/Makefile b/vendor/github.com/DATA-DOG/godog/Makefile deleted file mode 100644 index 042067df4c3..00000000000 --- a/vendor/github.com/DATA-DOG/godog/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -.PHONY: test gherkin bump - -VERS := $(shell grep 'const Version' -m 1 godog.go | awk -F\" '{print $$2}') - -test: - @echo "running all tests" - @go install ./... - @go fmt ./... - @golint github.com/DATA-DOG/godog - @golint github.com/DATA-DOG/godog/cmd/godog - go vet ./... - go test - godog -f progress -c 4 - -gherkin: - @if [ -z "$(VERS)" ]; then echo "Provide gherkin version like: 'VERS=commit-hash'"; exit 1; fi - @rm -rf gherkin - @mkdir gherkin - @curl -s -L https://github.com/cucumber/gherkin-go/tarball/$(VERS) | tar -C gherkin -zx --strip-components 1 - @rm -rf gherkin/{.travis.yml,.gitignore,*_test.go,gherkin-generate*,*.razor,*.jq,Makefile,CONTRIBUTING.md} - -bump: - @if [ -z "$(VERSION)" ]; then echo "Provide version like: 'VERSION=$(VERS) make bump'"; exit 1; fi - @echo "bumping version from: $(VERS) to $(VERSION)" - @sed -i.bak 's/$(VERS)/$(VERSION)/g' godog.go - @sed -i.bak 's/$(VERS)/$(VERSION)/g' examples/api/version.feature - @find . -name '*.bak' | xargs rm diff --git a/vendor/github.com/DATA-DOG/godog/README.md b/vendor/github.com/DATA-DOG/godog/README.md deleted file mode 100644 index cc3149bb604..00000000000 --- a/vendor/github.com/DATA-DOG/godog/README.md +++ /dev/null @@ -1,277 +0,0 @@ -[![Build Status](https://travis-ci.org/DATA-DOG/godog.svg?branch=master)](https://travis-ci.org/DATA-DOG/godog) -[![GoDoc](https://godoc.org/github.com/DATA-DOG/godog?status.svg)](https://godoc.org/github.com/DATA-DOG/godog) - -# Godog - -

Godog logo

- -**The API is likely to change a few times before we reach 1.0.0** - -Package godog is the official Cucumber BDD framework for Golang, it merges -specification and test documentation into one cohesive whole. The author -is a core member of [cucumber team](https://github.com/cucumber). - -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. - -The project is inspired by [behat][behat] and [cucumber][cucumber] and is -based on cucumber [gherkin3 parser][gherkin]. - -**Godog** does not intervene with the standard **go test** command and its -behavior. You can leverage both frameworks to functionally test your -application while maintaining all test related source code in **_test.go** -files. - -**Godog** acts similar compared to **go test** command. It uses go -compiler and linker tool in order to produce test executable. Godog -contexts needs to be exported same as Test functions for go test. - -**Godog** ships gherkin parser dependency as a subpackage. This will -ensure that it is always compatible with the installed version of godog. -So in general there are no vendor dependencies needed for installation. - -The following about section was taken from -[cucumber](https://cucumber.io/) homepage. - -## About - -#### A single source of truth - -Cucumber merges specification and test documentation into one cohesive whole. - -#### Living documentation - -Because they're automatically tested by Cucumber, your specifications are -always bang up-to-date. - -#### Focus on the customer - -Business and IT don't always understand each other. Cucumber's executable -specifications encourage closer collaboration, helping teams keep the -business goal in mind at all times. - -#### Less rework - -When automated testing is this much fun, teams can easily protect -themselves from costly regressions. - -### Install - - go get github.com/DATA-DOG/godog/cmd/godog - -### Example - -The following example can be [found -here](/examples/godogs). - -#### Step 1 - -Given we create a new go package **$GOPATH/src/godogs**. From now on, this -is our work directory `cd $GOPATH/src/godogs`. - -Imagine we have a **godog cart** to serve godogs for lunch. First of all, -we describe our feature in plain text - `vim -$GOPATH/src/godogs/features/godogs.feature`: - -``` gherkin -# file: $GOPATH/src/godogs/features/godogs.feature -Feature: eat godogs - In order to be happy - As a hungry gopher - I need to be able to eat godogs - - Scenario: Eat 5 out of 12 - Given there are 12 godogs - When I eat 5 - Then there should be 7 remaining -``` - -As a developer, your work is done as soon as you’ve made the program behave as -described in the Scenario. - -**NOTE:** same as **go test** godog respects package level isolation. All -your step definitions should be in your tested package root directory. In -this case - `$GOPATH/src/godogs` - -#### Step 2 - -If godog is installed in your GOPATH. We can run `godog` inside the -**$GOPATH/src/godogs** directory. You should see that the steps are -undefined: - -![Undefined step snippets](/screenshots/undefined.png?raw=true) - -If we wish to vendor godog dependency, we can do it as usual, using tools -you prefer: - - git clone https://github.com/DATA-DOG/godog.git $GOPATH/src/godogs/vendor/github.com/DATA-DOG/godog - -It gives you undefined step snippets to implement in your test context. -You may copy these snippets into your `godogs_test.go` file. - -Our directory structure should now look like: - -![Directory layout](/screenshots/dir-tree.png?raw=true) - -If you copy the snippets into our test file and run godog again. We should -see the step definition is now pending: - -![Pending step definition](/screenshots/pending.png?raw=true) - -You may change **ErrPending** to **nil** and the scenario will -pass successfully. - -Since we need a working implementation, we may start by implementing only what is necessary. - -#### Step 3 - -We only need a number of **godogs** for now. Lets keep it simple. - -``` go -/* file: $GOPATH/src/godogs/godogs.go */ -package main - -// Godogs available to eat -var Godogs int - -func main() { /* usual main func */ } -``` - -#### Step 4 - -Now lets implement our step definitions, which we can copy from generated -console output snippets in order to test our feature requirements: - -``` go -/* file: $GOPATH/src/godogs/godogs_test.go */ -package main - -import ( - "fmt" - - "github.com/DATA-DOG/godog" -) - -func thereAreGodogs(available int) error { - Godogs = available - return nil -} - -func iEat(num int) error { - if Godogs < num { - return fmt.Errorf("you cannot eat %d godogs, there are %d available", num, Godogs) - } - Godogs -= num - return nil -} - -func thereShouldBeRemaining(remaining int) error { - if Godogs != remaining { - return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, Godogs) - } - return nil -} - -func FeatureContext(s *godog.Suite) { - s.Step(`^there are (\d+) godogs$`, thereAreGodogs) - s.Step(`^I eat (\d+)$`, iEat) - s.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining) - - s.BeforeScenario(func(interface{}) { - Godogs = 0 // clean the state before every scenario - }) -} -``` - -Now when you run the `godog` again, you should see: - -![Passed suite](/screenshots/passed.png?raw=true) - -**Note:** we have hooked to **BeforeScenario** event in order to reset state. You may hook into -more events, like **AfterStep** to test against an error and print more details about the error -or state before failure. Or **BeforeSuite** to prepare a database. - -#### Running Godog with go test - -There was a question asked whether it is possible to run **godog** from -**go test** command. And the answer is yes. You can run it using go -[TestMain](https://golang.org/pkg/testing/#hdr-Main) func available since -go 1.4. In this case it is not necessary to have **godog** command -installed. See the following example: - -``` go -/* file: $GOPATH/src/godogs/godogs_test.go */ -package main - -import ( - "flag" - "os" - "testing" - - "github.com/DATA-DOG/godog" -) - -func TestMain(m *testing.M) { - args := os.Args - // args for godog - os.Args = []string{ - args[0], - "-f", "progress", - "features", - } - - status := godog.Run(func(s *godog.Suite) { - FeatureContext(s) - }) - - os.Args = args - flag.Parse() - - if st := m.Run(); st > status { - status = st - } - os.Exit(status) -} -``` - -### References and Tutorials - -- [how to use godog by semaphoreci](https://semaphoreci.com/community/tutorials/how-to-use-godog-for-behavior-driven-development-in-go) - -### Documentation - -See [godoc][godoc] for general API details. -See **.travis.yml** for supported **go** versions. -See `godog -h` for general command options. - -See implementation examples: - -- [rest API server](/examples/api) -- [rest API with Database](/examples/db) -- [godogs](/examples/godogs) - -### FAQ - -**Q:** Where can I configure common options globally? -**A:** You can't. Alias your common or project based commands: `alias godog-wip="godog --format=progress --tags=@wip"` - -### Contributions - -Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) - -please open an issue before to discuss whether these changes can be accepted. All backward incompatible changes are -and will be treated cautiously. - -### License - -All package dependencies are **MIT** or **BSD** licensed. - -**Godog** is licensed under the [three clause BSD license][license] - -[godoc]: http://godoc.org/github.com/DATA-DOG/godog "Documentation on godoc" -[golang]: https://golang.org/ "GO programming language" -[behat]: http://docs.behat.org/ "Behavior driven development framework for PHP" -[cucumber]: https://cucumber.io/ "Behavior driven development framework for Ruby" -[gherkin]: https://github.com/cucumber/gherkin-go "Gherkin3 parser for GO" -[license]: http://en.wikipedia.org/wiki/BSD_licenses "The three clause BSD license" diff --git a/vendor/github.com/DATA-DOG/godog/ast.go b/vendor/github.com/DATA-DOG/godog/ast.go deleted file mode 100644 index fe275e039c3..00000000000 --- a/vendor/github.com/DATA-DOG/godog/ast.go +++ /dev/null @@ -1,31 +0,0 @@ -package godog - -import "go/ast" - -func astContexts(f *ast.File) []string { - var contexts []string - for _, d := range f.Decls { - switch fun := d.(type) { - case *ast.FuncDecl: - for _, param := range fun.Type.Params.List { - switch expr := param.Type.(type) { - case *ast.StarExpr: - switch x := expr.X.(type) { - case *ast.Ident: - if x.Name == "Suite" { - contexts = append(contexts, fun.Name.Name) - } - case *ast.SelectorExpr: - switch t := x.X.(type) { - case *ast.Ident: - if t.Name == "godog" && x.Sel.Name == "Suite" { - contexts = append(contexts, fun.Name.Name) - } - } - } - } - } - } - } - return contexts -} diff --git a/vendor/github.com/DATA-DOG/godog/builder.go b/vendor/github.com/DATA-DOG/godog/builder.go deleted file mode 100644 index 6686e027a28..00000000000 --- a/vendor/github.com/DATA-DOG/godog/builder.go +++ /dev/null @@ -1,332 +0,0 @@ -package godog - -import ( - "bytes" - "fmt" - "go/build" - "go/parser" - "go/token" - "io/ioutil" - "os" - "os/exec" - "path" - "path/filepath" - "strings" - "text/template" - "time" - "unicode" -) - -var compiler = filepath.Join(build.ToolDir, "compile") -var linker = filepath.Join(build.ToolDir, "link") -var gopaths = filepath.SplitList(build.Default.GOPATH) -var goarch = build.Default.GOARCH -var goos = build.Default.GOOS - -var godogImportPath = "github.com/DATA-DOG/godog" -var runnerTemplate = template.Must(template.New("testmain").Parse(`package main - -import ( - "github.com/DATA-DOG/godog" - {{if .Contexts}}_test "{{.ImportPath}}"{{end}} - "os" -) - -func main() { - status := godog.Run(func (suite *godog.Suite) { - {{range .Contexts}} - _test.{{ . }}(suite) - {{end}} - }) - os.Exit(status) -}`)) - -// Build creates a test package like go test command. -// If there are no go files in tested directory, then -// it simply builds a godog executable to scan features. -// -// If there are go test files, it first builds a test -// package with standard go test command. -// -// Finally it generates godog suite executable which -// registers exported godog contexts from the test files -// of tested package. -// -// Returns the path to generated executable -func Build() (string, error) { - abs, err := filepath.Abs(".") - if err != nil { - return "", err - } - - bin := filepath.Join(abs, "godog.test") - // suffix with .exe for windows - if goos == "windows" { - bin += ".exe" - } - - // we allow package to be nil, if godog is run only when - // there is a feature file in empty directory - pkg := importPackage(abs) - src, anyContexts, err := buildTestMain(pkg) - if err != nil { - return bin, err - } - - workdir := fmt.Sprintf(filepath.Join("%s", "godog-%d"), os.TempDir(), time.Now().UnixNano()) - testdir := workdir - - // if none of test files exist, or there are no contexts found - // we will skip test package compilation, since it is useless - if anyContexts { - // first of all compile test package dependencies - // that will save was many compilations for dependencies - // go does it better - out, err := exec.Command("go", "test", "-i").CombinedOutput() - if err != nil { - return bin, fmt.Errorf("failed to compile package %s:\n%s", pkg.Name, string(out)) - } - - // let go do the dirty work and compile test - // package with it's dependencies. Older go - // versions does not accept existing file output - // so we create a temporary executable which will - // removed. - temp := fmt.Sprintf(filepath.Join("%s", "temp-%d.test"), os.TempDir(), time.Now().UnixNano()) - - // builds and compile the tested package. - // generated test executable will be removed - // since we do not need it for godog suite. - // we also print back the temp WORK directory - // go has built. We will reuse it for our suite workdir. - out, err = exec.Command("go", "test", "-c", "-work", "-o", temp).CombinedOutput() - if err != nil { - return bin, fmt.Errorf("failed to compile tested package %s:\n%s", pkg.Name, string(out)) - } - defer os.Remove(temp) - - // extract go-build temporary directory as our workdir - workdir = strings.TrimSpace(string(out)) - if !strings.HasPrefix(workdir, "WORK=") { - return bin, fmt.Errorf("expected WORK dir path, but got: %s", workdir) - } - workdir = strings.Replace(workdir, "WORK=", "", 1) - testdir = filepath.Join(workdir, pkg.ImportPath, "_test") - } else { - // still need to create temporary workdir - if err = os.MkdirAll(testdir, 0755); err != nil { - return bin, err - } - } - defer os.RemoveAll(workdir) - - // replace _testmain.go file with our own - testmain := filepath.Join(testdir, "_testmain.go") - err = ioutil.WriteFile(testmain, src, 0644) - if err != nil { - return bin, err - } - - // godog library may not be imported in tested package - // but we need it for our testmain package. - // So we look it up in available source paths - // including vendor directory, supported since 1.5. - try := maybeVendorPaths(abs) - for _, d := range build.Default.SrcDirs() { - try = append(try, filepath.Join(d, godogImportPath)) - } - godogPkg, err := locatePackage(try) - if err != nil { - return bin, err - } - - // make sure godog package archive is installed, gherkin - // will be installed as dependency of godog - cmd := exec.Command("go", "install", godogPkg.ImportPath) - cmd.Env = os.Environ() - out, err := cmd.CombinedOutput() - if err != nil { - return bin, fmt.Errorf("failed to install godog package:\n%s", string(out)) - } - - // collect all possible package dirs, will be - // used for includes and linker - pkgDirs := []string{workdir, testdir} - for _, gopath := range gopaths { - pkgDirs = append(pkgDirs, filepath.Join(gopath, "pkg", goos+"_"+goarch)) - } - pkgDirs = uniqStringList(pkgDirs) - - // compile godog testmain package archive - // we do not depend on CGO so a lot of checks are not necessary - testMainPkgOut := filepath.Join(testdir, "main.a") - args := []string{ - "-o", testMainPkgOut, - // "-trimpath", workdir, - "-p", "main", - "-complete", - } - // if godog library is in vendor directory - // link it with import map - if i := strings.LastIndex(godogPkg.ImportPath, "vendor/"); i != -1 { - args = append(args, "-importmap", godogImportPath+"="+godogPkg.ImportPath) - } - for _, inc := range pkgDirs { - args = append(args, "-I", inc) - } - args = append(args, "-pack", testmain) - cmd = exec.Command(compiler, args...) - cmd.Env = os.Environ() - out, err = cmd.CombinedOutput() - if err != nil { - return bin, fmt.Errorf("failed to compile testmain package:\n%s", string(out)) - } - - // link test suite executable - args = []string{ - "-o", bin, - "-buildmode=exe", - } - for _, link := range pkgDirs { - args = append(args, "-L", link) - } - args = append(args, testMainPkgOut) - cmd = exec.Command(linker, args...) - cmd.Env = os.Environ() - - out, err = cmd.CombinedOutput() - if err != nil { - msg := `failed to link test executable: - reason: %s - command: %s` - return bin, fmt.Errorf(msg, string(out), linker+" '"+strings.Join(args, "' '")+"'") - } - - return bin, nil -} - -func locatePackage(try []string) (*build.Package, error) { - for _, p := range try { - abs, err := filepath.Abs(p) - if err != nil { - continue - } - pkg, err := build.ImportDir(abs, 0) - if err != nil { - continue - } - return pkg, nil - } - return nil, fmt.Errorf("failed to find godog package in any of:\n%s", strings.Join(try, "\n")) -} - -func importPackage(dir string) *build.Package { - pkg, _ := build.ImportDir(dir, 0) - - // normalize import path for local import packages - // taken from go source code - // see: https://github.com/golang/go/blob/go1.7rc5/src/cmd/go/pkg.go#L279 - if pkg != nil && pkg.ImportPath == "." { - pkg.ImportPath = path.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) - } - - return pkg -} - -// from go src -func makeImportValid(r rune) rune { - // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. - const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" - if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { - return '_' - } - return r -} - -func uniqStringList(strs []string) (unique []string) { - uniq := make(map[string]void, len(strs)) - for _, s := range strs { - if _, ok := uniq[s]; !ok { - uniq[s] = void{} - unique = append(unique, s) - } - } - return -} - -// buildTestMain if given package is valid -// it scans test files for contexts -// and produces a testmain source code. -func buildTestMain(pkg *build.Package) ([]byte, bool, error) { - var contexts []string - var importPath string - name := "main" - if nil != pkg { - ctxs, err := processPackageTestFiles( - pkg.TestGoFiles, - pkg.XTestGoFiles, - ) - if err != nil { - return nil, false, err - } - contexts = ctxs - importPath = pkg.ImportPath - name = pkg.Name - } - - data := struct { - Name string - Contexts []string - ImportPath string - }{name, contexts, importPath} - - var buf bytes.Buffer - if err := runnerTemplate.Execute(&buf, data); err != nil { - return nil, len(contexts) > 0, err - } - return buf.Bytes(), len(contexts) > 0, nil -} - -// maybeVendorPaths determines possible vendor paths -// which goes levels down from given directory -// until it reaches GOPATH source dir -func maybeVendorPaths(dir string) (paths []string) { - for _, gopath := range gopaths { - gopath = filepath.Join(gopath, "src") - for strings.HasPrefix(dir, gopath) && dir != gopath { - paths = append(paths, filepath.Join(dir, "vendor", godogImportPath)) - dir = filepath.Dir(dir) - } - } - return -} - -// processPackageTestFiles runs through ast of each test -// file pack and looks for godog suite contexts to register -// on run -func processPackageTestFiles(packs ...[]string) ([]string, error) { - var ctxs []string - fset := token.NewFileSet() - for _, pack := range packs { - for _, testFile := range pack { - node, err := parser.ParseFile(fset, testFile, nil, 0) - if err != nil { - return ctxs, err - } - - ctxs = append(ctxs, astContexts(node)...) - } - } - var failed []string - for _, ctx := range ctxs { - runes := []rune(ctx) - if unicode.IsLower(runes[0]) { - expected := append([]rune{unicode.ToUpper(runes[0])}, runes[1:]...) - failed = append(failed, fmt.Sprintf("%s - should be: %s", ctx, string(expected))) - } - } - if len(failed) > 0 { - return ctxs, fmt.Errorf("godog contexts must be exported:\n\t%s", strings.Join(failed, "\n\t")) - } - return ctxs, nil -} diff --git a/vendor/github.com/DATA-DOG/godog/flags.go b/vendor/github.com/DATA-DOG/godog/flags.go deleted file mode 100644 index 69687263b7a..00000000000 --- a/vendor/github.com/DATA-DOG/godog/flags.go +++ /dev/null @@ -1,133 +0,0 @@ -package godog - -import ( - "flag" - "fmt" - "strings" -) - -var descFeaturesArgument = "Optional feature(s) to run. Can be:\n" + - s(4) + "- dir " + cl("(features/)", yellow) + "\n" + - s(4) + "- feature " + cl("(*.feature)", yellow) + "\n" + - s(4) + "- scenario at specific line " + cl("(*.feature:10)", yellow) + "\n" + - "If no feature paths are listed, suite tries " + cl("features", yellow) + " path by default.\n" - -var descConcurrencyOption = "Run the test suite with concurrency level:\n" + - s(4) + "- " + cl(`= 1`, yellow) + ": supports all types of formats.\n" + - s(4) + "- " + cl(`>= 2`, yellow) + ": only supports " + cl("progress", yellow) + ". Note, that\n" + - s(4) + "your context needs to support parallel execution." - -var descTagsOption = "Filter scenarios by tags. Expression can be:\n" + - s(4) + "- " + cl(`"@wip"`, yellow) + ": run all scenarios with wip tag\n" + - s(4) + "- " + cl(`"~@wip"`, yellow) + ": exclude all scenarios with wip tag\n" + - s(4) + "- " + cl(`"@wip && ~@new"`, yellow) + ": run wip scenarios, but exclude new\n" + - s(4) + "- " + cl(`"@wip,@undone"`, yellow) + ": run wip or undone scenarios" - -// FlagSet allows to manage flags by external suite runner -func FlagSet(format, tags *string, defs, sof, noclr *bool, cr *int) *flag.FlagSet { - descFormatOption := "How to format tests output. Available formats:\n" - for _, f := range formatters { - descFormatOption += s(4) + "- " + cl(f.name, yellow) + ": " + f.description + "\n" - } - descFormatOption = strings.TrimSpace(descFormatOption) - - set := flag.NewFlagSet("godog", flag.ExitOnError) - set.StringVar(format, "format", "pretty", descFormatOption) - set.StringVar(format, "f", "pretty", descFormatOption) - set.StringVar(tags, "tags", "", descTagsOption) - set.StringVar(tags, "t", "", descTagsOption) - set.IntVar(cr, "concurrency", 1, descConcurrencyOption) - set.IntVar(cr, "c", 1, descConcurrencyOption) - set.BoolVar(defs, "definitions", false, "Print all available step definitions.") - set.BoolVar(defs, "d", false, "Print all available step definitions.") - set.BoolVar(sof, "stop-on-failure", false, "Stop processing on first failed scenario.") - set.BoolVar(noclr, "no-colors", false, "Disable ansi colors.") - set.Usage = usage(set) - return set -} - -type flagged struct { - short, long, descr, dflt string -} - -func (f *flagged) name() string { - var name string - switch { - case len(f.short) > 0 && len(f.long) > 0: - name = fmt.Sprintf("-%s, --%s", f.short, f.long) - case len(f.long) > 0: - name = fmt.Sprintf("--%s", f.long) - case len(f.short) > 0: - name = fmt.Sprintf("-%s", f.short) - } - if f.dflt != "true" && f.dflt != "false" { - name += "=" + f.dflt - } - return name -} - -func usage(set *flag.FlagSet) func() { - return func() { - var list []*flagged - var longest int - set.VisitAll(func(f *flag.Flag) { - var fl *flagged - for _, flg := range list { - if flg.descr == f.Usage { - fl = flg - break - } - } - if nil == fl { - fl = &flagged{ - dflt: f.DefValue, - descr: f.Usage, - } - list = append(list, fl) - } - if len(f.Name) > 2 { - fl.long = f.Name - } else { - fl.short = f.Name - } - }) - - for _, f := range list { - if len(f.name()) > longest { - longest = len(f.name()) - } - } - - // prints an option or argument with a description, or only description - opt := func(name, desc string) string { - var ret []string - lines := strings.Split(desc, "\n") - ret = append(ret, s(2)+cl(name, green)+s(longest+2-len(name))+lines[0]) - if len(lines) > 1 { - for _, ln := range lines[1:] { - ret = append(ret, s(2)+s(longest+2)+ln) - } - } - return strings.Join(ret, "\n") - } - - // --- GENERAL --- - fmt.Println(cl("Usage:", yellow)) - fmt.Printf(s(2) + "godog [options] []\n\n") - // description - fmt.Println("Builds a test package and runs given feature files.") - fmt.Printf("Command should be run from the directory of tested package and contain buildable go source.\n\n") - - // --- ARGUMENTS --- - fmt.Println(cl("Arguments:", yellow)) - // --> features - fmt.Println(opt("features", descFeaturesArgument)) - - // --- OPTIONS --- - fmt.Println(cl("Options:", yellow)) - for _, f := range list { - fmt.Println(opt(f.name(), f.descr)) - } - fmt.Println("") - } -} diff --git a/vendor/github.com/DATA-DOG/godog/fmt.go b/vendor/github.com/DATA-DOG/godog/fmt.go deleted file mode 100644 index 172d10ff0c1..00000000000 --- a/vendor/github.com/DATA-DOG/godog/fmt.go +++ /dev/null @@ -1,387 +0,0 @@ -package godog - -import ( - "bytes" - "fmt" - "reflect" - "regexp" - "strings" - "text/template" - "time" - "unicode" - - "github.com/DATA-DOG/godog/gherkin" -) - -// some snippet formatting regexps -var snippetExprCleanup = regexp.MustCompile("([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+\\'])") -var snippetExprQuoted = regexp.MustCompile("(\\s*|^)\"(?:[^\"]*)\"(\\s+|$)") -var snippetMethodName = regexp.MustCompile("[^a-zA-Z\\_\\ ]") -var snippetNumbers = regexp.MustCompile("(\\d+)") - -var snippetHelperFuncs = template.FuncMap{ - "backticked": func(s string) string { - return "`" + s + "`" - }, -} - -var undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(` -{{ range . }}func {{ .Method }}({{ .Args }}) error { - return godog.ErrPending -} - -{{end}}func FeatureContext(s *godog.Suite) { {{ range . }} - s.Step({{ backticked .Expr }}, {{ .Method }}){{end}} -} -`)) - -type undefinedSnippet struct { - Method string - Expr string - argument interface{} // gherkin step argument -} - -type registeredFormatter struct { - name string - fmt Formatter - description string -} - -var formatters []*registeredFormatter - -func findFmt(format string) (f Formatter, err error) { - var names []string - for _, el := range formatters { - if el.name == format { - f = el.fmt - break - } - names = append(names, el.name) - } - - if f == nil { - err = fmt.Errorf(`unregistered formatter name: "%s", use one of: %s`, format, strings.Join(names, ", ")) - } - return -} - -// Format registers a feature suite output -// Formatter as the name and descriptiongiven. -// Formatter is used to represent suite output -func Format(name, description string, f Formatter) { - formatters = append(formatters, ®isteredFormatter{ - name: name, - fmt: f, - description: description, - }) -} - -// Formatter is an interface for feature runner -// output summary presentation. -// -// New formatters may be created to represent -// suite results in different ways. These new -// formatters needs to be registered with a -// godog.Format function call -type Formatter interface { - Feature(*gherkin.Feature, string) - Node(interface{}) - Failed(*gherkin.Step, *StepDef, error) - Passed(*gherkin.Step, *StepDef) - Skipped(*gherkin.Step) - Undefined(*gherkin.Step) - Pending(*gherkin.Step, *StepDef) - Summary() -} - -type stepType int - -const ( - passed stepType = iota - failed - skipped - undefined - pending -) - -func (st stepType) clr() color { - switch st { - case passed: - return green - case failed: - return red - case skipped: - return cyan - default: - return yellow - } -} - -type stepResult struct { - typ stepType - feature *feature - owner interface{} - step *gherkin.Step - def *StepDef - err error -} - -func (f stepResult) line() string { - return fmt.Sprintf("%s:%d", f.feature.Path, f.step.Location.Line) -} - -type basefmt struct { - owner interface{} - indent int - - started time.Time - features []*feature - failed []*stepResult - passed []*stepResult - skipped []*stepResult - undefined []*stepResult - pending []*stepResult -} - -func (f *basefmt) Node(n interface{}) { - switch t := n.(type) { - case *gherkin.TableRow: - f.owner = t - case *gherkin.Scenario: - f.owner = t - } -} - -func (f *basefmt) Feature(ft *gherkin.Feature, p string) { - f.features = append(f.features, &feature{Path: p, Feature: ft}) -} - -func (f *basefmt) Passed(step *gherkin.Step, match *StepDef) { - s := &stepResult{ - owner: f.owner, - feature: f.features[len(f.features)-1], - step: step, - def: match, - typ: passed, - } - f.passed = append(f.passed, s) -} - -func (f *basefmt) Skipped(step *gherkin.Step) { - s := &stepResult{ - owner: f.owner, - feature: f.features[len(f.features)-1], - step: step, - typ: skipped, - } - f.skipped = append(f.skipped, s) -} - -func (f *basefmt) Undefined(step *gherkin.Step) { - s := &stepResult{ - owner: f.owner, - feature: f.features[len(f.features)-1], - step: step, - typ: undefined, - } - f.undefined = append(f.undefined, s) -} - -func (f *basefmt) Failed(step *gherkin.Step, match *StepDef, err error) { - s := &stepResult{ - owner: f.owner, - feature: f.features[len(f.features)-1], - step: step, - def: match, - err: err, - typ: failed, - } - f.failed = append(f.failed, s) -} - -func (f *basefmt) Pending(step *gherkin.Step, match *StepDef) { - s := &stepResult{ - owner: f.owner, - feature: f.features[len(f.features)-1], - step: step, - def: match, - typ: pending, - } - f.pending = append(f.pending, s) -} - -func (f *basefmt) Summary() { - var total, passed, undefined int - for _, ft := range f.features { - for _, def := range ft.ScenarioDefinitions { - switch t := def.(type) { - case *gherkin.Scenario: - total++ - case *gherkin.ScenarioOutline: - for _, ex := range t.Examples { - if examples, hasExamples := examples(ex); hasExamples { - total += len(examples.TableBody) - } - } - } - } - } - passed = total - var owner interface{} - for _, undef := range f.undefined { - if owner != undef.owner { - undefined++ - owner = undef.owner - } - } - - var steps, parts, scenarios []string - nsteps := len(f.passed) + len(f.failed) + len(f.skipped) + len(f.undefined) + len(f.pending) - if len(f.passed) > 0 { - steps = append(steps, cl(fmt.Sprintf("%d passed", len(f.passed)), green)) - } - if len(f.failed) > 0 { - passed -= len(f.failed) - parts = append(parts, cl(fmt.Sprintf("%d failed", len(f.failed)), red)) - steps = append(steps, parts[len(parts)-1]) - } - if len(f.pending) > 0 { - passed -= len(f.pending) - parts = append(parts, cl(fmt.Sprintf("%d pending", len(f.pending)), yellow)) - steps = append(steps, cl(fmt.Sprintf("%d pending", len(f.pending)), yellow)) - } - if len(f.undefined) > 0 { - passed -= undefined - parts = append(parts, cl(fmt.Sprintf("%d undefined", undefined), yellow)) - steps = append(steps, cl(fmt.Sprintf("%d undefined", len(f.undefined)), yellow)) - } - if len(f.skipped) > 0 { - steps = append(steps, cl(fmt.Sprintf("%d skipped", len(f.skipped)), cyan)) - } - if passed > 0 { - scenarios = append(scenarios, cl(fmt.Sprintf("%d passed", passed), green)) - } - scenarios = append(scenarios, parts...) - elapsed := time.Since(f.started) - - fmt.Println("") - if total == 0 { - fmt.Println("No scenarios") - } else { - fmt.Println(fmt.Sprintf("%d scenarios (%s)", total, strings.Join(scenarios, ", "))) - } - - if nsteps == 0 { - fmt.Println("No steps") - } else { - fmt.Println(fmt.Sprintf("%d steps (%s)", nsteps, strings.Join(steps, ", "))) - } - fmt.Println(elapsed) - - if text := f.snippets(); text != "" { - fmt.Println(cl("\nYou can implement step definitions for undefined steps with these snippets:", yellow)) - fmt.Println(cl(text, yellow)) - } -} - -func (s *undefinedSnippet) Args() (ret string) { - var args []string - var pos, idx int - var breakLoop bool - for !breakLoop { - part := s.Expr[pos:] - ipos := strings.Index(part, "(\\d+)") - spos := strings.Index(part, "\"([^\"]*)\"") - switch { - case spos == -1 && ipos == -1: - breakLoop = true - case spos == -1: - idx++ - pos += ipos + len("(\\d+)") - args = append(args, reflect.Int.String()) - case ipos == -1: - idx++ - pos += spos + len("\"([^\"]*)\"") - args = append(args, reflect.String.String()) - case ipos < spos: - idx++ - pos += ipos + len("(\\d+)") - args = append(args, reflect.Int.String()) - case spos < ipos: - idx++ - pos += spos + len("\"([^\"]*)\"") - args = append(args, reflect.String.String()) - } - } - if s.argument != nil { - idx++ - switch s.argument.(type) { - case *gherkin.DocString: - args = append(args, "*gherkin.DocString") - case *gherkin.DataTable: - args = append(args, "*gherkin.DataTable") - } - } - - var last string - for i, arg := range args { - if last == "" || last == arg { - ret += fmt.Sprintf("arg%d, ", i+1) - } else { - ret = strings.TrimRight(ret, ", ") + fmt.Sprintf(" %s, arg%d, ", last, i+1) - } - last = arg - } - return strings.TrimSpace(strings.TrimRight(ret, ", ") + " " + last) -} - -func (f *basefmt) snippets() string { - if len(f.undefined) == 0 { - return "" - } - - var index int - var snips []*undefinedSnippet - // build snippets - for _, u := range f.undefined { - expr := snippetExprCleanup.ReplaceAllString(u.step.Text, "\\$1") - expr = snippetNumbers.ReplaceAllString(expr, "(\\d+)") - expr = snippetExprQuoted.ReplaceAllString(expr, " \"([^\"]*)\" ") - expr = "^" + strings.TrimSpace(expr) + "$" - - name := snippetNumbers.ReplaceAllString(u.step.Text, " ") - name = snippetExprQuoted.ReplaceAllString(name, " ") - name = snippetMethodName.ReplaceAllString(name, "") - var words []string - for i, w := range strings.Split(name, " ") { - if i != 0 { - w = strings.Title(w) - } else { - w = string(unicode.ToLower(rune(w[0]))) + w[1:] - } - words = append(words, w) - } - name = strings.Join(words, "") - if len(name) == 0 { - index++ - name = fmt.Sprintf("stepDefinition%d", index) - } - - var found bool - for _, snip := range snips { - if snip.Expr == expr { - found = true - break - } - } - if !found { - snips = append(snips, &undefinedSnippet{Method: name, Expr: expr, argument: u.step.Argument}) - } - } - - var buf bytes.Buffer - if err := undefinedSnippetsTpl.Execute(&buf, snips); err != nil { - panic(err) - } - return buf.String() -} diff --git a/vendor/github.com/DATA-DOG/godog/fmt_junit.go b/vendor/github.com/DATA-DOG/godog/fmt_junit.go deleted file mode 100644 index d0130ddbaee..00000000000 --- a/vendor/github.com/DATA-DOG/godog/fmt_junit.go +++ /dev/null @@ -1,185 +0,0 @@ -package godog - -import ( - "encoding/xml" - "fmt" - "io" - "os" - "time" - - "github.com/DATA-DOG/godog/gherkin" -) - -func init() { - Format("junit", "Prints junit compatible xml to stdout", &junitFormatter{ - suite: &junitPackageSuite{ - Name: "main", // @TODO: it should extract package name - TestSuites: make([]*junitTestSuite, 0), - }, - started: time.Now(), - }) -} - -type junitFormatter struct { - suite *junitPackageSuite - - // timing - started time.Time - caseStarted time.Time - featStarted time.Time - - outline *gherkin.ScenarioOutline - outlineExample int -} - -func (j *junitFormatter) Feature(feature *gherkin.Feature, path string) { - testSuite := &junitTestSuite{ - TestCases: make([]*junitTestCase, 0), - Name: feature.Name, - } - - if len(j.suite.TestSuites) > 0 { - j.current().Time = time.Since(j.featStarted).String() - } - j.featStarted = time.Now() - j.suite.TestSuites = append(j.suite.TestSuites, testSuite) -} - -func (j *junitFormatter) Node(node interface{}) { - suite := j.current() - tcase := &junitTestCase{} - - switch t := node.(type) { - case *gherkin.ScenarioOutline: - j.outline = t - return - case *gherkin.Scenario: - tcase.Name = t.Name - suite.Tests++ - j.suite.Tests++ - case *gherkin.Examples: - j.outlineExample = 0 - return - case *gherkin.TableRow: - j.outlineExample++ - tcase.Name = fmt.Sprintf("%s #%d", j.outline.Name, j.outlineExample) - suite.Tests++ - j.suite.Tests++ - default: - return - } - if len(suite.TestCases) > 0 { - suite.current().Time = time.Since(j.caseStarted).String() - } - j.caseStarted = time.Now() - suite.TestCases = append(suite.TestCases, tcase) -} - -func (j *junitFormatter) Failed(step *gherkin.Step, match *StepDef, err error) { - suite := j.current() - suite.Failures++ - j.suite.Failures++ - - tcase := suite.current() - tcase.Status = "failed" - tcase.Failure = &junitFailure{ - Message: fmt.Sprintf("%s %s: %s", step.Type, step.Text, err.Error()), - } -} - -func (j *junitFormatter) Passed(step *gherkin.Step, match *StepDef) { - suite := j.current() - - tcase := suite.current() - tcase.Status = "passed" -} - -func (j *junitFormatter) Skipped(step *gherkin.Step) { -} - -func (j *junitFormatter) Undefined(step *gherkin.Step) { - suite := j.current() - suite.Errors++ - j.suite.Errors++ - - tcase := suite.current() - tcase.Status = "undefined" - tcase.Error = append(tcase.Error, &junitError{ - Type: "undefined", - Message: fmt.Sprintf("%s %s", step.Type, step.Text), - }) -} - -func (j *junitFormatter) Pending(step *gherkin.Step, match *StepDef) { - suite := j.current() - suite.Errors++ - j.suite.Errors++ - - tcase := suite.current() - tcase.Status = "pending" - tcase.Error = append(tcase.Error, &junitError{ - Type: "pending", - Message: fmt.Sprintf("%s %s: TODO: write pending definition", step.Type, step.Text), - }) -} - -func (j *junitFormatter) Summary() { - j.suite.Time = time.Since(j.started).String() - io.WriteString(os.Stdout, xml.Header) - - enc := xml.NewEncoder(os.Stdout) - enc.Indent("", s(2)) - if err := enc.Encode(j.suite); err != nil { - fmt.Println("failed to write junit xml:", err) - } -} - -type junitFailure struct { - Message string `xml:"message,attr"` - Type string `xml:"type,attr,omitempty"` -} - -type junitError struct { - XMLName xml.Name `xml:"error,omitempty"` - Message string `xml:"message,attr"` - Type string `xml:"type,attr"` -} - -type junitTestCase struct { - XMLName xml.Name `xml:"testcase"` - Name string `xml:"name,attr"` - Status string `xml:"status,attr"` - Time string `xml:"time,attr"` - Failure *junitFailure `xml:"failure,omitempty"` - Error []*junitError -} - -type junitTestSuite struct { - XMLName xml.Name `xml:"testsuite"` - Name string `xml:"name,attr"` - Tests int `xml:"tests,attr"` - Skipped int `xml:"skipped,attr"` - Failures int `xml:"failures,attr"` - Errors int `xml:"errors,attr"` - Time string `xml:"time,attr"` - TestCases []*junitTestCase -} - -func (ts *junitTestSuite) current() *junitTestCase { - return ts.TestCases[len(ts.TestCases)-1] -} - -type junitPackageSuite struct { - XMLName xml.Name `xml:"testsuites"` - Name string `xml:"name,attr"` - Tests int `xml:"tests,attr"` - Skipped int `xml:"skipped,attr"` - Failures int `xml:"failures,attr"` - Errors int `xml:"errors,attr"` - Time string `xml:"time,attr"` - TestSuites []*junitTestSuite -} - -func (j *junitFormatter) current() *junitTestSuite { - return j.suite.TestSuites[len(j.suite.TestSuites)-1] -} diff --git a/vendor/github.com/DATA-DOG/godog/fmt_pretty.go b/vendor/github.com/DATA-DOG/godog/fmt_pretty.go deleted file mode 100644 index 8889ce89e5a..00000000000 --- a/vendor/github.com/DATA-DOG/godog/fmt_pretty.go +++ /dev/null @@ -1,395 +0,0 @@ -package godog - -import ( - "fmt" - "math" - "regexp" - "strings" - "time" - "unicode/utf8" - - "github.com/DATA-DOG/godog/gherkin" -) - -func init() { - Format("pretty", "Prints every feature with runtime statuses.", &pretty{ - basefmt: basefmt{ - started: time.Now(), - indent: 2, - }, - }) -} - -var outlinePlaceholderRegexp = regexp.MustCompile("<[^>]+>") - -// a built in default pretty formatter -type pretty struct { - basefmt - - // currently processed - feature *gherkin.Feature - scenario *gherkin.Scenario - outline *gherkin.ScenarioOutline - - // state - bgSteps int - steps int - commentPos int - - // whether scenario or scenario outline keyword was printed - scenarioKeyword bool - - // outline - outlineSteps []*stepResult - outlineNumExample int - outlineNumExamples int -} - -func (f *pretty) Feature(ft *gherkin.Feature, p string) { - if len(f.features) != 0 { - // not a first feature, add a newline - fmt.Println("") - } - f.features = append(f.features, &feature{Path: p, Feature: ft}) - fmt.Println(bcl(ft.Keyword+": ", white) + ft.Name) - if strings.TrimSpace(ft.Description) != "" { - for _, line := range strings.Split(ft.Description, "\n") { - fmt.Println(s(f.indent) + strings.TrimSpace(line)) - } - } - - f.feature = ft - f.scenario = nil - f.outline = nil - f.bgSteps = 0 - if ft.Background != nil { - f.bgSteps = len(ft.Background.Steps) - } -} - -// Node takes a gherkin node for formatting -func (f *pretty) Node(node interface{}) { - f.basefmt.Node(node) - - switch t := node.(type) { - case *gherkin.Examples: - f.outlineNumExamples = len(t.TableBody) - f.outlineNumExample++ - case *gherkin.Scenario: - f.scenario = t - f.outline = nil - f.steps = len(t.Steps) + f.bgSteps - f.scenarioKeyword = false - case *gherkin.ScenarioOutline: - f.outline = t - f.scenario = nil - f.outlineNumExample = -1 - f.scenarioKeyword = false - case *gherkin.TableRow: - f.steps = len(f.outline.Steps) + f.bgSteps - f.outlineSteps = []*stepResult{} - } -} - -// Summary sumarize the feature formatter output -func (f *pretty) Summary() { - // failed steps on background are not scenarios - var failedScenarios []*stepResult - for _, fail := range f.failed { - switch fail.owner.(type) { - case *gherkin.Scenario: - failedScenarios = append(failedScenarios, fail) - case *gherkin.ScenarioOutline: - failedScenarios = append(failedScenarios, fail) - } - } - if len(failedScenarios) > 0 { - fmt.Println("\n--- " + cl("Failed scenarios:", red) + "\n") - var unique []string - for _, fail := range failedScenarios { - var found bool - for _, in := range unique { - if in == fail.line() { - found = true - break - } - } - if !found { - unique = append(unique, fail.line()) - } - } - - for _, fail := range unique { - fmt.Println(" " + cl(fail, red)) - } - } - f.basefmt.Summary() -} - -func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) { - var msg string - clr := green - - ex := outline.Examples[f.outlineNumExample] - example, hasExamples := examples(ex) - if !hasExamples { - // do not print empty examples - return - } - - firstExample := f.outlineNumExamples == len(example.TableBody) - printSteps := firstExample && f.outlineNumExample == 0 - - for i, res := range f.outlineSteps { - // determine example row status - switch { - case res.typ == failed: - msg = res.err.Error() - clr = res.typ.clr() - case res.typ == undefined || res.typ == pending: - clr = res.typ.clr() - case res.typ == skipped && clr == green: - clr = cyan - } - if printSteps { - // in first example, we need to print steps - var text string - ostep := outline.Steps[i] - if res.def != nil { - if m := outlinePlaceholderRegexp.FindAllStringIndex(ostep.Text, -1); len(m) > 0 { - var pos int - for i := 0; i < len(m); i++ { - pair := m[i] - text += cl(ostep.Text[pos:pair[0]], cyan) - text += bcl(ostep.Text[pair[0]:pair[1]], cyan) - pos = pair[1] - } - text += cl(ostep.Text[pos:len(ostep.Text)], cyan) - } else { - text = cl(ostep.Text, cyan) - } - text += s(f.commentPos-f.length(ostep)+1) + cl(fmt.Sprintf("# %s", res.def.funcName()), black) - } else { - text = cl(ostep.Text, cyan) - } - // print the step outline - fmt.Println(s(f.indent*2) + cl(strings.TrimSpace(ostep.Keyword), cyan) + " " + text) - } - } - - cells := make([]string, len(example.TableHeader.Cells)) - max := longest(example) - // an example table header - if firstExample { - fmt.Println("") - fmt.Println(s(f.indent*2) + bcl(example.Keyword+": ", white) + example.Name) - - for i, cell := range example.TableHeader.Cells { - cells[i] = cl(cell.Value, cyan) + s(max[i]-len(cell.Value)) - } - fmt.Println(s(f.indent*3) + "| " + strings.Join(cells, " | ") + " |") - } - - // an example table row - row := example.TableBody[len(example.TableBody)-f.outlineNumExamples] - for i, cell := range row.Cells { - cells[i] = cl(cell.Value, clr) + s(max[i]-len(cell.Value)) - } - fmt.Println(s(f.indent*3) + "| " + strings.Join(cells, " | ") + " |") - - // if there is an error - if msg != "" { - fmt.Println(s(f.indent*4) + bcl(msg, red)) - } -} - -func (f *pretty) printStep(step *gherkin.Step, def *StepDef, c color) { - text := s(f.indent*2) + cl(strings.TrimSpace(step.Keyword), c) + " " - switch { - case def != nil: - if m := (def.Expr.FindStringSubmatchIndex(step.Text))[2:]; len(m) > 0 { - var pos, i int - for pos, i = 0, 0; i < len(m); i++ { - if math.Mod(float64(i), 2) == 0 { - text += cl(step.Text[pos:m[i]], c) - } else { - text += bcl(step.Text[pos:m[i]], c) - } - pos = m[i] - } - text += cl(step.Text[pos:len(step.Text)], c) - } else { - text += cl(step.Text, c) - } - text += s(f.commentPos-f.length(step)+1) + cl(fmt.Sprintf("# %s", def.funcName()), black) - default: - text += cl(step.Text, c) - } - - fmt.Println(text) - switch t := step.Argument.(type) { - case *gherkin.DataTable: - f.printTable(t, c) - case *gherkin.DocString: - var ct string - if len(t.ContentType) > 0 { - ct = " " + cl(t.ContentType, c) - } - fmt.Println(s(f.indent*3) + cl(t.Delimitter, c) + ct) - for _, ln := range strings.Split(t.Content, "\n") { - fmt.Println(s(f.indent*3) + cl(ln, c)) - } - fmt.Println(s(f.indent*3) + cl(t.Delimitter, c)) - } -} - -func (f *pretty) printStepKind(res *stepResult) { - // if has not printed background yet - switch { - // first background step - case f.bgSteps > 0 && f.bgSteps == len(f.feature.Background.Steps): - f.commentPos = f.longestStep(f.feature.Background.Steps, f.length(f.feature.Background)) - fmt.Println("\n" + s(f.indent) + bcl(f.feature.Background.Keyword+": "+f.feature.Background.Name, white)) - f.bgSteps-- - // subsequent background steps - case f.bgSteps > 0: - f.bgSteps-- - // first step of scenario, print header and calculate comment position - case f.scenario != nil: - // print scenario keyword and value if first example - if !f.scenarioKeyword { - f.commentPos = f.longestStep(f.scenario.Steps, f.length(f.scenario)) - if f.feature.Background != nil { - if bgLen := f.longestStep(f.feature.Background.Steps, f.length(f.feature.Background)); bgLen > f.commentPos { - f.commentPos = bgLen - } - } - text := s(f.indent) + bcl(f.scenario.Keyword+": ", white) + f.scenario.Name - text += s(f.commentPos-f.length(f.scenario)+1) + f.line(f.scenario.Location) - fmt.Println("\n" + text) - f.scenarioKeyword = true - } - f.steps-- - // first step of outline scenario, print header and calculate comment position - case f.outline != nil: - f.outlineSteps = append(f.outlineSteps, res) - f.steps-- - - // print scenario keyword and value if first example - if !f.scenarioKeyword { - f.commentPos = f.longestStep(f.outline.Steps, f.length(f.outline)) - if f.feature.Background != nil { - if bgLen := f.longestStep(f.feature.Background.Steps, f.length(f.feature.Background)); bgLen > f.commentPos { - f.commentPos = bgLen - } - } - text := s(f.indent) + bcl(f.outline.Keyword+": ", white) + f.outline.Name - text += s(f.commentPos-f.length(f.outline)+1) + f.line(f.outline.Location) - fmt.Println("\n" + text) - f.scenarioKeyword = true - } - if len(f.outlineSteps) == len(f.outline.Steps)+f.bgSteps { - // an outline example steps has went through - f.printOutlineExample(f.outline) - f.outlineNumExamples-- - } - return - } - - f.printStep(res.step, res.def, res.typ.clr()) - if res.err != nil { - fmt.Println(s(f.indent*2) + bcl(res.err, red)) - } - if res.typ == pending { - fmt.Println(s(f.indent*3) + cl("TODO: write pending definition", yellow)) - } -} - -// print table with aligned table cells -func (f *pretty) printTable(t *gherkin.DataTable, c color) { - var l = longest(t) - var cols = make([]string, len(t.Rows[0].Cells)) - for _, row := range t.Rows { - for i, cell := range row.Cells { - cols[i] = cell.Value + s(l[i]-len(cell.Value)) - } - fmt.Println(s(f.indent*3) + cl("| "+strings.Join(cols, " | ")+" |", c)) - } -} - -func (f *pretty) Passed(step *gherkin.Step, match *StepDef) { - f.basefmt.Passed(step, match) - f.printStepKind(f.passed[len(f.passed)-1]) -} - -func (f *pretty) Skipped(step *gherkin.Step) { - f.basefmt.Skipped(step) - f.printStepKind(f.skipped[len(f.skipped)-1]) -} - -func (f *pretty) Undefined(step *gherkin.Step) { - f.basefmt.Undefined(step) - f.printStepKind(f.undefined[len(f.undefined)-1]) -} - -func (f *pretty) Failed(step *gherkin.Step, match *StepDef, err error) { - f.basefmt.Failed(step, match, err) - f.printStepKind(f.failed[len(f.failed)-1]) -} - -func (f *pretty) Pending(step *gherkin.Step, match *StepDef) { - f.basefmt.Pending(step, match) - f.printStepKind(f.pending[len(f.pending)-1]) -} - -// longest gives a list of longest columns of all rows in Table -func longest(tbl interface{}) []int { - var rows []*gherkin.TableRow - switch t := tbl.(type) { - case *gherkin.Examples: - rows = append(rows, t.TableHeader) - rows = append(rows, t.TableBody...) - case *gherkin.DataTable: - rows = append(rows, t.Rows...) - } - - longest := make([]int, len(rows[0].Cells)) - for _, row := range rows { - for i, cell := range row.Cells { - if longest[i] < len(cell.Value) { - longest[i] = len(cell.Value) - } - } - } - return longest -} - -func (f *pretty) longestStep(steps []*gherkin.Step, base int) int { - ret := base - for _, step := range steps { - length := f.length(step) - if length > ret { - ret = length - } - } - return ret -} - -// a line number representation in feature file -func (f *pretty) line(loc *gherkin.Location) string { - return cl(fmt.Sprintf("# %s:%d", f.features[len(f.features)-1].Path, loc.Line), black) -} - -func (f *pretty) length(node interface{}) int { - switch t := node.(type) { - case *gherkin.Background: - return f.indent + utf8.RuneCountInString(strings.TrimSpace(t.Keyword)+": "+t.Name) - case *gherkin.Step: - return f.indent*2 + utf8.RuneCountInString(strings.TrimSpace(t.Keyword)+" "+t.Text) - case *gherkin.Scenario: - return f.indent + utf8.RuneCountInString(strings.TrimSpace(t.Keyword)+": "+t.Name) - case *gherkin.ScenarioOutline: - return f.indent + utf8.RuneCountInString(strings.TrimSpace(t.Keyword)+": "+t.Name) - } - panic(fmt.Sprintf("unexpected node %T to determine length", node)) -} diff --git a/vendor/github.com/DATA-DOG/godog/fmt_progress.go b/vendor/github.com/DATA-DOG/godog/fmt_progress.go deleted file mode 100644 index 36c8b128034..00000000000 --- a/vendor/github.com/DATA-DOG/godog/fmt_progress.go +++ /dev/null @@ -1,114 +0,0 @@ -package godog - -import ( - "fmt" - "math" - "sync" - "time" - - "github.com/DATA-DOG/godog/gherkin" -) - -func init() { - Format("progress", "Prints a character per step.", &progress{ - basefmt: basefmt{ - started: time.Now(), - indent: 2, - }, - stepsPerRow: 70, - }) -} - -type progress struct { - basefmt - sync.Mutex - stepsPerRow int - steps int -} - -func (f *progress) Node(n interface{}) { - f.Lock() - defer f.Unlock() - f.basefmt.Node(n) -} - -func (f *progress) Feature(ft *gherkin.Feature, p string) { - f.Lock() - defer f.Unlock() - f.basefmt.Feature(ft, p) -} - -func (f *progress) Summary() { - left := math.Mod(float64(f.steps), float64(f.stepsPerRow)) - if left != 0 { - if int(f.steps) > f.stepsPerRow { - fmt.Printf(s(f.stepsPerRow-int(left)) + fmt.Sprintf(" %d\n", f.steps)) - } else { - fmt.Printf(" %d\n", f.steps) - } - } - fmt.Println("") - - if len(f.failed) > 0 { - fmt.Println("\n--- " + cl("Failed steps:", red) + "\n") - for _, fail := range f.failed { - fmt.Println(s(4) + cl(fail.step.Keyword+" "+fail.step.Text, red) + cl(" # "+fail.line(), black)) - fmt.Println(s(6) + cl("Error: ", red) + bcl(fail.err, red) + "\n") - } - } - f.basefmt.Summary() -} - -func (f *progress) step(res *stepResult) { - switch res.typ { - case passed: - fmt.Print(cl(".", green)) - case skipped: - fmt.Print(cl("-", cyan)) - case failed: - fmt.Print(cl("F", red)) - case undefined: - fmt.Print(cl("U", yellow)) - case pending: - fmt.Print(cl("P", yellow)) - } - f.steps++ - if math.Mod(float64(f.steps), float64(f.stepsPerRow)) == 0 { - fmt.Printf(" %d\n", f.steps) - } -} - -func (f *progress) Passed(step *gherkin.Step, match *StepDef) { - f.Lock() - defer f.Unlock() - f.basefmt.Passed(step, match) - f.step(f.passed[len(f.passed)-1]) -} - -func (f *progress) Skipped(step *gherkin.Step) { - f.Lock() - defer f.Unlock() - f.basefmt.Skipped(step) - f.step(f.skipped[len(f.skipped)-1]) -} - -func (f *progress) Undefined(step *gherkin.Step) { - f.Lock() - defer f.Unlock() - f.basefmt.Undefined(step) - f.step(f.undefined[len(f.undefined)-1]) -} - -func (f *progress) Failed(step *gherkin.Step, match *StepDef, err error) { - f.Lock() - defer f.Unlock() - f.basefmt.Failed(step, match, err) - f.step(f.failed[len(f.failed)-1]) -} - -func (f *progress) Pending(step *gherkin.Step, match *StepDef) { - f.Lock() - defer f.Unlock() - f.basefmt.Pending(step, match) - f.step(f.pending[len(f.pending)-1]) -} diff --git a/vendor/github.com/DATA-DOG/godog/gherkin.go b/vendor/github.com/DATA-DOG/godog/gherkin.go deleted file mode 100644 index 4280eae9dcd..00000000000 --- a/vendor/github.com/DATA-DOG/godog/gherkin.go +++ /dev/null @@ -1,11 +0,0 @@ -package godog - -import "github.com/DATA-DOG/godog/gherkin" - -// examples is a helper func to cast gherkin.Examples -// or gherkin.BaseExamples if its empty -// @TODO: this should go away with gherkin update -func examples(ex interface{}) (*gherkin.Examples, bool) { - t, ok := ex.(*gherkin.Examples) - return t, ok -} diff --git a/vendor/github.com/DATA-DOG/godog/godog.go b/vendor/github.com/DATA-DOG/godog/godog.go deleted file mode 100644 index 5da8d34e0fb..00000000000 --- a/vendor/github.com/DATA-DOG/godog/godog.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Package godog is the official Cucumber BDD framework for Golang, it merges specification -and test documentation into one cohesive whole. - -Godog does not intervene with the standard "go test" command and it's behavior. -You can leverage both frameworks to functionally test your application while -maintaining all test related source code in *_test.go files. - -Godog acts similar compared to go test command. It uses go -compiler and linker tool in order to produce test executable. Godog -contexts needs to be exported same as Test functions for go test. - -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 output: - """ - 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 Cucumber the above description is taken from it's documentation. -*/ -package godog - -// Version of package - based on Semantic Versioning 2.0.0 http://semver.org/ -const Version = "v0.5.4" diff --git a/vendor/github.com/DATA-DOG/godog/logo.png b/vendor/github.com/DATA-DOG/godog/logo.png deleted file mode 100644 index 079509f568830a212271177aadc7603f0c29992d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48144 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 B4E+EA diff --git a/vendor/github.com/DATA-DOG/godog/run.go b/vendor/github.com/DATA-DOG/godog/run.go deleted file mode 100644 index 4f3257382c5..00000000000 --- a/vendor/github.com/DATA-DOG/godog/run.go +++ /dev/null @@ -1,124 +0,0 @@ -package godog - -import ( - "fmt" - "os" -) - -type initializer func(*Suite) - -type runner struct { - stopOnFailure bool - features []*feature - fmt Formatter // needs to support concurrency - initializer initializer -} - -func (r *runner) concurrent(rate int) (failed bool) { - queue := make(chan int, rate) - for i, ft := range r.features { - queue <- i // reserve space in queue - go func(fail *bool, feat *feature) { - defer func() { - <-queue // free a space in queue - }() - if r.stopOnFailure && *fail { - return - } - suite := &Suite{ - fmt: r.fmt, - stopOnFailure: r.stopOnFailure, - features: []*feature{feat}, - } - r.initializer(suite) - suite.run() - if suite.failed { - *fail = true - } - }(&failed, ft) - } - // wait until last are processed - for i := 0; i < rate; i++ { - queue <- i - } - close(queue) - - // print summary - r.fmt.Summary() - return -} - -func (r *runner) run() (failed bool) { - suite := &Suite{ - fmt: r.fmt, - stopOnFailure: r.stopOnFailure, - features: r.features, - } - r.initializer(suite) - suite.run() - - r.fmt.Summary() - return suite.failed -} - -// Run creates and runs the feature suite. -// uses contextInitializer to register contexts -// -// the concurrency option allows runner to -// initialize a number of suites to be run -// separately. Only progress formatter -// is supported when concurrency level is -// higher than 1 -// -// contextInitializer must be able to register -// the step definitions and event handlers. -func Run(contextInitializer func(suite *Suite)) int { - var defs, sof, noclr bool - var tags, format string - var concurrency int - flagSet := FlagSet(&format, &tags, &defs, &sof, &noclr, &concurrency) - err := flagSet.Parse(os.Args[1:]) - fatal(err) - - if defs { - s := &Suite{} - contextInitializer(s) - s.printStepDefinitions() - return 0 - } - - paths := flagSet.Args() - if len(paths) == 0 { - inf, err := os.Stat("features") - if err == nil && inf.IsDir() { - paths = []string{"features"} - } - } - - if concurrency > 1 && format != "progress" { - fatal(fmt.Errorf("when concurrency level is higher than 1, only progress format is supported")) - } - formatter, err := findFmt(format) - fatal(err) - - features, err := parseFeatures(tags, paths) - fatal(err) - - r := runner{ - fmt: formatter, - initializer: contextInitializer, - features: features, - stopOnFailure: sof, - } - - var failed bool - if concurrency > 1 { - failed = r.concurrent(concurrency) - } else { - failed = r.run() - } - if failed { - return 1 - } - return 0 -} diff --git a/vendor/github.com/DATA-DOG/godog/stepdef.go b/vendor/github.com/DATA-DOG/godog/stepdef.go deleted file mode 100644 index 6ce06cee961..00000000000 --- a/vendor/github.com/DATA-DOG/godog/stepdef.go +++ /dev/null @@ -1,189 +0,0 @@ -package godog - -import ( - "fmt" - "path/filepath" - "reflect" - "regexp" - "runtime" - "strconv" - "strings" - - "github.com/DATA-DOG/godog/gherkin" -) - -var matchFuncDefRef = regexp.MustCompile(`\(([^\)]+)\)`) - -// StepDef is a registered step definition -// contains a StepHandler and regexp which -// is used to match a step. Args which -// were matched by last executed step -// -// This structure is passed to the formatter -// when step is matched and is either failed -// or successful -type StepDef struct { - args []interface{} - hv reflect.Value - Expr *regexp.Regexp - Handler interface{} -} - -func (sd *StepDef) funcName() string { - ptr := sd.hv.Pointer() - f := runtime.FuncForPC(ptr) - file, line := f.FileLine(ptr) - dir := filepath.Dir(file) - - fn := strings.Replace(f.Name(), dir, "", -1) - var parts []string - for _, gr := range matchFuncDefRef.FindAllStringSubmatch(fn, -1) { - parts = append(parts, strings.Trim(gr[1], "_.")) - } - if len(parts) > 0 { - // case when suite is a structure with methods - fn = strings.Join(parts, ".") - } else { - // case when steps are just plain funcs - fn = strings.Trim(fn, "_.") - } - - return fmt.Sprintf("%s:%d -> %s", filepath.Base(file), line, fn) -} - -// run a step with the matched arguments using -// reflect -func (sd *StepDef) run() error { - typ := sd.hv.Type() - if len(sd.args) < typ.NumIn() { - return fmt.Errorf("func expects %d arguments, which is more than %d matched from step", typ.NumIn(), len(sd.args)) - } - var values []reflect.Value - for i := 0; i < typ.NumIn(); i++ { - param := typ.In(i) - switch param.Kind() { - case reflect.Int: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseInt(s, 10, 0) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to int: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(int(v))) - case reflect.Int64: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to int64: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(int64(v))) - case reflect.Int32: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to int32: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(int32(v))) - case reflect.Int16: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseInt(s, 10, 16) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to int16: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(int16(v))) - case reflect.Int8: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseInt(s, 10, 8) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to int8: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(int8(v))) - case reflect.String: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - values = append(values, reflect.ValueOf(s)) - case reflect.Float64: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseFloat(s, 64) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to float64: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(v)) - case reflect.Float32: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - v, err := strconv.ParseFloat(s, 32) - if err != nil { - return fmt.Errorf(`cannot convert argument %d: "%s" to float32: %s`, i, s, err) - } - values = append(values, reflect.ValueOf(float32(v))) - case reflect.Ptr: - arg := sd.args[i] - switch param.Elem().String() { - case "gherkin.DocString": - v, ok := arg.(*gherkin.DocString) - if !ok { - return fmt.Errorf(`cannot convert argument %d: "%v" of type "%T" to *gherkin.DocString`, i, arg, arg) - } - values = append(values, reflect.ValueOf(v)) - case "gherkin.DataTable": - v, ok := arg.(*gherkin.DataTable) - if !ok { - return fmt.Errorf(`cannot convert argument %d: "%v" of type "%T" to *gherkin.DocString`, i, arg, arg) - } - values = append(values, reflect.ValueOf(v)) - default: - return fmt.Errorf("the argument %d type %T is not supported", i, arg) - } - case reflect.Slice: - switch param { - case typeOfBytes: - s, err := sd.shouldBeString(i) - if err != nil { - return err - } - values = append(values, reflect.ValueOf([]byte(s))) - default: - return fmt.Errorf("the slice argument %d type %s is not supported", i, param.Kind()) - } - default: - return fmt.Errorf("the argument %d type %s is not supported", i, param.Kind()) - } - } - ret := sd.hv.Call(values)[0].Interface() - if nil == ret { - return nil - } - - return ret.(error) -} - -func (sd *StepDef) shouldBeString(idx int) (string, error) { - arg := sd.args[idx] - s, ok := arg.(string) - if !ok { - return "", fmt.Errorf(`cannot convert argument %d: "%v" of type "%T" to string`, idx, arg, arg) - } - return s, nil -} diff --git a/vendor/github.com/DATA-DOG/godog/suite.go b/vendor/github.com/DATA-DOG/godog/suite.go deleted file mode 100644 index 3ceaba5f18c..00000000000 --- a/vendor/github.com/DATA-DOG/godog/suite.go +++ /dev/null @@ -1,535 +0,0 @@ -package godog - -import ( - "fmt" - "os" - "path/filepath" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - "unicode/utf8" - - "github.com/DATA-DOG/godog/gherkin" -) - -var errorInterface = reflect.TypeOf((*error)(nil)).Elem() -var typeOfBytes = reflect.TypeOf([]byte(nil)) - -type feature struct { - *gherkin.Feature - Path string `json:"path"` -} - -// ErrUndefined is returned in case if step definition was not found -var ErrUndefined = fmt.Errorf("step is undefined") - -// ErrPending should be returned by step definition if -// step implementation is pending -var ErrPending = fmt.Errorf("step implementation is pending") - -// Suite allows various contexts -// to register steps and event handlers. -// -// When running a test suite, the instance of Suite -// is passed to all functions (contexts), which -// have it as a first and only argument. -// -// Note that all event hooks does not catch panic errors -// in order to have a trace information. Only step -// executions are catching panic error since it may -// be a context specific error. -type Suite struct { - steps []*StepDef - features []*feature - fmt Formatter - - failed bool - stopOnFailure bool - - // suite event handlers - beforeSuiteHandlers []func() - beforeScenarioHandlers []func(interface{}) - beforeStepHandlers []func(*gherkin.Step) - afterStepHandlers []func(*gherkin.Step, error) - afterScenarioHandlers []func(interface{}, error) - afterSuiteHandlers []func() -} - -// Step allows to register a *StepDef in Godog -// feature suite, the definition will be applied -// to all steps matching the given Regexp expr. -// -// It will panic if expr is not a valid regular -// expression or stepFunc is not a valid step -// handler. -// -// Note that if there are two definitions which may match -// the same step, then only the first matched handler -// will be applied. -// -// If none of the *StepDef is matched, then -// ErrUndefined error will be returned when -// running steps. -func (s *Suite) Step(expr interface{}, stepFunc interface{}) { - var regex *regexp.Regexp - - switch t := expr.(type) { - case *regexp.Regexp: - regex = t - case string: - regex = regexp.MustCompile(t) - case []byte: - regex = regexp.MustCompile(string(t)) - default: - panic(fmt.Sprintf("expecting expr to be a *regexp.Regexp or a string, got type: %T", expr)) - } - - v := reflect.ValueOf(stepFunc) - typ := v.Type() - if typ.Kind() != reflect.Func { - panic(fmt.Sprintf("expected handler to be func, but got: %T", stepFunc)) - } - if typ.NumOut() != 1 { - panic(fmt.Sprintf("expected handler to return an error, but it has more values in return: %d", typ.NumOut())) - } - if typ.Out(0).Kind() != reflect.Interface || !typ.Out(0).Implements(errorInterface) { - panic(fmt.Sprintf("expected handler to return an error interface, but we have: %s", typ.Out(0).Kind())) - } - s.steps = append(s.steps, &StepDef{ - Handler: stepFunc, - Expr: regex, - hv: v, - }) -} - -// BeforeSuite registers a function or method -// to be run once before suite runner. -// -// Use it to prepare the test suite for a spin. -// Connect and prepare database for instance... -func (s *Suite) BeforeSuite(f func()) { - s.beforeSuiteHandlers = append(s.beforeSuiteHandlers, f) -} - -// BeforeScenario registers a function or method -// to be run before every scenario or scenario outline. -// -// The interface argument may be *gherkin.Scenario -// or *gherkin.ScenarioOutline -// -// It is a good practice to restore the default state -// before every scenario so it would be isolated from -// any kind of state. -func (s *Suite) BeforeScenario(f func(interface{})) { - s.beforeScenarioHandlers = append(s.beforeScenarioHandlers, f) -} - -// BeforeStep registers a function or method -// to be run before every scenario -func (s *Suite) BeforeStep(f func(*gherkin.Step)) { - s.beforeStepHandlers = append(s.beforeStepHandlers, f) -} - -// AfterStep registers an function or method -// to be run after every scenario -// -// It may be convenient to return a different kind of error -// in order to print more state details which may help -// in case of step failure -// -// In some cases, for example when running a headless -// browser, to take a screenshot after failure. -func (s *Suite) AfterStep(f func(*gherkin.Step, error)) { - s.afterStepHandlers = append(s.afterStepHandlers, f) -} - -// AfterScenario registers an function or method -// to be run after every scenario or scenario outline -// -// The interface argument may be *gherkin.Scenario -// or *gherkin.ScenarioOutline -func (s *Suite) AfterScenario(f func(interface{}, error)) { - s.afterScenarioHandlers = append(s.afterScenarioHandlers, f) -} - -// AfterSuite registers a function or method -// to be run once after suite runner -func (s *Suite) AfterSuite(f func()) { - s.afterSuiteHandlers = append(s.afterSuiteHandlers, f) -} - -func (s *Suite) run() { - // run before suite handlers - for _, f := range s.beforeSuiteHandlers { - f() - } - // run features - for _, f := range s.features { - s.runFeature(f) - if s.failed && s.stopOnFailure { - // stop on first failure - break - } - } - // run after suite handlers - for _, f := range s.afterSuiteHandlers { - f() - } -} - -func (s *Suite) matchStep(step *gherkin.Step) *StepDef { - for _, h := range s.steps { - if m := h.Expr.FindStringSubmatch(step.Text); len(m) > 0 { - var args []interface{} - for _, m := range m[1:] { - args = append(args, m) - } - if step.Argument != nil { - args = append(args, step.Argument) - } - h.args = args - return h - } - } - return nil -} - -func (s *Suite) runStep(step *gherkin.Step, prevStepErr error) (err error) { - match := s.matchStep(step) - if match == nil { - s.fmt.Undefined(step) - return ErrUndefined - } - - if prevStepErr != nil { - s.fmt.Skipped(step) - return nil - } - - // run before step handlers - for _, f := range s.beforeStepHandlers { - f(step) - } - - defer func() { - if e := recover(); e != nil { - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("%v", e) - } - } - switch err { - case nil: - s.fmt.Passed(step, match) - case ErrPending: - s.fmt.Pending(step, match) - default: - s.fmt.Failed(step, match, err) - } - - // run after step handlers - for _, f := range s.afterStepHandlers { - f(step, err) - } - }() - - err = match.run() - return -} - -func (s *Suite) runSteps(steps []*gherkin.Step, prevErr error) (err error) { - err = prevErr - for _, step := range steps { - stepErr := s.runStep(step, err) - switch stepErr { - case ErrUndefined: - err = stepErr - case ErrPending: - err = stepErr - case nil: - default: - err = stepErr - } - } - return -} - -func (s *Suite) skipSteps(steps []*gherkin.Step) { - for _, step := range steps { - s.fmt.Skipped(step) - } -} - -func (s *Suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Background) (failErr error) { - s.fmt.Node(outline) - - for _, ex := range outline.Examples { - example, hasExamples := examples(ex) - if !hasExamples { - // @TODO: may need to print empty example node, but - // for backward compatibility, cannot cast to *gherkin.ExamplesBase - // at the moment - continue - } - - s.fmt.Node(example) - placeholders := example.TableHeader.Cells - groups := example.TableBody - - for _, group := range groups { - for _, f := range s.beforeScenarioHandlers { - f(outline) - } - var steps []*gherkin.Step - for _, outlineStep := range outline.Steps { - text := outlineStep.Text - for i, placeholder := range placeholders { - text = strings.Replace(text, "<"+placeholder.Value+">", group.Cells[i].Value, -1) - } - // clone a step - step := &gherkin.Step{ - Node: outlineStep.Node, - Text: text, - Keyword: outlineStep.Keyword, - Argument: outlineStep.Argument, - } - steps = append(steps, step) - } - - // run example table row - s.fmt.Node(group) - - // run background - var err error - if b != nil { - err = s.runSteps(b.Steps, err) - } - err = s.runSteps(steps, err) - - for _, f := range s.afterScenarioHandlers { - f(outline, err) - } - - if err != nil && err != ErrUndefined && err != ErrPending { - failErr = err - if s.stopOnFailure { - return - } - } - } - } - return -} - -func (s *Suite) runFeature(f *feature) { - s.fmt.Feature(f.Feature, f.Path) - for _, scenario := range f.ScenarioDefinitions { - var err error - if f.Background != nil { - s.fmt.Node(f.Background) - } - switch t := scenario.(type) { - case *gherkin.ScenarioOutline: - err = s.runOutline(t, f.Background) - case *gherkin.Scenario: - err = s.runScenario(t, f.Background) - } - if err != nil && err != ErrUndefined && err != ErrPending { - s.failed = true - if s.stopOnFailure { - return - } - } - } -} - -func (s *Suite) runScenario(scenario *gherkin.Scenario, b *gherkin.Background) (err error) { - // run before scenario handlers - for _, f := range s.beforeScenarioHandlers { - f(scenario) - } - - s.fmt.Node(scenario) - - // background - if b != nil { - err = s.runSteps(b.Steps, err) - } - - // scenario - err = s.runSteps(scenario.Steps, err) - - // run after scenario handlers - for _, f := range s.afterScenarioHandlers { - f(scenario, err) - } - - return -} - -func (s *Suite) printStepDefinitions() { - var longest int - for _, def := range s.steps { - n := utf8.RuneCountInString(def.Expr.String()) - if longest < n { - longest = n - } - } - for _, def := range s.steps { - n := utf8.RuneCountInString(def.Expr.String()) - location := def.funcName() - spaces := strings.Repeat(" ", longest-n) - fmt.Println(cl(def.Expr.String(), yellow)+spaces, cl("# "+location, black)) - } - if len(s.steps) == 0 { - fmt.Println("there were no contexts registered, could not find any step definition..") - } -} - -func parseFeatures(filter string, paths []string) (features []*feature, err error) { - for _, pat := range paths { - // check if line number is specified - parts := strings.Split(pat, ":") - path := parts[0] - line := -1 - if len(parts) > 1 { - line, err = strconv.Atoi(parts[1]) - if err != nil { - return features, fmt.Errorf("line number should follow after colon path delimiter") - } - } - // parse features - err = filepath.Walk(path, func(p string, f os.FileInfo, err error) error { - if err == nil && !f.IsDir() && strings.HasSuffix(p, ".feature") { - reader, err := os.Open(p) - if err != nil { - return err - } - ft, err := gherkin.ParseFeature(reader) - reader.Close() - if err != nil { - return err - } - features = append(features, &feature{Path: p, Feature: ft}) - // filter scenario by line number - if line != -1 { - var scenarios []interface{} - for _, def := range ft.ScenarioDefinitions { - var ln int - switch t := def.(type) { - case *gherkin.Scenario: - ln = t.Location.Line - case *gherkin.ScenarioOutline: - ln = t.Location.Line - } - if ln == line { - scenarios = append(scenarios, def) - break - } - } - ft.ScenarioDefinitions = scenarios - } - applyTagFilter(filter, ft) - } - return err - }) - // check error - switch { - case os.IsNotExist(err): - return features, fmt.Errorf(`feature path "%s" is not available`, path) - case os.IsPermission(err): - return features, fmt.Errorf(`feature path "%s" is not accessible`, path) - case err != nil: - return features, err - } - } - sort.Sort(featuresSortedByPath(features)) - return -} - -type featuresSortedByPath []*feature - -func (s featuresSortedByPath) Len() int { return len(s) } -func (s featuresSortedByPath) Less(i, j int) bool { return s[i].Path < s[j].Path } -func (s featuresSortedByPath) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func applyTagFilter(tags string, ft *gherkin.Feature) { - if len(tags) == 0 { - return - } - - var scenarios []interface{} - for _, scenario := range ft.ScenarioDefinitions { - if matchesTags(tags, allTags(ft, scenario)) { - scenarios = append(scenarios, scenario) - } - } - ft.ScenarioDefinitions = scenarios -} - -func allTags(nodes ...interface{}) []string { - var tags, tmp []string - for _, node := range nodes { - var gr []*gherkin.Tag - switch t := node.(type) { - case *gherkin.Feature: - gr = t.Tags - case *gherkin.ScenarioOutline: - gr = t.Tags - case *gherkin.Scenario: - gr = t.Tags - case *gherkin.Examples: - gr = t.Tags - } - - for _, gtag := range gr { - tag := strings.TrimSpace(gtag.Name) - if tag[0] == '@' { - tag = tag[1:] - } - copy(tmp, tags) - var found bool - for _, tg := range tmp { - if tg == tag { - found = true - break - } - } - if !found { - tags = append(tags, tag) - } - } - } - return tags -} - -func hasTag(tags []string, tag string) bool { - for _, t := range tags { - if t == tag { - return true - } - } - return false -} - -// based on http://behat.readthedocs.org/en/v2.5/guides/6.cli.html#gherkin-filters -func matchesTags(filter string, tags []string) (ok bool) { - ok = true - for _, andTags := range strings.Split(filter, "&&") { - var okComma bool - for _, tag := range strings.Split(andTags, ",") { - tag = strings.Replace(strings.TrimSpace(tag), "@", "", -1) - if tag[0] == '~' { - tag = tag[1:] - okComma = !hasTag(tags, tag) || okComma - } else { - okComma = hasTag(tags, tag) || okComma - } - } - ok = (false != okComma && ok && okComma) || false - } - return -} diff --git a/vendor/github.com/DATA-DOG/godog/utils.go b/vendor/github.com/DATA-DOG/godog/utils.go deleted file mode 100644 index d51ab21d098..00000000000 --- a/vendor/github.com/DATA-DOG/godog/utils.go +++ /dev/null @@ -1,50 +0,0 @@ -package godog - -import ( - "fmt" - "os" - "strings" -) - -// empty struct value takes no space allocation -type void struct{} - -// a color code type -type color int - -const ansiEscape = "\x1b" - -// some ansi colors -const ( - black color = iota + 30 - red - green - yellow - blue - magenta - cyan - white -) - -// colorizes foreground s with color c -func cl(s interface{}, c color) string { - return fmt.Sprintf("%s[%dm%v%s[0m", ansiEscape, c, s, ansiEscape) -} - -// colorizes foreground s with bold color c -func bcl(s interface{}, c color) string { - return fmt.Sprintf("%s[1;%dm%v%s[0m", ansiEscape, c, s, ansiEscape) -} - -// repeats a space n times -func s(n int) string { - return strings.Repeat(" ", n) -} - -// checks the error and exits with error status code -func fatal(err error) { - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 75e990632a9..20e8d7550b7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -7,12 +7,6 @@ "revision": "056c9bc7be7190eaa7715723883caffa5f8fa3e4", "revisionTime": "2015-05-01T06:40:42-04:00" }, - { - "checksumSHA1": "Kos2ch8973PnyyQ2JPAgWKtQV1A=", - "path": "github.com/DATA-DOG/godog", - "revision": "6e3b3f764a57d37691c0dfd007e7e586d3e452dc", - "revisionTime": "2016-08-07T16:35:39Z" - }, { "checksumSHA1": "Zi1ZEYvoDhlK2+AaxrNeqmyZ4wY=", "path": "github.com/DATA-DOG/godog/cmd/godog",