* Recovery drone file

* Fix makefile

* Update Makefile

* Fix makefile

* Fix makefile

* Disable make lint on drone temprory

* Update github.com/franela/goblin

* update drone file

* go vendor mode

* go test can itterate itselve

* Update Makefile

Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
Lunny Xiao 2020-12-07 00:28:07 +08:00 коммит произвёл GitHub
Родитель 0fbd0a0684
Коммит ba36357970
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 597 добавлений и 303 удалений

Просмотреть файл

@ -1,149 +1,166 @@
---
kind: pipeline
name: default
platform:
os: linux
arch: amd64
workspace:
base: /srv/app
base: /go
path: src/github.com/go-gitea/lgtm
pipeline:
test:
image: webhippie/golang:edge
pull: true
steps:
- name: test
pull: always
image: golang:1.15
commands:
- make clean
- make vet
#- make lint
- make test
- make build
settings:
group: testing
environment:
GOPATH: /srv/app
CGO_ENABLED: "1"
commands:
- make clean
- make vet
- make lint
- make test
- make build
when:
event: [ push, tag, pull_request ]
environment:
GOPROXY: https://goproxy.cn # proxy.golang.org is blocked in China, this proxy is not
GOSUMDB: sum.golang.org
CGO_ENABLED: 1
when:
event:
- push
- tag
- pull_request
test-mysql:
image: webhippie/golang:edge
pull: true
- name: test-mysql
pull: always
image: golang:1.15
commands:
- make test-mysql
settings:
group: testing
commands:
- make test-mysql
when:
event: [ push ]
when:
event:
- push
test-pgsql:
image: webhippie/golang:edge
pull: true
- name: test-pgsql
pull: always
image: golang:1.15
commands:
- make test-pgsql
settings:
group: testing
commands:
- make test-pgsql
when:
event: [ push ]
when:
event:
- push
coverage:
image: plugins/codecov
name: ${DRONE_REPO}
secrets: [ codecov_token ]
when:
event: [ push, pull_request ]
- name: coverage
pull: default
image: plugins/codecov
environment:
CODECOV_TOKEN:
from_secret: codecov_token
when:
event:
- push
- pull_request
updater:
image: appleboy/golang-testing:1.9.2
pull: true
environment:
GOPATH: /srv/app
commands:
- make release
when:
event: [ tag ]
- name: updater
pull: always
image: appleboy/golang-testing:1.9.2
commands:
- make release
environment:
GOPATH: /srv/app
when:
branch:
- master
event:
- push
updater:
image: appleboy/golang-testing:1.9.2
pull: true
environment:
GOPATH: /srv/app
commands:
- make release
when:
event: [ push ]
branch: [ master ]
docker:
image: plugins/docker:17.05
pull: true
secrets: [ docker_username, docker_password ]
- name: docker
pull: always
image: plugins/docker:17.05
settings:
group: release
repo: gitea/lgtm
auto_tag: true
dockerfile: Dockerfile
when:
event: [ push, tag ]
environment:
DOCKER_PASSWORD:
from_secret: docker_password
DOCKER_USERNAME:
from_secret: docker_username
when:
branch:
- master
event:
- push
docker:
image: plugins/docker:17.05
pull: true
secrets: [ docker_username, docker_password ]
group: release
repo: gitea/lgtm
when:
event: [ push ]
branch: [ master ]
release:
image: plugins/s3:1
pull: true
group: release
secrets: [ aws_access_key_id, aws_secret_access_key ]
- name: release
pull: always
image: plugins/s3:1
settings:
bucket: releases
endpoint: https://storage.gitea.io
path_style: true
strip_prefix: dist/release/
source: dist/release/*
target: /lgtm/master
when:
event: [ push ]
branch: [ master ]
release:
image: plugins/s3:1
pull: true
group: release
secrets: [ aws_access_key_id, aws_secret_access_key ]
bucket: releases
endpoint: https://storage.gitea.io
path_style: true
source: "dist/release/*"
strip_prefix: dist/release/
source: dist/release/*
target: /lgtm/${DRONE_TAG##v}
when:
event: [ tag ]
target: "/lgtm/${DRONE_TAG##v}"
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
event:
- tag
github:
image: plugins/github-release:1
pull: true
group: release
secrets: [ github_token ]
- name: github
pull: always
image: plugins/github-release:1
settings:
files:
- dist/release/*
when:
event: [ tag ]
- "dist/release/*"
group: release
environment:
GITHUB_TOKEN:
from_secret: github_token
when:
event:
- tag
discord:
image: appleboy/drone-discord
secrets: [ discord_webhook_id, discord_webhook_token ]
when:
event: [ push, tag, pull_request ]
status: [ changed, failure ]
- name: discord
pull: default
image: appleboy/drone-discord
environment:
DISCORD_WEBHOOK_ID:
from_secret: discord_webhook_id
DISCORD_WEBHOOK_TOKEN:
from_secret: discord_webhook_token
when:
event:
- push
- tag
status:
- changed
- failure
services:
mysql:
image: mysql:5.7
environment:
- MYSQL_DATABASE=test
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
when:
event: [ push ]
- name: mysql
pull: default
image: mysql:5.7
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: test
when:
event:
- push
pgsql:
image: postgres:9.5
environment:
- POSTGRES_DB=test
when:
event: [ push ]
- name: pgsql
pull: default
image: postgres:9.5
environment:
POSTGRES_DB: test
when:
event:
- push

Просмотреть файл

@ -11,7 +11,7 @@ LDFLAGS += -X "github.com/go-gitea/lgtm/version.VersionDev=$(SHA)"
TARGETS ?= linux darwin windows
ARCHS ?= amd64 386
PACKAGES ?= $(shell go list ./... | grep -v /vendor/)
PACKAGES ?= $(shell go list -mod=vendor ./... | grep -v /vendor/)
ifneq ($(shell uname), Darwin)
EXTLDFLAGS = -extldflags "-static" $(null)
@ -58,15 +58,19 @@ vet:
go vet $(PACKAGES)
.PHONY: lint
lint:
@which golint > /dev/null; if [ $$? -ne 0 ]; then \
go get -u github.com/golang/lint/golint; \
lint: golangci-lint
.PHONY: golangci-lint
golangci-lint:
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
export BINARY="golangci-lint"; \
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.31.0; \
fi
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
golangci-lint run --timeout 5m
.PHONY: test
test:
for PKG in $(PACKAGES); do go test -cover -coverprofile $$GOPATH/src/$$PKG/coverage.out $$PKG || exit 1; done;
go test -mod=vendor -cover -coverprofile coverage.out $(PACKAGES) || exit 1
.PHONY: check
check: test
@ -87,7 +91,7 @@ install: $(SOURCES)
build: $(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(SOURCES)
go build -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
go build -mod=vendor -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
release: release-dirs release-build release-copy release-check

2
go.mod
Просмотреть файл

@ -7,7 +7,7 @@ require (
github.com/Sirupsen/logrus v0.6.7-0.20150309155839-2cea0f0d141f
github.com/dgrijalva/jwt-go v2.2.1-0.20150401180636-c48cfd5d9711+incompatible
github.com/elazarl/go-bindata-assetfs v0.0.0-20150414184409-bea323321994
github.com/franela/goblin v0.0.0-20150112000940-2042c4d610d2
github.com/franela/goblin v0.0.0-20201006155558-6240afcb2eb7
github.com/gin-gonic/contrib v0.0.0-20150815172543-14f66d54cdb9
github.com/gin-gonic/gin v0.0.0-20160414233928-5caaac4c5c71
github.com/go-sql-driver/mysql v1.2.1-0.20151112163355-d512f204a577

2
go.sum
Просмотреть файл

@ -8,6 +8,8 @@ github.com/elazarl/go-bindata-assetfs v0.0.0-20150414184409-bea323321994 h1:6Ygv
github.com/elazarl/go-bindata-assetfs v0.0.0-20150414184409-bea323321994/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/franela/goblin v0.0.0-20150112000940-2042c4d610d2 h1:PcbwRGOqYeTQw76GRthRaxNGII82C/kx46ll3aNqDMQ=
github.com/franela/goblin v0.0.0-20150112000940-2042c4d610d2/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goblin v0.0.0-20201006155558-6240afcb2eb7 h1:eUae9KtuHjNg5e7DYkn57S/M/ndIICmV1bWs9ejYCx4=
github.com/franela/goblin v0.0.0-20201006155558-6240afcb2eb7/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo=
github.com/gin-gonic/contrib v0.0.0-20150815172543-14f66d54cdb9 h1:gISPkiYdlRqAEbns25dOAoT/w5dxhI4ACWUYfTr3dFQ=
github.com/gin-gonic/contrib v0.0.0-20150815172543-14f66d54cdb9/go.mod h1:iqneQ2Df3omzIVTkIfn7c1acsVnMGiSLn4XF5Blh3Yg=
github.com/gin-gonic/gin v0.0.0-20160414233928-5caaac4c5c71 h1:ML+SQEYkMC4dDaXPRUyIOI0mbbXBdIvquVspxzzJ54E=

8
vendor/github.com/franela/goblin/.travis.yml сгенерированный поставляемый
Просмотреть файл

@ -1,8 +0,0 @@
language: go
go:
- 1.1.2
- tip
notifications:
email:
- ionathan@gmail.com
- marcosnils@gmail.com

53
vendor/github.com/franela/goblin/README.md сгенерированный поставляемый
Просмотреть файл

@ -1,23 +1,22 @@
[![Build Status](https://travis-ci.org/franela/goblin.png?branch=master)](https://travis-ci.org/franela/goblin)
Goblin
======
[![Build Status](https://travis-ci.org/franela/goblin.svg)](https://travis-ci.org/franela/goblin)
[![Go Reportcard](https://goreportcard.com/badge/github.com/franela/goblin)](https://goreportcard.com/report/github.com/franela/goblin)
[![GoDoc](https://godoc.org/github.com/franela/goblin?status.svg)](https://godoc.org/github.com/franela/goblin)
[![License](https://img.shields.io/github/license/franela/goblin.svg)](https://github.com/franela/goblin/blob/master/LICENSE.md)
[![Release](https://img.shields.io/github/release/franela/goblin.svg)](https://github.com/franela/goblin/releases/latest)
A [Mocha](http://mochajs.org/) like BDD testing framework written in Go that requires no additional dependencies. Requires no extensive documentation nor complicated steps to get it running.
![](https://github.com/marcosnils/goblin/blob/master/goblin_logo.jpg?raw=true)
A [Mocha](http://visionmedia.github.io/mocha/) like BDD testing framework for Go
No extensive documentation nor complicated steps to get it running
Run tests as usual with `go test`
Colorful reports and beautiful syntax
Why Goblin?
-----------
Inspired by the flexibility and simplicity of Node BDD and frustrated by the
rigorousness of Go way of testing, we wanted to bring a new tool to
rigorousness of Go way of testing, we wanted to bring a new tool to
write self-describing and comprehensive code.
@ -25,12 +24,15 @@ write self-describing and comprehensive code.
What do I get with it?
----------------------
- Run tests as usual with `go test`
- Colorful reports and beautiful syntax
- Preserve the exact same syntax and behaviour as Node's Mocha
- Nest as many `Describe` and `It` blocks as you want
- Use `Before`, `BeforeEach`, `After` and `AfterEach` for setup and teardown your tests
- No need to remember confusing parameters in `Describe` and `It` blocks
- Use a declarative and expressive language to write your tests
- Plug different assertion libraries ([Gomega](https://github.com/onsi/gomega) supported so far)
- Plug different assertion libraries
- [Gomega](https://github.com/onsi/gomega) (supported so far)
- Skip your tests the same way as you would do in Mocha
- Automatic terminal support for colored outputs
- Two line setup is all you need to get up running
@ -54,13 +56,20 @@ import (
func Test(t *testing.T) {
g := Goblin(t)
g.Describe("Numbers", func() {
// Passing Test
g.It("Should add two numbers ", func() {
g.Assert(1+1).Equal(2)
})
// Failing Test
g.It("Should match equal numbers", func() {
g.Assert(2).Equal(4)
})
// Pending Test
g.It("Should substract two numbers")
// Excluded Test
g.Xit("Should add two numbers ", func() {
g.Assert(3+1).Equal(4)
})
})
}
```
@ -102,12 +111,12 @@ package foobar
import (
"testing"
. "github.com/franela/goblin"
goblin "github.com/franela/goblin"
. "github.com/onsi/gomega"
)
func Test(t *testing.T) {
g := Goblin(t)
g := goblin.Goblin(t)
//special hook for gomega
RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })
@ -120,13 +129,21 @@ func Test(t *testing.T) {
}
```
TODO:
FAQ
----
### How do I run specific tests?
If `-goblin.run=$REGES` is supplied to the `go test` command then only tests that match the supplied regex will run
Contributing
-----
We do have a couple of [issues](https://github.com/franela/goblin/issues) pending we'll be addressing soon. But feel free to
contribute and send us PRs (with tests please :smile:).
We do have a couple of [issues](https://github.com/franela/goblin/issues) pending. Feel free to contribute and send us PRs (with tests please :smile:).
Contributions:
Special Thanks
------------
Special thanks to [Leandro Reox](https://github.com/leandroreox) (Leitan) for the goblin logo.

103
vendor/github.com/franela/goblin/assertions.go сгенерированный поставляемый
Просмотреть файл

@ -6,6 +6,8 @@ import (
"strings"
)
// Assertion represents a fact stated about a source object. It contains the
// source object and function to call
type Assertion struct {
src interface{}
fail func(interface{})
@ -27,33 +29,108 @@ func objectsAreEqual(a, b interface{}) bool {
return false
}
func formatMessages(messages ...string) string {
if len(messages) > 0 {
return ", " + strings.Join(messages, " ")
// Format series of messages provided to an assertion. Separate messages from
// the preamble of assertion with a comma and concatenate messages using spaces.
// Messages that are purely whitespace will be wrapped with square brackets, so
// the developer can glean that something was actually reported in a message.
func formatMessages(messages ...interface{}) string {
// Concatenate messages together.
var fm strings.Builder
for _, message := range messages {
fm.WriteString(" ")
// Format message then wrap with square brackets if only
// whitespace.
m := fmt.Sprintf("%v", message)
if strings.TrimSpace(m) == "" {
m = fmt.Sprintf("[%s]", m)
}
fm.WriteString(m)
}
return ""
if fm.Len() == 0 {
return ""
}
return "," + fm.String()
}
func (a *Assertion) Eql(dst interface{}) {
a.Equal(dst)
// Eql is a shorthand alias of Equal for convenience
func (a *Assertion) Eql(dst interface{}, messages ...interface{}) {
a.Equal(dst, messages)
}
func (a *Assertion) Equal(dst interface{}) {
// Equal takes a destination object and asserts that a source object and
// destination object are equal to one another. It will fail the assertion and
// print a corresponding message if the objects are not equivalent.
func (a *Assertion) Equal(dst interface{}, messages ...interface{}) {
if !objectsAreEqual(a.src, dst) {
a.fail(fmt.Sprintf("%v %s %v", a.src, "does not equal", dst))
a.fail(fmt.Sprintf("%#v %s %#v%s", a.src, "does not equal", dst,
formatMessages(messages...)))
}
}
func (a *Assertion) IsTrue(messages ...string) {
// IsTrue asserts that a source is equal to true. Optional messages can be
// provided for inclusion in the displayed message if the assertion fails. It
// will fail the assertion if the source does not resolve to true.
func (a *Assertion) IsTrue(messages ...interface{}) {
if !objectsAreEqual(a.src, true) {
message := fmt.Sprintf("%v %s%s", a.src, "expected false to be truthy", formatMessages(messages...))
a.fail(fmt.Sprintf("%v %s%s", a.src,
"expected false to be truthy",
formatMessages(messages...)))
}
}
// IsFalse asserts that a source is equal to false. Optional messages can be
// provided for inclusion in the displayed message if the assertion fails. It
// will fail the assertion if the source does not resolve to false.
func (a *Assertion) IsFalse(messages ...interface{}) {
if !objectsAreEqual(a.src, false) {
a.fail(fmt.Sprintf("%v %s%s", a.src,
"expected true to be falsey",
formatMessages(messages...)))
}
}
// IsNil asserts that source is nil.
func (a *Assertion) IsNil(messages ...interface{}) {
if !objectsAreEqual(a.src, nil) {
message := fmt.Sprintf("%v %s%v", a.src, "expected to be nil", formatMessages(messages...))
a.fail(message)
}
}
func (a *Assertion) IsFalse(messages ...string) {
if !objectsAreEqual(a.src, false) {
message := fmt.Sprintf("%v %s%s", a.src, "expected true to be falsey", formatMessages(messages...))
// IsNotNil asserts that source is not nil.
func (a *Assertion) IsNotNil(messages ...interface{}) {
if objectsAreEqual(a.src, nil) {
message := fmt.Sprintf("%v %s%v", a.src, "is nil", formatMessages(messages...))
a.fail(message)
}
}
// IsZero asserts that source is a zero value for its respective type.
// If it is a structure, for example, all of its fields must have their
// respective zero value: "" for strings, 0 for int, etc. Slices, arrays
// and maps are only considered zero if they are nil. To check if these
// type of values are empty or not, use the len() from the data source
// with IsZero(). Example: g.Assert(len(list)).IsZero().
func (a *Assertion) IsZero(messages ...interface{}) {
valueOf := reflect.ValueOf(a.src)
if !valueOf.IsZero() {
message := fmt.Sprintf("%#v %s%v", a.src, "is not a zero value", formatMessages(messages...))
a.fail(message)
}
}
// IsNotZero asserts the contrary of IsZero.
func (a *Assertion) IsNotZero(messages ...interface{}) {
valueOf := reflect.ValueOf(a.src)
if valueOf.IsZero() {
message := fmt.Sprintf("%#v %s%v", a.src, "is a zero value", formatMessages(messages...))
a.fail(message)
}
}

3
vendor/github.com/franela/goblin/go.mod сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
module github.com/franela/goblin
go 1.14

36
vendor/github.com/franela/goblin/go.snippets сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
snippet gd
g.Describe("${1:name}", func() {
${2}
})
${0}
snippet git
g.It("${1:name}", func() {
${2}
})
${0}
snippet gait
g.It("${1:name}", func(done Done) {
done()
${2}
})
${0}
snippet gb
g.Before(func() {
${1}
})
${0}
snippet gbe
g.BeforeEach(func() {
${1}
})
${0}
snippet ga
g.After(func() {
${1}
})
${0}
snippet gae
g.AfterEach(func() {
${1}
})
${0}

331
vendor/github.com/franela/goblin/goblin.go сгенерированный поставляемый
Просмотреть файл

@ -3,7 +3,9 @@ package goblin
import (
"flag"
"fmt"
"regexp"
"runtime"
"sync"
"testing"
"time"
)
@ -14,6 +16,11 @@ type Runnable interface {
run(*G) bool
}
type Itable interface {
run(*G) bool
failed(string, []string)
}
func (g *G) Describe(name string, h func()) {
d := &Describe{name: name, h: h, parent: g.parent}
@ -27,25 +34,31 @@ func (g *G) Describe(name string, h func()) {
g.parent = d.parent
if g.parent == nil {
g.reporter.begin()
if g.parent == nil && d.hasTests {
g.reporter.Begin()
if d.run(g) {
g.t.Fail()
}
g.reporter.end()
g.reporter.End()
}
}
func (g *G) Timeout(time time.Duration) {
g.timeout = time
g.timer.Reset(time)
}
type Describe struct {
name string
h func()
children []Runnable
befores []func()
afters []func()
afterEach []func()
beforeEach []func()
hasTests bool
parent *Describe
name string
h func()
children []Runnable
befores []func()
afters []func()
afterEach []func()
beforeEach []func()
justBeforeEach []func()
hasTests bool
parent *Describe
}
func (d *Describe) runBeforeEach() {
@ -58,52 +71,101 @@ func (d *Describe) runBeforeEach() {
}
}
func (d *Describe) runAfterEach() {
func (d *Describe) runJustBeforeEach() {
if d.parent != nil {
d.parent.runAfterEach()
d.parent.runJustBeforeEach()
}
for _, b := range d.justBeforeEach {
b()
}
}
func (d *Describe) runAfterEach() {
for _, a := range d.afterEach {
a()
}
if d.parent != nil {
d.parent.runAfterEach()
}
}
func (d *Describe) run(g *G) bool {
g.reporter.beginDescribe(d.name)
failed := ""
failed := false
if d.hasTests {
g.reporter.BeginDescribe(d.name)
for _, b := range d.befores {
b()
}
}
for _, r := range d.children {
if r.run(g) {
failed = "true"
for _, r := range d.children {
if r.run(g) {
failed = true
}
}
}
if d.hasTests {
for _, a := range d.afters {
a()
}
g.reporter.EndDescribe()
}
g.reporter.endDescribe()
return failed != ""
return failed
}
type Failure struct {
stack []string
testName string
message string
Stack []string
TestName string
Message string
}
type It struct {
h interface{}
name string
parent *Describe
failure *Failure
failureMu sync.RWMutex
reporter Reporter
isAsync bool
}
func (it *It) run(g *G) bool {
g.currentIt = it
if it.h == nil {
g.reporter.ItIsPending(it.name)
return false
}
runIt(g, it)
failed := false
it.failureMu.RLock()
if it.failure != nil {
failed = true
}
it.failureMu.RUnlock()
if failed {
g.reporter.ItFailed(it.name)
g.reporter.Failure(it.failure)
} else {
g.reporter.ItPassed(it.name)
}
return failed
}
func (it *It) failed(msg string, stack []string) {
it.failureMu.Lock()
defer it.failureMu.Unlock()
it.failure = &Failure{Stack: stack, Message: msg, TestName: it.parent.name + " " + it.name}
}
type Xit struct {
h interface{}
name string
parent *Describe
@ -112,57 +174,35 @@ type It struct {
isAsync bool
}
func (it *It) run(g *G) bool {
g.currentIt = it
func (xit *Xit) run(g *G) bool {
g.currentIt = xit
if it.h == nil {
g.reporter.itIsPending(it.name)
return false
}
//TODO: should handle errors for beforeEach
it.parent.runBeforeEach()
runIt(g, it.h)
it.parent.runAfterEach()
failed := false
if it.failure != nil {
failed = true
}
if failed {
g.reporter.itFailed(it.name)
g.reporter.failure(it.failure)
} else {
g.reporter.itPassed(it.name)
}
return failed
g.reporter.ItIsExcluded(xit.name)
return false
}
func (it *It) failed(msg string, stack []string) {
it.failure = &Failure{stack: stack, message: msg, testName: it.parent.name + " " + it.name}
func (xit *Xit) failed(msg string, stack []string) {
xit.failure = nil
}
var timeout *time.Duration
var isTty *bool
func init() {
func parseFlags() {
//Flag parsing
timeout = flag.Duration("goblin.timeout", 5*time.Second, "Sets default timeouts for all tests")
isTty = flag.Bool("goblin.tty", true, "Sets the default output format (color / monochrome)")
flag.Parse()
if *regexParam != "" {
runRegex = regexp.MustCompile(*regexParam)
} else {
runRegex = nil
}
}
var timeout = flag.Duration("goblin.timeout", 5*time.Second, "Sets default timeouts for all tests")
var isTty = flag.Bool("goblin.tty", true, "Sets the default output format (color / monochrome)")
var regexParam = flag.String("goblin.run", "", "Runs only tests which match the supplied regex")
var runRegex *regexp.Regexp
func Goblin(t *testing.T, arguments ...string) *G {
var gobtimeout = timeout
if arguments != nil {
//Programatic flags
var args = flag.NewFlagSet("Goblin arguments", flag.ContinueOnError)
gobtimeout = args.Duration("goblin.timeout", 5*time.Second, "Sets timeouts for tests")
args.Parse(arguments)
}
g := &G{t: t, timeout: *gobtimeout}
parseFlags()
g := &G{t: t, timeout: *timeout}
var fancy TextFancier
if *isTty {
fancy = &TerminalFancier{}
@ -174,50 +214,66 @@ func Goblin(t *testing.T, arguments ...string) *G {
return g
}
func runIt(g *G, h interface{}) {
defer timeTrack(time.Now(), g)
func runIt(g *G, it *It) {
g.mutex.Lock()
g.timedOut = false
g.mutex.Unlock()
g.timer = time.NewTimer(g.timeout)
g.shouldContinue = make(chan bool)
if call, ok := h.(func()); ok {
if call, ok := it.h.(func()); ok {
// the test is synchronous
go func() { call(); g.shouldContinue <- true }()
} else if call, ok := h.(func(Done)); ok {
go func(c chan bool) {
it.parent.runBeforeEach()
it.parent.runJustBeforeEach()
timeTrack(g, func() { call() })
it.parent.runAfterEach()
c <- true
}(g.shouldContinue)
} else if call, ok := it.h.(func(Done)); ok {
doneCalled := 0
go func() {
call(func(msg ...interface{}) {
if len(msg) > 0 {
g.Fail(msg)
} else {
doneCalled++
if doneCalled > 1 {
g.Fail("Done called multiple times")
go func(c chan bool) {
it.parent.runBeforeEach()
it.parent.runJustBeforeEach()
timeTrack(g, func() {
call(func(msg ...interface{}) {
if len(msg) > 0 {
g.Fail(msg)
} else {
doneCalled++
if doneCalled > 1 {
g.Fail("Done called multiple times")
}
it.parent.runAfterEach()
c <- true
}
g.shouldContinue <- true
}
})
})
}()
}(g.shouldContinue)
} else {
panic("Not implemented.")
}
select {
case <-g.shouldContinue:
case <-time.After(g.timeout):
fmt.Println("Timedout")
case <-g.timer.C:
//Set to nil as it shouldn't continue
g.shouldContinue = nil
g.timedOut = true
g.Fail("Test exceeded " + fmt.Sprintf("%s", g.timeout))
}
// Reset timeout value
g.timeout = *timeout
}
type G struct {
t *testing.T
parent *Describe
currentIt *It
currentIt Itable
timeout time.Duration
reporter Reporter
timedOut bool
shouldContinue chan bool
mutex sync.Mutex
timer *time.Timer
}
func (g *G) SetReporter(r Reporter) {
@ -225,12 +281,35 @@ func (g *G) SetReporter(r Reporter) {
}
func (g *G) It(name string, h ...interface{}) {
it := &It{name: name, parent: g.parent, reporter: g.reporter}
notifyParents(g.parent)
if len(h) > 0 {
it.h = h[0]
if matchesRegex(name) {
it := &It{name: name, parent: g.parent, reporter: g.reporter}
if g.parent == nil {
panic(fmt.Sprintf("It(\"%s\") block should be written inside Describe() block.", name))
}
notifyParents(g.parent)
if len(h) > 0 {
it.h = h[0]
}
g.parent.children = append(g.parent.children, Runnable(it))
}
g.parent.children = append(g.parent.children, Runnable(it))
}
func (g *G) Xit(name string, h ...interface{}) {
if matchesRegex(name) {
xit := &Xit{name: name, parent: g.parent, reporter: g.reporter}
notifyParents(g.parent)
if len(h) > 0 {
xit.h = h[0]
}
g.parent.children = append(g.parent.children, Runnable(xit))
}
}
func matchesRegex(value string) bool {
if runRegex != nil {
return runRegex.MatchString(value)
}
return true
}
func notifyParents(d *Describe) {
@ -248,6 +327,10 @@ func (g *G) BeforeEach(h func()) {
g.parent.beforeEach = append(g.parent.beforeEach, h)
}
func (g *G) JustBeforeEach(h func()) {
g.parent.justBeforeEach = append(g.parent.justBeforeEach, h)
}
func (g *G) After(h func()) {
g.parent.afters = append(g.parent.afters, h)
}
@ -260,21 +343,57 @@ func (g *G) Assert(src interface{}) *Assertion {
return &Assertion{src: src, fail: g.Fail}
}
func timeTrack(start time.Time, g *G) {
g.reporter.itTook(time.Since(start))
func timeTrack(g *G, call func()) {
t := time.Now()
defer func() {
g.reporter.ItTook(time.Since(t))
}()
call()
}
func (g *G) Fail(error interface{}) {
//Skips 7 stacks due to the functions between the stack and the test
stack := ResolveStack(4)
message := fmt.Sprintf("%v", error)
g.currentIt.failed(message, stack)
func (g *G) errorCommon(msg string, fatal bool) {
if g.currentIt == nil {
panic("Asserts should be written inside an It() block.")
}
g.currentIt.failed(msg, ResolveStack(9))
if g.shouldContinue != nil {
g.shouldContinue <- true
}
if !g.timedOut {
//Stop test function execution
runtime.Goexit()
if fatal {
g.mutex.Lock()
defer g.mutex.Unlock()
if !g.timedOut {
//Stop test function execution
runtime.Goexit()
}
}
}
func (g *G) Fail(error interface{}) {
message := fmt.Sprintf("%v", error)
g.errorCommon(message, true)
}
func (g *G) FailNow() {
g.t.FailNow()
}
func (g *G) Failf(format string, args ...interface{}) {
message := fmt.Sprintf(format, args...)
g.errorCommon(message, true)
}
func (g *G) Fatalf(format string, args ...interface{}) {
message := fmt.Sprintf(format, args...)
g.errorCommon(message, true)
}
func (g *G) Errorf(format string, args ...interface{}) {
message := fmt.Sprintf(format, args...)
g.errorCommon(message, false)
}
func (g *G) Helper() {
g.t.Helper()
}

Двоичные данные
vendor/github.com/franela/goblin/goblin_output.png сгенерированный поставляемый

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 18 KiB

После

Ширина:  |  Высота:  |  Размер: 48 KiB

4
vendor/github.com/franela/goblin/mono_reporter.go сгенерированный поставляемый
Просмотреть файл

@ -24,3 +24,7 @@ func (self *Monochrome) WithCheck(text string) string {
func (self *Monochrome) Green(text string) string {
return text
}
func (self *Monochrome) Yellow(text string) string {
return text
}

73
vendor/github.com/franela/goblin/reporting.go сгенерированный поставляемый
Просмотреть файл

@ -4,19 +4,21 @@ import (
"fmt"
"strconv"
"strings"
"sync"
"time"
)
type Reporter interface {
beginDescribe(string)
endDescribe()
begin()
end()
failure(*Failure)
itTook(time.Duration)
itFailed(string)
itPassed(string)
itIsPending(string)
BeginDescribe(string)
EndDescribe()
Begin()
End()
Failure(*Failure)
ItTook(time.Duration)
ItFailed(string)
ItPassed(string)
ItIsPending(string)
ItIsExcluded(string)
}
type TextFancier interface {
@ -24,14 +26,16 @@ type TextFancier interface {
Gray(text string) string
Cyan(text string) string
Green(text string) string
Yellow(text string) string
WithCheck(text string) string
}
type DetailedReporter struct {
level, failed, passed, pending int
failures []*Failure
executionTime, totalExecutionTime time.Duration
fancy TextFancier
level, failed, passed, pending, excluded int
failures []*Failure
executionTime, totalExecutionTime time.Duration
executionTimeMu sync.RWMutex
fancy TextFancier
}
func (r *DetailedReporter) SetTextFancier(f TextFancier) {
@ -57,6 +61,10 @@ func (self *TerminalFancier) Green(text string) string {
return "\033[32m" + text + "\033[0m"
}
func (self *TerminalFancier) Yellow(text string) string {
return "\033[33m" + text + "\033[0m"
}
func (self *TerminalFancier) WithCheck(text string) string {
return "\033[32m\u2713\033[0m " + text
}
@ -65,7 +73,7 @@ func (r *DetailedReporter) getSpace() string {
return strings.Repeat(" ", (r.level+1)*2)
}
func (r *DetailedReporter) failure(failure *Failure) {
func (r *DetailedReporter) Failure(failure *Failure) {
r.failures = append(r.failures, failure)
}
@ -77,42 +85,52 @@ func (r *DetailedReporter) printWithCheck(text string) {
fmt.Printf("%v%v\n", r.getSpace(), r.fancy.WithCheck(text))
}
func (r *DetailedReporter) beginDescribe(name string) {
func (r *DetailedReporter) BeginDescribe(name string) {
fmt.Println("")
r.print(name)
r.level++
}
func (r *DetailedReporter) endDescribe() {
func (r *DetailedReporter) EndDescribe() {
r.level--
}
func (r *DetailedReporter) itTook(duration time.Duration) {
func (r *DetailedReporter) ItTook(duration time.Duration) {
r.executionTimeMu.Lock()
defer r.executionTimeMu.Unlock()
r.executionTime = duration
r.totalExecutionTime += duration
}
func (r *DetailedReporter) itFailed(name string) {
func (r *DetailedReporter) ItFailed(name string) {
r.failed++
r.print(r.fancy.Red(strconv.Itoa(r.failed) + ") " + name))
}
func (r *DetailedReporter) itPassed(name string) {
func (r *DetailedReporter) ItPassed(name string) {
r.passed++
r.printWithCheck(r.fancy.Gray(name))
}
func (r *DetailedReporter) itIsPending(name string) {
func (r *DetailedReporter) ItIsPending(name string) {
r.pending++
r.print(r.fancy.Cyan("- " + name))
}
func (r *DetailedReporter) begin() {
func (r *DetailedReporter) ItIsExcluded(name string) {
r.excluded++
r.print(r.fancy.Yellow("- " + name))
}
func (r *DetailedReporter) end() {
func (r *DetailedReporter) Begin() {
}
func (r *DetailedReporter) End() {
comp := fmt.Sprintf("%d tests complete", r.passed)
r.executionTimeMu.RLock()
t := fmt.Sprintf("(%d ms)", r.totalExecutionTime/time.Millisecond)
r.executionTimeMu.RUnlock()
//fmt.Printf("\n\n \033[32m%d tests complete\033[0m \033[90m(%d ms)\033[0m\n", r.passed, r.totalExecutionTime/time.Millisecond)
fmt.Printf("\n\n %v %v\n", r.fancy.Green(comp), r.fancy.Gray(t))
@ -122,15 +140,20 @@ func (r *DetailedReporter) end() {
fmt.Printf(" %v\n\n", r.fancy.Cyan(pend))
}
if r.excluded > 0 {
excl := fmt.Sprintf("%d test(s) excluded", r.excluded)
fmt.Printf(" %v\n\n", r.fancy.Yellow(excl))
}
if len(r.failures) > 0 {
fmt.Printf("%s \n\n", r.fancy.Red(fmt.Sprintf(" %d tests failed:", len(r.failures))))
}
for i, failure := range r.failures {
fmt.Printf(" %d) %s:\n\n", i+1, failure.testName)
fmt.Printf(" %s\n", r.fancy.Red(failure.message))
for _, stackItem := range failure.stack {
fmt.Printf(" %d) %s:\n\n", i+1, failure.TestName)
fmt.Printf(" %s\n", r.fancy.Red(failure.Message))
for _, stackItem := range failure.Stack {
fmt.Printf(" %s\n", r.fancy.Gray(stackItem))
}
}

2
vendor/modules.txt поставляемый
Просмотреть файл

@ -10,7 +10,7 @@ github.com/dgrijalva/jwt-go
# github.com/elazarl/go-bindata-assetfs v0.0.0-20150414184409-bea323321994
## explicit
github.com/elazarl/go-bindata-assetfs
# github.com/franela/goblin v0.0.0-20150112000940-2042c4d610d2
# github.com/franela/goblin v0.0.0-20201006155558-6240afcb2eb7
## explicit
github.com/franela/goblin
# github.com/gin-gonic/contrib v0.0.0-20150815172543-14f66d54cdb9