Сравнить коммиты
43 коммитов
Автор | SHA1 | Дата | |
---|---|---|---|
![]() |
6087fc101c | ||
![]() |
f5ec4cadce | ||
![]() |
ccc4a42649 | ||
![]() |
59344caf33 | ||
![]() |
56522e757a | ||
![]() |
bda4071975 | ||
![]() |
af6027bad2 | ||
![]() |
9ad168ae70 | ||
![]() |
4a15650887 | ||
![]() |
6f2a5fef98 | ||
![]() |
4e3e82b79e | ||
![]() |
26dafa0117 | ||
![]() |
3b25e9eb02 | ||
![]() |
78bab577c5 | ||
![]() |
0c030e0a6c | ||
![]() |
1b9806b25b | ||
![]() |
d2686eb13d | ||
![]() |
f0399fda41 | ||
![]() |
13639e7df7 | ||
![]() |
60442133fc | ||
![]() |
74fa488023 | ||
![]() |
4a4fd8ab3a | ||
![]() |
e03da742a5 | ||
![]() |
14fe127e3d | ||
![]() |
e55eab64f7 | ||
![]() |
da4633a421 | ||
![]() |
c5a88f62c2 | ||
![]() |
9b699ff9a8 | ||
![]() |
dc6950b1e3 | ||
![]() |
ecd2dfebbd | ||
![]() |
223efc3b14 | ||
![]() |
8edde7f30c | ||
![]() |
1e7c45eb78 | ||
![]() |
6e4f452389 | ||
![]() |
9b51734429 | ||
![]() |
901da7fa3d | ||
![]() |
bcf6bce793 | ||
![]() |
3abb346b28 | ||
![]() |
9558224cce | ||
![]() |
f85def32ee | ||
![]() |
201e526078 | ||
![]() |
4ade3314e8 | ||
![]() |
c3756d1aa2 |
127 изменённых файлов: 4679 добавлений и 840 удалений
5
.github/workflows/gorelease.yml
предоставленный
5
.github/workflows/gorelease.yml
предоставленный
|
@ -9,13 +9,12 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
GO_VERSION: 1.19.x
|
||||
GO_VERSION: stable
|
||||
jobs:
|
||||
gorelease:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Go stable
|
||||
if: env.GO_VERSION != 'tip'
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
@ -34,7 +33,7 @@ jobs:
|
|||
OUTPUT=$(gorelease 2>&1 || exit 0)
|
||||
echo "${OUTPUT}"
|
||||
OUTPUT="${OUTPUT//$'\n'/%0A}"
|
||||
echo "::set-output name=report::$OUTPUT"
|
||||
echo "report=$OUTPUT" >> $GITHUB_OUTPUT
|
||||
- name: Comment Report
|
||||
continue-on-error: true
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
|
|
2
.github/workflows/release-assets.yml
предоставленный
2
.github/workflows/release-assets.yml
предоставленный
|
@ -15,7 +15,7 @@ jobs:
|
|||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
go-version: stable
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Build artifacts
|
||||
|
|
8
.github/workflows/test.yml
предоставленный
8
.github/workflows/test.yml
предоставленный
|
@ -8,7 +8,7 @@ jobs:
|
|||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.16.x, 1.17.x, 1.19.x, 1.20.x, 1.21.x ] # Lowest supported and current stable versions.
|
||||
go-version: [ 1.16.x, 1.17.x, oldstable, stable ] # Lowest supported and current stable versions.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install Go
|
||||
|
@ -29,10 +29,10 @@ jobs:
|
|||
- name: Run gofmt
|
||||
run: gofmt -d -e . 2>&1 | tee outfile && test -z "$(cat outfile)" && rm outfile
|
||||
- name: Run staticcheck
|
||||
if: matrix.go-version == '1.20.x'
|
||||
if: matrix.go-version == 'stable'
|
||||
uses: dominikh/staticcheck-action@v1.3.1
|
||||
with:
|
||||
version: "2023.1.3"
|
||||
version: "latest"
|
||||
install-go: false
|
||||
cache-key: ${{ matrix.go }}
|
||||
|
||||
|
@ -49,7 +49,7 @@ jobs:
|
|||
go install ./cmd/godog
|
||||
godog -f progress --strict
|
||||
- name: Report on code coverage
|
||||
if: matrix.go-version == '1.17.x'
|
||||
if: matrix.go-version == 'stable'
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
|
|
2
.gitignore
предоставленный
2
.gitignore
предоставленный
|
@ -9,3 +9,5 @@ Gopkg.toml
|
|||
.vscode
|
||||
|
||||
_artifacts
|
||||
|
||||
vendor
|
||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -8,6 +8,26 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Step text is added to "step is undefined" error - ([669](https://github.com/cucumber/godog/pull/669) - [vearutop](https://github.com/vearutop))
|
||||
|
||||
### Changed
|
||||
- Replace deprecated `::set-output` - ([681](https://github.com/cucumber/godog/pull/681) - [nodeg](https://github.com/nodeg))
|
||||
|
||||
### Fixed
|
||||
- fix(errors): fix(errors): Fix expected Step argument count for steps with `context.Context` ([679](https://github.com/cucumber/godog/pull/679) - [tigh-latte](https://github.com/tigh-latte))
|
||||
- fix(formatter): On concurrent execution, execute formatter at end of Scenario - ([645](https://github.com/cucumber/godog/pull/645) - [tigh-latte](https://github.com/tigh-latte))
|
||||
|
||||
## [v0.15.0]
|
||||
|
||||
### Added
|
||||
- Improved the type checking of step return types and improved the error messages - ([647](https://github.com/cucumber/godog/pull/647) - [johnlon](https://github.com/johnlon))
|
||||
- Ambiguous step definitions will now be detected when strict mode is activated - ([636](https://github.com/cucumber/godog/pull/636)/([648](https://github.com/cucumber/godog/pull/648) - [johnlon](https://github.com/johnlon))
|
||||
- Provide support for attachments / embeddings including a new example in the examples dir - ([623](https://github.com/cucumber/godog/pull/623) - [johnlon](https://github.com/johnlon))
|
||||
|
||||
### Changed
|
||||
- Formatters now have a `Close` method and associated `io.Writer` changed to `io.WriteCloser`.
|
||||
|
||||
## [v0.14.1]
|
||||
|
||||
### Added
|
||||
|
@ -231,6 +251,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
|
|||
### Changed
|
||||
- Changed code references to DATA-DOG/godog to cucumber/godog to help get things building correctly. ([mxygem](https://github.com/mxygem))
|
||||
|
||||
[v0.15.0]: https://github.com/cucumber/godog/compare/v0.14.1...v0.15.0
|
||||
[v0.14.1]: https://github.com/cucumber/godog/compare/v0.14.0...v0.14.1
|
||||
[v0.14.0]: https://github.com/cucumber/godog/compare/v0.13.0...v0.14.0
|
||||
[v0.13.0]: https://github.com/cucumber/godog/compare/v0.12.6...v0.13.0
|
||||
|
|
|
@ -7,7 +7,7 @@ to give you a grounding in some of the basic concepts. You could also watch [thi
|
|||
|
||||
We want you to feel safe to make mistakes, and ask questions. If anything in this guide or anywhere else in the codebase doesn't make sense to you, please let us know! It's through your feedback that we can make this codebase more welcoming, so we'll be glad to hear thoughts.
|
||||
|
||||
You can chat with us in the [#committers-go](https://cucumberbdd.slack.com/archives/CA5NJPDJ4) channel in our [community Slack], or feel free to [raise an issue] if you're experiencing any friction trying make your contribution.
|
||||
You can chat with us in the `#committers` channel in our [community Discord](https://cucumber.io/docs/community/get-in-touch/#discord), or feel free to [raise an issue] if you're experiencing any friction trying make your contribution.
|
||||
|
||||
## Setup
|
||||
|
||||
|
@ -20,7 +20,7 @@ Once that's done, try running the tests:
|
|||
If everything passes, you're ready to hack!
|
||||
|
||||
[install go]: https://golang.org/doc/install
|
||||
[community Slack]: https://cucumber.io/community#slack
|
||||
[community Discord]: https://cucumber.io/community#discord
|
||||
[raise an issue]: https://github.com/cucumber/godog/issues/new/choose
|
||||
|
||||
## Changing dependencies
|
||||
|
|
138
Magefile.go
Обычный файл
138
Magefile.go
Обычный файл
|
@ -0,0 +1,138 @@
|
|||
//go:build mage
|
||||
// +build mage
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
// mage:import
|
||||
. "magefile/docker"
|
||||
)
|
||||
|
||||
var (
|
||||
GolangVolume = "golang.upstream"
|
||||
)
|
||||
|
||||
func init() {
|
||||
AppName = "godog"
|
||||
ImageName = "my/go"
|
||||
}
|
||||
|
||||
func Test() {
|
||||
TestNative()
|
||||
}
|
||||
func TestNative() {
|
||||
Bash(`sudo docker run -ti --rm \
|
||||
-h host \
|
||||
--net=bridge \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-v ` + GolangVolume + `:/usr/local/go:ro \
|
||||
\
|
||||
-v /gopath:/gopath:rw \
|
||||
-v ${PWD}:/app \
|
||||
\
|
||||
-e GOPATH=/gopath \
|
||||
-e GOCACHE=/gopath/gocache \
|
||||
\
|
||||
-w /app \
|
||||
-u 1000 \
|
||||
\
|
||||
--entrypoint=/bin/bash \
|
||||
\
|
||||
` + ImageName + " -c '" + `\
|
||||
go test -race -count=1 ./... \
|
||||
'`)
|
||||
}
|
||||
|
||||
func TestMakefile() {
|
||||
Bash(`sudo docker run -ti --rm \
|
||||
-h host \
|
||||
--net=bridge \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-v ` + GolangVolume + `:/usr/local/go:ro \
|
||||
\
|
||||
-v /gopath:/gopath:rw \
|
||||
-v ${PWD}:/app \
|
||||
\
|
||||
-e GOPATH=/gopath \
|
||||
-e GOCACHE=/gopath/gocache \
|
||||
\
|
||||
-w /app \
|
||||
-u 1000 \
|
||||
\
|
||||
--entrypoint=/bin/bash \
|
||||
\
|
||||
` + ImageName + " -c '" + `set -x; \
|
||||
make test \
|
||||
'`)
|
||||
}
|
||||
|
||||
func TestSnippets() {
|
||||
Bash(`sudo docker run -ti --rm \
|
||||
-h host \
|
||||
--net=bridge \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-v ` + GolangVolume + `:/usr/local/go:ro \
|
||||
\
|
||||
-v /gopath:/gopath:rw \
|
||||
-v ${PWD}:/app \
|
||||
\
|
||||
-e GOPATH=/gopath \
|
||||
-e GOCACHE=/gopath/gocache \
|
||||
\
|
||||
-w /app \
|
||||
-u 1000 \
|
||||
\
|
||||
--entrypoint=/bin/bash \
|
||||
\
|
||||
` + ImageName + " -c '" + `set -x; \
|
||||
godog run -f progress -c 4 \
|
||||
features/snippets.feature \
|
||||
'`)
|
||||
}
|
||||
|
||||
func TestTags() {
|
||||
Bash(`sudo docker run -ti --rm \
|
||||
-h host \
|
||||
--net=bridge \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-v ` + GolangVolume + `:/usr/local/go:ro \
|
||||
\
|
||||
-v /gopath:/gopath:rw \
|
||||
-v ${PWD}:/app \
|
||||
\
|
||||
-e GOPATH=/gopath \
|
||||
-e GOCACHE=/gopath/gocache \
|
||||
\
|
||||
-w /app \
|
||||
-u 1000 \
|
||||
\
|
||||
--entrypoint=/bin/bash \
|
||||
\
|
||||
` + ImageName + " -c '" + `set -x; \
|
||||
godog run -f progress -c 4 \
|
||||
features/tags.feature \
|
||||
'`)
|
||||
}
|
||||
|
||||
func Install() {
|
||||
Bash(`sudo docker run -ti --rm \
|
||||
-h host \
|
||||
--net=bridge \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-v ` + GolangVolume + `:/usr/local/go:ro \
|
||||
\
|
||||
-v /gopath:/gopath:rw \
|
||||
-v ${PWD}:/app \
|
||||
\
|
||||
-e GOPATH=/gopath \
|
||||
-e GOCACHE=/gopath/gocache \
|
||||
\
|
||||
-w /app \
|
||||
-u 1000 \
|
||||
\
|
||||
--entrypoint=/bin/bash \
|
||||
\
|
||||
` + ImageName + " -c '" + `set -x; \
|
||||
go install ./cmd/godog \
|
||||
'`)
|
||||
}
|
27
Makefile
27
Makefile
|
@ -2,21 +2,32 @@
|
|||
|
||||
VERS ?= $(shell git symbolic-ref -q --short HEAD || git describe --tags --exact-match)
|
||||
|
||||
FOUND_GO_VERSION := $(shell go version)
|
||||
EXPECTED_GO_VERSION = 1.17
|
||||
GO_MAJOR_VERSION = $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
|
||||
GO_MINOR_VERSION = $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
|
||||
MINIMUM_SUPPORTED_GO_MAJOR_VERSION = 1
|
||||
MINIMUM_SUPPORTED_GO_MINOR_VERSION = 16
|
||||
GO_VERSION_VALIDATION_ERR_MSG = Go version $(GO_MAJOR_VERSION).$(GO_MINOR_VERSION) is not supported, please update to at least $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION).$(MINIMUM_SUPPORTED_GO_MINOR_VERSION)
|
||||
|
||||
.PHONY: check-go-version
|
||||
check-go-version:
|
||||
@$(if $(findstring ${EXPECTED_GO_VERSION}, ${FOUND_GO_VERSION}),(exit 0),(echo Wrong go version! Please install ${EXPECTED_GO_VERSION}; exit 1))
|
||||
@if [ $(GO_MAJOR_VERSION) -gt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \
|
||||
exit 0 ;\
|
||||
elif [ $(GO_MAJOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \
|
||||
echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
|
||||
exit 1; \
|
||||
elif [ $(GO_MINOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MINOR_VERSION) ] ; then \
|
||||
echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
test: check-go-version
|
||||
@echo "running all tests"
|
||||
@go install ./...
|
||||
@go fmt ./...
|
||||
@go run honnef.co/go/tools/cmd/staticcheck@v0.2.2 github.com/cucumber/godog
|
||||
@go run honnef.co/go/tools/cmd/staticcheck@v0.2.2 github.com/cucumber/godog/cmd/godog
|
||||
@go run honnef.co/go/tools/cmd/staticcheck@v0.5.1 git.golang1.ru/softonik/godog
|
||||
@go run honnef.co/go/tools/cmd/staticcheck@v0.5.1 git.golang1.ru/softonik/godog/cmd/godog
|
||||
go vet ./...
|
||||
go test -race ./...
|
||||
godog -f progress -c 4
|
||||
go run ./cmd/godog -f progress -c 4
|
||||
|
||||
gherkin:
|
||||
@if [ -z "$(VERS)" ]; then echo "Provide gherkin version like: 'VERS=commit-hash'"; exit 1; fi
|
||||
|
@ -58,7 +69,7 @@ artifacts:
|
|||
|
||||
define _build
|
||||
mkdir $(ARTIFACT_DIR)/godog-$(VERS)-$1-$2
|
||||
env GOOS=$1 GOARCH=$2 go build -ldflags "-X github.com/cucumber/godog.Version=$(VERS)" -o $(ARTIFACT_DIR)/godog-$(VERS)-$1-$2/godog ./cmd/godog
|
||||
env GOOS=$1 GOARCH=$2 go build -ldflags "-X git.golang1.ru/softonik/godog.Version=$(VERS)" -o $(ARTIFACT_DIR)/godog-$(VERS)-$1-$2/godog ./cmd/godog
|
||||
cp README.md $(ARTIFACT_DIR)/godog-$(VERS)-$1-$2/README.md
|
||||
cp LICENSE $(ARTIFACT_DIR)/godog-$(VERS)-$1-$2/LICENSE
|
||||
cd $(ARTIFACT_DIR) && tar -c --use-compress-program="pigz --fast" -f godog-$(VERS)-$1-$2.tar.gz godog-$(VERS)-$1-$2 && cd ..
|
||||
|
|
18
README.md
18
README.md
|
@ -1,4 +1,3 @@
|
|||
[](https://vshymanskyy.github.io/StandWithUkraine)
|
||||
[](https://github.com/cucumber/godog/actions?query=branch%main+workflow%3Atest)
|
||||
[](https://pkg.go.dev/github.com/cucumber/godog)
|
||||
[](https://codecov.io/gh/cucumber/godog)
|
||||
|
@ -50,13 +49,7 @@ See the [releasing guide] for release flow details.
|
|||
|
||||
## Getting help
|
||||
|
||||
We have a [community Slack] where you can chat with other users, developers, and BDD practitioners.
|
||||
|
||||
Here are some useful channels to try:
|
||||
|
||||
- [#help-godog](https://cucumberbdd.slack.com/archives/CTNL1JCVA) - General Godog Adoption Help
|
||||
- [#committers-go](https://cucumberbdd.slack.com/archives/CA5NJPDJ4) - Golang focused Cucumber Contributors
|
||||
- [#committers](https://cucumberbdd.slack.com/archives/C62D0FK0E) - General Cucumber Contributors
|
||||
We have a [community Discord](https://cucumber.io/docs/community/get-in-touch/#discord) where you can chat with other users, developers, and BDD practitioners.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -292,6 +285,10 @@ When steps are orthogonal and small, you can combine them just like you do with
|
|||
|
||||
`TestFeatures` acts as a regular Go test, so you can leverage your IDE facilities to run and debug it.
|
||||
|
||||
### Attachments
|
||||
|
||||
An example showing how to make attachments (aka embeddings) to the results is shown in [_examples/attachments](/_examples/attachments/)
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Everyone interacting in this codebase and issue tracker is expected to follow the Cucumber [code of conduct](https://github.com/cucumber/cucumber/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
@ -579,4 +576,7 @@ A simple example can be [found here](/_examples/custom-formatter).
|
|||
[license]: https://en.wikipedia.org/wiki/MIT_License "The MIT license"
|
||||
[contributing guide]: https://github.com/cucumber/godog/blob/main/CONTRIBUTING.md
|
||||
[releasing guide]: https://github.com/cucumber/godog/blob/main/RELEASING.md
|
||||
[community Slack]: https://cucumber.io/community#slack
|
||||
[community Discord]: https://cucumber.io/community#discord
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ Cucumber Godog follows [Semantic Versioning]. Version numbers are in the format
|
|||
- Click "Publish release" to make the release public.
|
||||
|
||||
6. **Announce the Release:**
|
||||
- Make an announcement on relevant communication channels (e.g., [community Slack]) about the new release.
|
||||
- Make an announcement on relevant communication channels (e.g., [community Discord]) about the new release.
|
||||
|
||||
## Additional Considerations
|
||||
|
||||
|
@ -60,7 +60,7 @@ Cucumber Godog follows [Semantic Versioning]. Version numbers are in the format
|
|||
|
||||
Following these guidelines, including manual testing with external libraries, will help ensure a thorough release process for Cucumber Godog, allowing detection and resolution of potential backwards compatibility issues before tagging the release.
|
||||
|
||||
[community Slack]: https://cucumber.io/community#slack
|
||||
[community Discord]: https://cucumber.io/community#discord
|
||||
[website]: https://cucumber.github.io/godog/
|
||||
[Releases]: https://github.com/cucumber/godog/releases
|
||||
[Semantic Versioning]: http://semver.org
|
||||
|
|
|
@ -44,7 +44,7 @@ Now we have described a success case and an error when the request method is not
|
|||
Execute `godog run`. You should see the following result, which says that all of our
|
||||
steps are yet undefined and provide us with the snippets to implement them.
|
||||
|
||||

|
||||

|
||||
|
||||
### Step 3
|
||||
|
||||
|
@ -56,7 +56,7 @@ need to store state within steps (a response), we should introduce a structure w
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
type apiFeature struct {
|
||||
|
@ -114,7 +114,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
type apiFeature struct {
|
||||
|
@ -228,7 +228,7 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func getVersion(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -282,7 +282,7 @@ used to respond with the correct constant version number.
|
|||
|
||||
Run our tests to see whether everything is happening as we have expected: `go test -v`
|
||||
|
||||

|
||||

|
||||
|
||||
### Conclusions
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func getVersion(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
type apiFeature struct {
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
16
_examples/attachments/README.md
Обычный файл
16
_examples/attachments/README.md
Обычный файл
|
@ -0,0 +1,16 @@
|
|||
# An example of Making attachments to the reports
|
||||
|
||||
The JSON (and in future NDJSON) report formats allow the inclusion of data attachments.
|
||||
|
||||
These attachments could be console logs or file data or images for instance.
|
||||
|
||||
The example in this directory shows how the godog API is used to add attachments to the JSON report.
|
||||
|
||||
|
||||
## Run the example
|
||||
|
||||
You must use the '-v' flag or you will not see the cucumber JSON output.
|
||||
|
||||
go test -v attachments_test.go
|
||||
|
||||
|
89
_examples/attachments/attachments_test.go
Обычный файл
89
_examples/attachments/attachments_test.go
Обычный файл
|
@ -0,0 +1,89 @@
|
|||
package attachments_test
|
||||
|
||||
// This "demo" doesn't actually get run as a test by the build.
|
||||
|
||||
// This "example" shows how to attach data to the cucumber reports
|
||||
// Run the sample with : go test -v attachments_test.go
|
||||
// Then review the "embeddings" within the JSON emitted on the console.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
)
|
||||
|
||||
var opts = godog.Options{
|
||||
Output: colors.Colored(os.Stdout),
|
||||
Format: "cucumber", // cucumber json format
|
||||
}
|
||||
|
||||
func TestFeatures(t *testing.T) {
|
||||
o := opts
|
||||
o.TestingT = t
|
||||
|
||||
status := godog.TestSuite{
|
||||
Name: "attachments",
|
||||
Options: &o,
|
||||
ScenarioInitializer: InitializeScenario,
|
||||
}.Run()
|
||||
|
||||
if status == 2 {
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
if status != 0 {
|
||||
t.Fatalf("zero status code expected, %d received", status)
|
||||
}
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
|
||||
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("BeforeScenarioAttachment"), FileName: "Step Attachment 1", MediaType: "text/plain"},
|
||||
)
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("AfterScenarioAttachment"), FileName: "Step Attachment 2", MediaType: "text/plain"},
|
||||
)
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
ctx.StepContext().Before(func(ctx context.Context, st *godog.Step) (context.Context, error) {
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("BeforeStepAttachment"), FileName: "Step Attachment 3", MediaType: "text/plain"},
|
||||
)
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.StepContext().After(func(ctx context.Context, st *godog.Step, status godog.StepResultStatus, err error) (context.Context, error) {
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("AfterStepAttachment"), FileName: "Step Attachment 4", MediaType: "text/plain"},
|
||||
)
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
ctx.Step(`^I have attached two documents in sequence$`, func(ctx context.Context) (context.Context, error) {
|
||||
// the attached bytes will be base64 encoded by the framework and placed in the embeddings section of the cuke report
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("TheData1"), FileName: "Step Attachment 5", MediaType: "text/plain"},
|
||||
)
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("{ \"a\" : 1 }"), FileName: "Step Attachment 6", MediaType: "application/json"},
|
||||
)
|
||||
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.Step(`^I have attached two documents at once$`, func(ctx context.Context) (context.Context, error) {
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("TheData1"), FileName: "Step Attachment 7", MediaType: "text/plain"},
|
||||
godog.Attachment{Body: []byte("TheData2"), FileName: "Step Attachment 8", MediaType: "text/plain"},
|
||||
)
|
||||
|
||||
return ctx, nil
|
||||
})
|
||||
}
|
7
_examples/attachments/features/attachments.feature
Обычный файл
7
_examples/attachments/features/attachments.feature
Обычный файл
|
@ -0,0 +1,7 @@
|
|||
Feature: Attaching content to the cucumber report
|
||||
The cucumber JSON and NDJSON support the inclusion of attachments.
|
||||
These can be text or images or any data really.
|
||||
|
||||
Scenario: Attaching files to the report
|
||||
Given I have attached two documents in sequence
|
||||
And I have attached two documents at once
|
|
@ -5,7 +5,7 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# An example of API with DB
|
||||
|
||||
The following example demonstrates steps how we describe and test our API with DB using **godog**.
|
||||
To start with, see [API example](https://github.com/cucumber/godog/tree/master/_examples/api) before.
|
||||
To start with, see [API example](https://git.golang1.ru/softonik/godog/tree/master/_examples/api) before.
|
||||
We have extended it to be used with database.
|
||||
|
||||
The interesting point is, that we have [go-txdb](https://github.com/DATA-DOG/go-txdb) library,
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
txdb "github.com/DATA-DOG/go-txdb"
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
module github.com/cucumber/godog/_examples
|
||||
module git.golang1.ru/softonik/godog/_examples
|
||||
|
||||
go 1.16
|
||||
|
||||
replace github.com/cucumber/godog => ../
|
||||
replace git.golang1.ru/softonik/godog => ../
|
||||
|
||||
require (
|
||||
github.com/DATA-DOG/go-txdb v0.1.6
|
||||
github.com/cucumber/godog v0.14.0
|
||||
git.golang1.ru/softonik/godog v0.15.0
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.8.2
|
||||
)
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
|
|||
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/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
|
|
@ -15,12 +15,12 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/cucumber/godog/_examples/godogs"
|
||||
"git.golang1.ru/softonik/godog/_examples/godogs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
)
|
||||
|
||||
var opts = godog.Options{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
This example is to help reproduce issue [#383](https://github.com/cucumber/godog/issues/383)
|
||||
This example is to help reproduce issue [#383](https://git.golang1.ru/softonik/godog/issues/383)
|
||||
|
||||
To run the example:
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@ module incorrect-project-structure
|
|||
|
||||
go 1.13
|
||||
|
||||
require github.com/cucumber/godog v0.14.0
|
||||
require git.golang1.ru/softonik/godog v0.15.0
|
||||
|
||||
replace github.com/cucumber/godog => ../../
|
||||
replace git.golang1.ru/softonik/godog => ../../
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package main
|
||||
|
||||
import "github.com/cucumber/godog"
|
||||
import "git.golang1.ru/softonik/godog"
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
|
||||
|
|
28
attachment_test.go
Обычный файл
28
attachment_test.go
Обычный файл
|
@ -0,0 +1,28 @@
|
|||
package godog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAttach(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
ctx = Attach(ctx, Attachment{Body: []byte("body1"), FileName: "fileName1", MediaType: "mediaType1"})
|
||||
ctx = Attach(ctx, Attachment{Body: []byte("body2"), FileName: "fileName2", MediaType: "mediaType2"})
|
||||
|
||||
attachments := Attachments(ctx)
|
||||
|
||||
assert.Equal(t, 2, len(attachments))
|
||||
|
||||
assert.Equal(t, []byte("body1"), attachments[0].Body)
|
||||
assert.Equal(t, "fileName1", attachments[0].FileName)
|
||||
assert.Equal(t, "mediaType1", attachments[0].MediaType)
|
||||
|
||||
assert.Equal(t, []byte("body2"), attachments[1].Body)
|
||||
assert.Equal(t, "fileName2", attachments[1].FileName)
|
||||
assert.Equal(t, "mediaType2", attachments[1].MediaType)
|
||||
}
|
|
@ -5,8 +5,8 @@ import (
|
|||
"go/build"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/builder"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/builder"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -40,7 +40,7 @@ The test runner can be executed with the same flags as when using godog run.`,
|
|||
|
||||
func buildCmdRunFunc(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println(colors.Yellow("Use of godog CLI is deprecated, please use *testing.T instead."))
|
||||
fmt.Println(colors.Yellow("See https://github.com/cucumber/godog/discussions/478 for details."))
|
||||
fmt.Println(colors.Yellow("See https://git.golang1.ru/softonik/godog/discussions/478 for details."))
|
||||
|
||||
bin, err := filepath.Abs(buildOutput)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
)
|
||||
|
||||
var version bool
|
||||
|
|
|
@ -9,9 +9,9 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/builder"
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/builder"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
)
|
||||
|
||||
var opts flags.Options
|
||||
|
@ -44,7 +44,7 @@ buildable go source.`,
|
|||
|
||||
func runCmdRunFunc(cmd *cobra.Command, args []string) error {
|
||||
fmt.Println(colors.Yellow("Use of godog CLI is deprecated, please use *testing.T instead."))
|
||||
fmt.Println(colors.Yellow("See https://github.com/cucumber/godog/discussions/478 for details."))
|
||||
fmt.Println(colors.Yellow("See https://git.golang1.ru/softonik/godog/discussions/478 for details."))
|
||||
|
||||
osArgs := os.Args[1:]
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
// CreateVersionCmd creates the version subcommand.
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cucumber/godog/cmd/godog/internal"
|
||||
"git.golang1.ru/softonik/godog/cmd/godog/internal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -3,7 +3,7 @@ package godog_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func ExampleTestSuite_Run_subtests() {
|
||||
|
|
|
@ -153,3 +153,43 @@ Feature: undefined step snippets
|
|||
ctx.Step(`^"([^"]*)", which costs £(\d+)$`, whichCosts)
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Для русских сценариев генерируются русские функции
|
||||
Given a feature "undefined.feature" file:
|
||||
"""
|
||||
# language: ru
|
||||
|
||||
Функционал: суперфича
|
||||
|
||||
Сценарий: делает что-то полезное
|
||||
Дано что-то
|
||||
Когда я делаю ещё что-то
|
||||
То получается ещё более что-то
|
||||
"""
|
||||
When I run feature suite
|
||||
Then the following steps should be undefined:
|
||||
"""
|
||||
получается ещё более что-то
|
||||
что-то
|
||||
я делаю ещё что-то
|
||||
"""
|
||||
And the undefined step snippets should be:
|
||||
"""
|
||||
func получаетсяЕщёБолееЧтото() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func чтото() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func яДелаюЕщёЧтото() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`^получается ещё более что-то$`, получаетсяЕщёБолееЧтото)
|
||||
ctx.Step(`^что-то$`, чтото)
|
||||
ctx.Step(`^я делаю ещё что-то$`, яДелаюЕщёЧтото)
|
||||
}
|
||||
"""
|
||||
|
|
|
@ -125,3 +125,75 @@ Feature: tag filters
|
|||
"""
|
||||
a feature path "four"
|
||||
"""
|
||||
|
||||
Scenario: empty filter and scenarios with f-tag - are executed only
|
||||
Given a feature "normal.feature" file:
|
||||
"""
|
||||
Feature: f-tagged
|
||||
|
||||
Scenario: one
|
||||
Given a feature path "one"
|
||||
|
||||
Scenario: two
|
||||
Given a feature path "two"
|
||||
|
||||
@f
|
||||
Scenario: three
|
||||
Given a feature path "three"
|
||||
|
||||
@f
|
||||
Scenario: four
|
||||
Given a feature path "four"
|
||||
"""
|
||||
When I run feature suite with tags ""
|
||||
Then the suite should have passed
|
||||
And I should have 2 scenario registered
|
||||
And the following steps should be passed:
|
||||
"""
|
||||
a feature path "three"
|
||||
a feature path "four"
|
||||
"""
|
||||
|
||||
Scenario: two feature files and scenarios with f-tag - are executed only
|
||||
Given a feature "normal.feature" file:
|
||||
"""
|
||||
Feature: f-tagged
|
||||
|
||||
Scenario: one
|
||||
Given a feature path "one"
|
||||
|
||||
Scenario: two
|
||||
Given a feature path "two"
|
||||
|
||||
@f
|
||||
Scenario: three
|
||||
Given a feature path "three"
|
||||
|
||||
@f
|
||||
Scenario: four
|
||||
Given a feature path "four"
|
||||
"""
|
||||
And a feature "another.feature" file:
|
||||
"""
|
||||
Feature: non-tagged
|
||||
|
||||
Scenario: five
|
||||
Given a feature path "five"
|
||||
|
||||
Scenario: six
|
||||
Given a feature path "six"
|
||||
|
||||
Scenario: seven
|
||||
Given a feature path "seven"
|
||||
|
||||
Scenario: eight
|
||||
Given a feature path "eight"
|
||||
"""
|
||||
When I run feature suite with tags ""
|
||||
Then the suite should have passed
|
||||
And I should have 2 scenario registered
|
||||
And the following steps should be passed:
|
||||
"""
|
||||
a feature path "three"
|
||||
a feature path "four"
|
||||
"""
|
||||
|
|
8
flags.go
8
flags.go
|
@ -8,8 +8,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
// repeats a space n times
|
||||
|
@ -121,7 +121,7 @@ func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
|
|||
set.BoolVar(&opt.ShowStepDefinitions, prefix+"definitions", defShowStepDefinitions, "Print all available step definitions.")
|
||||
set.BoolVar(&opt.ShowStepDefinitions, prefix+"d", defShowStepDefinitions, "Print all available step definitions.")
|
||||
set.BoolVar(&opt.StopOnFailure, prefix+"stop-on-failure", defStopOnFailure, "Stop processing on first failed scenario.")
|
||||
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined steps.")
|
||||
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined or ambiguous steps.")
|
||||
set.BoolVar(&opt.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.")
|
||||
set.Var(&randomSeed{&opt.Randomize}, prefix+"random", descRandomOption)
|
||||
set.BoolVar(&opt.ShowHelp, "godog.help", false, "Show usage help.")
|
||||
|
@ -208,7 +208,7 @@ func usage(set *flag.FlagSet, w io.Writer) func() {
|
|||
|
||||
// --- GENERAL ---
|
||||
fmt.Fprintln(w, colors.Yellow("Usage:"))
|
||||
fmt.Fprintf(w, s(2)+"go test [options]\n\n")
|
||||
fmt.Fprint(w, s(2)+"go test [options]\n\n")
|
||||
|
||||
// --- OPTIONS ---
|
||||
fmt.Fprintln(w, colors.Yellow("Options:"))
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/formatters"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/formatters"
|
||||
)
|
||||
|
||||
func TestFlagsShouldRandomizeAndGenerateSeed(t *testing.T) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
)
|
||||
|
||||
// Choose randomly assigns a convenient pseudo-random seed value.
|
||||
|
|
|
@ -3,7 +3,7 @@ package godog
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
10
fmt.go
10
fmt.go
|
@ -6,11 +6,11 @@ import (
|
|||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/formatters"
|
||||
internal_fmt "github.com/cucumber/godog/internal/formatters"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"github.com/cucumber/godog/internal/storage"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
internal_fmt "git.golang1.ru/softonik/godog/internal/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/internal/storage"
|
||||
)
|
||||
|
||||
// FindFmt searches available formatters registered
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func Test_FindFmt(t *testing.T) {
|
||||
|
|
|
@ -70,9 +70,16 @@ type Formatter interface {
|
|||
Skipped(*messages.Pickle, *messages.PickleStep, *StepDefinition)
|
||||
Undefined(*messages.Pickle, *messages.PickleStep, *StepDefinition)
|
||||
Pending(*messages.Pickle, *messages.PickleStep, *StepDefinition)
|
||||
Ambiguous(*messages.Pickle, *messages.PickleStep, *StepDefinition, error)
|
||||
Summary()
|
||||
}
|
||||
|
||||
// FlushFormatter is a `Formatter` but can be flushed.
|
||||
type FlushFormatter interface {
|
||||
Formatter
|
||||
Flush()
|
||||
}
|
||||
|
||||
// FormatterFunc builds a formatter with given
|
||||
// suite name and io.Writer to record output
|
||||
type FormatterFunc func(string, io.Writer) Formatter
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func Test_FindFmt(t *testing.T) {
|
||||
|
|
24
go.mod
24
go.mod
|
@ -1,13 +1,27 @@
|
|||
module github.com/cucumber/godog
|
||||
module git.golang1.ru/softonik/godog
|
||||
|
||||
go 1.16
|
||||
go 1.24.2
|
||||
|
||||
require (
|
||||
git.golang1.ru/softonik/godog_and_gomega v1.0.0
|
||||
github.com/cucumber/gherkin/go/v26 v26.2.0
|
||||
github.com/hashicorp/go-memdb v1.3.4
|
||||
github.com/hashicorp/go-memdb v1.3.5
|
||||
github.com/onsi/gomega v1.37.0
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
51
go.sum
51
go.sum
|
@ -1,26 +1,33 @@
|
|||
git.golang1.ru/softonik/godog_and_gomega v1.0.0 h1:2BhCJnuCW5mnRRFk7hN0thyz6Zj64udGhjVtVrjvmYQ=
|
||||
git.golang1.ru/softonik/godog_and_gomega v1.0.0/go.mod h1:Xf4wTfJZU3W8dULgIkyou+dd36zZ8Kw2FPD3cr3dR10=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI=
|
||||
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/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI=
|
||||
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c=
|
||||
github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg=
|
||||
github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo=
|
||||
github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y=
|
||||
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=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
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/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
|
@ -28,24 +35,30 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
|||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
|
||||
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
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=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
var astContextSrc = `package main
|
||||
|
||||
import (
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func MyContext(s *godog.Suite) {
|
||||
|
@ -18,7 +18,7 @@ func MyContext(s *godog.Suite) {
|
|||
var astTwoContextSrc = `package lib
|
||||
|
||||
import (
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func ApiContext(s *godog.Suite) {
|
||||
|
|
|
@ -23,13 +23,13 @@ var (
|
|||
compiler = filepath.Join(tooldir, "compile")
|
||||
linker = filepath.Join(tooldir, "link")
|
||||
gopaths = filepath.SplitList(build.Default.GOPATH)
|
||||
godogImportPath = "github.com/cucumber/godog"
|
||||
godogImportPath = "git.golang1.ru/softonik/godog"
|
||||
|
||||
// godep
|
||||
runnerTemplate = template.Must(template.New("testmain").Parse(`package main
|
||||
|
||||
import (
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
{{if or .TestSuiteContexts .ScenarioContexts}}_test "{{.ImportPath}}"{{end}}
|
||||
{{if or .XTestSuiteContexts .XScenarioContexts}}_xtest "{{.ImportPath}}_test"{{end}}
|
||||
{{if or .XTestSuiteContexts .XScenarioContexts}}"testing/internal/testdeps"{{end}}
|
||||
|
@ -70,7 +70,7 @@ func main() {
|
|||
// temp file for import
|
||||
tempFileTemplate = template.Must(template.New("temp").Parse(`package {{.Name}}
|
||||
|
||||
import "github.com/cucumber/godog"
|
||||
import "git.golang1.ru/softonik/godog"
|
||||
|
||||
var _ = godog.Version
|
||||
`))
|
||||
|
|
|
@ -12,8 +12,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/internal/builder"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/internal/builder"
|
||||
)
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {}
|
||||
|
@ -51,7 +51,7 @@ var builderTestFile = `package godogs
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
func thereAreGodogs(available int) error {
|
||||
|
@ -91,7 +91,7 @@ var builderXTestFile = `package godogs_test
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
|
||||
"godogs"
|
||||
)
|
||||
|
@ -138,7 +138,7 @@ func main() {
|
|||
|
||||
var emptyBuilderTestFile = `package godogs
|
||||
|
||||
import "github.com/cucumber/godog"
|
||||
import "git.golang1.ru/softonik/godog"
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {}
|
||||
`
|
||||
|
|
|
@ -39,7 +39,7 @@ built-in formatters are:
|
|||
|
||||
flagSet.BoolVarP(&opts.ShowStepDefinitions, prefix+"definitions", "d", opts.ShowStepDefinitions, "print all available step definitions")
|
||||
flagSet.BoolVar(&opts.StopOnFailure, prefix+"stop-on-failure", opts.StopOnFailure, "stop processing on first failed scenario")
|
||||
flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined steps")
|
||||
flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined or ambiguous steps")
|
||||
|
||||
flagSet.Int64Var(&opts.Randomize, prefix+"random", opts.Randomize, `randomly shuffle the scenario execution order
|
||||
--random
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
)
|
||||
|
||||
func Test_BindFlagsShouldRespectFlagDefaults(t *testing.T) {
|
||||
|
|
|
@ -38,7 +38,7 @@ type Options struct {
|
|||
// Stops on the first failure
|
||||
StopOnFailure bool
|
||||
|
||||
// Fail suite when there are pending or undefined steps
|
||||
// Fail suite when there are pending or undefined or ambiguous steps
|
||||
Strict bool
|
||||
|
||||
// Forces ansi color stripping
|
||||
|
@ -48,6 +48,9 @@ type Options struct {
|
|||
// from feature files
|
||||
Tags string
|
||||
|
||||
// Dialect to be used to parse feature files. If not set, default to "en".
|
||||
Dialect string
|
||||
|
||||
// The formatter name
|
||||
Format string
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -36,6 +36,7 @@ var (
|
|||
skipped = models.Skipped
|
||||
undefined = models.Undefined
|
||||
pending = models.Pending
|
||||
ambiguous = models.Ambiguous
|
||||
)
|
||||
|
||||
type sortFeaturesByName []*models.Feature
|
||||
|
|
680
internal/formatters/fmt_ast.go
Обычный файл
680
internal/formatters/fmt_ast.go
Обычный файл
|
@ -0,0 +1,680 @@
|
|||
package formatters
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/pkg/formatters/ast"
|
||||
)
|
||||
|
||||
func ASTRegister() {
|
||||
formatters.Format("ast", "Prints every feature with runtime statuses + updates ast.", ASTFormatterFunc)
|
||||
}
|
||||
|
||||
// ASTFormatterFunc implements the FormatterFunc for the AST formatter
|
||||
func ASTFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||
return &AST{Base: NewBase(suite, out)}
|
||||
}
|
||||
|
||||
// AST is a formatter for readable output.
|
||||
type AST struct {
|
||||
*Base
|
||||
firstFeature *bool
|
||||
}
|
||||
|
||||
// TestRunStarted is triggered on test start.
|
||||
func (f *AST) TestRunStarted() {
|
||||
f.Base.TestRunStarted()
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
firstFeature := true
|
||||
f.firstFeature = &firstFeature
|
||||
}
|
||||
|
||||
// Feature receives gherkin document.
|
||||
func (f *AST) Feature(gd *messages.GherkinDocument, p string, c []byte) {
|
||||
f.Lock.Lock()
|
||||
if !*f.firstFeature {
|
||||
fmt.Fprintln(f.out, "")
|
||||
}
|
||||
|
||||
*f.firstFeature = false
|
||||
f.Lock.Unlock()
|
||||
|
||||
f.Base.Feature(gd, p, c)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printFeature(gd.Feature)
|
||||
}
|
||||
|
||||
// Pickle takes a gherkin node for formatting.
|
||||
func (f *AST) Pickle(pickle *messages.Pickle) {
|
||||
f.Base.Pickle(pickle)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
if len(pickle.Steps) == 0 {
|
||||
f.printUndefinedPickle(pickle)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Passed captures passed step.
|
||||
func (f *AST) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Passed(pickle, step, match)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Skipped captures skipped step.
|
||||
func (f *AST) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Skipped(pickle, step, match)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Undefined captures undefined step.
|
||||
func (f *AST) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Undefined(pickle, step, match)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Failed captures failed step.
|
||||
func (f *AST) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||
f.Base.Failed(pickle, step, match, err)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Failed captures failed step.
|
||||
func (f *AST) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||
f.Base.Ambiguous(pickle, step, match, err)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Pending captures pending step.
|
||||
func (f *AST) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Pending(pickle, step, match)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
func (f *AST) printFeature(feature *messages.Feature) {
|
||||
fmt.Fprintln(f.out, keywordAndName(feature.Keyword, feature.Name))
|
||||
if strings.TrimSpace(feature.Description) != "" {
|
||||
for _, line := range strings.Split(feature.Description, "\n") {
|
||||
fmt.Fprintln(f.out, s(f.indent)+strings.TrimSpace(line))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *AST) scenarioLengths(pickle *messages.Pickle) (scenarioHeaderLength int, maxLength int) {
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||
|
||||
scenarioHeaderLength = f.lengthPickle(astScenario.Keyword, astScenario.Name)
|
||||
maxLength = f.longestStep(astScenario.Steps, scenarioHeaderLength)
|
||||
|
||||
if astBackground != nil {
|
||||
maxLength = f.longestStep(astBackground.Steps, maxLength)
|
||||
}
|
||||
|
||||
return scenarioHeaderLength, maxLength
|
||||
}
|
||||
|
||||
func (f *AST) printScenarioHeader(pickle *messages.Pickle, astScenario *messages.Scenario, spaceFilling int) {
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
text := s(f.indent) + keywordAndName(astScenario.Keyword, astScenario.Name)
|
||||
text += s(spaceFilling) + line(feature.Uri, astScenario.Location)
|
||||
fmt.Fprintln(f.out, "\n"+text)
|
||||
}
|
||||
|
||||
func (f *AST) printUndefinedPickle(pickle *messages.Pickle) {
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||
|
||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||
|
||||
if astBackground != nil {
|
||||
fmt.Fprintln(f.out, "\n"+s(f.indent)+keywordAndName(astBackground.Keyword, astBackground.Name))
|
||||
for _, step := range astBackground.Steps {
|
||||
text := s(f.indent*2) + cyan(strings.TrimSpace(step.Keyword)) + " " + cyan(step.Text)
|
||||
fmt.Fprintln(f.out, text)
|
||||
}
|
||||
}
|
||||
|
||||
// do not print scenario headers and examples multiple times
|
||||
if len(astScenario.Examples) > 0 {
|
||||
exampleTable, exampleRow := feature.FindExample(pickle.AstNodeIds[1])
|
||||
firstExampleRow := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||
|
||||
if !(firstExamplesTable && firstExampleRow) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||
|
||||
for _, examples := range astScenario.Examples {
|
||||
max := longestExampleRow(examples, cyan, cyan)
|
||||
|
||||
fmt.Fprintln(f.out, "")
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+keywordAndName(examples.Keyword, examples.Name))
|
||||
|
||||
f.printTableHeader(examples.TableHeader, max)
|
||||
|
||||
for _, row := range examples.TableBody {
|
||||
f.printTableRow(row, max, cyan)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Summary renders summary information.
|
||||
func (f *AST) Summary() {
|
||||
failedStepResults := f.Storage.MustGetPickleStepResultsByStatus(failed)
|
||||
if len(failedStepResults) > 0 {
|
||||
fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n")
|
||||
|
||||
sort.Sort(sortPickleStepResultsByPickleStepID(failedStepResults))
|
||||
|
||||
for _, fail := range failedStepResults {
|
||||
pickle := f.Storage.MustGetPickle(fail.PickleID)
|
||||
pickleStep := f.Storage.MustGetPickleStep(fail.PickleStepID)
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
|
||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
scenarioDesc := fmt.Sprintf("%s: %s", astScenario.Keyword, pickle.Name)
|
||||
|
||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||
stepDesc := strings.TrimSpace(astStep.Keyword) + " " + pickleStep.Text
|
||||
|
||||
fmt.Fprintln(f.out, s(f.indent)+red(scenarioDesc)+line(feature.Uri, astScenario.Location))
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+red(stepDesc)+line(feature.Uri, astStep.Location))
|
||||
fmt.Fprint(f.out, s(f.indent*3)+redb(fmt.Sprintf("%+v", fail.Err)))
|
||||
}
|
||||
}
|
||||
|
||||
f.SummaryBottom()
|
||||
}
|
||||
func (f *AST) SummaryBottom() {
|
||||
var totalSc, passedSc, undefinedSc int
|
||||
var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt, ambiguousSt int
|
||||
|
||||
pickleResults := f.Storage.MustGetPickleResults()
|
||||
for _, pr := range pickleResults {
|
||||
var prStatus models.StepResultStatus
|
||||
totalSc++
|
||||
|
||||
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pr.PickleID)
|
||||
|
||||
if len(pickleStepResults) == 0 {
|
||||
prStatus = undefined
|
||||
}
|
||||
|
||||
for _, sr := range pickleStepResults {
|
||||
totalSt++
|
||||
|
||||
switch sr.Status {
|
||||
case passed:
|
||||
passedSt++
|
||||
case failed:
|
||||
prStatus = failed
|
||||
failedSt++
|
||||
case ambiguous:
|
||||
prStatus = ambiguous
|
||||
ambiguousSt++
|
||||
case skipped:
|
||||
skippedSt++
|
||||
case undefined:
|
||||
prStatus = undefined
|
||||
undefinedSt++
|
||||
case pending:
|
||||
prStatus = pending
|
||||
pendingSt++
|
||||
}
|
||||
}
|
||||
|
||||
if prStatus == passed {
|
||||
passedSc++
|
||||
} else if prStatus == undefined {
|
||||
undefinedSc++
|
||||
}
|
||||
}
|
||||
|
||||
var steps, parts, scenarios []string
|
||||
if passedSt > 0 {
|
||||
steps = append(steps, green(fmt.Sprintf("%d passed", passedSt)))
|
||||
}
|
||||
if failedSt > 0 {
|
||||
parts = append(parts, red(fmt.Sprintf("%d failed", failedSt)))
|
||||
steps = append(steps, red(fmt.Sprintf("%d failed", failedSt)))
|
||||
}
|
||||
if pendingSt > 0 {
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d pending", pendingSt)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d pending", pendingSt)))
|
||||
}
|
||||
if ambiguousSt > 0 {
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt)))
|
||||
}
|
||||
if undefinedSt > 0 {
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d undefined", undefinedSt)))
|
||||
} else if undefinedSc > 0 {
|
||||
// there may be some scenarios without steps
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc)))
|
||||
}
|
||||
if skippedSt > 0 {
|
||||
steps = append(steps, cyan(fmt.Sprintf("%d skipped", skippedSt)))
|
||||
}
|
||||
if passedSc > 0 {
|
||||
scenarios = append(scenarios, green(fmt.Sprintf("%d passed", passedSc)))
|
||||
}
|
||||
scenarios = append(scenarios, parts...)
|
||||
|
||||
testRunStartedAt := f.Storage.MustGetTestRunStarted().StartedAt
|
||||
elapsed := utils.TimeNowFunc().Sub(testRunStartedAt)
|
||||
|
||||
fmt.Fprintln(f.out, "")
|
||||
|
||||
if totalSc == 0 {
|
||||
fmt.Fprintln(f.out, "No scenarios")
|
||||
} else {
|
||||
fmt.Fprintf(f.out, "%d scenarios (%s), ", totalSc, strings.Join(scenarios, ", "))
|
||||
}
|
||||
|
||||
if totalSt == 0 {
|
||||
fmt.Fprintln(f.out, "No steps")
|
||||
} else {
|
||||
fmt.Fprintf(f.out, "%d steps (%s)\n", totalSt, strings.Join(steps, ", "))
|
||||
}
|
||||
|
||||
elapsedString := elapsed.String()
|
||||
if elapsed.Nanoseconds() == 0 {
|
||||
// go 1.5 and 1.6 prints 0 instead of 0s, if duration is zero.
|
||||
elapsedString = "0s"
|
||||
}
|
||||
fmt.Fprintln(f.out, elapsedString)
|
||||
|
||||
// prints used randomization seed
|
||||
seed, err := strconv.ParseInt(os.Getenv("GODOG_SEED"), 10, 64)
|
||||
if err == nil && seed != 0 {
|
||||
fmt.Fprintln(f.out, "")
|
||||
fmt.Fprintln(f.out, "Randomized with seed:", colors.Yellow(seed))
|
||||
}
|
||||
|
||||
if text := f.Snippets(); text != "" {
|
||||
fmt.Fprintln(f.out, "")
|
||||
fmt.Fprintln(f.out, yellow("You can implement step definitions for undefined steps with these snippets:"))
|
||||
fmt.Fprintln(f.out, yellow(text))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *AST) Snippets() string {
|
||||
undefinedStepResults := f.Storage.MustGetPickleStepResultsByStatus(undefined)
|
||||
if len(undefinedStepResults) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var index int
|
||||
var snips []undefinedSnippet
|
||||
// build snippets
|
||||
for _, u := range undefinedStepResults {
|
||||
pickleStep := f.Storage.MustGetPickleStep(u.PickleStepID)
|
||||
|
||||
steps := []string{pickleStep.Text}
|
||||
arg := pickleStep.Argument
|
||||
if u.Def != nil {
|
||||
steps = u.Def.Undefined
|
||||
arg = nil
|
||||
}
|
||||
for _, step := range steps {
|
||||
expr := snippetExprCleanup.ReplaceAllString(step, "\\$1")
|
||||
expr = snippetNumbers.ReplaceAllString(expr, "(\\d+)")
|
||||
expr = snippetExprQuoted.ReplaceAllString(expr, "$1\"([^\"]*)\"$2")
|
||||
expr = "^" + strings.TrimSpace(expr) + "$"
|
||||
|
||||
name := snippetNumbers.ReplaceAllString(step, " ")
|
||||
name = snippetExprQuoted.ReplaceAllString(name, " ")
|
||||
name = strings.TrimSpace(snippetMethodName.ReplaceAllString(name, ""))
|
||||
var words []string
|
||||
for i, w := range strings.Split(name, " ") {
|
||||
switch {
|
||||
case i != 0:
|
||||
w = strings.Title(w)
|
||||
case len(w) > 0:
|
||||
r := []rune(w)
|
||||
w = string(unicode.ToLower(r[0])) + string(r[1:])
|
||||
}
|
||||
words = append(words, w)
|
||||
}
|
||||
name = strings.Join(words, "")
|
||||
if len(name) == 0 {
|
||||
index++
|
||||
name = fmt.Sprintf("StepDefinitioninition%d", index)
|
||||
}
|
||||
|
||||
var found bool
|
||||
for _, snip := range snips {
|
||||
if snip.Expr == expr {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
s := undefinedSnippet{Method: name, Expr: expr, argument: arg}
|
||||
snips = append(snips, s)
|
||||
ast.ДобавитьШаг("`"+expr+"`", name, s.Args())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := AST_undefinedSnippetsTpl.Execute(&buf, snips); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// there may be trailing spaces
|
||||
return strings.Replace(buf.String(), " \n", "\n", -1)
|
||||
}
|
||||
|
||||
var AST_undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(`
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {}
|
||||
// ---
|
||||
|
||||
|
||||
{{ range . }}func {{ .Method }}({{ .Args }}) {
|
||||
}
|
||||
{{end}}{{ range . }}
|
||||
ctx.Step({{ backticked .Expr }}, {{ .Method }}){{end}}
|
||||
|
||||
`))
|
||||
|
||||
func (f *AST) printOutlineExample(pickle *messages.Pickle, step *messages.PickleStep, backgroundSteps int) {
|
||||
var errorMsg string
|
||||
var clr = green
|
||||
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||
|
||||
exampleTable, exampleRow := feature.FindExample(pickle.AstNodeIds[1])
|
||||
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||
|
||||
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleIDUntilStep(pickle.Id, step.Id)
|
||||
|
||||
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
||||
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
||||
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||
}
|
||||
|
||||
if len(exampleTable.TableBody) == 0 {
|
||||
// do not print empty examples
|
||||
return
|
||||
}
|
||||
|
||||
lastStep := len(pickleStepResults) == len(pickle.Steps)
|
||||
if !lastStep {
|
||||
// do not print examples unless all steps has finished
|
||||
return
|
||||
}
|
||||
|
||||
for _, result := range pickleStepResults {
|
||||
// determine example row status
|
||||
switch {
|
||||
case result.Status == failed:
|
||||
errorMsg = result.Err.Error()
|
||||
clr = result.Status.Color()
|
||||
case result.Status == ambiguous:
|
||||
errorMsg = result.Err.Error()
|
||||
clr = result.Status.Color()
|
||||
case result.Status == undefined || result.Status == pending:
|
||||
clr = result.Status.Color()
|
||||
case result.Status == skipped && clr == nil:
|
||||
clr = cyan
|
||||
}
|
||||
|
||||
if firstExamplesTable && printExampleHeader {
|
||||
// in first example, we need to print steps
|
||||
|
||||
pickleStep := f.Storage.MustGetPickleStep(result.PickleStepID)
|
||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||
|
||||
var text = ""
|
||||
if result.Def != nil {
|
||||
if m := outlinePlaceholderRegexp.FindAllStringIndex(astStep.Text, -1); len(m) > 0 {
|
||||
var pos int
|
||||
for i := 0; i < len(m); i++ {
|
||||
pair := m[i]
|
||||
text += cyan(astStep.Text[pos:pair[0]])
|
||||
text += cyanb(astStep.Text[pair[0]:pair[1]])
|
||||
pos = pair[1]
|
||||
}
|
||||
text += cyan(astStep.Text[pos:len(astStep.Text)])
|
||||
} else {
|
||||
text = cyan(astStep.Text)
|
||||
}
|
||||
|
||||
_, maxLength := f.scenarioLengths(pickle)
|
||||
stepLength := f.lengthPickleStep(astStep.Keyword, astStep.Text)
|
||||
|
||||
text += s(maxLength - stepLength)
|
||||
text += " " + blackb("# "+DefinitionID(result.Def))
|
||||
}
|
||||
|
||||
// print the step outline
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+cyan(strings.TrimSpace(astStep.Keyword))+" "+text)
|
||||
|
||||
if pickleStep.Argument != nil {
|
||||
if table := pickleStep.Argument.DataTable; table != nil {
|
||||
f.printTable(table, cyan)
|
||||
}
|
||||
|
||||
if docString := astStep.DocString; docString != nil {
|
||||
f.printDocString(docString)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max := longestExampleRow(exampleTable, clr, cyan)
|
||||
|
||||
// an example table header
|
||||
if printExampleHeader {
|
||||
fmt.Fprintln(f.out, "")
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+keywordAndName(exampleTable.Keyword, exampleTable.Name))
|
||||
|
||||
f.printTableHeader(exampleTable.TableHeader, max)
|
||||
}
|
||||
|
||||
f.printTableRow(exampleRow, max, clr)
|
||||
|
||||
if errorMsg != "" {
|
||||
fmt.Fprintln(f.out, s(f.indent*4)+redb(errorMsg))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *AST) printTableRow(row *messages.TableRow, max []int, clr colors.ColorFunc) {
|
||||
cells := make([]string, len(row.Cells))
|
||||
|
||||
for i, cell := range row.Cells {
|
||||
val := clr(cell.Value)
|
||||
ln := utf8.RuneCountInString(val)
|
||||
cells[i] = val + s(max[i]-ln)
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+"| "+strings.Join(cells, " | ")+" |")
|
||||
}
|
||||
|
||||
func (f *AST) printTableHeader(row *messages.TableRow, max []int) {
|
||||
f.printTableRow(row, max, cyan)
|
||||
}
|
||||
|
||||
func (f *AST) printStep(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
astRule := feature.FindRule(pickle.AstNodeIds[0])
|
||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||
|
||||
var astBackgroundStep bool
|
||||
var firstExecutedBackgroundStep bool
|
||||
var backgroundSteps int
|
||||
|
||||
if astBackground != nil {
|
||||
backgroundSteps = len(astBackground.Steps)
|
||||
|
||||
for idx, step := range astBackground.Steps {
|
||||
if step.Id == pickleStep.AstNodeIds[0] {
|
||||
astBackgroundStep = true
|
||||
firstExecutedBackgroundStep = idx == 0
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
firstPickle := isFirstPickleAndNoRule(feature, pickle, astRule) || isFirstScenarioInRule(astRule, astScenario)
|
||||
|
||||
if astBackgroundStep && !firstPickle {
|
||||
return
|
||||
}
|
||||
|
||||
if astBackgroundStep && firstExecutedBackgroundStep {
|
||||
fmt.Fprintln(f.out, "\n"+s(f.indent)+keywordAndName(astBackground.Keyword, astBackground.Name))
|
||||
}
|
||||
|
||||
if !astBackgroundStep && len(astScenario.Examples) > 0 {
|
||||
f.printOutlineExample(pickle, pickleStep, backgroundSteps)
|
||||
return
|
||||
}
|
||||
|
||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||
stepLength := f.lengthPickleStep(astStep.Keyword, pickleStep.Text)
|
||||
|
||||
firstExecutedScenarioStep := astScenario.Steps[0].Id == pickleStep.AstNodeIds[0]
|
||||
if !astBackgroundStep && firstExecutedScenarioStep {
|
||||
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||
}
|
||||
|
||||
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStep.Id)
|
||||
text := s(f.indent*2) + pickleStepResult.Status.Color()(strings.TrimSpace(astStep.Keyword)) + " " + pickleStepResult.Status.Color()(pickleStep.Text)
|
||||
if pickleStepResult.Def != nil {
|
||||
text += s(maxLength - stepLength + 1)
|
||||
text += blackb("# " + DefinitionID(pickleStepResult.Def))
|
||||
}
|
||||
fmt.Fprintln(f.out, text)
|
||||
|
||||
if pickleStep.Argument != nil {
|
||||
if table := pickleStep.Argument.DataTable; table != nil {
|
||||
f.printTable(table, cyan)
|
||||
}
|
||||
|
||||
if docString := astStep.DocString; docString != nil {
|
||||
f.printDocString(docString)
|
||||
}
|
||||
}
|
||||
|
||||
if pickleStepResult.Err != nil {
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+redb(fmt.Sprintf("%+v", pickleStepResult.Err)))
|
||||
}
|
||||
|
||||
if pickleStepResult.Status == pending {
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+yellow("TODO: write pending definition"))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *AST) printDocString(docString *messages.DocString) {
|
||||
var ct string
|
||||
|
||||
if len(docString.MediaType) > 0 {
|
||||
ct = " " + cyan(docString.MediaType)
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+cyan(docString.Delimiter)+ct)
|
||||
|
||||
for _, ln := range strings.Split(docString.Content, "\n") {
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+cyan(ln))
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+cyan(docString.Delimiter))
|
||||
}
|
||||
|
||||
// print table with aligned table cells
|
||||
// @TODO: need to make example header cells bold
|
||||
func (f *AST) printTable(t *messages.PickleTable, c colors.ColorFunc) {
|
||||
maxColLengths := maxColLengths(t, c)
|
||||
var cols = make([]string, len(t.Rows[0].Cells))
|
||||
|
||||
for _, row := range t.Rows {
|
||||
for i, cell := range row.Cells {
|
||||
val := c(cell.Value)
|
||||
colLength := utf8.RuneCountInString(val)
|
||||
cols[i] = val + s(maxColLengths[i]-colLength)
|
||||
}
|
||||
|
||||
fmt.Fprintln(f.out, s(f.indent*3)+"| "+strings.Join(cols, " | ")+" |")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *AST) longestStep(steps []*messages.Step, pickleLength int) int {
|
||||
max := pickleLength
|
||||
|
||||
for _, step := range steps {
|
||||
length := f.lengthPickleStep(step.Keyword, step.Text)
|
||||
if length > max {
|
||||
max = length
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
func (f *AST) lengthPickleStep(keyword, text string) int {
|
||||
return f.indent*2 + utf8.RuneCountInString(strings.TrimSpace(keyword)+" "+text)
|
||||
}
|
||||
|
||||
func (f *AST) lengthPickle(keyword, name string) int {
|
||||
return f.indent + utf8.RuneCountInString(strings.TrimSpace(keyword)+": "+name)
|
||||
}
|
|
@ -13,11 +13,11 @@ import (
|
|||
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"github.com/cucumber/godog/internal/storage"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/internal/storage"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
// BaseFormatterFunc implements the FormatterFunc for the base formatter.
|
||||
|
@ -85,10 +85,14 @@ func (f *Base) Failed(*messages.Pickle, *messages.PickleStep, *formatters.StepDe
|
|||
func (f *Base) Pending(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
||||
}
|
||||
|
||||
// Ambiguous captures ambiguous step.
|
||||
func (f *Base) Ambiguous(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition, error) {
|
||||
}
|
||||
|
||||
// Summary renders summary information.
|
||||
func (f *Base) Summary() {
|
||||
var totalSc, passedSc, undefinedSc int
|
||||
var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt int
|
||||
var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt, ambiguousSt int
|
||||
|
||||
pickleResults := f.Storage.MustGetPickleResults()
|
||||
for _, pr := range pickleResults {
|
||||
|
@ -110,6 +114,9 @@ func (f *Base) Summary() {
|
|||
case failed:
|
||||
prStatus = failed
|
||||
failedSt++
|
||||
case ambiguous:
|
||||
prStatus = ambiguous
|
||||
ambiguousSt++
|
||||
case skipped:
|
||||
skippedSt++
|
||||
case undefined:
|
||||
|
@ -140,6 +147,10 @@ func (f *Base) Summary() {
|
|||
parts = append(parts, yellow(fmt.Sprintf("%d pending", pendingSt)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d pending", pendingSt)))
|
||||
}
|
||||
if ambiguousSt > 0 {
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d ambiguous", ambiguousSt)))
|
||||
}
|
||||
if undefinedSt > 0 {
|
||||
parts = append(parts, yellow(fmt.Sprintf("%d undefined", undefinedSc)))
|
||||
steps = append(steps, yellow(fmt.Sprintf("%d undefined", undefinedSt)))
|
||||
|
@ -227,7 +238,8 @@ func (f *Base) Snippets() string {
|
|||
case i != 0:
|
||||
w = strings.Title(w)
|
||||
case len(w) > 0:
|
||||
w = string(unicode.ToLower(rune(w[0]))) + w[1:]
|
||||
r := []rune(w)
|
||||
w = string(unicode.ToLower(r[0])) + string(r[1:])
|
||||
}
|
||||
words = append(words, w)
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/internal/flags"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/internal/flags"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -42,7 +42,7 @@ And step failed f2s3:4
|
|||
|
||||
Scenario: f2s4
|
||||
When step passed f2s4:1
|
||||
Then step is undefined f2s4:2
|
||||
Then something unknown happens f2s4:2
|
||||
And step passed f2s4:3
|
||||
`)},
|
||||
)
|
||||
|
@ -116,8 +116,8 @@ scenario "f2s3" passed
|
|||
|
||||
step invoked: "f2s4:1", passed
|
||||
step "step passed f2s4:1" finished with status passed
|
||||
.Ustep "step is undefined f2s4:2" finished with status undefined
|
||||
scenario "f2s4" ended with error "step is undefined"
|
||||
.Ustep "something unknown happens f2s4:2" finished with status undefined
|
||||
scenario "f2s4" ended with error "step is undefined: something unknown happens f2s4:2"
|
||||
-step "step passed f2s4:3" finished with status skipped
|
||||
13
|
||||
|
||||
|
@ -139,12 +139,12 @@ scenario "f2s4" ended with error "step is undefined"
|
|||
|
||||
You can implement step definitions for undefined steps with these snippets:
|
||||
|
||||
func stepIsUndefinedFS(arg1, arg2, arg3 int) error {
|
||||
func somethingUnknownHappensFS(arg1, arg2, arg3 int) error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`+"`"+`^step is undefined f(\d+)s(\d+):(\d+)$`+"`"+`, stepIsUndefinedFS)
|
||||
ctx.Step(`+"`"+`^something unknown happens f(\d+)s(\d+):(\d+)$`+"`"+`, somethingUnknownHappensFS)
|
||||
}
|
||||
|
||||
`, out.String())
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
)
|
||||
|
||||
type csiState int
|
||||
|
|
|
@ -12,14 +12,15 @@ package formatters
|
|||
*/
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
|
@ -100,7 +101,8 @@ func (f *Cuke) buildCukeElements(pickles []*messages.Pickle) (res []cukeElement)
|
|||
cukeStep.Result.Duration = &d
|
||||
if stepResult.Status == undefined ||
|
||||
stepResult.Status == pending ||
|
||||
stepResult.Status == skipped {
|
||||
stepResult.Status == skipped ||
|
||||
stepResult.Status == ambiguous {
|
||||
cukeStep.Result.Duration = nil
|
||||
}
|
||||
|
||||
|
@ -139,6 +141,12 @@ type cukeMatch struct {
|
|||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
type cukeEmbedding struct {
|
||||
Name string `json:"name"`
|
||||
MimeType string `json:"mime_type"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type cukeStep struct {
|
||||
Keyword string `json:"keyword"`
|
||||
Name string `json:"name"`
|
||||
|
@ -147,6 +155,7 @@ type cukeStep struct {
|
|||
Match cukeMatch `json:"match"`
|
||||
Result cukeResult `json:"result"`
|
||||
DataTable []*cukeDataTableRow `json:"rows,omitempty"`
|
||||
Embeddings []cukeEmbedding `json:"embeddings,omitempty"`
|
||||
}
|
||||
|
||||
type cukeDataTableRow struct {
|
||||
|
@ -290,10 +299,25 @@ func (f *Cuke) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleSt
|
|||
cukeStep.Result.Error = stepResult.Err.Error()
|
||||
}
|
||||
|
||||
if stepResult.Status == undefined || stepResult.Status == pending {
|
||||
if stepResult.Status == undefined || stepResult.Status == pending || stepResult.Status == ambiguous {
|
||||
cukeStep.Match.Location = fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line)
|
||||
}
|
||||
|
||||
if stepResult.Attachments != nil {
|
||||
attachments := []cukeEmbedding{}
|
||||
|
||||
for _, a := range stepResult.Attachments {
|
||||
attachments = append(attachments, cukeEmbedding{
|
||||
Name: a.Name,
|
||||
Data: base64.StdEncoding.EncodeToString(a.Data),
|
||||
MimeType: a.MimeType,
|
||||
})
|
||||
}
|
||||
|
||||
if len(attachments) > 0 {
|
||||
cukeStep.Embeddings = attachments
|
||||
}
|
||||
}
|
||||
return cukeStep
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
|
@ -153,6 +153,31 @@ func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep)
|
|||
if pickleStepResult.Err != nil {
|
||||
errMsg = pickleStepResult.Err.Error()
|
||||
}
|
||||
|
||||
if pickleStepResult.Attachments != nil {
|
||||
for _, attachment := range pickleStepResult.Attachments {
|
||||
|
||||
f.event(&struct {
|
||||
Event string `json:"event"`
|
||||
Location string `json:"location"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
ContentEncoding string `json:"contentEncoding"`
|
||||
FileName string `json:"fileName"`
|
||||
MimeType string `json:"mimeType"`
|
||||
Body string `json:"body"`
|
||||
}{
|
||||
"Attachment",
|
||||
fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line),
|
||||
utils.TimeNowFunc().UnixNano() / nanoSec,
|
||||
messages.AttachmentContentEncoding_BASE64.String(),
|
||||
attachment.Name,
|
||||
attachment.MimeType,
|
||||
string(attachment.Data),
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
f.event(&struct {
|
||||
Event string `json:"event"`
|
||||
Location string `json:"location"`
|
||||
|
@ -173,7 +198,7 @@ func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep)
|
|||
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||
for _, stepResult := range pickleStepResults {
|
||||
switch stepResult.Status {
|
||||
case passed, failed, undefined, pending:
|
||||
case passed, failed, undefined, pending, ambiguous:
|
||||
status = stepResult.Status.String()
|
||||
}
|
||||
}
|
||||
|
@ -293,6 +318,16 @@ func (f *Events) Pending(pickle *messages.Pickle, step *messages.PickleStep, mat
|
|||
f.step(pickle, step)
|
||||
}
|
||||
|
||||
// Ambiguous captures ambiguous step.
|
||||
func (f *Events) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||
f.Base.Ambiguous(pickle, step, match, err)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.step(pickle, step)
|
||||
}
|
||||
|
||||
func (f *Events) scenarioLocation(pickle *messages.Pickle) string {
|
||||
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||
scenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||
|
|
108
internal/formatters/fmt_flushwrap.go
Обычный файл
108
internal/formatters/fmt_flushwrap.go
Обычный файл
|
@ -0,0 +1,108 @@
|
|||
package formatters
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
// WrapOnFlush wrap a `formatters.Formatter` in a `formatters.FlushFormatter`, which only
|
||||
// executes when `Flush` is called
|
||||
func WrapOnFlush(fmt formatters.Formatter) formatters.FlushFormatter {
|
||||
return &onFlushFormatter{
|
||||
fmt: fmt,
|
||||
fns: make([]func(), 0),
|
||||
mu: &sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
type onFlushFormatter struct {
|
||||
fmt formatters.Formatter
|
||||
fns []func()
|
||||
mu *sync.Mutex
|
||||
}
|
||||
|
||||
func (o *onFlushFormatter) Pickle(pickle *messages.Pickle) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Pickle(pickle)
|
||||
})
|
||||
}
|
||||
|
||||
func (o *onFlushFormatter) Passed(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Passed(pickle, step, definition)
|
||||
})
|
||||
}
|
||||
|
||||
// Ambiguous implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition, err error) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Ambiguous(pickle, step, definition, err)
|
||||
})
|
||||
}
|
||||
|
||||
// Defined implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Defined(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Defined(pickle, step, definition)
|
||||
})
|
||||
}
|
||||
|
||||
// Failed implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Failed(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition, err error) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Failed(pickle, step, definition, err)
|
||||
})
|
||||
}
|
||||
|
||||
// Feature implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Feature(pickle *messages.GherkinDocument, p string, c []byte) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Feature(pickle, p, c)
|
||||
})
|
||||
}
|
||||
|
||||
// Pending implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Pending(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Pending(pickle, step, definition)
|
||||
})
|
||||
}
|
||||
|
||||
// Skipped implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Skipped(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Skipped(pickle, step, definition)
|
||||
})
|
||||
}
|
||||
|
||||
// Summary implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Summary() {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Summary()
|
||||
})
|
||||
}
|
||||
|
||||
// TestRunStarted implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) TestRunStarted() {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.TestRunStarted()
|
||||
})
|
||||
}
|
||||
|
||||
// Undefined implements formatters.Formatter.
|
||||
func (o *onFlushFormatter) Undefined(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition) {
|
||||
o.fns = append(o.fns, func() {
|
||||
o.fmt.Undefined(pickle, step, definition)
|
||||
})
|
||||
}
|
||||
|
||||
// Flush the logs.
|
||||
func (o *onFlushFormatter) Flush() {
|
||||
o.mu.Lock()
|
||||
defer o.mu.Unlock()
|
||||
for _, fn := range o.fns {
|
||||
fn()
|
||||
}
|
||||
}
|
53
internal/formatters/fmt_flushwrap_test.go
Обычный файл
53
internal/formatters/fmt_flushwrap_test.go
Обычный файл
|
@ -0,0 +1,53 @@
|
|||
package formatters
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var flushMock = DummyFormatter{}
|
||||
|
||||
func TestFlushWrapOnFormatter(t *testing.T) {
|
||||
flushMock.tt = t
|
||||
|
||||
fmt := WrapOnFlush(&flushMock)
|
||||
|
||||
fmt.Feature(document, str, byt)
|
||||
fmt.TestRunStarted()
|
||||
fmt.Pickle(pickle)
|
||||
fmt.Defined(pickle, step, definition)
|
||||
fmt.Passed(pickle, step, definition)
|
||||
fmt.Skipped(pickle, step, definition)
|
||||
fmt.Undefined(pickle, step, definition)
|
||||
fmt.Failed(pickle, step, definition, err)
|
||||
fmt.Pending(pickle, step, definition)
|
||||
fmt.Ambiguous(pickle, step, definition, err)
|
||||
fmt.Summary()
|
||||
|
||||
assert.Equal(t, 0, flushMock.CountFeature)
|
||||
assert.Equal(t, 0, flushMock.CountTestRunStarted)
|
||||
assert.Equal(t, 0, flushMock.CountPickle)
|
||||
assert.Equal(t, 0, flushMock.CountDefined)
|
||||
assert.Equal(t, 0, flushMock.CountPassed)
|
||||
assert.Equal(t, 0, flushMock.CountSkipped)
|
||||
assert.Equal(t, 0, flushMock.CountUndefined)
|
||||
assert.Equal(t, 0, flushMock.CountFailed)
|
||||
assert.Equal(t, 0, flushMock.CountPending)
|
||||
assert.Equal(t, 0, flushMock.CountAmbiguous)
|
||||
assert.Equal(t, 0, flushMock.CountSummary)
|
||||
|
||||
fmt.Flush()
|
||||
|
||||
assert.Equal(t, 1, flushMock.CountFeature)
|
||||
assert.Equal(t, 1, flushMock.CountTestRunStarted)
|
||||
assert.Equal(t, 1, flushMock.CountPickle)
|
||||
assert.Equal(t, 1, flushMock.CountDefined)
|
||||
assert.Equal(t, 1, flushMock.CountPassed)
|
||||
assert.Equal(t, 1, flushMock.CountSkipped)
|
||||
assert.Equal(t, 1, flushMock.CountUndefined)
|
||||
assert.Equal(t, 1, flushMock.CountFailed)
|
||||
assert.Equal(t, 1, flushMock.CountPending)
|
||||
assert.Equal(t, 1, flushMock.CountAmbiguous)
|
||||
assert.Equal(t, 1, flushMock.CountSummary)
|
||||
}
|
|
@ -9,8 +9,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -117,6 +117,12 @@ func (f *JUnit) buildJUNITPackageSuite() JunitPackageSuite {
|
|||
tc.Failure = &junitFailure{
|
||||
Message: fmt.Sprintf("Step %s: %s", pickleStep.Text, stepResult.Err),
|
||||
}
|
||||
case ambiguous:
|
||||
tc.Status = ambiguous.String()
|
||||
tc.Error = append(tc.Error, &junitError{
|
||||
Type: "ambiguous",
|
||||
Message: fmt.Sprintf("Step %s", pickleStep.Text),
|
||||
})
|
||||
case skipped:
|
||||
tc.Error = append(tc.Error, &junitError{
|
||||
Type: "skipped",
|
||||
|
|
|
@ -3,8 +3,8 @@ package formatters
|
|||
import (
|
||||
"io"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/storage"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/storage"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
|
@ -97,6 +97,13 @@ func (r repeater) Pending(pickle *messages.Pickle, step *messages.PickleStep, de
|
|||
}
|
||||
}
|
||||
|
||||
// Ambiguous triggers Ambiguous for all added formatters.
|
||||
func (r repeater) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition, err error) {
|
||||
for _, f := range r {
|
||||
f.Ambiguous(pickle, step, definition, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Summary triggers Summary for all added formatters.
|
||||
func (r repeater) Summary() {
|
||||
for _, f := range r {
|
||||
|
|
164
internal/formatters/fmt_multi_test.go
Обычный файл
164
internal/formatters/fmt_multi_test.go
Обычный файл
|
@ -0,0 +1,164 @@
|
|||
package formatters
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
mock = DummyFormatter{}
|
||||
base = BaseFormatter{}
|
||||
|
||||
document = &messages.GherkinDocument{}
|
||||
str = "theString"
|
||||
byt = []byte("bytes")
|
||||
pickle = &messages.Pickle{}
|
||||
step = &messages.PickleStep{}
|
||||
definition = &formatters.StepDefinition{}
|
||||
err = errors.New("expected")
|
||||
)
|
||||
|
||||
// TestRepeater tests the delegation of the repeater functions.
|
||||
func TestRepeater(t *testing.T) {
|
||||
mock.tt = t
|
||||
f := make(repeater, 0)
|
||||
f = append(f, &mock)
|
||||
f = append(f, &mock)
|
||||
f = append(f, &base)
|
||||
|
||||
f.Feature(document, str, byt)
|
||||
f.TestRunStarted()
|
||||
f.Pickle(pickle)
|
||||
f.Defined(pickle, step, definition)
|
||||
f.Passed(pickle, step, definition)
|
||||
f.Skipped(pickle, step, definition)
|
||||
f.Undefined(pickle, step, definition)
|
||||
f.Failed(pickle, step, definition, err)
|
||||
f.Pending(pickle, step, definition)
|
||||
f.Ambiguous(pickle, step, definition, err)
|
||||
|
||||
assert.Equal(t, 2, mock.CountFeature)
|
||||
assert.Equal(t, 2, mock.CountTestRunStarted)
|
||||
assert.Equal(t, 2, mock.CountPickle)
|
||||
assert.Equal(t, 2, mock.CountDefined)
|
||||
assert.Equal(t, 2, mock.CountPassed)
|
||||
assert.Equal(t, 2, mock.CountSkipped)
|
||||
assert.Equal(t, 2, mock.CountUndefined)
|
||||
assert.Equal(t, 2, mock.CountFailed)
|
||||
assert.Equal(t, 2, mock.CountPending)
|
||||
assert.Equal(t, 2, mock.CountAmbiguous)
|
||||
}
|
||||
|
||||
type BaseFormatter struct {
|
||||
*Base
|
||||
}
|
||||
|
||||
type DummyFormatter struct {
|
||||
*Base
|
||||
|
||||
tt *testing.T
|
||||
CountFeature int
|
||||
CountTestRunStarted int
|
||||
CountPickle int
|
||||
CountDefined int
|
||||
CountPassed int
|
||||
CountSkipped int
|
||||
CountUndefined int
|
||||
CountFailed int
|
||||
CountPending int
|
||||
CountAmbiguous int
|
||||
CountSummary int
|
||||
}
|
||||
|
||||
// SetStorage assigns gherkin data storage.
|
||||
// func (f *DummyFormatter) SetStorage(st *storage.Storage) {
|
||||
// }
|
||||
|
||||
// TestRunStarted is triggered on test start.
|
||||
func (f *DummyFormatter) TestRunStarted() {
|
||||
f.CountTestRunStarted++
|
||||
}
|
||||
|
||||
// Feature receives gherkin document.
|
||||
func (f *DummyFormatter) Feature(d *messages.GherkinDocument, s string, b []byte) {
|
||||
assert.Equal(f.tt, document, d)
|
||||
assert.Equal(f.tt, str, s)
|
||||
assert.Equal(f.tt, byt, b)
|
||||
f.CountFeature++
|
||||
}
|
||||
|
||||
// Pickle receives scenario.
|
||||
func (f *DummyFormatter) Pickle(p *messages.Pickle) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
f.CountPickle++
|
||||
}
|
||||
|
||||
// Defined receives step definition.
|
||||
func (f *DummyFormatter) Defined(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
f.CountDefined++
|
||||
}
|
||||
|
||||
// Passed captures passed step.
|
||||
func (f *DummyFormatter) Passed(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
f.CountPassed++
|
||||
}
|
||||
|
||||
// Skipped captures skipped step.
|
||||
func (f *DummyFormatter) Skipped(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
|
||||
f.CountSkipped++
|
||||
}
|
||||
|
||||
// Undefined captures undefined step.
|
||||
func (f *DummyFormatter) Undefined(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
|
||||
f.CountUndefined++
|
||||
}
|
||||
|
||||
// Failed captures failed step.
|
||||
func (f *DummyFormatter) Failed(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition, e error) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
assert.Equal(f.tt, err, e)
|
||||
|
||||
f.CountFailed++
|
||||
}
|
||||
|
||||
// Pending captures pending step.
|
||||
func (f *DummyFormatter) Pending(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
|
||||
f.CountPending++
|
||||
}
|
||||
|
||||
// Ambiguous captures ambiguous step.
|
||||
func (f *DummyFormatter) Ambiguous(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition, e error) {
|
||||
assert.Equal(f.tt, pickle, p)
|
||||
assert.Equal(f.tt, s, step)
|
||||
assert.Equal(f.tt, d, definition)
|
||||
f.CountAmbiguous++
|
||||
}
|
||||
|
||||
// Pickle receives scenario.
|
||||
func (f *DummyFormatter) Summary() {
|
||||
f.CountSummary++
|
||||
}
|
|
@ -2,31 +2,33 @@ package formatters_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
)
|
||||
|
||||
const fmtOutputTestsFeatureDir = "formatter-tests/features"
|
||||
|
||||
var tT *testing.T
|
||||
|
||||
func Test_FmtOutput(t *testing.T) {
|
||||
tT = t
|
||||
pkg := os.Getenv("GODOG_TESTED_PACKAGE")
|
||||
os.Setenv("GODOG_TESTED_PACKAGE", "github.com/cucumber/godog")
|
||||
os.Setenv("GODOG_TESTED_PACKAGE", "git.golang1.ru/softonik/godog")
|
||||
|
||||
featureFiles, err := listFmtOutputTestsFeatureFiles()
|
||||
require.Nil(t, err)
|
||||
|
||||
formatters := []string{"cucumber", "events", "junit", "pretty", "progress", "junit,pretty"}
|
||||
|
||||
for _, fmtName := range formatters {
|
||||
for _, featureFile := range featureFiles {
|
||||
testName := fmt.Sprintf("%s/%s", fmtName, featureFile)
|
||||
|
@ -61,20 +63,104 @@ func listFmtOutputTestsFeatureFiles() (featureFiles []string, err error) {
|
|||
|
||||
func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
|
||||
fmtOutputScenarioInitializer := func(ctx *godog.ScenarioContext) {
|
||||
stepIndex := 0
|
||||
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
if strings.Contains(sc.Name, "attachment") {
|
||||
att := godog.Attachments(ctx)
|
||||
attCount := len(att)
|
||||
if attCount != 0 {
|
||||
assert.FailNowf(tT, "Unexpected attachments: "+sc.Name, "should have been empty, found %d", attCount)
|
||||
}
|
||||
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("BeforeScenarioAttachment"), FileName: "Before Scenario Attachment 1", MediaType: "text/plain"},
|
||||
)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||
|
||||
if strings.Contains(sc.Name, "attachment") {
|
||||
att := godog.Attachments(ctx)
|
||||
attCount := len(att)
|
||||
if attCount != 4 {
|
||||
assert.FailNow(tT, "Unexpected attachments: "+sc.Name, "expected 4, found %d", attCount)
|
||||
}
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("AfterScenarioAttachment"), FileName: "After Scenario Attachment 2", MediaType: "text/plain"},
|
||||
)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
ctx.StepContext().Before(func(ctx context.Context, st *godog.Step) (context.Context, error) {
|
||||
stepIndex++
|
||||
|
||||
if strings.Contains(st.Text, "attachment") {
|
||||
att := godog.Attachments(ctx)
|
||||
attCount := len(att)
|
||||
|
||||
// 1 for before scenario ONLY if this is the 1st step
|
||||
expectedAttCount := 0
|
||||
if stepIndex == 1 {
|
||||
expectedAttCount = 1
|
||||
}
|
||||
|
||||
if attCount != expectedAttCount {
|
||||
assert.FailNow(tT, "Unexpected attachments: "+st.Text, "expected 1, found %d\n%+v", attCount, att)
|
||||
}
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("BeforeStepAttachment"), FileName: "Before Step Attachment 3", MediaType: "text/plain"},
|
||||
)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.StepContext().After(func(ctx context.Context, st *godog.Step, status godog.StepResultStatus, err error) (context.Context, error) {
|
||||
|
||||
if strings.Contains(st.Text, "attachment") {
|
||||
att := godog.Attachments(ctx)
|
||||
attCount := len(att)
|
||||
|
||||
// 1 for before scenario ONLY if this is the 1st step
|
||||
// 1 for before before step
|
||||
// 2 from from step
|
||||
expectedAttCount := 3
|
||||
if stepIndex == 1 {
|
||||
expectedAttCount = 4
|
||||
}
|
||||
|
||||
if attCount != expectedAttCount {
|
||||
// 1 from before scenario, 1 from before step, 1 from step
|
||||
assert.FailNow(tT, "Unexpected attachments: "+st.Text, "expected 4, found %d", attCount)
|
||||
}
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("AfterStepAttachment"), FileName: "After Step Attachment 4", MediaType: "text/plain"},
|
||||
)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
|
||||
ctx.Step(`^(?:a )?failing step`, failingStepDef)
|
||||
ctx.Step(`^(?:a )?pending step$`, pendingStepDef)
|
||||
ctx.Step(`^(?:a )?passing step$`, passingStepDef)
|
||||
ctx.Step(`^ambiguous step.*$`, ambiguousStepDef)
|
||||
ctx.Step(`^ambiguous step$`, ambiguousStepDef)
|
||||
ctx.Step(`^odd (\d+) and even (\d+) number$`, oddEvenStepDef)
|
||||
ctx.Step(`^(?:a )?a step with a single attachment call for multiple attachments$`, stepWithSingleAttachmentCall)
|
||||
ctx.Step(`^(?:a )?a step with multiple attachment calls$`, stepWithMultipleAttachmentCalls)
|
||||
}
|
||||
|
||||
return func(t *testing.T) {
|
||||
fmt.Printf("fmt_output_test for format %10s : sample file %v\n", fmtName, featureFilePath)
|
||||
expectOutputPath := strings.Replace(featureFilePath, "features", fmtName, 1)
|
||||
expectOutputPath = strings.TrimSuffix(expectOutputPath, path.Ext(expectOutputPath))
|
||||
if _, err := os.Stat(expectOutputPath); err != nil {
|
||||
t.Skipf("Couldn't find expected output file %q", expectOutputPath)
|
||||
// the test author needs to write an "expected output" file for any formats they want the test feature to be verified against
|
||||
t.Skipf("Skipping test for feature '%v' for format '%v', because no 'expected output' file %q", featureFilePath, fmtName, expectOutputPath)
|
||||
}
|
||||
|
||||
expectedOutput, err := ioutil.ReadFile(expectOutputPath)
|
||||
expectedOutput, err := os.ReadFile(expectOutputPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
@ -84,6 +170,7 @@ func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
|
|||
Format: fmtName,
|
||||
Paths: []string{featureFilePath},
|
||||
Output: out,
|
||||
Strict: true,
|
||||
}
|
||||
|
||||
godog.TestSuite{
|
||||
|
@ -92,15 +179,41 @@ func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
|
|||
Options: &opts,
|
||||
}.Run()
|
||||
|
||||
expected := string(expectedOutput)
|
||||
actual := buf.String()
|
||||
// normalise on unix line ending so expected vs actual works cross platform
|
||||
expected := normalise(string(expectedOutput))
|
||||
actual := normalise(buf.String())
|
||||
|
||||
assert.Equalf(t, expected, actual, "path: %s", expectOutputPath)
|
||||
|
||||
// display as a side by side listing as the output of the assert is all one line with embedded newlines and useless
|
||||
if expected != actual {
|
||||
fmt.Printf("Error: fmt: %s, path: %s\n", fmtName, expectOutputPath)
|
||||
compareLists(expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func passingStepDef() error { return nil }
|
||||
func normalise(s string) string {
|
||||
|
||||
func oddEvenStepDef(odd, even int) error { return oddOrEven(odd, even) }
|
||||
m := regexp.MustCompile("fmt_output_test.go:[0-9]+")
|
||||
normalised := m.ReplaceAllString(s, "fmt_output_test.go:XXX")
|
||||
normalised = strings.Replace(normalised, "\r\n", "\n", -1)
|
||||
normalised = strings.Replace(normalised, "\\r\\n", "\\n", -1)
|
||||
|
||||
return normalised
|
||||
}
|
||||
|
||||
func passingStepDef() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ambiguousStepDef() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func oddEvenStepDef(odd, even int) error {
|
||||
return oddOrEven(odd, even)
|
||||
}
|
||||
|
||||
func oddOrEven(odd, even int) error {
|
||||
if odd%2 == 0 {
|
||||
|
@ -115,3 +228,118 @@ func oddOrEven(odd, even int) error {
|
|||
func pendingStepDef() error { return godog.ErrPending }
|
||||
|
||||
func failingStepDef() error { return fmt.Errorf("step failed") }
|
||||
|
||||
func stepWithSingleAttachmentCall(ctx context.Context) (context.Context, error) {
|
||||
aCount := len(godog.Attachments(ctx))
|
||||
if aCount != 2 {
|
||||
// 1 from before scenario, 1 from before step
|
||||
assert.FailNowf(tT, "Unexpected Attachments found", "should have been 2, but found %v", aCount)
|
||||
}
|
||||
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("TheData1"), FileName: "TheFilename1", MediaType: "text/plain"},
|
||||
godog.Attachment{Body: []byte("TheData2"), FileName: "TheFilename2", MediaType: "text/plain"},
|
||||
)
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
func stepWithMultipleAttachmentCalls(ctx context.Context) (context.Context, error) {
|
||||
aCount := len(godog.Attachments(ctx))
|
||||
if aCount != 1 {
|
||||
assert.FailNowf(tT, "Unexpected Attachments found", "Expected 1 Attachment, but found %v", aCount)
|
||||
}
|
||||
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("TheData1"), FileName: "TheFilename3", MediaType: "text/plain"},
|
||||
)
|
||||
ctx = godog.Attach(ctx,
|
||||
godog.Attachment{Body: []byte("TheData2"), FileName: "TheFilename4", MediaType: "text/plain"},
|
||||
)
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// wrapString wraps a string into chunks of the given width.
|
||||
func wrapString(s string, width int) []string {
|
||||
var result []string
|
||||
for len(s) > width {
|
||||
result = append(result, s[:width])
|
||||
s = s[width:]
|
||||
}
|
||||
result = append(result, s)
|
||||
return result
|
||||
}
|
||||
|
||||
// compareLists compares two lists of strings and prints them with wrapped text.
|
||||
func compareLists(expected, actual string) {
|
||||
list1 := strings.Split(expected, "\n")
|
||||
list2 := strings.Split(actual, "\n")
|
||||
|
||||
// Get the length of the longer list
|
||||
maxLength := len(list1)
|
||||
if len(list2) > maxLength {
|
||||
maxLength = len(list2)
|
||||
}
|
||||
|
||||
colWid := 60
|
||||
fmtTitle := fmt.Sprintf("%%4s: %%-%ds | %%-%ds\n", colWid+2, colWid+2)
|
||||
fmtData := fmt.Sprintf("%%4d: %%-%ds | %%-%ds %%s\n", colWid+2, colWid+2)
|
||||
|
||||
fmt.Printf(fmtTitle, "#", "expected", "actual")
|
||||
|
||||
for i := 0; i < maxLength; i++ {
|
||||
var val1, val2 string
|
||||
|
||||
// Get the value from list1 if it exists
|
||||
if i < len(list1) {
|
||||
val1 = list1[i]
|
||||
} else {
|
||||
val1 = "N/A"
|
||||
}
|
||||
|
||||
// Get the value from list2 if it exists
|
||||
if i < len(list2) {
|
||||
val2 = list2[i]
|
||||
} else {
|
||||
val2 = "N/A"
|
||||
}
|
||||
|
||||
// Wrap both strings into slices of strings with fixed width
|
||||
wrapped1 := wrapString(val1, colWid)
|
||||
wrapped2 := wrapString(val2, colWid)
|
||||
|
||||
// Find the number of wrapped lines needed for the current pair
|
||||
maxWrappedLines := len(wrapped1)
|
||||
if len(wrapped2) > maxWrappedLines {
|
||||
maxWrappedLines = len(wrapped2)
|
||||
}
|
||||
|
||||
// Print the wrapped lines with alignment
|
||||
for j := 0; j < maxWrappedLines; j++ {
|
||||
var line1, line2 string
|
||||
|
||||
// Get the wrapped line or use an empty string if it doesn't exist
|
||||
if j < len(wrapped1) {
|
||||
line1 = wrapped1[j]
|
||||
} else {
|
||||
line1 = ""
|
||||
}
|
||||
|
||||
if j < len(wrapped2) {
|
||||
line2 = wrapped2[j]
|
||||
} else {
|
||||
line2 = ""
|
||||
}
|
||||
|
||||
status := "same"
|
||||
// if val1 != val2 {
|
||||
if line1 != line2 {
|
||||
status = "different"
|
||||
}
|
||||
|
||||
delim := "¬"
|
||||
// Print the wrapped lines with fixed-width column
|
||||
fmt.Printf(fmtData, i+1, delim+line1+delim, delim+line2+delim, status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -114,6 +114,16 @@ func (f *Pretty) Failed(pickle *messages.Pickle, step *messages.PickleStep, matc
|
|||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Failed captures failed step.
|
||||
func (f *Pretty) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||
f.Base.Ambiguous(pickle, step, match, err)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.printStep(pickle, step)
|
||||
}
|
||||
|
||||
// Pending captures pending step.
|
||||
func (f *Pretty) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Pending(pickle, step, match)
|
||||
|
@ -233,7 +243,7 @@ func (f *Pretty) Summary() {
|
|||
f.Base.Summary()
|
||||
}
|
||||
|
||||
func (f *Pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps int) {
|
||||
func (f *Pretty) printOutlineExample(pickle *messages.Pickle, step *messages.PickleStep, backgroundSteps int) {
|
||||
var errorMsg string
|
||||
var clr = green
|
||||
|
||||
|
@ -245,7 +255,7 @@ func (f *Pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
|||
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||
|
||||
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleIDUntilStep(pickle.Id, step.Id)
|
||||
|
||||
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
||||
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
||||
|
@ -269,6 +279,9 @@ func (f *Pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
|||
case result.Status == failed:
|
||||
errorMsg = result.Err.Error()
|
||||
clr = result.Status.Color()
|
||||
case result.Status == ambiguous:
|
||||
errorMsg = result.Err.Error()
|
||||
clr = result.Status.Color()
|
||||
case result.Status == undefined || result.Status == pending:
|
||||
clr = result.Status.Color()
|
||||
case result.Status == skipped && clr == nil:
|
||||
|
@ -406,7 +419,7 @@ func (f *Pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleS
|
|||
}
|
||||
|
||||
if !astBackgroundStep && len(astScenario.Examples) > 0 {
|
||||
f.printOutlineExample(pickle, backgroundSteps)
|
||||
f.printOutlineExample(pickle, pickleStep, backgroundSteps)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
|
@ -42,7 +42,7 @@ func (f *Progress) Summary() {
|
|||
left := math.Mod(float64(*f.Steps), float64(f.StepsPerRow))
|
||||
if left != 0 {
|
||||
if *f.Steps > f.StepsPerRow {
|
||||
fmt.Fprintf(f.out, s(f.StepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.Steps))
|
||||
fmt.Fprint(f.out, s(f.StepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.Steps))
|
||||
} else {
|
||||
fmt.Fprintf(f.out, " %d\n", *f.Steps)
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ func (f *Progress) step(pickleStepID string) {
|
|||
fmt.Fprint(f.out, red("F"))
|
||||
case undefined:
|
||||
fmt.Fprint(f.out, yellow("U"))
|
||||
case ambiguous:
|
||||
fmt.Fprint(f.out, yellow("A"))
|
||||
case pending:
|
||||
fmt.Fprint(f.out, yellow("P"))
|
||||
}
|
||||
|
@ -149,6 +151,16 @@ func (f *Progress) Failed(pickle *messages.Pickle, step *messages.PickleStep, ma
|
|||
f.step(step.Id)
|
||||
}
|
||||
|
||||
// Ambiguous steps.
|
||||
func (f *Progress) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||
f.Base.Ambiguous(pickle, step, match, err)
|
||||
|
||||
f.Lock.Lock()
|
||||
defer f.Lock.Unlock()
|
||||
|
||||
f.step(step.Id)
|
||||
}
|
||||
|
||||
// Pending captures pending step.
|
||||
func (f *Progress) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||
f.Base.Pending(pickle, step, match)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
[
|
||||
{
|
||||
"uri": "formatter-tests/features/scenario_with_attachment.feature",
|
||||
"id": "feature-with-attachment",
|
||||
"keyword": "Feature",
|
||||
"name": "feature with attachment",
|
||||
"description": " describes\n an attachment\n feature",
|
||||
"line": 1,
|
||||
"elements": [
|
||||
{
|
||||
"id": "feature-with-attachment;scenario-with-attachment",
|
||||
"keyword": "Scenario",
|
||||
"name": "scenario with attachment",
|
||||
"description": "",
|
||||
"line": 6,
|
||||
"type": "scenario",
|
||||
"steps": [
|
||||
{
|
||||
"keyword": "Given ",
|
||||
"name": "a step with a single attachment call for multiple attachments",
|
||||
"line": 7,
|
||||
"match": {
|
||||
"location": "fmt_output_test.go:119"
|
||||
},
|
||||
"result": {
|
||||
"status": "passed",
|
||||
"duration": 0
|
||||
},
|
||||
"embeddings": [
|
||||
{
|
||||
"name": "Before Scenario Attachment 1",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QmVmb3JlU2NlbmFyaW9BdHRhY2htZW50"
|
||||
},
|
||||
{
|
||||
"name": "Before Step Attachment 3",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QmVmb3JlU3RlcEF0dGFjaG1lbnQ="
|
||||
},
|
||||
{
|
||||
"name": "TheFilename1",
|
||||
"mime_type": "text/plain",
|
||||
"data": "VGhlRGF0YTE="
|
||||
},
|
||||
{
|
||||
"name": "TheFilename2",
|
||||
"mime_type": "text/plain",
|
||||
"data": "VGhlRGF0YTI="
|
||||
},
|
||||
{
|
||||
"name": "After Step Attachment 4",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QWZ0ZXJTdGVwQXR0YWNobWVudA=="
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"keyword": "And ",
|
||||
"name": "a step with multiple attachment calls",
|
||||
"line": 8,
|
||||
"match": {
|
||||
"location": "fmt_output_test.go:119"
|
||||
},
|
||||
"result": {
|
||||
"status": "passed",
|
||||
"duration": 0
|
||||
},
|
||||
"embeddings": [
|
||||
{
|
||||
"name": "Before Step Attachment 3",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QmVmb3JlU3RlcEF0dGFjaG1lbnQ="
|
||||
},
|
||||
{
|
||||
"name": "TheFilename3",
|
||||
"mime_type": "text/plain",
|
||||
"data": "VGhlRGF0YTE="
|
||||
},
|
||||
{
|
||||
"name": "TheFilename4",
|
||||
"mime_type": "text/plain",
|
||||
"data": "VGhlRGF0YTI="
|
||||
},
|
||||
{
|
||||
"name": "After Step Attachment 4",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QWZ0ZXJTdGVwQXR0YWNobWVudA=="
|
||||
},
|
||||
{
|
||||
"name": "After Scenario Attachment 2",
|
||||
"mime_type": "text/plain",
|
||||
"data": "QWZ0ZXJTY2VuYXJpb0F0dGFjaG1lbnQ="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,6 +1,6 @@
|
|||
[
|
||||
{
|
||||
"uri": "formatter-tests/features/some_scenarions_including_failing.feature",
|
||||
"uri": "formatter-tests/features/some_scenarios_including_failing.feature",
|
||||
"id": "some-scenarios",
|
||||
"keyword": "Feature",
|
||||
"name": "some scenarios",
|
||||
|
@ -66,7 +66,7 @@
|
|||
"name": "pending step",
|
||||
"line": 9,
|
||||
"match": {
|
||||
"location": "formatter-tests/features/some_scenarions_including_failing.feature:9"
|
||||
"location": "formatter-tests/features/some_scenarios_including_failing.feature:9"
|
||||
},
|
||||
"result": {
|
||||
"status": "pending"
|
||||
|
@ -98,7 +98,7 @@
|
|||
"name": "undefined",
|
||||
"line": 13,
|
||||
"match": {
|
||||
"location": "formatter-tests/features/some_scenarions_including_failing.feature:13"
|
||||
"location": "formatter-tests/features/some_scenarios_including_failing.feature:13"
|
||||
},
|
||||
"result": {
|
||||
"status": "undefined"
|
||||
|
@ -116,6 +116,39 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "some-scenarios;ambiguous",
|
||||
"keyword": "Scenario",
|
||||
"name": "ambiguous",
|
||||
"description": "",
|
||||
"line": 16,
|
||||
"type": "scenario",
|
||||
"steps": [
|
||||
{
|
||||
"keyword": "When ",
|
||||
"name": "ambiguous step",
|
||||
"line": 17,
|
||||
"match": {
|
||||
"location": "formatter-tests/features/some_scenarios_including_failing.feature:17"
|
||||
},
|
||||
"result": {
|
||||
"status": "ambiguous",
|
||||
"error_message": "ambiguous step definition, step text: ambiguous step\n matches:\n ^ambiguous step.*$\n ^ambiguous step$"
|
||||
}
|
||||
},
|
||||
{
|
||||
"keyword": "Then ",
|
||||
"name": "passing step",
|
||||
"line": 18,
|
||||
"match": {
|
||||
"location": "fmt_output_test.go:XXX"
|
||||
},
|
||||
"result": {
|
||||
"status": "skipped"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,57 +1,57 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/scenario_outline.feature:2","source":"@outline @tag\nFeature: outline\n\n @scenario\n Scenario Outline: outline\n Given passing step\n When passing step\n Then odd \u003codd\u003e and even \u003ceven\u003e number\n\n @tagged\n Examples: tagged\n | odd | even |\n | 1 | 2 |\n | 2 | 0 |\n | 3 | 11 |\n\n @tag2\n Examples:\n | odd | even |\n | 1 | 14 |\n | 3 | 9 |\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_outline.feature:13","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_outline.feature:13","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_outline.feature:14","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871,"status":"failed","summary":"2 is not odd"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_outline.feature:14","timestamp":-6795364578871,"status":"failed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_outline.feature:15","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871,"status":"failed","summary":"11 is not even"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_outline.feature:15","timestamp":-6795364578871,"status":"failed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_outline.feature:20","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_outline.feature:20","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_outline.feature:21","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_outline.feature:8","definition_id":"fmt_output_test.go:103 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef","arguments":[[4,5],[5,15]]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_outline.feature:8","timestamp":-6795364578871,"status":"failed","summary":"9 is not even"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_outline.feature:21","timestamp":-6795364578871,"status":"failed"}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/scenario_with_attachment.feature:1","source":"Feature: feature with attachment\n describes\n an attachment\n feature\n\n Scenario: scenario with attachment\n Given a step with a single attachment call for multiple attachments\n And a step with multiple attachment calls\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_with_attachment.feature:6","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_attachment.feature:7","definition_id":"fmt_output_test.go:XXX -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.stepWithSingleAttachmentCall","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"Before Scenario Attachment 1","mimeType":"text/plain","body":"BeforeScenarioAttachment"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"Before Step Attachment 3","mimeType":"text/plain","body":"BeforeStepAttachment"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename1","mimeType":"text/plain","body":"TheData1"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename2","mimeType":"text/plain","body":"TheData2"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"After Step Attachment 4","mimeType":"text/plain","body":"AfterStepAttachment"}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_attachment.feature:8","definition_id":"fmt_output_test.go:XXX -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.stepWithMultipleAttachmentCalls","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"Before Step Attachment 3","mimeType":"text/plain","body":"BeforeStepAttachment"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename3","mimeType":"text/plain","body":"TheData1"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename4","mimeType":"text/plain","body":"TheData2"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"After Step Attachment 4","mimeType":"text/plain","body":"AfterStepAttachment"}
|
||||
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"After Scenario Attachment 2","mimeType":"text/plain","body":"AfterScenarioAttachment"}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_attachment.feature:8","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_with_attachment.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestRunFinished","status":"passed","timestamp":-6795364578871,"snippets":"","memory":""}
|
|
@ -1,16 +1,16 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/scenario_with_background.feature:1","source":"Feature: single scenario with background\n\n Background: named\n Given passing step\n And passing step\n\n Scenario: scenario\n When passing step\n Then passing step\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_with_background.feature:7","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:4","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:4","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_background.feature:4","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_background.feature:4","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:5","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:5","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_background.feature:5","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_background.feature:5","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:8","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:8","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_background.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_background.feature:8","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:9","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_background.feature:9","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_background.feature:9","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_background.feature:9","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_with_background.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/single_scenario_with_passing_step.feature:1","source":"Feature: single passing scenario\n describes\n a single scenario\n feature\n\n Scenario: one step passing\n Given a passing step\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/single_scenario_with_passing_step.feature:6","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/single_scenario_with_passing_step.feature:7","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/single_scenario_with_passing_step.feature:7","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/single_scenario_with_passing_step.feature:7","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/single_scenario_with_passing_step.feature:7","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/single_scenario_with_passing_step.feature:6","timestamp":-6795364578871,"status":"passed"}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/some_scenarions_including_failing.feature:1","source":"Feature: some scenarios\n\n Scenario: failing\n Given passing step\n When failing step\n Then passing step\n\n Scenario: pending\n When pending step\n Then passing step\n\n Scenario: undefined\n When undefined\n Then passing step\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:3","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:4","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:4","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:4","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:5","definition_id":"fmt_output_test.go:117 -\u003e github.com/cucumber/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:5","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:5","timestamp":-6795364578871,"status":"failed","summary":"step failed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:6","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:6","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:3","timestamp":-6795364578871,"status":"failed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:8","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:9","definition_id":"fmt_output_test.go:115 -\u003e github.com/cucumber/godog/internal/formatters_test.pendingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:9","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:9","timestamp":-6795364578871,"status":"pending"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:10","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:10","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:10","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:8","timestamp":-6795364578871,"status":"pending"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:12","timestamp":-6795364578871}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:13","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:13","timestamp":-6795364578871,"status":"undefined"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarions_including_failing.feature:14","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarions_including_failing.feature:14","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:14","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarions_including_failing.feature:12","timestamp":-6795364578871,"status":"undefined"}
|
||||
{"event":"TestRunFinished","status":"failed","timestamp":-6795364578871,"snippets":"You can implement step definitions for undefined steps with these snippets:\n\nfunc undefined() error {\n\treturn godog.ErrPending\n}\n\nfunc InitializeScenario(ctx *godog.ScenarioContext) {\n\tctx.Step(`^undefined$`, undefined)\n}\n","memory":""}
|
|
@ -0,0 +1,36 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/some_scenarios_including_failing.feature:1","source":"Feature: some scenarios\n\n Scenario: failing\n Given passing step\n When failing step\n Then passing step\n\n Scenario: pending\n When pending step\n Then passing step\n\n Scenario: undefined\n When undefined\n Then passing step\n\n Scenario: ambiguous\n When ambiguous step\n Then passing step\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:3","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:4","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:4","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:4","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:5","definition_id":"fmt_output_test.go:117 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:5","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:5","timestamp":-6795364578871,"status":"failed","summary":"step failed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:6","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:6","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:6","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:3","timestamp":-6795364578871,"status":"failed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:8","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:9","definition_id":"fmt_output_test.go:115 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.pendingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:9","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:9","timestamp":-6795364578871,"status":"pending"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:10","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:10","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:10","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:8","timestamp":-6795364578871,"status":"pending"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:12","timestamp":-6795364578871}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:13","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:13","timestamp":-6795364578871,"status":"undefined"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:14","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:14","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:14","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:12","timestamp":-6795364578871,"status":"undefined"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:16","timestamp":-6795364578871}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:17","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:17","timestamp":-6795364578871,"status":"ambiguous","summary":"ambiguous step definition, step text: ambiguous step\n matches:\n ^ambiguous step.*$\n ^ambiguous step$"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/some_scenarios_including_failing.feature:18","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/some_scenarios_including_failing.feature:18","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:18","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/some_scenarios_including_failing.feature:16","timestamp":-6795364578871,"status":"ambiguous"}
|
||||
{"event":"TestRunFinished","status":"failed","timestamp":-6795364578871,"snippets":"You can implement step definitions for undefined steps with these snippets:\n\nfunc undefined() error {\n\treturn godog.ErrPending\n}\n\nfunc InitializeScenario(ctx *godog.ScenarioContext) {\n\tctx.Step(`^undefined$`, undefined)\n}\n","memory":""}
|
|
@ -1,27 +1,27 @@
|
|||
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
|
||||
{"event":"TestSource","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:1","source":"Feature: two scenarios with background fail\n\n Background:\n Given passing step\n And failing step\n\n Scenario: one\n When passing step\n Then passing step\n\n Scenario: two\n Then passing step\n"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:7","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","definition_id":"fmt_output_test.go:117 -\u003e github.com/cucumber/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","definition_id":"fmt_output_test.go:117 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","timestamp":-6795364578871,"status":"failed","summary":"step failed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:8","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:8","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:8","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:8","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:9","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:9","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:9","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:9","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:7","timestamp":-6795364578871,"status":"failed"}
|
||||
{"event":"TestCaseStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:11","timestamp":-6795364578871}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:4","timestamp":-6795364578871,"status":"passed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","definition_id":"fmt_output_test.go:117 -\u003e github.com/cucumber/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","definition_id":"fmt_output_test.go:117 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:5","timestamp":-6795364578871,"status":"failed","summary":"step failed"}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:12","definition_id":"fmt_output_test.go:101 -\u003e github.com/cucumber/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"StepDefinitionFound","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:12","definition_id":"fmt_output_test.go:101 -\u003e git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef","arguments":[]}
|
||||
{"event":"TestStepStarted","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:12","timestamp":-6795364578871}
|
||||
{"event":"TestStepFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:12","timestamp":-6795364578871,"status":"skipped"}
|
||||
{"event":"TestCaseFinished","location":"formatter-tests/features/two_scenarios_with_background_fail.feature:11","timestamp":-6795364578871,"status":"failed"}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
Feature: feature with attachment
|
||||
describes
|
||||
an attachment
|
||||
feature
|
||||
|
||||
Scenario: scenario with attachment
|
||||
Given a step with a single attachment call for multiple attachments
|
||||
And a step with multiple attachment calls
|
|
@ -12,3 +12,7 @@ Feature: some scenarios
|
|||
Scenario: undefined
|
||||
When undefined
|
||||
Then passing step
|
||||
|
||||
Scenario: ambiguous
|
||||
When ambiguous step
|
||||
Then passing step
|
|
@ -1,9 +1,9 @@
|
|||
<bold-white>Feature:</bold-white> outline
|
||||
|
||||
<bold-white>Scenario Outline:</bold-white> outline <bold-black># formatter-tests/features/scenario_outline.feature:5</bold-black>
|
||||
<cyan>Given</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>odd </cyan><bold-cyan><odd></bold-cyan><cyan> and even </cyan><bold-cyan><even></bold-cyan><cyan> number</cyan> <bold-black># fmt_output_test.go:103 -> github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef</bold-black>
|
||||
<cyan>Given</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>odd </cyan><bold-cyan><odd></bold-cyan><cyan> and even </cyan><bold-cyan><even></bold-cyan><cyan> number</cyan> <bold-black># fmt_output_test.go:103 -> git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef</bold-black>
|
||||
|
||||
<bold-white>Examples:</bold-white> tagged
|
||||
| <cyan>odd</cyan> | <cyan>even</cyan> |
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<bold-white>Feature:</bold-white> single scenario with background
|
||||
|
||||
<bold-white>Background:</bold-white> named
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> scenario <bold-black># formatter-tests/features/scenario_with_background.feature:7</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit,pretty" tests="1" skipped="0" failures="0" errors="0" time="0">
|
||||
<testsuite name="single scenario with background" tests="1" skipped="0" failures="0" errors="0" time="0">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
feature
|
||||
|
||||
<bold-white>Scenario:</bold-white> one step passing <bold-black># formatter-tests/features/single_scenario_with_passing_step.feature:6</bold-black>
|
||||
<green>Given</green> <green>a passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>a passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit,pretty" tests="1" skipped="0" failures="0" errors="0" time="0">
|
||||
<testsuite name="single passing scenario" tests="1" skipped="0" failures="0" errors="0" time="0">
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
<bold-white>Feature:</bold-white> some scenarios
|
||||
|
||||
<bold-white>Scenario:</bold-white> failing <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:3</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>When</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> github.com/cucumber/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> pending <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:8</bold-black>
|
||||
<yellow>When</yellow> <yellow>pending step</yellow> <bold-black># fmt_output_test.go:115 -> github.com/cucumber/godog/internal/formatters_test.pendingStepDef</bold-black>
|
||||
<yellow>TODO: write pending definition</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> undefined <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:12</bold-black>
|
||||
<yellow>When</yellow> <yellow>undefined</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit,pretty" tests="3" skipped="0" failures="1" errors="2" time="0">
|
||||
<testsuite name="some scenarios" tests="3" skipped="0" failures="1" errors="2" time="0">
|
||||
<testcase name="failing" status="failed" time="0">
|
||||
<failure message="Step failing step: step failed"></failure>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="pending" status="pending" time="0">
|
||||
<error message="Step pending step: TODO: write pending definition" type="pending"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="undefined" status="undefined" time="0">
|
||||
<error message="Step undefined" type="undefined"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
<red>Scenario: failing</red> <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red> <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:5</bold-black>
|
||||
<red>Error: </red><bold-red>step failed</bold-red>
|
||||
|
||||
|
||||
3 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>)
|
||||
7 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>, <cyan>3 skipped</cyan>)
|
||||
0s
|
||||
|
||||
<yellow>You can implement step definitions for undefined steps with these snippets:</yellow>
|
||||
<yellow>
|
||||
func undefined() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`^undefined$`, undefined)
|
||||
}
|
||||
</yellow>
|
|
@ -0,0 +1,66 @@
|
|||
<bold-white>Feature:</bold-white> some scenarios
|
||||
|
||||
<bold-white>Scenario:</bold-white> failing <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:3</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>When</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> pending <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:8</bold-black>
|
||||
<yellow>When</yellow> <yellow>pending step</yellow> <bold-black># fmt_output_test.go:115 -> git.golang1.ru/softonik/godog/internal/formatters_test.pendingStepDef</bold-black>
|
||||
<yellow>TODO: write pending definition</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> undefined <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:12</bold-black>
|
||||
<yellow>When</yellow> <yellow>undefined</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> ambiguous <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:16</bold-black>
|
||||
<yellow>When</yellow> <yellow>ambiguous step</yellow>
|
||||
<bold-red>ambiguous step definition, step text: ambiguous step
|
||||
matches:
|
||||
^ambiguous step.*$
|
||||
^ambiguous step$</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit,pretty" tests="4" skipped="0" failures="1" errors="2" time="0">
|
||||
<testsuite name="some scenarios" tests="4" skipped="0" failures="1" errors="2" time="0">
|
||||
<testcase name="failing" status="failed" time="0">
|
||||
<failure message="Step failing step: step failed"></failure>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="pending" status="pending" time="0">
|
||||
<error message="Step pending step: TODO: write pending definition" type="pending"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="undefined" status="undefined" time="0">
|
||||
<error message="Step undefined" type="undefined"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="ambiguous" status="ambiguous" time="0">
|
||||
<error message="Step ambiguous step" type="ambiguous"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
<red>Scenario: failing</red> <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red> <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:5</bold-black>
|
||||
<red>Error: </red><bold-red>step failed</bold-red>
|
||||
|
||||
|
||||
4 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>)
|
||||
9 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>, <cyan>4 skipped</cyan>)
|
||||
0s
|
||||
|
||||
<yellow>You can implement step definitions for undefined steps with these snippets:</yellow>
|
||||
<yellow>
|
||||
func undefined() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`^undefined$`, undefined)
|
||||
}
|
||||
</yellow>
|
|
@ -1,16 +1,16 @@
|
|||
<bold-white>Feature:</bold-white> two scenarios with background fail
|
||||
|
||||
<bold-white>Background:</bold-white>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>And</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> github.com/cucumber/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>And</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
|
||||
<bold-white>Scenario:</bold-white> one <bold-black># formatter-tests/features/two_scenarios_with_background_fail.feature:7</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> two <bold-black># formatter-tests/features/two_scenarios_with_background_fail.feature:11</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit,pretty" tests="2" skipped="0" failures="2" errors="0" time="0">
|
||||
<testsuite name="two scenarios with background fail" tests="2" skipped="0" failures="2" errors="0" time="0">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="junit" tests="3" skipped="0" failures="1" errors="2" time="0">
|
||||
<testsuite name="some scenarios" tests="3" skipped="0" failures="1" errors="2" time="0">
|
||||
<testsuites name="junit" tests="4" skipped="0" failures="1" errors="2" time="0">
|
||||
<testsuite name="some scenarios" tests="4" skipped="0" failures="1" errors="2" time="0">
|
||||
<testcase name="failing" status="failed" time="0">
|
||||
<failure message="Step failing step: step failed"></failure>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
|
@ -13,5 +13,9 @@
|
|||
<error message="Step undefined" type="undefined"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
<testcase name="ambiguous" status="ambiguous" time="0">
|
||||
<error message="Step ambiguous step" type="ambiguous"></error>
|
||||
<error message="Step passing step" type="skipped"></error>
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
|
@ -1,28 +1,28 @@
|
|||
<bold-white>Feature:</bold-white> rules with examples with backgrounds
|
||||
|
||||
<bold-white>Background:</bold-white> for first rule
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Example:</bold-white> rule 1 example 1 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:9</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Example:</bold-white> rule 1 example 2 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:13</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Background:</bold-white> for second rule
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Example:</bold-white> rule 1 example 1 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:24</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Example:</bold-white> rule 2 example 2 <bold-black># formatter-tests/features/rules_with_examples_with_backgrounds.feature:28</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
4 scenarios (<green>4 passed</green>)
|
||||
16 steps (<green>16 passed</green>)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<bold-white>Feature:</bold-white> outline
|
||||
|
||||
<bold-white>Scenario Outline:</bold-white> outline <bold-black># formatter-tests/features/scenario_outline.feature:5</bold-black>
|
||||
<cyan>Given</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>odd </cyan><bold-cyan><odd></bold-cyan><cyan> and even </cyan><bold-cyan><even></bold-cyan><cyan> number</cyan> <bold-black># fmt_output_test.go:103 -> github.com/cucumber/godog/internal/formatters_test.oddEvenStepDef</bold-black>
|
||||
<cyan>Given</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>odd </cyan><bold-cyan><odd></bold-cyan><cyan> and even </cyan><bold-cyan><even></bold-cyan><cyan> number</cyan> <bold-black># fmt_output_test.go:103 -> git.golang1.ru/softonik/godog/internal/formatters_test.oddEvenStepDef</bold-black>
|
||||
|
||||
<bold-white>Examples:</bold-white> tagged
|
||||
| <cyan>odd</cyan> | <cyan>even</cyan> |
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<bold-white>Feature:</bold-white> single scenario with background
|
||||
|
||||
<bold-white>Background:</bold-white> named
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>And</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> scenario <bold-black># formatter-tests/features/scenario_with_background.feature:7</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>When</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Then</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
1 scenarios (<green>1 passed</green>)
|
||||
4 steps (<green>4 passed</green>)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
feature
|
||||
|
||||
<bold-white>Scenario:</bold-white> one step passing <bold-black># formatter-tests/features/single_scenario_with_passing_step.feature:6</bold-black>
|
||||
<green>Given</green> <green>a passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<green>Given</green> <green>a passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
1 scenarios (<green>1 passed</green>)
|
||||
1 steps (<green>1 passed</green>)
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<bold-white>Feature:</bold-white> some scenarios
|
||||
|
||||
<bold-white>Scenario:</bold-white> failing <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:3</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>When</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> github.com/cucumber/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> pending <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:8</bold-black>
|
||||
<yellow>When</yellow> <yellow>pending step</yellow> <bold-black># fmt_output_test.go:115 -> github.com/cucumber/godog/internal/formatters_test.pendingStepDef</bold-black>
|
||||
<yellow>TODO: write pending definition</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> undefined <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:12</bold-black>
|
||||
<yellow>When</yellow> <yellow>undefined</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
<red>Scenario: failing</red> <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red> <bold-black># formatter-tests/features/some_scenarions_including_failing.feature:5</bold-black>
|
||||
<red>Error: </red><bold-red>step failed</bold-red>
|
||||
|
||||
|
||||
3 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>)
|
||||
7 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>, <cyan>3 skipped</cyan>)
|
||||
0s
|
||||
|
||||
<yellow>You can implement step definitions for undefined steps with these snippets:</yellow>
|
||||
<yellow>
|
||||
func undefined() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`^undefined$`, undefined)
|
||||
}
|
||||
</yellow>
|
|
@ -0,0 +1,46 @@
|
|||
<bold-white>Feature:</bold-white> some scenarios
|
||||
|
||||
<bold-white>Scenario:</bold-white> failing <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:3</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>When</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> pending <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:8</bold-black>
|
||||
<yellow>When</yellow> <yellow>pending step</yellow> <bold-black># fmt_output_test.go:115 -> git.golang1.ru/softonik/godog/internal/formatters_test.pendingStepDef</bold-black>
|
||||
<yellow>TODO: write pending definition</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> undefined <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:12</bold-black>
|
||||
<yellow>When</yellow> <yellow>undefined</yellow>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> ambiguous <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:16</bold-black>
|
||||
<yellow>When</yellow> <yellow>ambiguous step</yellow>
|
||||
<bold-red>ambiguous step definition, step text: ambiguous step
|
||||
matches:
|
||||
^ambiguous step.*$
|
||||
^ambiguous step$</bold-red>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:XXX -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
<red>Scenario: failing</red> <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red> <bold-black># formatter-tests/features/some_scenarios_including_failing.feature:5</bold-black>
|
||||
<red>Error: </red><bold-red>step failed</bold-red>
|
||||
|
||||
|
||||
4 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>)
|
||||
9 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>, <cyan>4 skipped</cyan>)
|
||||
0s
|
||||
|
||||
<yellow>You can implement step definitions for undefined steps with these snippets:</yellow>
|
||||
<yellow>
|
||||
func undefined() error {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
ctx.Step(`^undefined$`, undefined)
|
||||
}
|
||||
</yellow>
|
|
@ -1,16 +1,16 @@
|
|||
<bold-white>Feature:</bold-white> two scenarios with background fail
|
||||
|
||||
<bold-white>Background:</bold-white>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>And</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> github.com/cucumber/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<green>Given</green> <green>passing step</green> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<red>And</red> <red>failing step</red> <bold-black># fmt_output_test.go:117 -> git.golang1.ru/softonik/godog/internal/formatters_test.failingStepDef</bold-black>
|
||||
<bold-red>step failed</bold-red>
|
||||
|
||||
<bold-white>Scenario:</bold-white> one <bold-black># formatter-tests/features/two_scenarios_with_background_fail.feature:7</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>When</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
<bold-white>Scenario:</bold-white> two <bold-black># formatter-tests/features/two_scenarios_with_background_fail.feature:11</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> github.com/cucumber/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
<cyan>Then</cyan> <cyan>passing step</cyan> <bold-black># fmt_output_test.go:101 -> git.golang1.ru/softonik/godog/internal/formatters_test.passingStepDef</bold-black>
|
||||
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<green>.</green><red>F</red><cyan>-</cyan><yellow>P</yellow><cyan>-</cyan><yellow>U</yellow><cyan>-</cyan> 7
|
||||
<green>.</green><red>F</red><cyan>-</cyan><yellow>P</yellow><cyan>-</cyan><yellow>U</yellow><cyan>-</cyan><yellow>A</yellow><cyan>-</cyan> 9
|
||||
|
||||
|
||||
--- <red>Failed steps:</red>
|
||||
|
||||
<red>Scenario: failing</red><bold-black> # formatter-tests/features/some_scenarions_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red><bold-black> # formatter-tests/features/some_scenarions_including_failing.feature:5</bold-black>
|
||||
<red>Scenario: failing</red><bold-black> # formatter-tests/features/some_scenarios_including_failing.feature:3</bold-black>
|
||||
<red>When failing step</red><bold-black> # formatter-tests/features/some_scenarios_including_failing.feature:5</bold-black>
|
||||
<red>Error: </red><bold-red>step failed</bold-red>
|
||||
|
||||
|
||||
3 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>)
|
||||
7 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 undefined</yellow>, <cyan>3 skipped</cyan>)
|
||||
4 scenarios (<red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>)
|
||||
9 steps (<green>1 passed</green>, <red>1 failed</red>, <yellow>1 pending</yellow>, <yellow>1 ambiguous</yellow>, <yellow>1 undefined</yellow>, <cyan>4 skipped</cyan>)
|
||||
0s
|
||||
|
||||
<yellow>You can implement step definitions for undefined steps with these snippets:</yellow>
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
// some snippet formatting regexps
|
||||
var snippetExprCleanup = regexp.MustCompile(`([\/\[\]\(\)\\^\$\.\|\?\*\+\'])`)
|
||||
var snippetExprQuoted = regexp.MustCompile(`(\W|^)"(?:[^"]*)"(\W|$)`)
|
||||
var snippetMethodName = regexp.MustCompile(`[^a-zA-Z\_\ ]`)
|
||||
var snippetMethodName = regexp.MustCompile("[^a-zA-Zа-яА-ЯёЁ\\_\\ ]")
|
||||
var snippetNumbers = regexp.MustCompile(`(\d+)`)
|
||||
|
||||
var snippetHelperFuncs = template.FuncMap{
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
// this zeroes the time throughout whole test suite
|
||||
|
|
|
@ -3,8 +3,8 @@ package models_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"github.com/cucumber/godog/internal/testutils"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/internal/testutils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ package models
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/utils"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/utils"
|
||||
)
|
||||
|
||||
// TestRunStarted ...
|
||||
|
@ -18,6 +18,13 @@ type PickleResult struct {
|
|||
StartedAt time.Time
|
||||
}
|
||||
|
||||
// PickleAttachment ...
|
||||
type PickleAttachment struct {
|
||||
Name string
|
||||
MimeType string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// PickleStepResult ...
|
||||
type PickleStepResult struct {
|
||||
Status StepResultStatus
|
||||
|
@ -28,6 +35,8 @@ type PickleStepResult struct {
|
|||
PickleStepID string
|
||||
|
||||
Def *StepDefinition
|
||||
|
||||
Attachments []PickleAttachment
|
||||
}
|
||||
|
||||
// NewStepResult ...
|
||||
|
@ -35,6 +44,7 @@ func NewStepResult(
|
|||
status StepResultStatus,
|
||||
pickleID, pickleStepID string,
|
||||
match *StepDefinition,
|
||||
attachments []PickleAttachment,
|
||||
err error,
|
||||
) PickleStepResult {
|
||||
return PickleStepResult{
|
||||
|
@ -44,6 +54,7 @@ func NewStepResult(
|
|||
PickleID: pickleID,
|
||||
PickleStepID: pickleStepID,
|
||||
Def: match,
|
||||
Attachments: attachments,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +72,8 @@ const (
|
|||
Undefined
|
||||
// Pending ...
|
||||
Pending
|
||||
// Ambiguous ...
|
||||
Ambiguous
|
||||
)
|
||||
|
||||
// Color ...
|
||||
|
@ -90,6 +103,8 @@ func (st StepResultStatus) String() string {
|
|||
return "undefined"
|
||||
case Pending:
|
||||
return "pending"
|
||||
case Ambiguous:
|
||||
return "ambiguous"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package models_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cucumber/godog/colors"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog/colors"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
)
|
||||
|
||||
type stepResultStatusTestCase struct {
|
||||
|
@ -21,6 +22,7 @@ var stepResultStatusTestCases = []stepResultStatusTestCase{
|
|||
{st: models.Skipped, str: "skipped", clr: colors.Cyan},
|
||||
{st: models.Undefined, str: "undefined", clr: colors.Yellow},
|
||||
{st: models.Pending, str: "pending", clr: colors.Yellow},
|
||||
{st: models.Ambiguous, str: "ambiguous", clr: colors.Yellow},
|
||||
{st: -1, str: "unknown", clr: colors.Yellow},
|
||||
}
|
||||
|
||||
|
@ -32,3 +34,21 @@ func Test_StepResultStatus(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_NewStepResuklt(t *testing.T) {
|
||||
status := models.StepResultStatus(123)
|
||||
pickleID := "pickleId"
|
||||
pickleStepID := "pickleStepID"
|
||||
match := &models.StepDefinition{}
|
||||
attachments := make([]models.PickleAttachment, 0)
|
||||
err := fmt.Errorf("intentional")
|
||||
|
||||
results := models.NewStepResult(status, pickleID, pickleStepID, match, attachments, err)
|
||||
|
||||
assert.Equal(t, status, results.Status)
|
||||
assert.Equal(t, pickleID, results.PickleID)
|
||||
assert.Equal(t, pickleStepID, results.PickleStepID)
|
||||
assert.Equal(t, match, results.Def)
|
||||
assert.Equal(t, attachments, results.Attachments)
|
||||
assert.Equal(t, err, results.Err)
|
||||
}
|
||||
|
|
|
@ -9,16 +9,16 @@ import (
|
|||
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
)
|
||||
|
||||
var typeOfBytes = reflect.TypeOf([]byte(nil))
|
||||
|
||||
// matchable errors
|
||||
var (
|
||||
ErrUnmatchedStepArgumentNumber = errors.New("func received more arguments than expected")
|
||||
ErrUnmatchedStepArgumentNumber = errors.New("func expected more arguments than given")
|
||||
ErrCannotConvert = errors.New("cannot convert argument")
|
||||
ErrUnsupportedArgumentType = errors.New("unsupported argument type")
|
||||
ErrUnsupportedParameterType = errors.New("func has unsupported parameter type")
|
||||
)
|
||||
|
||||
// StepDefinition ...
|
||||
|
@ -36,6 +36,9 @@ type StepDefinition struct {
|
|||
var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem()
|
||||
|
||||
// Run a step with the matched arguments using reflect
|
||||
// Returns one of ...
|
||||
// (context, error)
|
||||
// (context, godog.Steps)
|
||||
func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}) {
|
||||
var values []reflect.Value
|
||||
|
||||
|
@ -51,7 +54,7 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}
|
|||
}
|
||||
|
||||
if len(sd.Args) < numIn {
|
||||
return ctx, fmt.Errorf("%w: expected %d arguments, matched %d from step", ErrUnmatchedStepArgumentNumber, typ.NumIn(), len(sd.Args))
|
||||
return ctx, fmt.Errorf("%w: expected %d arguments, matched %d from step", ErrUnmatchedStepArgumentNumber, numIn, len(sd.Args))
|
||||
}
|
||||
|
||||
for i := 0; i < numIn; i++ {
|
||||
|
@ -161,7 +164,8 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}
|
|||
|
||||
return ctx, fmt.Errorf(`%w %d: "%v" of type "%T" to *messages.PickleTable`, ErrCannotConvert, i, arg, arg)
|
||||
default:
|
||||
return ctx, fmt.Errorf("%w: the argument %d type %T is not supported %s", ErrUnsupportedArgumentType, i, arg, param.Elem().String())
|
||||
// the error here is that the declared function has an unsupported param type - really this ought to be trapped at registration ti,e
|
||||
return ctx, fmt.Errorf("%w: the data type of parameter %d type *%s is not supported", ErrUnsupportedParameterType, i, param.Elem().String())
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch param {
|
||||
|
@ -172,10 +176,13 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}
|
|||
}
|
||||
values = append(values, reflect.ValueOf([]byte(s)))
|
||||
default:
|
||||
return ctx, fmt.Errorf("%w: the slice argument %d type %s is not supported", ErrUnsupportedArgumentType, i, param.Kind())
|
||||
// the problem is the function decl is not using a support slice type as the param
|
||||
return ctx, fmt.Errorf("%w: the slice parameter %d type []%s is not supported", ErrUnsupportedParameterType, i, param.Elem().Kind())
|
||||
}
|
||||
case reflect.Struct:
|
||||
return ctx, fmt.Errorf("%w: the struct parameter %d type %s is not supported", ErrUnsupportedParameterType, i, param.String())
|
||||
default:
|
||||
return ctx, fmt.Errorf("%w: the argument %d type %s is not supported", ErrUnsupportedArgumentType, i, param.Kind())
|
||||
return ctx, fmt.Errorf("%w: the parameter %d type %s is not supported", ErrUnsupportedParameterType, i, param.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,17 +191,43 @@ func (sd *StepDefinition) Run(ctx context.Context) (context.Context, interface{}
|
|||
return ctx, nil
|
||||
}
|
||||
|
||||
if len(res) == 1 {
|
||||
r := res[0].Interface()
|
||||
// Note that the step fn return types were validated at Initialise in test_context.go stepWithKeyword()
|
||||
|
||||
if ctx, ok := r.(context.Context); ok {
|
||||
// single return value may be one of ...
|
||||
// error
|
||||
// context.Context
|
||||
// godog.Steps
|
||||
result0 := res[0].Interface()
|
||||
if len(res) == 1 {
|
||||
|
||||
// if the single return value is a context then just return it
|
||||
if ctx, ok := result0.(context.Context); ok {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return ctx, res[0].Interface()
|
||||
// return type is presumably one of nil, "error" or "Steps" so place it into second return position
|
||||
return ctx, result0
|
||||
}
|
||||
|
||||
return res[0].Interface().(context.Context), res[1].Interface()
|
||||
// multi-value value return must be
|
||||
// (context, error) and the context value must not be nil
|
||||
if ctx, ok := result0.(context.Context); ok {
|
||||
return ctx, res[1].Interface()
|
||||
}
|
||||
|
||||
result1 := res[1].Interface()
|
||||
errMsg := ""
|
||||
if result1 != nil {
|
||||
errMsg = fmt.Sprintf(", step def also returned an error: %v", result1)
|
||||
}
|
||||
|
||||
text := sd.StepDefinition.Expr.String()
|
||||
|
||||
if result0 == nil {
|
||||
panic(fmt.Sprintf("step definition '%v' with return type (context.Context, error) must not return <nil> for the context.Context value%s", text, errMsg))
|
||||
}
|
||||
|
||||
panic(fmt.Errorf("step definition '%v' has return type (context.Context, error), but found %v rather than a context.Context value%s", text, result0, errMsg))
|
||||
}
|
||||
|
||||
func (sd *StepDefinition) shouldBeString(idx int) (string, error) {
|
||||
|
|
|
@ -5,23 +5,105 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/formatters"
|
||||
"github.com/cucumber/godog/internal/models"
|
||||
"git.golang1.ru/softonik/godog"
|
||||
"git.golang1.ru/softonik/godog/formatters"
|
||||
"git.golang1.ru/softonik/godog/internal/models"
|
||||
messages "github.com/cucumber/messages/go/v21"
|
||||
)
|
||||
|
||||
type ctxKey string
|
||||
|
||||
func TestShouldSupportContext(t *testing.T) {
|
||||
func TestShouldSupportVoidHandlerReturn(t *testing.T) {
|
||||
wasCalled := false
|
||||
initialCtx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
fn := func(ctx context.Context) {
|
||||
wasCalled = true
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{}
|
||||
|
||||
ctx, err := def.Run(initialCtx)
|
||||
assert.True(t, wasCalled)
|
||||
// ctx is passed thru
|
||||
assert.Equal(t, initialCtx, ctx)
|
||||
assert.Nil(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestShouldSupportNilContextReturn(t *testing.T) {
|
||||
initialCtx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
wasCalled := false
|
||||
fn := func(ctx context.Context) context.Context {
|
||||
wasCalled = true
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
// nil context is permitted if is single return value
|
||||
return nil
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(initialCtx)
|
||||
assert.True(t, wasCalled)
|
||||
// original context is substituted for a nil return value
|
||||
// << JL : IS THIS A BUG? TWO ARG API DOESN'T ALLOW THIS
|
||||
assert.Equal(t, initialCtx, ctx)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestShouldSupportNilErrorReturn(t *testing.T) {
|
||||
initialCtx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
wasCalled := false
|
||||
fn := func(ctx context.Context) error {
|
||||
wasCalled = true
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
// nil error is permitted
|
||||
return nil
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(initialCtx)
|
||||
assert.True(t, wasCalled)
|
||||
// original context is passed thru if method doesn't return context.
|
||||
assert.Equal(t, initialCtx, ctx)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestShouldSupportContextReturn(t *testing.T) {
|
||||
ctx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
fn := func(ctx context.Context, a int64, b int32, c int16, d int8) context.Context {
|
||||
fn := func(ctx context.Context) context.Context {
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
return context.WithValue(ctx, ctxKey("updated"), 321)
|
||||
|
@ -34,18 +116,69 @@ func TestShouldSupportContext(t *testing.T) {
|
|||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", "1"}
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(ctx)
|
||||
assert.Nil(t, err)
|
||||
// converys the context
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
assert.Equal(t, 321, ctx.Value(ctxKey("updated")))
|
||||
}
|
||||
|
||||
func TestShouldSupportContextAndError(t *testing.T) {
|
||||
func TestShouldSupportErrorReturn(t *testing.T) {
|
||||
ctx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
expectedErr := fmt.Errorf("expected error")
|
||||
|
||||
fn := func(ctx context.Context) error {
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
return expectedErr
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(ctx)
|
||||
// conveys the returned error
|
||||
assert.Equal(t, expectedErr, err)
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
}
|
||||
|
||||
func TestShouldSupportContextAndErrorReturn(t *testing.T) {
|
||||
|
||||
ctx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
expectedErr := fmt.Errorf("expected error")
|
||||
|
||||
fn := func(ctx context.Context) (context.Context, error) {
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
return context.WithValue(ctx, ctxKey("updated"), 321), expectedErr
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(ctx)
|
||||
// conveys error and context
|
||||
assert.Equal(t, expectedErr, err)
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
assert.Equal(t, 321, ctx.Value(ctxKey("updated")))
|
||||
}
|
||||
|
||||
func TestShouldSupportContextAndNilErrorReturn(t *testing.T) {
|
||||
|
||||
ctx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
fn := func(ctx context.Context, a int64, b int32, c int16, d int8) (context.Context, error) {
|
||||
fn := func(ctx context.Context) (context.Context, error) {
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
return context.WithValue(ctx, ctxKey("updated"), 321), nil
|
||||
|
@ -58,146 +191,54 @@ func TestShouldSupportContextAndError(t *testing.T) {
|
|||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", "1"}
|
||||
def.Args = []interface{}{}
|
||||
ctx, err := def.Run(ctx)
|
||||
// conveys nil error and context
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
assert.Equal(t, 321, ctx.Value(ctxKey("updated")))
|
||||
}
|
||||
|
||||
func TestShouldSupportEmptyHandlerReturn(t *testing.T) {
|
||||
fn := func(a int64, b int32, c int16, d int8) {}
|
||||
func TestShouldRejectNilContextWhenMultiValueReturn(t *testing.T) {
|
||||
|
||||
ctx := context.WithValue(context.Background(), ctxKey("original"), 123)
|
||||
|
||||
fn := func(ctx context.Context) (context.Context, error) {
|
||||
assert.Equal(t, 123, ctx.Value(ctxKey("original")))
|
||||
|
||||
// nil context is illegal.
|
||||
return nil, fmt.Errorf("expected error")
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
Expr: regexp.MustCompile("some regex string"),
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", "1"}
|
||||
if _, err := def.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
def.Args = []interface{}{}
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
pe := e.(string)
|
||||
assert.Equal(t, "step definition 'some regex string' with return type (context.Context, error) must not return <nil> for the context.Context value, step def also returned an error: expected error", pe)
|
||||
}
|
||||
}()
|
||||
|
||||
def.Run(ctx)
|
||||
|
||||
assert.Fail(t, "should not get here")
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", strings.Repeat("1", 9)}
|
||||
if _, err := def.Run(context.Background()); err == nil {
|
||||
t.Fatalf("expected convertion fail for int8, but got none")
|
||||
}
|
||||
func TestArgumentCountChecks(t *testing.T) {
|
||||
|
||||
wasCalled := false
|
||||
fn := func(a int, b int) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
func TestShouldSupportIntTypes(t *testing.T) {
|
||||
fn := func(a int64, b int32, c int16, d int8) error { return nil }
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", "1"}
|
||||
if _, err := def.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "1", "1", strings.Repeat("1", 9)}
|
||||
if _, err := def.Run(context.Background()); err == nil {
|
||||
t.Fatalf("expected convertion fail for int8, but got none")
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldSupportFloatTypes(t *testing.T) {
|
||||
fn := func(a float64, b float32) error { return nil }
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1.1", "1.09"}
|
||||
if _, err := def.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1.08", strings.Repeat("1", 65) + ".67"}
|
||||
if _, err := def.Run(context.Background()); err == nil {
|
||||
t.Fatalf("expected convertion fail for float32, but got none")
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldNotSupportOtherPointerTypesThanGherkin(t *testing.T) {
|
||||
fn1 := func(a *int) error { return nil }
|
||||
fn2 := func(a *messages.PickleDocString) error { return nil }
|
||||
fn3 := func(a *messages.PickleTable) error { return nil }
|
||||
|
||||
def1 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn1,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn1),
|
||||
Args: []interface{}{(*int)(nil)},
|
||||
}
|
||||
def2 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn2,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn2),
|
||||
Args: []interface{}{&messages.PickleDocString{}},
|
||||
}
|
||||
def3 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn3,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn3),
|
||||
Args: []interface{}{(*messages.PickleTable)(nil)},
|
||||
}
|
||||
|
||||
if _, err := def1.Run(context.Background()); err == nil {
|
||||
t.Fatalf("expected conversion error, but got none")
|
||||
}
|
||||
|
||||
if _, err := def2.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if _, err := def3.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldSupportOnlyByteSlice(t *testing.T) {
|
||||
fn1 := func(a []byte) error { return nil }
|
||||
fn2 := func(a []string) error { return nil }
|
||||
|
||||
def1 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn1,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn1),
|
||||
Args: []interface{}{"str"},
|
||||
}
|
||||
def2 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn2,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn2),
|
||||
Args: []interface{}{[]string{}},
|
||||
}
|
||||
|
||||
if _, err := def1.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if _, err := def2.Run(context.Background()); err == nil {
|
||||
t.Fatalf("expected conversion error, but got none")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnexpectedArguments(t *testing.T) {
|
||||
fn := func(a, b int) error { return nil }
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
|
@ -206,24 +247,24 @@ func TestUnexpectedArguments(t *testing.T) {
|
|||
}
|
||||
|
||||
def.Args = []interface{}{"1"}
|
||||
_, err := def.Run(context.Background())
|
||||
assert.False(t, wasCalled)
|
||||
assert.Equal(t, `func expected more arguments than given: expected 2 arguments, matched 1 from step`, err.(error).Error())
|
||||
assert.True(t, errors.Is(err.(error), models.ErrUnmatchedStepArgumentNumber))
|
||||
|
||||
_, res := def.Run(context.Background())
|
||||
if res == nil {
|
||||
t.Fatalf("expected an error due to wrong number of arguments, but got none")
|
||||
// FIXME - extra args are ignored - but should be reported at runtime
|
||||
def.Args = []interface{}{"1", "2", "IGNORED-EXTRA-ARG"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.True(t, wasCalled)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
err, ok := res.(error)
|
||||
if !ok {
|
||||
t.Fatalf("expected an error due to wrong number of arguments, but got %T instead", res)
|
||||
func TestArgumentCountChecksWithContext(t *testing.T) {
|
||||
wasCalled := false
|
||||
fn := func(ctx context.Context, a int, b int) {
|
||||
wasCalled = true
|
||||
}
|
||||
|
||||
if !errors.Is(err, models.ErrUnmatchedStepArgumentNumber) {
|
||||
t.Fatalf("expected an error due to wrong number of arguments, but got %v instead", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepDefinition_Run_StepShouldBeString(t *testing.T) {
|
||||
test := func(t *testing.T, fn interface{}) {
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
|
@ -231,6 +272,171 @@ func TestStepDefinition_Run_StepShouldBeString(t *testing.T) {
|
|||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1"}
|
||||
_, err := def.Run(context.Background())
|
||||
assert.False(t, wasCalled)
|
||||
assert.Equal(t, `func expected more arguments than given: expected 2 arguments, matched 1 from step`, err.(error).Error())
|
||||
assert.True(t, errors.Is(err.(error), models.ErrUnmatchedStepArgumentNumber))
|
||||
}
|
||||
|
||||
func TestShouldSupportIntTypes(t *testing.T) {
|
||||
var aActual int64
|
||||
var bActual int32
|
||||
var cActual int16
|
||||
var dActual int8
|
||||
|
||||
fn := func(a int64, b int32, c int16, d int8) {
|
||||
aActual = a
|
||||
bActual = b
|
||||
cActual = c
|
||||
dActual = d
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1", "2", "3", "4"}
|
||||
_, err := def.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, int64(1), aActual)
|
||||
assert.Equal(t, int32(2), bActual)
|
||||
assert.Equal(t, int16(3), cActual)
|
||||
assert.Equal(t, int8(4), dActual)
|
||||
|
||||
// 128 doesn't fit in signed 8bit int
|
||||
def.Args = []interface{}{"1", "2", "3", "128"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.Equal(t, `cannot convert argument 3: "128" to int8: strconv.ParseInt: parsing "128": value out of range`, err.(error).Error())
|
||||
|
||||
def.Args = []interface{}{"1", "2", "99999", "4"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.Equal(t, `cannot convert argument 2: "99999" to int16: strconv.ParseInt: parsing "99999": value out of range`, err.(error).Error())
|
||||
|
||||
def.Args = []interface{}{"1", strings.Repeat("2", 32), "3", "4"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.Equal(t, `cannot convert argument 1: "22222222222222222222222222222222" to int32: strconv.ParseInt: parsing "22222222222222222222222222222222": value out of range`, err.(error).Error())
|
||||
|
||||
def.Args = []interface{}{strings.Repeat("1", 32), "2", "3", "4"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.Equal(t, `cannot convert argument 0: "11111111111111111111111111111111" to int64: strconv.ParseInt: parsing "11111111111111111111111111111111": value out of range`, err.(error).Error())
|
||||
}
|
||||
|
||||
func TestShouldSupportFloatTypes(t *testing.T) {
|
||||
var aActual float64
|
||||
var bActual float32
|
||||
fn := func(a float64, b float32) {
|
||||
aActual = a
|
||||
bActual = b
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
def.Args = []interface{}{"1.1", "2.2"}
|
||||
_, err := def.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, float64(1.1), aActual)
|
||||
assert.Equal(t, float32(2.2), bActual)
|
||||
|
||||
def.Args = []interface{}{"1.1", strings.Repeat("2", 65) + ".22"}
|
||||
_, err = def.Run(context.Background())
|
||||
assert.Equal(t, `cannot convert argument 1: "22222222222222222222222222222222222222222222222222222222222222222.22" to float32: strconv.ParseFloat: parsing "22222222222222222222222222222222222222222222222222222222222222222.22": value out of range`, err.(error).Error())
|
||||
}
|
||||
|
||||
func TestShouldSupportGherkinDocstring(t *testing.T) {
|
||||
var actualDocString *messages.PickleDocString
|
||||
fnDocstring := func(a *messages.PickleDocString) {
|
||||
actualDocString = a
|
||||
}
|
||||
|
||||
expectedDocString := &messages.PickleDocString{Content: "hello"}
|
||||
defDocstring := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fnDocstring,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fnDocstring),
|
||||
Args: []interface{}{expectedDocString},
|
||||
}
|
||||
|
||||
_, err := defDocstring.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, expectedDocString, actualDocString)
|
||||
}
|
||||
|
||||
func TestShouldSupportGherkinTable(t *testing.T) {
|
||||
|
||||
var actualTable *messages.PickleTable
|
||||
fnTable := func(a *messages.PickleTable) {
|
||||
actualTable = a
|
||||
}
|
||||
|
||||
expectedTable := &messages.PickleTable{}
|
||||
defTable := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fnTable,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fnTable),
|
||||
Args: []interface{}{expectedTable},
|
||||
}
|
||||
|
||||
_, err := defTable.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, expectedTable, actualTable)
|
||||
}
|
||||
|
||||
func TestShouldSupportOnlyByteSlice(t *testing.T) {
|
||||
var aActual []byte
|
||||
fn1 := func(a []byte) {
|
||||
aActual = a
|
||||
}
|
||||
fn2 := func(a []string) {
|
||||
assert.Fail(t, "fn2 should not be called")
|
||||
}
|
||||
|
||||
def1 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn1,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn1),
|
||||
Args: []interface{}{"str"},
|
||||
}
|
||||
|
||||
def2 := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn2,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn2),
|
||||
Args: []interface{}{[]string{}},
|
||||
}
|
||||
|
||||
_, err := def1.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []byte{'s', 't', 'r'}, aActual)
|
||||
|
||||
_, err = def2.Run(context.Background())
|
||||
assert.Equal(t, `func has unsupported parameter type: the slice parameter 0 type []string is not supported`, err.(error).Error())
|
||||
assert.True(t, errors.Is(err.(error), models.ErrUnsupportedParameterType))
|
||||
}
|
||||
|
||||
// this test is superficial compared to the ones above where the actual error messages the user woudl see are verified
|
||||
func TestStepDefinition_Run_StepArgsShouldBeString(t *testing.T) {
|
||||
test := func(t *testing.T, fn interface{}, expectedError string) {
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
},
|
||||
HandlerValue: reflect.ValueOf(fn),
|
||||
}
|
||||
|
||||
// some value that is not a string
|
||||
def.Args = []interface{}{12}
|
||||
|
||||
_, res := def.Run(context.Background())
|
||||
|
@ -246,26 +452,30 @@ func TestStepDefinition_Run_StepShouldBeString(t *testing.T) {
|
|||
if !errors.Is(err, models.ErrCannotConvert) {
|
||||
t.Fatalf("expected a string convertion error, but got '%v' instead", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedError, err.Error())
|
||||
}
|
||||
|
||||
// Ensure step type error if step argument is not a string
|
||||
// for all supported types.
|
||||
test(t, func(a int) error { return nil })
|
||||
test(t, func(a int64) error { return nil })
|
||||
test(t, func(a int32) error { return nil })
|
||||
test(t, func(a int16) error { return nil })
|
||||
test(t, func(a int8) error { return nil })
|
||||
test(t, func(a string) error { return nil })
|
||||
test(t, func(a float64) error { return nil })
|
||||
test(t, func(a float32) error { return nil })
|
||||
test(t, func(a *godog.Table) error { return nil })
|
||||
test(t, func(a *godog.DocString) error { return nil })
|
||||
test(t, func(a []byte) error { return nil })
|
||||
const toStringError = `cannot convert argument 0: "12" of type "int" to string`
|
||||
shouldNotBeCalled := func() { assert.Fail(t, "shound not be called") }
|
||||
test(t, func(a int) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a int64) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a int32) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a int16) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a int8) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a string) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a float64) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a float32) { shouldNotBeCalled() }, toStringError)
|
||||
test(t, func(a *godog.Table) { shouldNotBeCalled() }, `cannot convert argument 0: "12" of type "int" to *messages.PickleTable`)
|
||||
test(t, func(a *godog.DocString) { shouldNotBeCalled() }, `cannot convert argument 0: "12" of type "int" to *messages.PickleDocString`)
|
||||
test(t, func(a []byte) { shouldNotBeCalled() }, toStringError)
|
||||
|
||||
}
|
||||
|
||||
func TestStepDefinition_Run_InvalidHandlerParamConversion(t *testing.T) {
|
||||
test := func(t *testing.T, fn interface{}) {
|
||||
test := func(t *testing.T, fn interface{}, expectedError string) {
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
|
@ -285,44 +495,49 @@ func TestStepDefinition_Run_InvalidHandlerParamConversion(t *testing.T) {
|
|||
t.Fatalf("expected an unsupported argument type error, but got %T instead", res)
|
||||
}
|
||||
|
||||
if !errors.Is(err, models.ErrUnsupportedArgumentType) {
|
||||
if !errors.Is(err, models.ErrUnsupportedParameterType) {
|
||||
// FIXME JL - check logic as the error message was wrong
|
||||
t.Fatalf("expected an unsupported argument type error, but got '%v' instead", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedError, err.Error())
|
||||
}
|
||||
|
||||
shouldNotBeCalled := func() { assert.Fail(t, "shound not be called") }
|
||||
|
||||
// Lists some unsupported argument types for step handler.
|
||||
|
||||
// Pointers should work only for godog.Table/godog.DocString
|
||||
test(t, func(a *int) error { return nil })
|
||||
test(t, func(a *int64) error { return nil })
|
||||
test(t, func(a *int32) error { return nil })
|
||||
test(t, func(a *int16) error { return nil })
|
||||
test(t, func(a *int8) error { return nil })
|
||||
test(t, func(a *string) error { return nil })
|
||||
test(t, func(a *float64) error { return nil })
|
||||
test(t, func(a *float32) error { return nil })
|
||||
test(t, func(a *int) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *int is not supported")
|
||||
test(t, func(a *int64) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *int64 is not supported")
|
||||
test(t, func(a *int32) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *int32 is not supported")
|
||||
test(t, func(a *int16) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *int16 is not supported")
|
||||
test(t, func(a *int8) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *int8 is not supported")
|
||||
test(t, func(a *string) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *string is not supported")
|
||||
test(t, func(a *float64) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *float64 is not supported")
|
||||
test(t, func(a *float32) { shouldNotBeCalled() }, "func has unsupported parameter type: the data type of parameter 0 type *float32 is not supported")
|
||||
|
||||
// I cannot pass structures
|
||||
test(t, func(a godog.Table) error { return nil })
|
||||
test(t, func(a godog.DocString) error { return nil })
|
||||
test(t, func(a testStruct) error { return nil })
|
||||
test(t, func(a godog.Table) { shouldNotBeCalled() }, "func has unsupported parameter type: the struct parameter 0 type messages.PickleTable is not supported")
|
||||
test(t, func(a godog.DocString) { shouldNotBeCalled() }, "func has unsupported parameter type: the struct parameter 0 type messages.PickleDocString is not supported")
|
||||
test(t, func(a testStruct) { shouldNotBeCalled() }, "func has unsupported parameter type: the struct parameter 0 type models_test.testStruct is not supported")
|
||||
|
||||
// I cannot use maps
|
||||
test(t, func(a map[string]interface{}) error { return nil })
|
||||
test(t, func(a map[string]int) error { return nil })
|
||||
// // I cannot use maps
|
||||
test(t, func(a map[string]interface{ body() }) { shouldNotBeCalled() }, "func has unsupported parameter type: the parameter 0 type map is not supported")
|
||||
test(t, func(a map[string]int) { shouldNotBeCalled() }, "func has unsupported parameter type: the parameter 0 type map is not supported")
|
||||
|
||||
// Slice works only for byte
|
||||
test(t, func(a []int) error { return nil })
|
||||
test(t, func(a []string) error { return nil })
|
||||
test(t, func(a []bool) error { return nil })
|
||||
// // Slice works only for byte
|
||||
test(t, func(a []int) { shouldNotBeCalled() }, "func has unsupported parameter type: the slice parameter 0 type []int is not supported")
|
||||
test(t, func(a []string) { shouldNotBeCalled() }, "func has unsupported parameter type: the slice parameter 0 type []string is not supported")
|
||||
test(t, func(a []bool) { shouldNotBeCalled() }, "func has unsupported parameter type: the slice parameter 0 type []bool is not supported")
|
||||
|
||||
// I cannot use bool
|
||||
test(t, func(a bool) error { return nil })
|
||||
// // I cannot use bool
|
||||
test(t, func(a bool) { shouldNotBeCalled() }, "func has unsupported parameter type: the parameter 0 type bool is not supported")
|
||||
|
||||
}
|
||||
|
||||
func TestStepDefinition_Run_StringConversionToFunctionType(t *testing.T) {
|
||||
test := func(t *testing.T, fn interface{}, args []interface{}) {
|
||||
test := func(t *testing.T, fn interface{}, args []interface{}, expectedError string) {
|
||||
def := &models.StepDefinition{
|
||||
StepDefinition: formatters.StepDefinition{
|
||||
Handler: fn,
|
||||
|
@ -344,26 +559,30 @@ func TestStepDefinition_Run_StringConversionToFunctionType(t *testing.T) {
|
|||
if !errors.Is(err, models.ErrCannotConvert) {
|
||||
t.Fatalf("expected a cannot convert argument type error, but got '%v' instead", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedError, err.Error())
|
||||
}
|
||||
|
||||
shouldNotBeCalled := func() { assert.Fail(t, "shound not be called") }
|
||||
|
||||
// Lists some unsupported argument types for step handler.
|
||||
|
||||
// Cannot convert invalid int
|
||||
test(t, func(a int) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a int64) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a int32) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a int16) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a int8) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a int) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to int: strconv.ParseInt: parsing "a": invalid syntax`)
|
||||
test(t, func(a int64) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to int64: strconv.ParseInt: parsing "a": invalid syntax`)
|
||||
test(t, func(a int32) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to int32: strconv.ParseInt: parsing "a": invalid syntax`)
|
||||
test(t, func(a int16) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to int16: strconv.ParseInt: parsing "a": invalid syntax`)
|
||||
test(t, func(a int8) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to int8: strconv.ParseInt: parsing "a": invalid syntax`)
|
||||
|
||||
// Cannot convert invalid float
|
||||
test(t, func(a float32) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a float64) error { return nil }, []interface{}{"a"})
|
||||
test(t, func(a float32) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to float32: strconv.ParseFloat: parsing "a": invalid syntax`)
|
||||
test(t, func(a float64) { shouldNotBeCalled() }, []interface{}{"a"}, `cannot convert argument 0: "a" to float64: strconv.ParseFloat: parsing "a": invalid syntax`)
|
||||
|
||||
// Cannot convert to DataArg
|
||||
test(t, func(a *godog.Table) error { return nil }, []interface{}{"194"})
|
||||
test(t, func(a *godog.Table) { shouldNotBeCalled() }, []interface{}{"194"}, `cannot convert argument 0: "194" of type "string" to *messages.PickleTable`)
|
||||
|
||||
// Cannot convert to DocString ?
|
||||
test(t, func(a *godog.DocString) error { return nil }, []interface{}{"194"})
|
||||
test(t, func(a *godog.DocString) { shouldNotBeCalled() }, []interface{}{"194"}, `cannot convert argument 0: "194" of type "string" to *messages.PickleDocString`)
|
||||
|
||||
}
|
||||
|
||||
|
@ -381,11 +600,9 @@ type testStruct struct {
|
|||
}
|
||||
|
||||
func TestShouldSupportDocStringToStringConversion(t *testing.T) {
|
||||
fn := func(a string) error {
|
||||
if a != "hello" {
|
||||
return fmt.Errorf("did not get hello")
|
||||
}
|
||||
return nil
|
||||
var aActual string
|
||||
fn := func(a string) {
|
||||
aActual = a
|
||||
}
|
||||
|
||||
def := &models.StepDefinition{
|
||||
|
@ -398,7 +615,7 @@ func TestShouldSupportDocStringToStringConversion(t *testing.T) {
|
|||
}},
|
||||
}
|
||||
|
||||
if _, err := def.Run(context.Background()); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
_, err := def.Run(context.Background())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "hello", aActual)
|
||||
}
|
||||
|
|
Показаны не все изменённые файлы, т.к. их слишком много Показать больше
Загрузка…
Создание таблицы
Сослаться в новой задаче