Improve example with concurrency support (#573)
Этот коммит содержится в:
родитель
75d5cab90d
коммит
d3aec7142e
3 изменённых файлов: 84 добавлений и 23 удалений
|
@ -1,4 +1,37 @@
|
|||
package godogs
|
||||
|
||||
// Godogs available to eat.
|
||||
var Godogs int
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Godogs is an example behavior holder.
|
||||
type Godogs int
|
||||
|
||||
// Add increments Godogs count.
|
||||
func (g *Godogs) Add(n int) {
|
||||
*g = *g + Godogs(n)
|
||||
}
|
||||
|
||||
// Eat decrements Godogs count or fails if there is not enough available.
|
||||
func (g *Godogs) Eat(n int) error {
|
||||
ng := Godogs(n)
|
||||
|
||||
if (g == nil && ng > 0) || ng > *g {
|
||||
return fmt.Errorf("you cannot eat %d godogs, there are %d available", n, g.Available())
|
||||
}
|
||||
|
||||
if ng > 0 {
|
||||
*g = *g - ng
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Available returns the number of currently available Godogs.
|
||||
func (g *Godogs) Available() int {
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return int(*g)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package godogs
|
||||
package godogs_test
|
||||
|
||||
// This example shows how to set up test suite runner with Go subtests and godog command line parameters.
|
||||
// Sample commands:
|
||||
|
@ -15,6 +15,7 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/cucumber/godog/_examples/godogs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
|
@ -22,7 +23,10 @@ import (
|
|||
"github.com/cucumber/godog/colors"
|
||||
)
|
||||
|
||||
var opts = godog.Options{Output: colors.Colored(os.Stdout)}
|
||||
var opts = godog.Options{
|
||||
Output: colors.Colored(os.Stdout),
|
||||
Concurrency: 4,
|
||||
}
|
||||
|
||||
func init() {
|
||||
godog.BindFlags("godog.", flag.CommandLine, &opts)
|
||||
|
@ -48,38 +52,54 @@ func TestFeatures(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func thereAreGodogs(available int) error {
|
||||
Godogs = available
|
||||
return nil
|
||||
type godogsCtxKey struct{}
|
||||
|
||||
func godogsToContext(ctx context.Context, g godogs.Godogs) context.Context {
|
||||
return context.WithValue(ctx, godogsCtxKey{}, &g)
|
||||
}
|
||||
|
||||
func iEat(num int) error {
|
||||
if Godogs < num {
|
||||
return fmt.Errorf("you cannot eat %d godogs, there are %d available", num, Godogs)
|
||||
func godogsFromContext(ctx context.Context) *godogs.Godogs {
|
||||
g, _ := ctx.Value(godogsCtxKey{}).(*godogs.Godogs)
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
// Concurrent execution of scenarios may lead to race conditions on shared resources.
|
||||
// Use context to maintain data separation and avoid data races.
|
||||
|
||||
// Step definition can optionally receive context as a first argument.
|
||||
|
||||
func thereAreGodogs(ctx context.Context, available int) {
|
||||
godogsFromContext(ctx).Add(available)
|
||||
}
|
||||
|
||||
// Step definition can return error, context, context and error, or nothing.
|
||||
|
||||
func iEat(ctx context.Context, num int) error {
|
||||
return godogsFromContext(ctx).Eat(num)
|
||||
}
|
||||
|
||||
func thereShouldBeRemaining(ctx context.Context, remaining int) error {
|
||||
available := godogsFromContext(ctx).Available()
|
||||
if available != remaining {
|
||||
return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, available)
|
||||
}
|
||||
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 thereShouldBeNoneRemaining() error {
|
||||
return thereShouldBeRemaining(0)
|
||||
func thereShouldBeNoneRemaining(ctx context.Context) error {
|
||||
return thereShouldBeRemaining(ctx, 0)
|
||||
}
|
||||
|
||||
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
|
||||
ctx.BeforeSuite(func() { Godogs = 0 })
|
||||
ctx.BeforeSuite(func() { fmt.Println("Get the party started!") })
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
Godogs = 0 // clean the state before every scenario
|
||||
return ctx, nil
|
||||
// Add initial godogs to context.
|
||||
return godogsToContext(ctx, 0), nil
|
||||
})
|
||||
|
||||
ctx.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cucumber/gherkin/go/v26 v26.0.2 h1:DjNKtTIv5VG0F1XaJ2xYNk+ck8pJWRNFzyajkc/Y4l4=
|
||||
github.com/cucumber/gherkin/go/v26 v26.0.2/go.mod h1:Xf+SrSuFbivEDZvmHjTShord3zlEkqsj7QB4sxl1SuU=
|
||||
github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0=
|
||||
github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI=
|
||||
github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s=
|
||||
github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
|
@ -15,6 +19,7 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ
|
|||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8=
|
||||
github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g=
|
||||
github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
|
@ -22,6 +27,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
|
@ -37,6 +43,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
|||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -46,6 +53,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче