diff --git a/README.md b/README.md index 5cf7fb7..941c41f 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Since we need a working implementation, we may start by implementing only what i #### Step 3 -We only need a number of **godogs** for now. Let's define steps. +We only need a number of **godogs** for now. Lets keep it simple. ``` go /* file: examples/godogs/godog.go */ @@ -121,7 +121,8 @@ func main() { /* usual main func */ } #### Step 4 -Now let's finish our step implementations in order to test our feature requirements: +Now lets implement our step definitions, which we can copy from generated +console output snippets in order to test our feature requirements: ``` go /* file: examples/godogs/godog_test.go */ diff --git a/builder.go b/builder.go index 5c23990..42624ab 100644 --- a/builder.go +++ b/builder.go @@ -57,35 +57,35 @@ func Build() (string, error) { if err != nil { return "", err } - pkg, err := build.ImportDir(abs, 0) - if err != nil { - return "", err - } - bin := filepath.Join(pkg.Dir, "godog.test") + 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, _ := build.ImportDir(abs, 0) src, anyContexts, err := buildTestMain(pkg) if err != nil { return bin, err } - // 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)) - } - 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 @@ -130,7 +130,7 @@ func Build() (string, error) { // 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 := []string{filepath.Join(pkg.Dir, "vendor", godogImportPath)} + try := []string{filepath.Join(abs, "vendor", godogImportPath)} for _, d := range build.Default.SrcDirs() { try = append(try, filepath.Join(d, godogImportPath)) } @@ -143,7 +143,7 @@ func Build() (string, error) { // will be installed as dependency of godog cmd := exec.Command("go", "install", godogPkg.ImportPath) cmd.Env = os.Environ() - out, err = cmd.CombinedOutput() + out, err := cmd.CombinedOutput() if err != nil { return bin, fmt.Errorf("failed to install godog package:\n%s", string(out)) } @@ -193,6 +193,7 @@ func Build() (string, error) { args = append(args, testMainPkgOut) cmd = exec.Command(linker, args...) cmd.Env = os.Environ() + out, err = cmd.CombinedOutput() if err != nil { return bin, fmt.Errorf("failed to link test executable:\n%s", string(out)) @@ -232,22 +233,28 @@ func uniqStringList(strs []string) (unique []string) { // run the test suite. If TestMain func is found in tested // source, it will be removed so it can be replaced func buildTestMain(pkg *build.Package) ([]byte, bool, error) { - contexts, err := processPackageTestFiles( - pkg.TestGoFiles, - pkg.XTestGoFiles, - ) - if err != nil { - return nil, false, err + var contexts []string + var importPath string + if nil != pkg { + ctxs, err := processPackageTestFiles( + pkg.TestGoFiles, + pkg.XTestGoFiles, + ) + if err != nil { + return nil, false, err + } + contexts = ctxs + importPath = pkg.ImportPath } data := struct { Name string Contexts []string ImportPath string - }{pkg.Name, contexts, pkg.ImportPath} + }{pkg.Name, contexts, importPath} var buf bytes.Buffer - if err = runnerTemplate.Execute(&buf, data); err != nil { + if err := runnerTemplate.Execute(&buf, data); err != nil { return nil, len(contexts) > 0, err } return buf.Bytes(), len(contexts) > 0, nil diff --git a/examples/godogs/godog.go b/examples/godogs/godog.go index 45d328c..5d1fa5c 100644 --- a/examples/godogs/godog.go +++ b/examples/godogs/godog.go @@ -1,3 +1,4 @@ +/* file: examples/godogs/godog.go */ package main // Godogs to eat diff --git a/examples/godogs/godog_test.go b/examples/godogs/godog_test.go new file mode 100644 index 0000000..4e4b992 --- /dev/null +++ b/examples/godogs/godog_test.go @@ -0,0 +1,38 @@ +/* file: examples/godogs/godog_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 + }) +} diff --git a/screenshots/passed.png b/screenshots/passed.png index 2897ac5..3e156f6 100644 Binary files a/screenshots/passed.png and b/screenshots/passed.png differ diff --git a/screenshots/undefined.png b/screenshots/undefined.png index c8b92eb..0b7c96c 100644 Binary files a/screenshots/undefined.png and b/screenshots/undefined.png differ